View previous topic :: View next topic |
Author |
Message |
davt
Joined: 07 Oct 2003 Posts: 66 Location: England
|
16f876 and a/d interrupt not working |
Posted: Tue Jan 13, 2004 9:19 am |
|
|
Hi all
PCW compiler
IDE version 3.23
PCB version 3.129
PCM version 3.129
16f876 @ 20mhz clock
I have a program below which reads from a potentiometer on pin a0 and internal ref. It then adjusts the PWM output which is on pin rc2/ccp1.
What is not working is the a/d interrupt - when I start the conversion in Main, nothing happens, there is no a/d interrupt. All the fuses are correctly set so there is no problem there.
I can tell the a/d interrupt is not serviced because I placed a test code in it to toggle port pin b7.
#include <16f876.h>
#use delay(clock=20000000)
#define on 1
#define off 0
#define yes 1
#define no 0
#byte tris_a = 0x85
#byte tris_b = 0x86
#byte tris_c = 0x87
#byte intcon = 0x0b
#byte pie1 = 0x8c
#byte tmr2 = 0x11
#byte pr2 = 0x92
#byte t2con = 0x12
#byte ccpr1l = 0x15
#byte ccpr1h = 0x16
#byte ccp1con = 0x17
#byte adcon0 = 1f
#byte adcon1 = 9f
#byte adresh = 0x1e
#byte adresl = 0x9e
#byte port_b = 0x06
#byte port_c = 0x07
#bit start_ad = 0x1f.2
#bit test = port_b.7
//////////////////////////////////////////////////////////////////////////////////////////
short toggle;
//////////////////////////////////////////////////////////////////////////////////////////
#int_ad
get_adc_result()
{
long ad_result;
toggle=toggle^1; // test
test=toggle; // toggle port b.7
ad_result=0x0000;
ad_result=adresh;
ad_result=ad_result<<8;
ad_result=ad_result | adresl;
if(ad_result>=8)
{
ad_result=ad_result>>3; // divide by 8
ccpr1l=ad_result; // update PWM
}
}
//////////////////////////////////////////////////////////////////////////////////////////
void main()
{
tris_a=0b00001; // port a an0 input rest outputs
tris_b=0x00; // port b all outputs
tris_c=0x00; // port c all outputs
port_b=0x00; // clear all pins on port b
pie1=0x40; // enable a/d peripheral
adcon0=0x81; // fosc/32, ra0, a/d off, a/d operating
adcon1=0x8e; // an0 is a/d input, rest port a digital, internal ref, right justified
t2con=0x04; // timer2 on, postscale=1
ccp1con=0x3c; // PWM on and lsb's set
pr2=0x82; // sets period
ccpr1l=0x20; // sets duty cycle
intcon=0xc0; // enable global interrupts and peripherals
while(1)
{
start_ad=yes;
While(start_ad);
delay_ms(50); // delay before starting a/d again
}
}
Many thanks for your help.
Dave |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Jan 13, 2004 9:43 am |
|
|
I brief glanced at the code and saw 2 things.
1. Your comment says that you are toggling b.7 but the code you posted affects b.0
2. start_ad is not cleared. |
|
|
davt
Joined: 07 Oct 2003 Posts: 66 Location: England
|
|
Posted: Tue Jan 13, 2004 10:13 am |
|
|
Thanks Mark
The 'test' bit is port_b.7 as set in the line #bit test = port_b.7 and 'start_ad' is bit 2 in the adcon0 register which is reset when the conversion has completed.
Dave |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Jan 13, 2004 10:30 am |
|
|
This doesn't toggle bit 7
toggle=toggle^1; // test
test=toggle; // toggle port b.7 |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
|
Posted: Tue Jan 13, 2004 10:32 am |
|
|
Maybe you could use this
Code: |
#define ADCON0 0xFC2
#bit GO_DONE = ADCON0.2
|
and this
Code: |
While(GO_DONE);
Analog_Input_2_RAW=read_adc(ADC_READ_ONLY);
|
|
|
|
neil
Joined: 08 Sep 2003 Posts: 128
|
toggling a bit |
Posted: Tue Jan 13, 2004 10:45 am |
|
|
Maybe I'm misunderstanding something here, but given that 'toggle' is a short, then ex-or ing it with '1' will invert its state. 'test' is also a short, so equating one to the other surely should work, no?
1 ^ 1 = 0
0 ^ 1 = 1
Anyway, a neater way of toggling a port I/O, which I am using to debug my code right now is this:
test^=1; // same as test = test ^ 1
I guess this does a read-modify-write to the port pin.
Hope this clarifies things!
Neil. |
|
|
davt
Joined: 07 Oct 2003 Posts: 66 Location: England
|
|
Posted: Tue Jan 13, 2004 10:46 am |
|
|
Hi
I looked at the c/asm listing and start_ad is described as:
.................... start_ad=yes;
009A: BSF 01.2 <<<<<<< THIS SHOULD BE ADCON0.2 (0x1f.2)
....................
.................... while(start_ad);
009B: BTFSC 01.2
009C: GOTO 09B
.................... {};
but I set 'start_ad' as - #bit start_ad = adcon0.2
the compiler has changed this to 01.2 - is this a bug??
Dave |
|
|
neil
Joined: 08 Sep 2003 Posts: 128
|
|
Posted: Tue Jan 13, 2004 10:55 am |
|
|
Damn compiler! If you are telling the compiler that the name you have chosen is assigned to a certain bit in a certain register and then setting that bit, I don't see any reason for the compiler to change it! This is only one step away from assembly!
I would try choosing another name for the bit, see if the compiler is doing something strange there. If that doesn't help, do a #asm and code that bit in assembly, see if the prog works then!
eg:
#asm
bcf 0x03.5; // not sure about this, is bank switching needed?
bsf 0x1f.2;
#endasm |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Jan 13, 2004 11:05 am |
|
|
I wish to retract this
Quote: |
This doesn't toggle bit 7
toggle=toggle^1; // test
test=toggle; // toggle port b.7
|
Didn't look close enough. Thought test = portb |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
davt
Joined: 07 Oct 2003 Posts: 66 Location: England
|
|
Posted: Wed Jan 14, 2004 3:27 am |
|
|
Hi all
Many thanks for your thoughts!
Spent a whole day looking at the code started to blame the compiler (sorry CCs) went home had a few beers.
New day fresh start solved the problem in 30seconds.
#byte adcon0 = 1f
#byte adcon1 = 9f
Should be:
#byte adcon0 =0x1f
#byte adcon1 = 0x9f
Thanks.
Dave |
|
|
neil
Joined: 08 Sep 2003 Posts: 128
|
|
Posted: Wed Jan 14, 2004 3:35 am |
|
|
D'oh!!!!! I should have spotted that! Looks like the compiler was ignoring the 'f' and treating it as '1'. Why did the compiler not generate an error?! Why in fact does CCS not generate 'warnings' like many compilers do?!
These little pitfalls get the best of us. |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Wed Jan 14, 2004 4:52 am |
|
|
Hi davt,
Quote: |
Spent a whole day looking at the code started to blame the compiler (sorry CCS) went home had a few beers.
New day fresh start solved the problem in 30seconds.
|
Conclusion:
Next time you get a problem, don't blame CCS, just drink some beers.
Cheers,
Humberto |
|
|
|