|
|
View previous topic :: View next topic |
Author |
Message |
girichavana
Joined: 21 Oct 2008 Posts: 17
|
Comparator in PIC16F877A |
Posted: Tue Dec 29, 2009 5:24 am |
|
|
Hi
I want to test the Comparator module in my board with the internal reference.
Following is my code. In this I am continuously getting the interrupt.
Please let me know the mistake.
Code: |
/***************** Comparator **********************/
#include<16F877A.h>
#device adc = 10
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock = 8000000)
#define use_portb_lcd TRUE
#include<lcd.c>
int1 flag=0;
#INT_COMP
void isr()
{
flag = ~flag;
}
void main(void)
{
int16 adc_value;
float volts;
lcd_init();
lcd_gotoxy(1,1); lcd_putc("\f Comparator");
setup_comparator(A0_VR_A1_VR);
setup_vref(VREF_HIGH|15);
enable_interrupts(INT_COMP);
enable_interrupts(GLOBAL);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(7);
delay_us(20);
while(TRUE)
{
if(flag)
{
lcd_gotoxy(1,2); lcd_putc("LOW Battery");
delay_ms(500);
enable_interrupts(INT_COMP);
}else
{
lcd_gotoxy(1,2); lcd_putc("HIGH");
delay_ms(500);
enable_interrupts(INT_COMP);
}
adc_value = read_adc();
volts = (float)(adc_value * 5)/1023.0;
lcd_gotoxy(1,1);printf(lcd_putc,"Voltage = %3.2f V\r\n", volts);
}
}
|
I am giving the variable voltage to the RA0.
Thanks and Regards. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Dec 29, 2009 1:39 pm |
|
|
When a PIC peripheral module doesn't work, you can often find the
reason in the data sheet. The 16F877A data sheet says, in the
Comparator Interrupts section:
Quote: |
The user, in the Interrupt Service Routine, can clear the
interrupt in the following manner:
a) Any read or write of CMCON will end the
mismatch condition.
b) Clear flag bit CMIF.
A mismatch condition will continue to set flag bit CMIF.
Reading CMCON will end the mismatch condition and
allow flag bit CMIF to be cleared.
|
Both of those things must be done. The 2nd one is done by CCS
in code that is inserted at the end of the ISR. The 1st one must
be done by you.
To read the CMCON register, define the address of the register with
a #byte statement. Then read the CMCON register into a local
variable inside the ISR. This will satisfy item a) above.
Look in this section of the PIC data sheet to find the address of CMCON:
Quote: | FIGURE 2-3: PIC16F876A/877A REGISTER FILE MAP |
Quote: | while(TRUE)
{
if(flag)
{
lcd_gotoxy(1,2); lcd_putc("LOW Battery");
delay_ms(500);
enable_interrupts(INT_COMP);
}else
{
lcd_gotoxy(1,2); lcd_putc("HIGH");
delay_ms(500);
enable_interrupts(INT_COMP);
|
In this code, you are re-enabling INT_COMP interrupts. They never
get disabled. Why do think you need to re-enabled them ?
Quote: |
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(7);
|
Here, you have not set any pins to be analog input. You need to call
the setup_adc_ports() function, with the appropriate constant as a
parameter. These constants are listed in the 16F877A.h file.
You will find that, with this PIC, there is no way to have only AN7
(by itself) be an analog pin. The pins are set in preselected groups.
Normally, if you only want one analog pin on this series of PICs,
you would choose AN0. It can be selected by itself. You can see
this in the 16F877A.h file. |
|
|
|
|
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
|