This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Storing ADC values in C8051F206 memory

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!

Parents
  • 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

Reply
  • 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

Children