To get familiar with A/D conversion on a Pic 16f877A. I have done a simple program to test the conversion process.
I'M using internal clock reference and only input AN0. Crystal is 10MHz.
The problem is that according to my code the conversion should be perform only once and than send that conversion to PORTB. but in fact as soon as I change the voltage at the input AN0 the PORTB get updated with a new conversion.
Please can somebody tell me what I did wrong?
Here's my code
void adc_init (void)
{
ADCON0=0x41; // AN0 noGO et power on fosc/16
ADCON1=0x4E; //
//ADIF=0;
//ADIE=1;
//PEIE=1;
//GIE=1;
Delay(300);
}
unsigned char adc_get (void)
{
ADGO=1; // enable conversion A/D AN0
Delay(300);
return ADRESH; // Return the result of the conversion
}
void main(void)
{
unsigned char Conversion;
ADCON0=0x01;
ADCON1=0x46;
TRISA=0x01;
TRISB=0x00;
adc_init(); //set the control of A/D
Conversion=(adc_get()); // Make the conversion store it in Conversion
PORTB=Conversion; // PORTB take the state of conversion
Well, I can see how you'd get that idea - programming in C on a PC, when your main() function ends, the program terminates, and returns to the command prompt, or whatever. On a microcontroller, there's nothing else to return to - it has nothing to do other than run your program, so the only logical thing for it to do when it reaches the end is to just keep running it again - unless you tell it to stop. Depending on the compiler, this might mean it just keeps running past the end of your function, through empty (or maybe not empty...) program memory, loops back around to the beginning, and starts over again - or the compiler might put in a GOTO that sends it back to the start of the main() function again.
Either way, it's not going to stop at the end unless you actually tell it to - such as by putting a 'while(1){}' at the end of the main() function. Generally speaking, it is not common to write a microcontroller program that only runs once on power-up - usually people put all their main code inside a while(1) loop inside the main() function, after any necessary run-once initialization code.
This is not all the real program but a way to monitor that port to be sure it output what I want. Now I'll be able to use it in the real program that is actually a program that never end like you said.
Most C compilers generate "exit" code when main() returns. With nothing else to do an no operating system the generated code might look like the following
Code:
exit: goto exit
which repeatedly executes an instruction which branches to itself. If there are interrupts enabled and nothing to do in main all is well. If this was not the intention or interrupts are disabled then you have a brick.
But... You're making a generalization based on what a C compiler on a PC would do - plus some speculation, with the 'exit: goto exit' bit. It's this kind of generalization that caused the problem in the first place - the OP expected it to run once and stop like you predict (presumably since that's what would happen on a PC), but the compiler did not do that.
But... You're making a generalization based on what a C compiler on a PC would do - plus some speculation, with the 'exit: goto exit' bit. It's this kind of generalization that caused the problem in the first place - the OP expected it to run once and stop like you predict (presumably since that's what would happen on a PC), but the compiler did not do that.
Not true, I could care less what a C Compiler on a PC would or would not do. I'm looking at the assembly language output of two embedded compilers. One is from IAR and the other is from HI-Tech. There is no speculation about it at all.
We don't know what happened in the OP's case since we can't look at the compiler startup file to see what happens when main returns. In one case main() isn't even called since that would consume a stack entry.