Thiết kế hệ thống đo chu kỳ xung gồm 6 kênh, hệ thống hiện thị sử dụng màn hình LCD 16*2 với thông tin hiển thị trên màn hình gồm số hiệu kênh và chu kỳ xung việc lựa chọn kênh hiển thị qua bàn phím, sử dụng bàn phím điện thoại, bộ vi xử lý sử dụng onchip 89c51. Tín hiệu xung đưa đến chân INT1 của vi điều khiển.
ai giúp em làm bài này với. em viết code như dưới mà chạy mô phỏng không đúng
;------KHAI BAO VA DINH NGHIA-----
RS EQU P2.0
EN EQU P2.4
LCD EQU P0
ROW1 EQU P2.7
ROW2 EQU P2.6
COL1 EQU P2.3
COL2 EQU P2.2
COL3 EQU P2.1
STATE1 EQU P1.0
STATE2 EQU P1.1
STATE3 EQU P1.2
XUNG_VAO EQU INT1 ;chan tin hieu dau vao INT1
;-------CHUONG TRINH---------
ORG 0000H
MOV TMOD,#09H ; gate0=1 timer0=mode1 C/#T=0 Bo dem
MOV TCON,#00H
LJMP MAIN
ORG 0013H
NGAT_INT1:
ACALL DO_DORONG_XUNG
ACALL MH_CHINH
RETI
ORG 0030H
MAIN:
SETB EA ; cho phep ngat cuc bo
SETB EX1 ; cho phep ngat ngoai 1
SETB IT1 ; chon cach ngat ngoai 1 la ngat theo suon
ACALL KT_LCD
ACALL MH_CHO
SETB XUNG_VAO
;--------QUET PHIM--------------
QUETPHIM:
SETB ROW1
SETB ROW2
SETB COL1
SETB COL2
SETB COL3
;--------------
CLR ROW1 ; Cho hang 1=0
JNB COL1,KEY1
JNB COL2,KEY2
JNB COL3,KEY3
SETB ROW1
;---------------------------------
CLR ROW2
JNB COL1,KEY4
JNB COL2,KEY5
JNB COL3,KEY6
SETB ROW2
JMP QUETPHIM
;----------------------------------
KEY1:
JNB COL1,KEY1
MOV R7,#'1'
SETB ROW1
CLR STATE1 ; KENH 1 (000)
CLR STATE2
CLR STATE3
JMP FREE
KEY2:
JNB COL2,KEY2
MOV R7,#'2'
SETB ROW1
SETB STATE1 ;KENH2 (001)
CLR STATE2
CLR STATE3
JMP FREE
KEY3:
JNB COL3,KEY3
MOV R7,#'3'
SETB ROW1
CLR STATE1 ;KENH3 (010)
SETB STATE2
CLR STATE3
JMP FREE
KEY4:
JNB COL1,KEY4
MOV R7,#'4'
SETB ROW2
SETB STATE1 ;KENH4 (011)
SETB STATE2
CLR STATE3
JMP FREE
KEY5:
JNB COL2,KEY5
MOV R7,#'5'
SETB ROW2
CLR STATE1 ;KENH5 (100)
CLR STATE2
SETB STATE3
JMP FREE
KEY6:
JNB COL3,KEY6
MOV R7,#'6'
SETB ROW2
SETB STATE1 ; KENH6 (101)
CLR STATE2
SETB STATE3
JMP FREE
;-------------------------------------
FREE:
ACALL MH_CHINH
JMP QUETPHIM
HERE: SJMP HERE ; Cho o day cho den khi co ngat
DO_DORONG_XUNG:
MOV R1,#00H
MOV R0,#00H
KT_XUNG:
MOV TH0,#00 ; Khoi dau gia tri bo dem timer0
MOV TL0,#00
JB XUNG_VAO,TIMER0 ; Cho muc thap cua xung,
;cho den khi muc thap thi tiep tuc chay
;Neu xung dau vao co muc cao thi quay lai,
SJMP KT_XUNG
TIMER0:
SETB TR0 ; chay timer 0
;---------------------------------
XUNG_MTHAP:
JNB XUNG_VAO,XUNG_MTHAP ;neu xung vao co muc thap
MOV R0,TL0 ;lay noi dung byte thap--> R0
MOV R1,TH0 ;lay noi dung byte cao --> R1
CLR TR0
CLR TF0
RET
;-------HIEN THI LCD--------------
MH_CHO:
MOV A,#80h ; ??a con tr? v? ??u d?ng th? nh?t
ACALL GUI_LENH
MOV A,#"K"
ACALL GUI_DULIEU
MOV A,#"e"
ACALL GUI_DULIEU
MOV A,#"n"
ACALL GUI_DULIEU
MOV A,#"h"
ACALL GUI_DULIEU
MOV A,#" "
ACALL GUI_DULIEU
MOV A,#"T"
ACALL GUI_DULIEU
MOV A,#"h"
ACALL GUI_DULIEU
MOV A,#"u"
ACALL GUI_DULIEU
MOV A,#":"
ACALL GUI_DULIEU
MOV A,#" "
ACALL GUI_DULIEU
RET
;-----------DONG 2------------
MH_CHINH:
MOV A,#8Ah
ACALL GUI_LENH
MOV A,R7
ACALL GUI_DULIEU
MOV A, #0C0h ; ??a con tr? v? v? tr? th? nh?t d?ng th? 2
ACALL GUI_LENH
MOV A, #"P"
ACALL GUI_DULIEU
MOV A ,#"W"
ACALL GUI_DULIEU
MOV A,#"="
ACALL GUI_DULIEU
MOV R3,#HIGH(10000)
MOV R2,#LOW(10000)
LCALL DIV16_16
MOV A,R2
ADD A,#30H
ACALL GUI_DULIEU;R5
MOV R3 ,#HIGH(1000)
MOV R2 ,#LOW(1000)
LCALL DIV16_16
MOV A ,R2
ADD A ,#30H
ACALL GUI_DULIEU; R4
MOV R3 ,#HIGH(100)
MOV R2 ,#LOW(100)
LCALL DIV16_16
MOV A ,R2
ADD A ,#30H
ACALL GUI_DULIEU ; R3
MOV R3 ,#HIGH(10)
MOV R2 ,#LOW(10)
LCALL DIV16_16
MOV A ,R2
ADD A ,#30H
ACALL GUI_DULIEU ;R2
MOV A ,R0
SUBB A,#1 ;bu sai so
ADD A ,#30H
ACALL GUI_DULIEU
MOV A,#"u"
ACALL GUI_DULIEU
MOV A,#"s"
ACALL GUI_DULIEU
JMP QUETPHIM
div16_16:
;16-bit division is the division of one 16-bit value by another 16-bit value,
;returning a 16-bit quotient and a 16-bit remainder.
;I used r1/r0 for dividend/remainder and r3/r2 for divisor/quotient.
CLR C ;Clear carry initially
MOV B ,#00h ;Clear B since B will count the number of left-shifted bits
div1:
INC B ;Increment counter for each left shift
MOV A ,R2 ;Move the current divisor low byte into the accumulator
RLC A ;Shift low-byte left, rotate through carry to apply highest bit to high-byte
MOV R2 ,A ;Save the updated divisor low-byte
MOV A ,R3 ;Move the current divisor high byte into the accumulator
RLC A ;Shift high-byte left high, rotating in carry from low-byte
MOV R3 ,A ;Save the updated divisor high-byte
JNC div1 ;Repeat until carry flag is set from high-byte
div2: ;Shift right the divisor
MOV A ,R3 ;Move high-byte of divisor into accumulator
RRC A ;Rotate high-byte of divisor right and into carry
MOV R3 ,A ;Save updated value of high-byte of divisor
MOV A ,R2 ;Move low-byte of divisor into accumulator
RRC A ;Rotate low-byte of divisor right, with carry from high-byte
MOV R2 ,A ;Save updated value of low-byte of divisor
CLR C ;Clear carry, we don't need it anymore
MOV 07h ,R1 ;Make a safe copy of the dividend high-byte
MOV 06h ,R0 ;Make a safe copy of the dividend low-byte
MOV A ,R0 ;Move low-byte of dividend into accumulator
SUBB A ,R2 ;Dividend - shifted divisor = result bit (no factor, only 0 or 1)
MOV R0 ,A ;Save updated dividend
MOV A ,R1 ;Move high-byte of dividend into accumulator
SUBB A ,R3 ;Subtract high-byte of divisor (all together 16-bit substraction)
MOV R1 ,A ;Save updated high-byte back in high-byte of divisor
JNC div3 ;If carry flag is NOT set, result is 1
MOV R1 ,07h ;Otherwise result is 0, save copy of divisor to undo subtraction
MOV R0 ,06h
div3:
CPL C ;Invert carry, so it can be directly copied into result
MOV A ,R4
RLC A ;Shift carry flag into temporary result
MOV R4 ,A
MOV A ,R5
RLC A
MOV R5 ,A
DJNZ B ,div2 ;Now count backwards and repeat until "B" is zero
MOV R3 ,05h ;Move result to R3/R2
MOV R2 ,04h ;Move result to R3/R2
RET
KT_LCD:
MOV A,#01H
ACALL GUI_LENH
ACALL DELAY_LCD
MOV A,#38H
ACALL GUI_LENH
MOV A,#0CH
ACALL GUI_LENH
RET
;------------HAM GUI LENH DEN LCD--------
GUI_LENH:
CLR RS
SETB EN
ACALL DELAY
MOV LCD,A
CLR EN
RET
;---------HAM GUI DU LIEU DEN LCD----------
GUI_DULIEU:
SETB RS
SETB EN
ACALL DELAY
MOV LCD,A
CLR EN
RET
;..............................................
DELAY:
MOV R6,#50
DELAY1:
DJNZ R6,DELAY1
RET
;..............................................
DELAY_LCD:
MOV R5,#50
DELAY2:
MOV R6,#100
DELAY3:
DJNZ R6,DELAY3
DJNZ R5,DELAY2
RET
END
ai giúp em làm bài này với. em viết code như dưới mà chạy mô phỏng không đúng
;------KHAI BAO VA DINH NGHIA-----
RS EQU P2.0
EN EQU P2.4
LCD EQU P0
ROW1 EQU P2.7
ROW2 EQU P2.6
COL1 EQU P2.3
COL2 EQU P2.2
COL3 EQU P2.1
STATE1 EQU P1.0
STATE2 EQU P1.1
STATE3 EQU P1.2
XUNG_VAO EQU INT1 ;chan tin hieu dau vao INT1
;-------CHUONG TRINH---------
ORG 0000H
MOV TMOD,#09H ; gate0=1 timer0=mode1 C/#T=0 Bo dem
MOV TCON,#00H
LJMP MAIN
ORG 0013H
NGAT_INT1:
ACALL DO_DORONG_XUNG
ACALL MH_CHINH
RETI
ORG 0030H
MAIN:
SETB EA ; cho phep ngat cuc bo
SETB EX1 ; cho phep ngat ngoai 1
SETB IT1 ; chon cach ngat ngoai 1 la ngat theo suon
ACALL KT_LCD
ACALL MH_CHO
SETB XUNG_VAO
;--------QUET PHIM--------------
QUETPHIM:
SETB ROW1
SETB ROW2
SETB COL1
SETB COL2
SETB COL3
;--------------
CLR ROW1 ; Cho hang 1=0
JNB COL1,KEY1
JNB COL2,KEY2
JNB COL3,KEY3
SETB ROW1
;---------------------------------
CLR ROW2
JNB COL1,KEY4
JNB COL2,KEY5
JNB COL3,KEY6
SETB ROW2
JMP QUETPHIM
;----------------------------------
KEY1:
JNB COL1,KEY1
MOV R7,#'1'
SETB ROW1
CLR STATE1 ; KENH 1 (000)
CLR STATE2
CLR STATE3
JMP FREE
KEY2:
JNB COL2,KEY2
MOV R7,#'2'
SETB ROW1
SETB STATE1 ;KENH2 (001)
CLR STATE2
CLR STATE3
JMP FREE
KEY3:
JNB COL3,KEY3
MOV R7,#'3'
SETB ROW1
CLR STATE1 ;KENH3 (010)
SETB STATE2
CLR STATE3
JMP FREE
KEY4:
JNB COL1,KEY4
MOV R7,#'4'
SETB ROW2
SETB STATE1 ;KENH4 (011)
SETB STATE2
CLR STATE3
JMP FREE
KEY5:
JNB COL2,KEY5
MOV R7,#'5'
SETB ROW2
CLR STATE1 ;KENH5 (100)
CLR STATE2
SETB STATE3
JMP FREE
KEY6:
JNB COL3,KEY6
MOV R7,#'6'
SETB ROW2
SETB STATE1 ; KENH6 (101)
CLR STATE2
SETB STATE3
JMP FREE
;-------------------------------------
FREE:
ACALL MH_CHINH
JMP QUETPHIM
HERE: SJMP HERE ; Cho o day cho den khi co ngat
DO_DORONG_XUNG:
MOV R1,#00H
MOV R0,#00H
KT_XUNG:
MOV TH0,#00 ; Khoi dau gia tri bo dem timer0
MOV TL0,#00
JB XUNG_VAO,TIMER0 ; Cho muc thap cua xung,
;cho den khi muc thap thi tiep tuc chay
;Neu xung dau vao co muc cao thi quay lai,
SJMP KT_XUNG
TIMER0:
SETB TR0 ; chay timer 0
;---------------------------------
XUNG_MTHAP:
JNB XUNG_VAO,XUNG_MTHAP ;neu xung vao co muc thap
MOV R0,TL0 ;lay noi dung byte thap--> R0
MOV R1,TH0 ;lay noi dung byte cao --> R1
CLR TR0
CLR TF0
RET
;-------HIEN THI LCD--------------
MH_CHO:
MOV A,#80h ; ??a con tr? v? ??u d?ng th? nh?t
ACALL GUI_LENH
MOV A,#"K"
ACALL GUI_DULIEU
MOV A,#"e"
ACALL GUI_DULIEU
MOV A,#"n"
ACALL GUI_DULIEU
MOV A,#"h"
ACALL GUI_DULIEU
MOV A,#" "
ACALL GUI_DULIEU
MOV A,#"T"
ACALL GUI_DULIEU
MOV A,#"h"
ACALL GUI_DULIEU
MOV A,#"u"
ACALL GUI_DULIEU
MOV A,#":"
ACALL GUI_DULIEU
MOV A,#" "
ACALL GUI_DULIEU
RET
;-----------DONG 2------------
MH_CHINH:
MOV A,#8Ah
ACALL GUI_LENH
MOV A,R7
ACALL GUI_DULIEU
MOV A, #0C0h ; ??a con tr? v? v? tr? th? nh?t d?ng th? 2
ACALL GUI_LENH
MOV A, #"P"
ACALL GUI_DULIEU
MOV A ,#"W"
ACALL GUI_DULIEU
MOV A,#"="
ACALL GUI_DULIEU
MOV R3,#HIGH(10000)
MOV R2,#LOW(10000)
LCALL DIV16_16
MOV A,R2
ADD A,#30H
ACALL GUI_DULIEU;R5
MOV R3 ,#HIGH(1000)
MOV R2 ,#LOW(1000)
LCALL DIV16_16
MOV A ,R2
ADD A ,#30H
ACALL GUI_DULIEU; R4
MOV R3 ,#HIGH(100)
MOV R2 ,#LOW(100)
LCALL DIV16_16
MOV A ,R2
ADD A ,#30H
ACALL GUI_DULIEU ; R3
MOV R3 ,#HIGH(10)
MOV R2 ,#LOW(10)
LCALL DIV16_16
MOV A ,R2
ADD A ,#30H
ACALL GUI_DULIEU ;R2
MOV A ,R0
SUBB A,#1 ;bu sai so
ADD A ,#30H
ACALL GUI_DULIEU
MOV A,#"u"
ACALL GUI_DULIEU
MOV A,#"s"
ACALL GUI_DULIEU
JMP QUETPHIM
div16_16:
;16-bit division is the division of one 16-bit value by another 16-bit value,
;returning a 16-bit quotient and a 16-bit remainder.
;I used r1/r0 for dividend/remainder and r3/r2 for divisor/quotient.
CLR C ;Clear carry initially
MOV B ,#00h ;Clear B since B will count the number of left-shifted bits
div1:
INC B ;Increment counter for each left shift
MOV A ,R2 ;Move the current divisor low byte into the accumulator
RLC A ;Shift low-byte left, rotate through carry to apply highest bit to high-byte
MOV R2 ,A ;Save the updated divisor low-byte
MOV A ,R3 ;Move the current divisor high byte into the accumulator
RLC A ;Shift high-byte left high, rotating in carry from low-byte
MOV R3 ,A ;Save the updated divisor high-byte
JNC div1 ;Repeat until carry flag is set from high-byte
div2: ;Shift right the divisor
MOV A ,R3 ;Move high-byte of divisor into accumulator
RRC A ;Rotate high-byte of divisor right and into carry
MOV R3 ,A ;Save updated value of high-byte of divisor
MOV A ,R2 ;Move low-byte of divisor into accumulator
RRC A ;Rotate low-byte of divisor right, with carry from high-byte
MOV R2 ,A ;Save updated value of low-byte of divisor
CLR C ;Clear carry, we don't need it anymore
MOV 07h ,R1 ;Make a safe copy of the dividend high-byte
MOV 06h ,R0 ;Make a safe copy of the dividend low-byte
MOV A ,R0 ;Move low-byte of dividend into accumulator
SUBB A ,R2 ;Dividend - shifted divisor = result bit (no factor, only 0 or 1)
MOV R0 ,A ;Save updated dividend
MOV A ,R1 ;Move high-byte of dividend into accumulator
SUBB A ,R3 ;Subtract high-byte of divisor (all together 16-bit substraction)
MOV R1 ,A ;Save updated high-byte back in high-byte of divisor
JNC div3 ;If carry flag is NOT set, result is 1
MOV R1 ,07h ;Otherwise result is 0, save copy of divisor to undo subtraction
MOV R0 ,06h
div3:
CPL C ;Invert carry, so it can be directly copied into result
MOV A ,R4
RLC A ;Shift carry flag into temporary result
MOV R4 ,A
MOV A ,R5
RLC A
MOV R5 ,A
DJNZ B ,div2 ;Now count backwards and repeat until "B" is zero
MOV R3 ,05h ;Move result to R3/R2
MOV R2 ,04h ;Move result to R3/R2
RET
KT_LCD:
MOV A,#01H
ACALL GUI_LENH
ACALL DELAY_LCD
MOV A,#38H
ACALL GUI_LENH
MOV A,#0CH
ACALL GUI_LENH
RET
;------------HAM GUI LENH DEN LCD--------
GUI_LENH:
CLR RS
SETB EN
ACALL DELAY
MOV LCD,A
CLR EN
RET
;---------HAM GUI DU LIEU DEN LCD----------
GUI_DULIEU:
SETB RS
SETB EN
ACALL DELAY
MOV LCD,A
CLR EN
RET
;..............................................
DELAY:
MOV R6,#50
DELAY1:
DJNZ R6,DELAY1
RET
;..............................................
DELAY_LCD:
MOV R5,#50
DELAY2:
MOV R6,#100
DELAY3:
DJNZ R6,DELAY3
DJNZ R5,DELAY2
RET
END