We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Dear all,
I am new to C8051 assembly language programming. To start off, my supervisor has tasked me to acquire DC signals into the ADC and store them in memory locations. The next phase will be interfacing with LCD.
I have fixed a DC variable voltage source from 0-3V into P1.7 of C8051F206 development board which I have configured as analog input. I will be using Port 3 for output.
I have tried to step through my program and I was able to see the values change at memory location 40H as I adjusted the input voltage for one time. When I tried to step through the second time, the system halted.
Could you share with me what I could do to allow the program run continuously and stores incoming dc values in several memory locations as I tuned my input voltage source?
My mediocre source code is as follow:
************* ;-Header File- ;************* $include (c8051f200.inc) ORG 0000H LJMP CONFIG ORG 0100H ;*************** ;-Configuration- ;*************** CONFIG: MOV PRT0MX,#004H ; PRT0MX: Initial Reset Value MOV PRT1MX,#000H ; PRT1MX: Initial Reset Value MOV PRT2MX,#000H ; PRT2MX: Initial Reset Value MOV P2MODE,#0FFH ; Set Port 2 as Input MOV P0MODE,#0FFH ; Set Port 0 as Input MOV P1MODE,#000H ; Set Port 1 as Analog input MOV PRT3CF,#000H ; Set Port 3 as Output CLR RS1 CLR RS0 ;******************* ;-ADC configuration- ;******************* MOV AMX0SL,#2FH ; Select Port 1.7 for analog use MOV ADC0CF,#80H ; 16 system clocks and 1 amp gain MOV ADC0CN,#0C1H ; ADC Control MOV REF0CN,#03H ; Use VDD as reference voltage ;*************** ;-Main Function- ;*************** MAIN: ACALL CONVERT ; Call subroutine "CONVERT" ;******************************************* ;-Convert Analog Signals to Digital Signals- ;******************************************* CONVERT: CLR ADCINT SETB ADBUSY ; Start Conversion ;****** ;-Poll- ;****** POLL: JNB ADCINT,POLL ; Poll to see whether conversion is done ;*********************************** ;-Store data in memory location- ;*********************************** STORE: MOV A,ADC0H MOV 40H,A RET END ; End of Program
Thank you for your advice in advance!
Another hint: Since you are new to assembly language, you may not understand that END is an assembler directive, and not a processor instruction. You can read about END in the assembler documentation. Once you understand what it does, then once again as yourself, "what does it mean for the execution of a program running on a microcontroller to 'end'?"
ACALL pushes the address of the instruction that follows ACALL in this case it is CLR ADCINT on to the stack, least-significant-byte first, most-significant-byte second. The Program Counter is then updated so that program execution continues at the indicated address.
After the RET is first executed, it pops the return address off the stack into the instruction pointer then resumes execution at the location.
As RET is executed for the second time, there is no subroutine called, thus it proceeds to end.
Please correct me if I am wrong. Thanks.
I am trying to store a 12-bit data. My data in ADC0H:ADC0L are right justified with ADCOCN set to #0C0H. Why is there an error in my following code when I tried to move ADC0L ? Thanks.
;*********************************** ;-Store 8 sets of 12-bit data- ;*********************************** MOV R1,#8 MOV R0,#40H MOV R2,#60H STORE: MOV @R0,ADC0H INC R0 MOV @R2,ADC0L INC R2 DJNZ R1,STORE
"As RET is executed for the second time, there is no subroutine called, thus it proceeds to end."
Now you need to consider the 2nd question - what actually happens at 'END'?
Hint: as Russ said, 'END' is not a processor instruction; it simply provides some information to the Assembler.
See: http://www.keil.com/support/man/docs/a51/a51_st_end.htm
What happens when you run your car, and compes to a stop sign saying "End of Road" and you continue to drive your car at the same speed?
Correct!
Correct, except it would be better to say "As the RET ... is executed" (not after). The RET instruction is what pops the address from the stack and jumps to that address.
This is where you are having a problem. When RET is executed for the second time, it does exactly the same as the first time: it pops two bytes from the stack and the jumps to that location. However, because no subroutine was called the second time, the numbers that RET gets from the stack the second time are junk! As a result, it jumps to some unknown location and that's when your program crashes.
So, if you want the program to run continuously, you need to code it so that the ACALL is run over and over again, forever. Or, if you want it to run one time and then stop, you need to write explicit code to make it stop (or at least appear to stop).
One more time, END is not an instruction that the processor can execute. It is a directive to the assembler. You must understand this. Only bad things will happen if your program ever reaches the END statement.
-- Russ
This is a frequent pitfall for beginners; eg, see
www.8052.com/.../read.phtml