View previous topic :: View next topic |
Author |
Message |
webgiorgio
Joined: 02 Oct 2009 Posts: 123 Location: Denmark
|
trouble with 16F876A adc |
Posted: Sun Nov 22, 2009 5:16 am |
|
|
I'm trying to use a 16F876A for the first time.
Doing compile I get errors from the 2nd to the 4th line like "expecting an identifier" and "expecting a declatration"
Code: | setup_adc_ports(RA0_RA1_RA2_RA4_ANALOG);
setup_adc( ADC_CLOCK_DIV_8 );
set_adc_channel(0);
delay_us(20); |
Looking to the 16F876A.h file seem to be all right... :( |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Nov 22, 2009 10:11 am |
|
|
Always post your compiler version. |
|
![](templates/subSilver/images/spacer.gif) |
webgiorgio
Joined: 02 Oct 2009 Posts: 123 Location: Denmark
|
|
Posted: Tue Nov 24, 2009 12:06 pm |
|
|
I'm sorry, 4.057 |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Nov 24, 2009 12:25 pm |
|
|
Quote: | setup_adc_ports(RA0_RA1_RA2_RA4_ANALOG); |
This constant is not in the list of allowable constants for that function,
as given in the 16F876A.h file. Look in that file, in this section:
Quote: | // Constants used in SETUP_ADC_PORTS() are: |
Here's the file location:
Quote: | c:\program files\picc\devices\16f876a.h |
|
|
![](templates/subSilver/images/spacer.gif) |
webgiorgio
Joined: 02 Oct 2009 Posts: 123 Location: Denmark
|
|
Posted: Fri Nov 27, 2009 7:03 am |
|
|
With SETUP_ADC_PORTS(ALL_ANALOG); I have the same error: "expecting an identifier" and "expecting a declatration"
Here all the code:
Code: | #include <C:\Programmi\PICC4\Devices\16F876A.h>
#device ADC=10
#fuses XT, NOWDT, NOLVP
#use delay(clock = 4000000)
#define cuni PIN_B6 //cifra unità pin 17
#define cdeci PIN_C5 //cifra decine pin 18
#define ccenti PIN_B7 //cifra centinaia pin 1
#define pin_knord PIN_C2 //pin 2
#define pin_pulsante PIN_A3 //pin 3
#fuses XT, NOWDT
int in, pulsante, a, FN, sm05, sm06, clock;
int8 numero, cifra_on, uni, deci, centi; //256
int16 velox, tempo, tempo2, tempo3, misura, adc_value; //65536
float rpm; //
//--------------------------------------------------------------------------
#int_RTCC
void RTCC_isr() //Interrupt Service Routine
{
set_timer0(135); //ricarica il timer0. 132 (teorico) incrementi per l'overflow
//aggiornamento valore del display ogni mezzo secondo
tempo2++;
if(tempo2>500)
{
sm05=!sm05; //bit con periodo 1s
tempo2=0;
if (misura==0) {velox=0;}
else velox=6000/misura; //60000/misura=rpm
}
//clock per far lampeggiare le cifre
tempo3++;
if(tempo3>200)
{
sm06=!sm06; //bit con periodo 0.4 s
tempo3=0;
}
//conteggio in ms del tempo che passa
tempo++;
if (tempo>2000) { //tempo eccessivo fra gli impulsi dell'anemometro
tempo=0; //riazzera il tempo e la misura
misura=0;
}
}
//--------------------------------------------------------------------------
SETUP_ADC_PORTS(ALL_ANALOG);
//setup_adc( ADC_CLOCK_DIV_8 );
//set_adc_channel(0);
//delay_us(20);
void main() { //inizio programma principale
set_tris_a(0x1F); //0001 1111 ra7...ra0
set_tris_b(0x00); //0000 0000
set_tris_c(0x03); //0000 0011
set_timer0(135);
setup_timer_0 (RTCC_INTERNAL|RTCC_DIV_8);
enable_interrupts(int_rtcc); //abilito l'interrupt da tmr0
enable_interrupts(global); //abilito tutti gli interrupts
//condizioni iniziali
velox=0;
tempo=0;
cifra_on=1;
while(1) //ciclo continuo-------------------------------------------------
{
adc_value = read_adc();
//lettura ingressi
pulsante=!input(pin_pulsante);
//riconosce il fronte negativo
if ((in==0 & a==1)) FN=1;
else FN=0;
a=in;
//al fronte negativo salva il tempo e lo azzera dinuovo
if (FN) {
misura=tempo;
tempo=0;
}
//ricava le tre cifre dal valore velox
uni = velox%10;
deci = (velox/10)%10;
centi = velox/100;
//shift delle cifre
cifra_on++;
if (cifra_on>3) cifra_on=1;
if (cifra_on==1) { output_b(0xFF); output_bit(ccenti, 1); numero=centi; }
else output_bit(ccenti, 0);
if (cifra_on==2) { output_b(0xFF); output_bit(cdeci, 1); numero=deci; }
else output_bit(cdeci, 0);
if (cifra_on==3) { output_b(0xFF); output_bit(cuni, 1); numero=uni; }
else output_bit(cuni, 0);
output_bit(pin_knord, pulsante);
} //fine ciclo while
} //fine main |
|
|
![](templates/subSilver/images/spacer.gif) |
dyeatman
Joined: 06 Sep 2003 Posts: 1924 Location: Norman, OK
|
|
Posted: Fri Nov 27, 2009 10:24 am |
|
|
The line is out in the "middle of nowhere" in your code. Try moving the line inside the MAIN procedure.... _________________ Google and Forum Search are some of your best tools!!!! |
|
![](templates/subSilver/images/spacer.gif) |
webgiorgio
Joined: 02 Oct 2009 Posts: 123 Location: Denmark
|
|
Posted: Sat Nov 28, 2009 12:33 pm |
|
|
you are right. Thank you.
Is better to move also the variable declaration inside the main()?
I would like to have as analog input:
RA0/AN0
RA1/AN1
RA2/AN2
RA5/AN4
And RA3/AN3 as digital input.
There isn't this case in the .h file. Can I add a
#define RA0_RA1_RA2_RA4_ANALOG 0x?? ?
Lookink to the 16f876a datasheet, page 128, (AD port configuration control bits) there isn't the combintation that I would like, so pheraps the answer is no. Right?
What can I do? configure with all_analog and read the switch input as an analog? (input is a switch with a pull-up) |
|
![](templates/subSilver/images/spacer.gif) |
dyeatman
Joined: 06 Sep 2003 Posts: 1924 Location: Norman, OK
|
|
Posted: Sat Nov 28, 2009 12:46 pm |
|
|
Where you declare the variable determines the "scope" of the variable.
Defining them up front gives them a global scope and they can be seen in
all the procedures.
Defining them within a procedure gives them a local scope and they can
only be accessed by that procedure. The upside is that the RAM can be
reused by the compiler after exiting the procedure. However, unless you
end up being short on RAM I would recommend leaving them where they
are.
I try to keep as many variables as possible at the global level where I can
use them for passing information to/from a procedure rather than using
calling parameters. It keeps things simple for me but lots of folks have
different coding styles and will likely disagree with mine.
As far as the Analog ports, they can only be used in the combinations
shown in the datasheet due to limitations of the chip design. Reading a
switch input as an analog signal can be done but is the "hard" way to
accomplish the objective. Can you not use a different pin? _________________ Google and Forum Search are some of your best tools!!!! |
|
![](templates/subSilver/images/spacer.gif) |
webgiorgio
Joined: 02 Oct 2009 Posts: 123 Location: Denmark
|
|
Posted: Sun Nov 29, 2009 9:44 am |
|
|
Yes, I will do this for the next card, now I've already print and weld the pcb.
Thank you for the "variable scope" explanation, I agree with your way of programming. ![Wink](images/smiles/icon_wink.gif) |
|
![](templates/subSilver/images/spacer.gif) |
|