|
|
View previous topic :: View next topic |
Author |
Message |
Marcos Guest
|
Read PIN 16F628 i still have doubts |
Posted: Sun Sep 24, 2006 6:39 pm |
|
|
In my Code i have doubts with:
1 - Is ok My read PIN?I used setup_comparator(RA0_RA1_RA2_RA3_);. I need onli read righ or low.
2 - will be infinite My loop While(1)?i uded kbhit();
I need finish this project tomorrow , but i never did work with PIC16F628, so, i `m have surpises with it.
Code: | #include <16F628A.h>
#fuses INTRC_IO,NOWDT,PUT,BROWNOUT,NOLVP,NOMCLR
#include "usart.h"
#use delay (clock=4000000)
#use rs232(baud=9600,xmit=PIN_B2,rcv=PIN_B1)
SET_TRIS_A( 0xFF ); // 11111111
SET_TRIS_B( 0x0E ); // 00000010
setup_comparator(RA0_RA1_RA2_RA3_);
unsigned char lerDip();
void main(void)
{
unsigned char saida;
unsigned char dados;
unsigned char aux = 0x00;
unsigned char mascara_a = 0xF0;// 11110000
unsigned char entra;
unsigned char conf_dip;
int1 fotodiodo;
unsigned char endereco;
while(1)
{
conf_dip = lerDip();
aux = (conf_dip | mascara_a);
entra = 0x00;
entra = kbhit();
if(entra);
{
dados = getc();
}
if (dados == aux)
{
fotodiodo = 0;
fotodiodo = input(PIN_A0);
}
if (fotodiodo)
{
saida = 0xFF;// 11111111
printf("%c",saida);
}
else
{ saida = 0x00; // 00000000
printf("%c",saida);
}
}
}
unsigned char lerDip()
{
int8 a1;
int8 a2;
int8 a3;
int8 res;
res = 0x00;
res |= a1;
if (a1)
res |= (a2 << 1);
if (a2)
res |= (a3 << 2);
if (a3)
return res;
} |
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
Re: Read PIN 16F628 i still have doubts |
Posted: Mon Sep 25, 2006 2:35 am |
|
|
First of all, don't start a new thread when you are still dealing with the same problem.
Marcos wrote: | 1 - Is ok My read PIN?I used setup_comparator(RA0_RA1_RA2_RA3_);. I need onli read righ or low. | This is not going to work:
- In order to have this function called you will have to place it somewhere in your program flow, i.e. within a function! Now it is just a function declaration and will never be executed.
- How did you make up the constant RA0_RA1_RA2_RA3_ ? It does not exist in the header file 16F628A.h and makes no sense at all. In your other thread you were told to disable the comparator by using the constant NC_NC_NC_NC.
Quote: |
2 - will be infinite My loop While(1)?i uded kbhit(); | I'm not sure what you want to ask here. If you want to know if your program will loop forever, then the answer is yes.
Quote: | I need finish this project tomorrow , but i never did work with PIC16F628, so, i `m have surpises with it. | Also I'm suspecting this is one of your first C programs...
Code: | #include <16F628A.h>
#fuses INTRC_IO,NOWDT,PUT,BROWNOUT,NOLVP,NOMCLR
#include "usart.h" <-- Do you need this include file? I don't know it
and it doesn't look like you are using non-standard functions.
#use delay (clock=4000000)
#use rs232(baud=9600,xmit=PIN_B2,rcv=PIN_B1) <-- Add ERRORS directive to avoid problems with a locked UART
SET_TRIS_A( 0xFF ); // 11111111 <-- You only need to set TRIS when using #use FAST_IO or FIXED_IO
SET_TRIS_B( 0x0E ); // 00000010 <-- 0x0E != 00000010
setup_comparator(RA0_RA1_RA2_RA3_); <-- Move this line into main() and set parameter to NC_NC_NC_NC
unsigned char lerDip();
void main(void)
{
unsigned char saida;
unsigned char dados;
unsigned char aux = 0x00;
unsigned char mascara_a = 0xF0;// 11110000
unsigned char entra;
unsigned char conf_dip;
int1 fotodiodo;
unsigned char endereco;
while(1)
{
conf_dip = lerDip();
aux = (conf_dip | mascara_a);
entra = 0x00; <-- You don't need this line
entra = kbhit();
if(entra);
{
dados = getc();
}
if (dados == aux)
{
fotodiodo = 0; <-- You don't need this line
fotodiodo = input(PIN_A0);
}
if (fotodiodo)
{
saida = 0xFF;// 11111111
printf("%c",saida);
}
else
{ saida = 0x00; // 00000000
printf("%c",saida); <-- You realize 0x00 is a non-printable ASCII character ? (will not show in Hyperterm).
}
}
}
unsigned char lerDip() <-- This whole function makes no sense at all.....
{ Did you post with 'Disable HTML in this post' marked?
int8 a1;
int8 a2;
int8 a3;
int8 res;
res = 0x00;
res |= a1;
if (a1)
res |= (a2 << 1);
if (a2)
res |= (a3 << 2);
if (a3)
return res;
} |
|
|
|
Marcos Guest
|
|
Posted: Mon Sep 25, 2006 6:00 am |
|
|
Hi!!! Thanks for the informations.
Code: | folow my program correct:
#include <16F628A.h>
#fuses INTRC_IO,NOWDT,PUT,BROWNOUT,NOLVP,NOMCLR
#include "usart.h"
#use delay (clock=4000000)
#use rs232(baud=9600,xmit=PIN_B2,rcv=PIN_B1)
setup_comparator(NC_NC_NC_NC
unsigned char lerDip();
void main(void)
{
unsigned char saida;
unsigned char dados;
unsigned char aux = 0x00;
unsigned char mascara_a = 0xF0;// 11110000
unsigned char entra;
unsigned char conf_dip;
int1 fotodiodo;
while(1)
{
conf_dip = lerDip();
aux = (conf_dip | mascara_a);
entra = kbhit();
if(entra);
{
dados = getc();
}
if (dados == aux)
{
fotodiodo = input(PIN_A0);
}
if (fotodiodo)
{
saida = 0xFF;// 11111111
printf("%c",saida);
}
else
{ saida = 0x00; // 00000000
printf("%c",saida); // i need that this printf will go to other PIC.
}
}
}
unsigned char lerDip() // [color=red]i call this function because i need to read pin a1,a2,a3. this 3 bits will return me a address 000 to 111. This address
depends tha read is high or low. For example:pi_1 = high
pin_2 = low - pin_3 = high. i return in variable res [b]101[/b].[/color]
int8 a1;
int8 a2;
int8 a3;
int8 res;
res = 0x00;
res |= a1;
res |= (a2 << 1);
res |= (a3 << 2);
return res;
}
|
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Sep 25, 2006 7:03 am |
|
|
Your program looks better, but it still doesn't work, does it.....?
You didn't incorporate all my suggestions. I get the feeling I'm doing your homework, and you are not even paying attention !
Get rid of the line
Change Code: | #use rs232(baud=9600,xmit=PIN_B2,rcv=PIN_B1)
| to Code: | #use rs232(baud=9600,xmit=PIN_B2,rcv=PIN_B1, ERRORS)
| This causes the compiler to clear an error-flag in the UART on buffer overruns, otherwise the UART might stall and you stop receiving anything.
Code: | setup_comparator(NC_NC_NC_NC | I told you to move this line into main(), here it is not being executed and is useless.
Code: | if(entra);
{
dados = getc();
} | A major error! Get rid of the ';' after the if, because that is equivalent to an 'empty statement'. Now this 'empty statement' is executed when the 'if' statement is true. Effectively your code is equivalent to
Code: | if(entra)
{
}
dados = getc(); |
Code: | saida = 0xFF;// 11111111
printf("%c",saida);
|
Don't you think that is shorter and easier to read? Now the code is self explaining, you don't have to document that 0xFF equals 0b11111111 because the code already tells you so.
Your function lerDip() is not working because it is not reading the port but the variables a1, a2 and a3 . I leave it to you to figure this out. |
|
|
Marcos Guest
|
|
Posted: Mon Sep 25, 2006 7:29 am |
|
|
Thanks again ckielstra
i corrected my function ler_dip();
Follow:
Code: | unsigned char ler_dip()
{
int8 a1;
int8 a2;
int8 a3;
int8 res;
res = 0;
res |= (input(PIN_A1)); // variable res or a1.
res |= ((input(PIN_A2)) << 1); //variable res or a2
res |= ((input(PIN_A3)) << 2); // variable res or a3.
return res;
} |
My function usart.h is the USART initialization
Follo to you see:
Code: | #locate porta = 0x05
#locate portb = 0x06
char usart_rx, usart_tx, txreg, rcreg, spbrg;
// Apenas configura��o da USART
struct rxsta_reg
{
int rx9d : 1;
int oerr : 1;
int ferr : 1;
int aden : 1;
int cren : 1;
int sren : 1;
int rx9 : 1;
int spen : 1;
} rcsta; // estrutura os bits de rc com default 1;
struct txsta_reg
{
int tx9d : 1;
int trmt : 1;
int brgh : 1;
int xxx : 1;
int sync : 1;
int txen : 1;
int tx9 : 1;
int csrc : 1;
} txsta; // estrutura os bits de tx com default 1;
//endere�ando vari�veis
#locate rcsta = 0x18
#locate txreg = 0x19
#locate rxreg = 0x1a
#locate txsta = 0x98
#locate spbrg = 0x99 |
i didnt understand about printf("%c", variable).
Isnt possible running it?
My program is to fire sensor addressed where PIN_a1,PIN_a2_,PIN_a3 are my 3 bits address . The PIN_a0 i will conect a fotodiode that is responsible for detecte smoke. When he fotodiode receive smoke , he works because the PIN_ao need stay high.My sensor only answer your state high or low to TX_PIN when receive your address in RX.
Do you understand?
for example : My adress sensor physical configurate in PIN a1,a2,a3 is
101.when my RX receive 8 bits that is 11111010 i will answer acording with fotodiode status.
if my RX PIN receive other data : 11110010. i dont answer. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Sep 25, 2006 8:18 am |
|
|
Your usart.h file is not executing any code, it is only defining some variables that you never use. Most likely you copied this code from another compiler... and you don't need it in the CCS compiler. Get rid of it.
Quote: | didnt understand about printf("%c", variable).
Isnt possible running it? | You can use your code and it will run without problems. My problem with it is that printf is a very flexible function but therefor has a lot of overhead. You use printf in it's most basic form, then using putc() is much more efficient and saves you a variable.
Your function ler_dip() might function now. Just get rid of the variables you no longer use (a1, a2 and a3).
Quote: | My program is to fire sensor addressed where PIN_a1,PIN_a2_,PIN_a3 are my 3 bits address . The PIN_a0 i will conect a fotodiode that is responsible for detecte smoke. When he fotodiode receive smoke , he works because the PIN_ao need stay high.My sensor only answer your state high or low to TX_PIN when receive your address in RX.
Do you understand? | This sounds like you want to connect multiple smoke detectors to the same physical wire, a multi-drop connection. What kind of hardware are you using? RS-232, RS-485, other? |
|
|
Marcos Guest
|
|
Posted: Mon Sep 25, 2006 10:05 am |
|
|
Hi Ckielstra!
Yes, i have many fire sensors in same wire.
My firmware in Control Central is:
Send information and wait answer from sensor.if sensor answer with 11111111 high LEd read. if him responde 00000000 hig led green.
If dont answer in 250ms ( timeout), low red and green.
In the forst time i will not use RS485 or other. I will use only PIC-USART . Is small test in litlle distance. i will conect Control Central to sensors only with PIC USART TX and RX .
i think that in table test dont have problems. What do you think about this? |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Sep 25, 2006 12:33 pm |
|
|
I think your idea can work but only as a hobby project. For more serious applications you should use a more tough protocol with included error checking and all the lot.
I have the same troublesome feelings about your physical communication medium. Directly coupling the PIC UARTs will only work up to a distance of two meters (maybe more on lower baudrates). Multidrop in this setup however requires some caution or the output circuits will cause a short-circuit. I'm not an expert in this field, but you could create something using open collector outputs. Check the FLOAT_HIGH parameter for the #use RS232 directive. Also try the FLOAT_HIGH keyword as a search paramter in this forum and you will find more info. |
|
|
Marcos Guest
|
|
Posted: Mon Sep 25, 2006 4:43 pm |
|
|
Hi Again.
i saw that you have a lot of experience in Firmware and CCS compiler, so , i would like that you see my program and try verify when is the problems. Folow my central controler program:
Code: | #include <16F628A.h>
#fuses INTRC_IO,NOWDT,PUT,BROWNOUT,NOLVP,NOMCLR
#use delay (clock=4000000)
#use rs232(baud=9600,xmit=PIN_B2,rcv=PIN_B1,ERRORS)
#define NUM_SENSORES 4
void configurar_status_sensor(int nr_sensor, int status);
void desativar_sensor(int nr_sensor);
void main()
{
unsigned char mascara;
unsigned char saida;
unsigned char entra;
unsigned char dados;
int timeout;
timeout = 250;
mascara = 0xF0; // 11110000
while(1)
{
int i = 0;
while(i < NUM_SENSORES)
{
saida = (mascara | (i << 1));
putc(saida);
delay_ms(250);
entra = kbhit();
if (entra)
{
dados = getc();
if (dados == 0x00 || 0xFF) {
configurar_status_sensor(i, dados); }
else
{
desativar_sensor(i);
}
}
else{
timeout = TRUE;
}
i++;
}
}
}
void configurar_status_sensor(int nr_sensor, unsigned char dados)
{
switch (nr_sensor)
{
case 0: // sensor 0
if(!dados)
output_high(PIN_A0); // on green led
else
output_high(PIN_A1);// on red led
break;
case 1: // Sensor 1
if(!dados)
output_high(PIN_B3); // on green led
else
output_high(PIN_B0);; // on red led
break;
case 2: // Sensor 2
if(!dados)
output_high(PIN_B5); // on green led
else
output_high(PIN_B3); // on red led
break;
case 3: // Sensor 3
if(!dados)
output_high(PIN_B7); // on green led
else
output_high(PIN_A2);// on red led
break;
default:
break;
}
void desativar_sensor(int nr_sensor) {
switch (nr_sensor)
{
case 1:
output_low(PIN_A0);// off led
output_low(PIN_A1);// off led
break;
case 2:
output_low(PIN_B3); // off led
output_low(PIN_B0); // off led
break;
case 3:
output_low(PIN_B5); // off led
output_low(PIN_A3); // off led
break;
case 4:
output_low(PIN_A2); // off led
output_low(PIN_B7);// off led
break;
}
} |
The program is: Send 8 bits from central controler - TX PIN ,that are conected with sensors RX PIN.
In this case i have 4 fire sensors conected in my central control.
i need send 8 bits that is 11110000 - to sensor 0. After send i need wait a answer from sensor 0. This answer from sensor is 00000000(if normal sensor) , 11111111( if sensor is with alarm). The third case is a dont receive data because my sensor dont exist in my wire.
So , when i receive data i will active led (green-normal ) or ( red- alarm). If dont receive data the i off both leds.
After this i send 11110010 - to sensor 1. and the same process.
After i send 11110100 to sensor 2. and the same process.
after i send 11110110 to sensor 3.
After sensor 3, i will start again all process.
The fire sensor code you know but i will send again.
Code: | #include <16F628A.h>
#fuses INTRC_IO,NOWDT,PUT,BROWNOUT,NOLVP,NOMCLR
#include "usart.h"
#use delay (clock=4000000)
#use rs232(baud=9600,xmit=PIN_B2,rcv=PIN_B1)
unsigned char ler_dip();
void main(void)
{
unsigned char dados;
unsigned char aux = 0x00;
unsigned char mascara_a = 0xF0;// 11110000
unsigned char entra;
unsigned char conf_dip;
int1 fotodiodo;
setup_comparator(NC_NC_NC_NC);
conf_dip = ler_dip();
aux = ( mascara_a | (conf_dip << 1)); entra = kbhit();
if(entra)
{
dados = getc();
}
if (dados == aux)
{
fotodiodo = input(PIN_A0);
}
if (fotodiodo)
{
putc(0b11111111);
}
else
{ putc(0b00000000);
}
}
unsigned char ler_dip()
{
int8 a1;
int8 a2;
int8 a3;
int8 res;
res |= (input(PIN_A1));
res |= ((input(PIN_A2)) << 1);
res |= ((input(PIN_A3)) << 2);
return res;
} |
When receive 8 bits that is the same your address , he answers acording with fotodiodo status. Note that the sensor only can answer when your address is the same that have variable aux.
My problems.
1 - I dont see diference when i input 5V or 0V in ler_dip()variables .
This information is very important because her is responsible for address in sensor that is responsible for comparate with variable aux.
2- I dont know how much time is necessary to execute function.For example: i need send 8 bits to sensors and wait a answer for how much time?i'm using 9600bps.
3 - i'm have problems because all leds in my central control are on when i on the system.
sorry for many questions , but i already try all possibilities that i know . I'm initial programmer. so..many doubts. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Sep 25, 2006 6:19 pm |
|
|
Hi Marcos,
Just tell me, in the fire sensor:
- Why do you still include the usart.h? I told you to get rid of it twice.
- Why didn't you add the ERRORS directive to #use rs232 (it is in your controller). I only asked you to do so twice...
- Why did you remove the while(1) after asking me if it was correct to have it in there? Now you introduced an error.
- Why did you remove the 'res = 0;' from the ler_dip() function? Now you created another error. But you do still have the a1, a2 and a3 variables that I told you to get rid off...
I'm feeling tired... probably because it is late at night here, but I'm sorry to say that right now you are not a great inspiration.
Besides the above mentioned new errors there are several other problems as well. My suggestion is that you start all over with a simple as possible system, get that working and then expand on that. Forget about multiple sensors, first get it working with one sensor before trying to connect more devices. Even better, forget about any sensors at all and use a standard PC with Hyperterm to emulate a sensor (you can see the data sent by the controller and you can type a response on the keyboard).
This is how all big projects are setup. You start building and testing small pieces. And than one by one they are connected together. If some (large) piece is essential but not tested yet, then insert some temporary dummy program code that will return a known fixed value. This way if something fails you know it will be in the last added part.
Good luck. I'm off to bed. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|