| Details |
Message |
|
Read-Only
Author NY Yeo
Posted 24-Aug-2007 03:10 GMT
Toolset C51
|
 Storing ADC values in C8051F206 memory
NY Yeo
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!
|
|
|
Read-Only
Author Russ Cooper
Posted 24-Aug-2007 03:37 GMT
Toolset C51
|
 RE: Storing ADC values in C8051F206 memory
Russ Cooper
Your program is actually pretty good. You have organized it well
and included lots of helpful comments.
To understand why it halts the second time, think about these
questions:
1. After the RET is executed the first time, which instruction is
executed next?
2. How did the processor know which instruction to execute after
the RET?
3. After the RET is executed the second time, which instruction is
executed next?
-- Russ
|
|
|
Read-Only
Author NY Yeo
Posted 24-Aug-2007 03:41 GMT
Toolset C51
|
 RE: Storing ADC values in C8051F206 memory
NY Yeo
I tried to store the same values in 8 successive memory locations
as I step through the program. Whenever I change the ADC input dc
voltage, the values from ADCOH remains unchanged. Please see below
for my code:
;***********************************
;-Store data in 8 memory locations-
;***********************************
MOV R1,#8
MOV R0,#40H
STORE: MOV @R0,ADC0H
INC R0
DJNZ R1,STORE
RET
END ; End of Program
|
|
|
Read-Only
Author NY Yeo
Posted 24-Aug-2007 04:04 GMT
Toolset C51
|
 RE: Storing ADC values in C8051F206 memory
NY Yeo
Thanks Russ. In fact, I do not need RET at the moment since I am
not calling any more subroutines after CONVERT.
However, I am still unable store different values in successive
memory locations as I adjust my input voltage source. Is there any
interrupts, polling, etc needed so that every time I tune my input
voltage, the new value is stored in the next memory location?
|
|
|
Read-Only
Author Russ Cooper
Posted 24-Aug-2007 04:46 GMT
Toolset C51
|
 RE: Storing ADC values in C8051F206 memory
Russ Cooper
Thanks Russ. In fact, I do not need RET at the moment since I
am not calling any more subroutines after CONVERT.
Yes, you do. You are calling CONVERT with an ACALL. Therefore, the
CONVERT subroutine should end with a RET, as in your original
post.
The next question is, what happens after the RET is
executed? You really need to think about the three questions I gave
in my previous message, before you go on to worry about the A/D
converter, or how to store values in memory, or anything else.
Hint: What does it mean for a program running on a microcontroller
to "end"?
-- Russ
|
|
|
Read-Only
Author Russ Cooper
Posted 24-Aug-2007 04:58 GMT
Toolset C51
|
 RE: Storing ADC values in C8051F206 memory
Russ Cooper
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'?"
|
|
|
Read-Only
Author NY Yeo
Posted 24-Aug-2007 05:44 GMT
Toolset C51
|
 RE: Storing ADC values in C8051F206 memory
NY Yeo
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.
|
|
|
Read-Only
Author NY Yeo
Posted 24-Aug-2007 05:51 GMT
Toolset C51
|
 RE: Storing ADC values in C8051F206 memory
NY Yeo
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
|
|
|
Read-Only
Author Andy Neil
Posted 24-Aug-2007 07:21 GMT
Toolset C51
|
 And so to the 2nd question
Andy Neil
"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
|
|
|
Read-Only
Author Per Westermark
Posted 24-Aug-2007 09:53 GMT
Toolset C51
|
 RE: And so to the 2nd question
Per Westermark
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?
|
|
|
Read-Only
Author Russ Cooper
Posted 24-Aug-2007 11:14 GMT
Toolset C51
|
 RE: Storing ADC values in C8051F206 memory
Russ Cooper
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.
Correct!
After the RET is first executed, it pops the return address off
the stack into the instruction pointer then resumes execution at the
location.
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.
As RET is executed for the second time, there is no subroutine
called, thus it proceeds to end.
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
|
|
|
Read-Only
Author Andy Neil
Posted 2-Sep-2007 21:57 GMT
Toolset C51
|
 Cross reference
Andy Neil
This is a frequent pitfall for beginners; eg, see
http://www.8052.com/forum/read.phtml?id=143902
|
|