Measurement of Amplitude of any Input Wave by 8051:
This is a simple program to find the highest amplitude in an input wave, sine, triangular or square, it works with all.
The assembly Code:
;define the adc address and control pins
ADC_A BIT P2.0
ADC_B BIT P2.1
ADC_C BIT P2.2
ADC_SC BIT P2.3
ADC_ALE BIT P2.4
ADC_EOC BIT P2.5
;define the lcd control pins
RS BIT P2.6
EN BIT P2.7
;program starts from this address
.ORG 0000H
LJMP MAIN
INITIALIZE_LCD: ;lcd initialization sub-routine
MOV A, #38H
LCALL WRITE_CMD
MOV A, #0CH
LCALL WRITE_CMD
MOV A, #06H
LCALL WRITE_CMD
RET
;*********************************
WRITE_CMD: ;sub-routine to write a command to lcd's instruction register
CLR RS ;rs=0 for selecting command register
MOV P0, A
SETB EN
CLR EN
LCALL LCD_DELAY
RET
;*********************************
WRITE_CHAR: ;sub-routine to write a data to lcd's data register
SETB RS ;rs=1 for selecting data register
MOV P0, A
SETB EN
CLR EN
LCALL LCD_DELAY
RET
;********************************
LCD_DELAY: ;subroutine to generate a delay between consequent lcd write operations
MOV R0, #5H
L2: MOV R1, #0FFH
L1: DJNZ R1, L1
DJNZ R0, L2
RET
;**********************************
DISPLAY_VOLT: ;subroutine to display volts: in the lcd
MOV A, #85H
LCALL WRITE_CMD
MOV A, #'V'
ACALL WRITE_CHAR
ACALL LCD_DELAY
MOV A, #'O'
ACALL WRITE_CHAR
ACALL LCD_DELAY
MOV A, #'L'
ACALL WRITE_CHAR
ACALL LCD_DELAY
MOV A, #'T'
ACALL WRITE_CHAR
ACALL LCD_DELAY
MOV A, #':'
ACALL WRITE_CHAR
ACALL LCD_DELAY
RET
;**************************************
DISPLAY: ;subroutine to display the digits of the measured voltage
MOV A, R6 ;display the digit before decimal point
ADD A, #30H
LCALL WRITE_CHAR
MOV A, #2EH ;display the decimal point
LCALL WRITE_CHAR
MOV A, R5 ;display the digit after the decimal point
ADD A, #30H
LCALL WRITE_CHAR
RET
;***********************************
READ_ADC: ;sub-routine to read from adc
SETB ADC_EOC ;intialize default values of the control signals
CLR ADC_ALE
CLR ADC_SC
CLR ADC_A ;specify the address of the adc channel to read from
CLR ADC_B
CLR ADC_C
SETB ADC_ALE ;latch the address of the channel to adc
SETB ADC_SC ;initiate a pulse on sc to start the conversion
CLR ADC_ALE
CLR ADC_SC
WAIT: JNB ADC_EOC, WAIT
;conversion complete, read the converted data
NOP
MOV A, P1
NOP
SETB ADC_EOC
RET
;************************************************
FIND_MAX_AMPLITUDE: ;subroutine to find the max amplitude
MOV R7, #0FFH
REPEAT: DEC R7
LCALL READ_ADC
;find the max amplitude
MOV R2, A ;store the current signal amplitude in r2
MOV A, R3 ;load accumulator with the previous signal amplitude
SUBB A, R2 ;subtract current amplitude from previous amplitude
JC STORE_HIGHER_AMPLITUDE
AJMP CHECK
STORE_HIGHER_AMPLITUDE:
MOV A, R2
MOV R3, A
CHECK: MOV A, R7
JNZ REPEAT
RET
;************************************************
ADJUST:
;scale down the input adc value by 5
MOV A, R3
MOV B, #5D
DIV AB
MOV R4, A ;r4 contains the hex, have to convert it into decimal
;convert the hext to two separate decimal digits to be displayed
HEX_TO_DECIMAL:
MOV A, R4
MOV B, #10D ;divide by 10
DIV AB
MOV R5, B ;r5 contains the value after decimal
MOV R6, A ;r6 contains the value before decimal point
RET
;**************************************************
MAIN: ;here lies the main program
MOV R3, #00H ;default max amplitude
MOV P1, #0FFH ;set p1 input port
MOV P0, #00H ;set p0 output port
LCALL INITIALIZE_LCD
LCALL DISPLAY_VOLT
LCALL FIND_MAX_AMPLITUDE
LCALL ADJUST
LCALL DISPLAY
MOV A, #80H
LCALL WRITE_CMD
AJMP MAIN
END