|
|
View previous topic :: View next topic |
Author |
Message |
STIX
Joined: 17 Jun 2006 Posts: 12
|
Help with ADC |
Posted: Wed Jun 21, 2006 9:29 am |
|
|
I have been trying to take a temperature sensor reading with the ADC on my pic16f877a MCU. The sensor is sensing room temperature (24°C), and in my code, a red LED is suppose to be turn on if the reading is that of the room temperature. If the reading is above room temperature, a green LED turns on. The problem I'm having is that the green LED is coming on. I've checked the output of the temperature sensor and it is reading the room temerature. Can anyone tell me if I'm doing something wrong the code? Thanks.
Code: | #include <16f877a.h>
#device *=16
#device ADC=10
#fuses HS,NOWDT,NOPUT,NOPROTECT,NODEBUG,BROWNOUT,NOLVP,NOCPD,NOWRT
#byte PORTA = 0x05
#byte PORTB = 0x06
#byte TRISA = 0x85
#byte TRISB = 0x86
#byte ADCON0 = 0x1F
#byte ADCON1 = 0x9F
#byte ADRESH = 0x1E
#byte ADRESL = 0x9E
#bit GO = ADCON0.2
void main (void)
{
float v, temp;
long ad;
TRISA = 1; //PORTA set as input
TRISB = 0; //PORTB set as output
ADCON1 = 0x80; //Right justify result
while (1)
{
ADCON0 = 0; //Select AN0 as input, sensor attached to AN0
ADCON0 = 0x41; //Turn A/D to read AN0, select FOSC/8 clock
while (GO == 1);
ad = 256*ADRESH;
ad = ad + ADRESL;
v = (float)ad;
v = v*(5000/1024);
temp = v/10;
if (temp > 30.0)
turn on green LED;
else
turn on red LED;
}
} |
|
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Wed Jun 21, 2006 9:42 am |
|
|
First of all, 'GO' needs to be set to a '1' in order to initiate an A/D conversion. You have nothing, in your code, that is setting it to a '1'. Even if you did, your code would continually run through your while(GO ==1) loop until the conversion was complete. Try someting like this:
Code: | if(!inprocess && read)
{
GO = 1;// start A/D conversion
inprocess = 1;// set flag so we don't enter this over and over
read = 0;// flag set in Timer1 to indicate that it's time to play
}
if(inprocess && !GO)// if a conversion has been started and it's done
{
ad = make16(ADRESH, ADRESL);// stuff the result into ad
inprocess = 0;
v = (float)ad;
v = v*(5000/1024);
temp = v/10;
if (temp > 30.0)
turn on green LED;
else
turn on red LED;
}
|
See if that will work for you. Plus, when you turn on the green LED, you'll need to turn OFF the red LED. The same for turning on the red LED.
Ronald |
|
|
STIX
Joined: 17 Jun 2006 Posts: 12
|
|
Posted: Wed Jun 21, 2006 10:32 am |
|
|
Thanks for the tip on setting the GO bit. But what does the "read = 0" suppose to do? I've never used Timer1 before, so could you clarify on how to use Timer1? Thanks again. |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Wed Jun 21, 2006 1:53 pm |
|
|
The Timers are used when you want something to occur at a very specified time. Look at the different timers, that are available, in the spec. sheet. Some are eight-bit timers and others are 16-bit timers. You configure them to take the clock pulses, from the main oscillator circuit, and then divide those pulses by programmable dividers. The Timer will count the final result and when the Timer's register rolls over from 255-0 (for eight-bit timers) or from 65535-0 (for 16-bit timers) an interrupt will occur and the program will service the Timer's interrupt routine. The 'read' variable is an int1 (one bit variable) and the Timer set's that bit when the Timer routine is serviced.
The A/D section is in the main() body and constantly looks to see if the 'read' bit is set. The 'read = 0' is simply setting that bit to '0' for the next time the Timer gets ready to set it for another A/D conversion.
Ronald |
|
|
|
|
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
|