Tổng hợp bài tập ôn tập môn Vi xử lý thông qua thí nghiệm | Đại học Bách khoa Thành phố Hồ Chí Minh
Tổng hợp bài tập ôn tập môn Vi xử lý của Đại học Bách khoa Thành phố Hồ Chí Minh với những kiến thức và thông tin bổ ích giúp sinh viên tham khảo, ôn luyện và phục vụ nhu cầu học tập của mình cụ thể là có định hướng ôn tập, nắm vững kiến thức môn học và làm bài tốt trong những bài kiểm tra, bài tiểu luận, bài tập kết thúc học phần, từ đó học tập tốt và có kết quả cao cũng như có thể vận dụng tốt những kiến thức mình đã học vào thực tiễn cuộc sống. Mời bạn đọc đón xem!
Môn: Vi xử lý (EE2039)
Trường: Đại học Bách khoa Thành phố Hồ Chí Minh
Thông tin:
Tác giả:
Preview text:
lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN Ôn thi TN VXL
Các chương trình con tính toán thường sử dụng
Chia số 16 bit cho số 8 bit
.DEF OPD1_L=R24 ;byte thấp của số nhị phân 16 bit
.DEF OPD1_H=R25 ;byte cao của số nhị phân 16 bit .DEF OPD2=R22 ;Số 8 bit .DEF OPD3=R23 .DEF COUNT=R18
;DIV16_8 chia số nhị phân 16 bit OPD1 cho 8 bit OPD2 (Xem giải thuật chia ở Chương 0)
;Input: OPD1_H,OPD1_L= SBC(GPR16-31) ; OPD2=SC(GPR0-31)
;Output:OPD1_H,OPD1_L=thương số ; OPD3=SD(GPR0-31) ;Sử dụng COUNT(GPR16-31)
;---------------------------------------
DIV16_8: LDI COUNT,16 ;COUNT=đếm 16 CLR OPD3 ;xóa dư số
SH_NXT: CLC ;C=0=bit thương số
LSL OPD1_L ;dịch trái SBC L,bit0=C=thương số
ROL OPD1_H ;quay trái SBC H,C=bit7
ROL OPD3 ;dịch bit7 SBC H vào dư số
BRCS OV_C ;tràn bit C=1,chia được
SUB OPD3,OPD2 ;trừ dư số với số chia BRCC GT_TH ;C=0 chia được
ADD OPD3,OPD2 ;C=1 không chia được,không trừ RJMP NEXT
OV_C: SUB OPD3,OPD2 ;trừ dư số với số chia
GT_TH: SBR OPD1_L,1 ;chia được,thương số=1
NEXT: DEC COUNT ;đếm số lần dịch SBC
BRNE SH_NXT ;chưa đủ tiếp tục dịch bit RET
Chia số 8 bit cho số 8 bit ;SO BI CHIA :R17 ;SO CHIA: R16 ;THƯƠNG SO R17 ;DƯ R16 8DIV8: PUSH R15 CLR R15 LP: SUB R17, R16 BRCS FINAL INC R15 RJMP LP FINAL: ADD R17, R16 MOV R16, R17 MOV R17, R15 POP R15 RET lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
Nhân số 16 bit cho 8 bit
;Số 16bitR17:R16 số 8bit R20 ;OUTPUT số R13:R12:R10 MUL16_8: LDI R20,250 ;NHAN 250 MUL R16,R20 MOV R10,R0 MOV R11,R1 MUL R17,R20 MOV R12,R0 MOV R13,R1 ADD R12,R11 CLR R0 ADC R13,R0 ;R13:R12:R10 RET
Dịch phải số 24 bit 9 lần (chia 512) ;DICH PHAI 10 LAN R13:R12:R10 ;OUTPUT R13:r12 ;cắt bỏ 8 bit thấp R10 SHIFT_R9: LSR R12 BST R13,0 BLD R12,7
LSR R13 ;dịch phải số 16bit 1 lần RET
BÀI 1: I/O PORT - DELAY - LCD BÀI 1
a) Kết nối 1 port của AVR (VD PORT A) vào dip switch. Kết nối 1 port khác vào bar LED (Ví dụ PORT B)
b) Viết chương trình ọc liên tục trạng thái của DIP Switch và gửi ra LED. Nếu Swich ở trạng thái OFF, LED tương ứng sẽ tắt. DIP SWITCH:
- Khai báo INPUT: DDR = 0, iện trở kéo lên: PORT = 1
- Đọc PIN ,1:OFF | 0:ON BARLED/ LED:
- Khai báo OUTPUT: DDR=1
- Xuất PORT: 1:ON .cseg .org 0x00 START: LDI R16, 0x00
OUT DDRA, R16 //PORTA -INPUT -- DIP SW lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN LDI R16, 0xFF OUT PORTA, R16 //DIEN TRO KEO LEN
OUT DDRB, R16 //PORTB -OUTPUT -- BAR LED OUT PORTB, R16
MAIN: IN R17, PINA //PINA = 0 --> 0N -- LED SANG --> PB = 1 COM R17 //PB = NOT(PINA) OUT PORTB, R17 RJMP MAIN //TIEP TUC DOC PIN A BÀI 2
a) Kết nối và thực hiện chương trình 琀 nh 琀 ch của 2 nibble cao và thấp của PORTA và gửi ra PORT B.
Coi như 2 nibble này là 2 số không dấu VD: PORTA = 0b0111_1111, thì PORTB = 7*15.
b) 2 nibble này là 2 số không dấu
Tách 2 Nibble của 1 thanh ghi 8 BIT AND vời $0F hoặc $F0 rồi SWAP
- Số không dấu: MUL R17, R18 bình thường kết quả sẽ lưu dạng R1:R0 (R0 byte thấp) - Số
có dấu: Kiểm tra BIT3 nếu là số âm thì mở rộng bit rôi MULS ;Bai 2a .cseg .org 0x00 START: LDI R16, 0x00
OUT DDRA, R16 //PORTA -INPUT -- DIP SW LDI R16, 0xFF
OUT PORTA, R16 //DIEN TRO KEO LEN
OUT DDRB, R16 //PORTB -OUTPUT -- BAR LED OUT PORTB, R16
MAIN: IN R17, PINA //R17 <-- PINA(DIPSW)
LDI R16, 0x0F //R16 <-- 00001111
AND R16, R17 //R16 <-- NIBBLE THAP
LDI R18, 0xF0 //R16 <-- 11110000
AND R18, R17 //R18 <-- NIBBLE CAO(BYTE CAO)
SWAP R18 //CHUYEN VE BYTE THAP
MUL R18, R16 // R1:R0 <-- NIBBLE CAO x NIBBLE THAP (KO DAU)
OUT PORTB, R0 //PB(BARLED) <-- R0 (BYTE THAP) RJMP MAIN ;Bai 2b .cseg .org 0x00 START: LDI R16, 0x00
OUT DDRA, R16 //PORTA -INPUT -- DIP SW LDI R16, 0xFF
OUT PORTA, R16 //DIEN TRO KEO LEN
OUT DDRB, R16 //PORTB -OUTPUT -- BAR LED OUT PORTB, R16
MAIN: IN R17, PINA //R17 <-- PINA(DIPSW)
LDI R16, 0x0F //R16 <-- 00001111
AND R16, R17 //R16 <-- NIBBLE THAP
SBRC R16, 3 //MO RONG BIT NEU LA SO AM lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN ORI R16, 0xF0
LDI R18, 0xF0 //R16 <-- 11110000
AND R18, R17 //R18 <-- NIBBLE CAO(BYTE CAO)
SWAP R18 //CHUYEN VE BYTE THAP
SBRC R18, 3 //MO RONG BIT NEU LA SO AM ORI R18, 0xF0
MULS R18, R16 // R1:R0 <-- NIBBLE CAO x NIBBLE THAP (CO DAU)
OUT PORTB, R0 //PB(BARLED) <-- R0 (BYTE THAP) RJMP MAIN BÀI 3
a) Viết chương trình con Delay1ms và dùng nó để viết chương trình tạo xung vuông tần số 1Khz trên
PA0. 500hz → TH = TL = 1ms
b) Dùng chương trình con này viết các chương trình con Delay10ms, Delay100ms, Delay1s. Tính MC DELAY:
- Khi CKDIV8 = 1 (không được lập trình), 1 chu kỳ máy (MC) = 125ns ngược lại thì 1MC = 1us - Tách
số MC ra thành 琀 ch, vòng ngoài số nhỏ, Vòng trong số lớn
;{[(4x250-1)+4]x8-1 +1 +4(CALL) +4(RET) = 8032 MC sai so 32MC
;{[(4x249-1)+4]x8-1 +1 +4(CALL) +4(RET) = 8000 MC sai so 0MC DELAY1MS: LDI R16, 8 ;1MC LP1: LDI R17, 249 ;1MC LP2: DEC R17 ;1MC NOP ;1MC BRNE LP2 ;2/1MC DEC R16 ;1MC BRNE LP1 ;2/1MC RET ;4MC lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN DELAY10MS: LDI R18, 10 LP3: CALL DELAY1MS DEC R18 BRNE LP3 RET
DELAY100MS: LDI R18, 100 LP4: CALL DELAY1MS DEC R18 BRNE LP4 RET ;1000 = 4x250
;{[(8002x250-1)+4]x4 -1 +1 +4(CALL) +4(RET) = 8002020 MC sai so 2020MC DELAY1S: LDI R18, 4 ;1MC LP5: LDI R19, 250 ;1MC LP6: RCALL DELAY1MS;7999MC DEC R19 ;1MC BRNE LP6 ;2/1MC DEC R18 ;1MC BRNE LP5 ;2/1MC RET ;4MC
; INPUT:R16 Thơi gian delay = R16.100us
;------------------------------------------------------- DELAY_US:
MOV R15,R16 ;1MC n?p data cho R15 LDI R16,200 ;1MC s? d?ng R16
L1: MOV R14,R16 ;1MC n?p data cho R14 L2: DEC R14 ;1MC NOP ;1MC BRNE L2 ;2/1MC DEC R15 ;1MC BRNE L1 ;2/1MC RET ;4MC Bài 4: a)
Kết nối các tín hiệu cần thiết từ 1 port của AVR ến các tín hiệu iều khiển thanh ghi dịch trên
header J13. Kết nối ngõ ra của thanh ghi dịch ến Bar LED. b)
Dùng các chương trình trong ví dụ mẫu trong tài liệu hướng dẫn thì nghiệm, viết chương trình tạo
hiệu ứng LED sáng dần từ trái qua phải, sau o tắt dần từ trái qua phải sau mỗi khoảng thời gian 500ms. Thanh ghi dịch: lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN - Các chân: SDI (DS) Tín hiệu data cần dịch LACK (ST_CP)
Xung cạnh lên lưu data thanh ghi dịch vào thanh
ghi lưu trữ nếu tín hiệu OE = 0 thì xuất ra chân Q luôn CLK (SH_CP)
Xung cạnh lên ể dịch bit từ chân SDI vào thanh
ghi dịch và dịch trái thanh ghi dịch /CLR (/MR)
Bằng = 0 thì xoá data thanh ghi dịch cần delay 100ms
- Các thao tác thiết lập:
+ Khai báo 4 output iều khiển
+ Lack, Clk = 0 (có thể bỏ qua) + Xoá Data, MR =1 - Các thao tác: Xoá DATA
SBI port, MR chờ 100ms CBI port, MR
Dịch nối tiếp data tư thanh ghi MCU vào thanh
Kiểm tra bit7(bit0) của thanh ghi MCU ặt tín
ghi dịch (mỗi cạnh lên 1 bit)
hiệu SDI tương ứng CLK =1 CLK =0
dịch trái(phải) thanh ghi MCU.
Đẩy song song data từ thanh ghi dịch vào thanh Lack = 1 Lack 0 ghi lưu trữ lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
.include "m324padef.inc" ; Include Atmega324pa definitions
.DEF DATAR = R20 ;KHAI BÁO THANH GHI CHỨA DATA CẦN DỊCH
.EQU SRPORT = PORTA ; KHAI BÁO PORTA ĐIỀU KHIỂN .EQU SRDDR = DDRA .EQU SDI = 0 ;PA0 .EQU LACK = 1 .EQU CLK = 2
.EQU MR = 3 ;MR NHẬN 0 = XOÁ MAIN: RCALL INITPORT RCALL XOADATA LOOP: RCALL DELAY500MS LDI DATAR, 0B10000000 RCALL SANGDAN LDI DATAR, 0B11111111 RCALL TATDAN RJMP LOOP INITPORT:
LDI R16, 0X0F; BAT 4 CHAN DIEU KHIEN LA OUTPUT OUT SRDDR, R16 RET XOADATA: CBI SRPORT, MR RCALL DELAY500MS SBI SRPORT, MR TATDAN:
LDI R19, 9 ;DÊM HIEN THI 8 LAN LOOPLACK:
LDI R18, 8; ĐẾM DỊCH 8 BIT
MOV R15, DATAR ;THANH GHI CÁC TRẠNG THÁI HIEN THI LSR DATAR ; THAY ĐỔI CHIEU LOOPCLK:
SBRC R15, 7 ;KIEM TRA BIT 7(0) THANH GHI DATA SBI SRPORT, SDI SBI SRPORT, CLK ; DỊCH BIT CBI SRPORT, CLK
LSL R15 ;DỊCH TRAI(PHAI)THANH GHI TRANG THAI CBI SRPORT, SDI DEC R18 lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN BRNE LOOPCLK
SBI SRPORT, LACK ;HIEN THI RA BAR CBI SRPORT, LACK RCALL DELAY500MS DEC R19 BRNE LOOPLACK RET SANGDAN:
LDI R19, 8 ;DÊM HIEN THI 8 LAN LOOPLACK2:
LDI R18, 8; ĐẾM DỊCH 8 BIT
MOV R15, DATAR ;THANH GHI CÁC TRẠNG THÁI HIEN THI ASR DATAR ; THAY ĐỔI CHIEU LOOPCLK2:
SBRC R15, 7 ;KIEM TRA BIT 7(0) THANH GHI DATA SBI SRPORT, SDI SBI SRPORT, CLK ; DỊCH BIT CBI SRPORT, CLK
LSL R15 ;DỊCH TRAI(PHAI)THANH GHI TRANG THAI CBI SRPORT, SDI DEC R18 BRNE LOOPCLK2
SBI SRPORT, LACK ;HIEN THI RA BAR CBI SRPORT, LACK RCALL DELAY500MS DEC R19 BRNE LOOPLACK2 RET
;{[(4x250-1)+4]x8-1 +1 +4(CALL) +4(RET) = 8032 MC sai so 32MC
;{[(4x249-1)+4]x8-1 +1 +4(CALL) +4(RET) = 8000 MC sai so 0MC DELAY1MS: PUSH R16 PUSH R17 LDI R16, 8 ;1MC LP1: LDI R17, 249 ;1MC LP2: DEC R17 ;1MC NOP ;1MC BRNE LP2 ;2/1MC DEC R16 ;1MC BRNE LP1 ;2/1MC POP R17 POP R16 RET ;4MC DELAY500MS: PUSH R18 PUSH R19 LDI R18, 2 ;1MC LP5: LDI R19, 250 ;1MC LP6: RCALL DELAY1MS;7999MC DEC R19 ;1MC BRNE LP6 ;2/1MC DEC R18 ;1MC BRNE LP5 ;2/1MC lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN POP R19 POP R18 RET ;4MC lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN Bài 5: c)
Kết nối 1 switch ến 1 chân port của AVR, kết nối module BAR LED ến 1 port
của AVR, kết nối LCD ến 1 port của AVR d)
Viết chương trình ếm số lần nhấn phím và hiển thị ra LCD LCD : - Thiết lập LCD : Kết nối các chân: RS (Chọn thanh ghi)
=0 chọn thanh ghi lệnh | =1 chọn thanh ghi data RW
=0 ghi dữ liệu vào LCD | =1 ọc dữ liệu từ LCD EN
Xung cạnh lên ể truy xuất LCD. Ở chế ộ 4bit mỗi
xung chỉ truyền ược 4bit (Cao trước) nên cần 2 xung. D4,D5,D6,D7
4 chân Data ọc hay ghi ều ẩy lên byte cao Truyền lệnh:
- Đặt byte cao của lệnh lên tín hiệu data
- RS = 0 ể chọn thanh ghi lệnh - RW = 0 chọn chế ộ ghi
- Xung EN cạnh lên ể truyền lệnh - Delay 50ms - SWAP byte lệnh
- Xung EN cạnh lên ể truyền lệnh - Delay 50ms
;RS=0-> lenh| =1 -> data
;Input: R17 chứa mã lệnh/data 4 bit cao lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
;-------------------------------------------------- OUT_LCD4: OUT LCDPORT,R17 SBI LCDPORT,EN CBI LCDPORT,EN RET OUT_LCD: LDI R16,1 ;chờ 100us RCALL DELAY_US
IN R16,LCDPORT ;đọc PORT LCD
ANDI R16,(1<PUSH R16 ;cât R16 PUSH R17 ;cất R17 ANDI R17,$F0 ;lấy 4 bit cao OR R17,R16 ;ghép bit RS
RCALL OUT_LCD4 ;ghi ra LCD LDI R16,1 ;chờ 100us RCALL DELAY_US POP R17 ;phuc hôi R17, r16 POP R16
SWAP R17 ;đảo byte thấp lệnh lên
ANDI R17,$F0 ;l?y 4 bit th?p chuy?n thành cao OR R17,R16 ;ghép bit RS
RCALL OUT_LCD4 ;ghi ra LCD RET Mã lệnh (hex) Chức năng 01 Xoá màn hình 02
Trở về vị trí ầu dòng 04
Con trỏ dịch trái sau mỗi lần ọc /ghi 05
Dịch màn hình sang phải sau mỗi lần ọc /ghi 06
Con trỏ dịch phải sau mỗi lần ọc /ghi 07
Dịch màn hình sang trái sau mỗi lần ọc /ghi 08
Tắt màn hình và con trỏ 0A
Tắt màn hình, hiện con trỏ 0C
Hiện màn hình, tắt con trỏ 0E
Hiện màn hình, kí tự ược trỏ ko nhấp nháy 0F
Hiện màn hình, kí tự ược trỏ nhấp nháy 10 Dịch con trỏ sang trái 14 Dịch con trỏ sang Phải 18 Dịch màn hình sang trái 1C Dịch màn hình sang phải 80 8F
Chuyển con trỏ ến ầu dòng 1 cuối dòng 1 C0 CF
Chuyển con trỏ ến ầu dòng 2 cuối dòng 2 38
Giao tiếp 8bit , 2 dòng, 5x8 dot 28
Giao tiếp 4bit , 2 dòng, 5x8 dot Khởi ộng LCD lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN RESET_LCD:
LDI R16,250 ;delay 25ms RCALL DELAY_US ;ctc delay 100usxR16 LDI R16,250 ;delay 25ms RCALL DELAY_US
LDI R16, 0XFF ;SET OUTPUT CHO PORTLCD OUT LCDDDR, R16 CBI LCDPORT,RS ;RS=0 ghi l?nh
LDI R17,$30 ;mã lênh=$30 lần 1 RCALL OUT_LCD4 LDI R16,42 ;delay 4.2ms RCALL DELAY_US CBI LCDPORT,RS
LDI R17,$30 ;mã lệnh=$30 lần 2 RCALL OUT_LCD4 LDI R16,2 ;delay 200us RCALL DELAY_US CBI LCDPORT,RS LDI R17,$20 ;mã lệnh=$20 RCALL OUT_LCD4 RET INIT_LCD4: CBI LCDPORT,RS ;RS=0 ghi l?nh
LDI R17,$28 ;Function set - giao tiep 4 bit, 1 dòng, font 5x8 RCALL OUT_LCD CBI LCDPORT,RS ;RS=0 ghi l?nh LDI R17,$01 ;Clear display RCALL OUT_LCD
LDI R16,20 ;ch? 2ms sau l?nh Clear display RCALL DELAY_US CBI LCDPORT,RS ;RS=0 ghi l?nh
LDI R17,$0C ;hiện màn hình, tắt con trỏ RCALL OUT_LCD CBI LCDPORT,RS ;RS=0 ghi l?nh
LDI R17,$06 ;con trỏ dịch phải sau mỗi lần đọc/ghi RCALL OUT_LCD RET
Xuất số BCD 2 nibble trong thanh ghi R17 ra LCD NUM_DISP: PUSH R17 ;cất data
SWAP R17 ;đưa nibble cao ve thap
ANDI R17,0X0F ;che lây số BCD cao
ORI R17,0X30 ;chuyển sang mã ASCII cộng 0x30 SBI LCDPORT,RS ;RS=1 ghi data LDI R16,1 ;chờ 100us RCALL DELAY_US
RCALL OUT_LCD ;hiển thị giá trị POP R17 ;phục hồi data
;nếu R17 là 1 BCD ko nén chỉ cần khúc dưới
ANDI R17,0X0F ;che lấy số BCD thấp
ORI R17,0X30 ;chuyển sang mã ASCII và tương tự lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN SBI LCDPORT,RS LDI R16,1 RCALL DELAY_US RCALL OUT_LCD RET
Hiển thị một chuỗi ký tự kết thúc bằng null trong flash rom .ORG 0X200 MSG1: .DB "THU " ,$00 MSG2: .DB "NGAY" ,$00
- Đưa ịa chỉ bắt ầu chuỗi vào con trỏ Z LDI ZH,HIGH(MSG1<<1) LDI ZL,LOW(MSG1<<1)
- Đưa con trỏ LCD ến vị trí bắt ầu hiển thị MSG_DISP:
LPM R17,Z+ ;lấy mã ASCII ký tự từ Flash ROM
CPI R17, $00 ;kiểm tra ký tụ kết thúc
BREQ EXIT_MSG ;ký tự NULL thoát LDI R16,1 ;chờ 100us RCALL DELAY_US
SBI LCDPORT,RS ;RS=1 ghi data hiển thị LCD
RCALL OUT_LCD ;ghi mã ASCII ký tu ra
LCD RJMP MSG_DISP ;tiếp tục EXIT_MSG: RET
VD: iếm số lần nhấn nút hiển thi ra barled và LCD lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
.include "m324padef.inc" ; Include Atmega324pa definitions
.org 0x0000 ; interrupt vector table RJMP MAIN
;******************************* Program ID ********************************* .org 0x200
line1: .db "SO LAN NHAN NUT: ",0
.equ LCDPORT = PORTA ; Set signal port reg to PORTA
.equ LCDDDR = DDRA ; Set signal port dir reg to PORTA
.equ LCDPIN = PINA ; Set clear signal port pin reg to PORTA .equ RS = 0 .equ RW = 1 .equ EN = 2 .ORG 0x40 MAIN: LDI R16, 0xFF
OUT DDRB, R16 ; PORTB - BAR LED
CBI DDRC, 0; PINC0 - NUT NHAN
SBI PORTC, 0; DIEN TRO KEO LEN RCALL RESET_LCD RCALL INIT_LCD4
LDI R18, 0 ; BIEN DEM SO LAN NHAN LOOP:
OUT PORTB, R18 ;XUAT RA BARLED
ldi ZH, high(line1<<1) ; point to the information that is to be displayed lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
ldi ZL, low(line1<<1) CBI LCDPORT, RS ; XUAT LENH LDI R17, 0X80 RCALL OUT_LCD RCALL MSG_DISP CBI LCDPORT, RS LDI R17, 0XC7 ; GIUA DONG 2 RCALL OUT_LCD MOV R17, R18
RCALL CHUYENTHANHBCD ;NIBBLE CAO R17 / THAP R16 MOV R10, R16
RCALL NUM_DISP ; IN SO TRONG R17 RA MOV R17, R10 RCALL NUM_DISP
KIEMTRANUTNHAN: ; CO CHONG RUNG SBIC PINC, 0 RJMP KIEMTRANUTNHAN LDI R16, 1 RCALL DELAY_US SBIC PINC, 0 RJMP KIEMTRANUTNHAN INC R18 WAITBUT: SBIS PINC, 0 ;CHO NHA PHIM RJMP WAITBUT CBI LCDPORT, RS LDI R17, $01 RCALL OUT_LCD LDI R16, 200 RCALL DELAY_US RJMP LOOP
;RS=0-> lenh| =1 -> data
;Input: R17 chứa mã lệnh/data 4 bit cao
;-------------------------------------------------- OUT_LCD4: OUT LCDPORT,R17 SBI LCDPORT,EN CBI LCDPORT,EN RET OUT_LCD: LDI R16,1 ;chờ 100us RCALL DELAY_US
IN R16,LCDPORT ;đọc PORT LCD
ANDI R16,(1<PUSH R16 ;cât R16 PUSH R17 ;cất R17 ANDI R17,$F0 ;lấy 4 bit cao OR R17,R16 ;ghép bit RS RCALL OUT_LCD4 ;ghi ra LCD lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN LDI R16,1 ;chờ 100us RCALL DELAY_US POP R17 ;phuc hôi R17, r16 POP R16
SWAP R17 ;đảo byte thấp lệnh lên lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
ANDI R17,$F0 ;l?y 4 bit th?p chuy?n thành cao OR R17,R16 ;ghép bit RS RCALL OUT_LCD4 ;ghi ra LCD RET RESET_LCD: LDI R16,250 ;delay 25ms
RCALL DELAY_US ;ctc delay 100usxR16 LDI R16,250 ;delay 25ms RCALL DELAY_US
LDI R16, 0XFF ;SET OUTPUT CHO PORTLCD OUT LCDDDR, R16 CBI LCDPORT,RS ;RS=0 ghi l?nh
LDI R17,$30 ;mã lênh=$30 lần 1 RCALL OUT_LCD4 LDI R16,42 ;delay 4.2ms RCALL DELAY_US CBI LCDPORT,RS
LDI R17,$30 ;mã lệnh=$30 lần 2 RCALL OUT_LCD4 LDI R16,2 ;delay 200us RCALL DELAY_US CBI LCDPORT,RS LDI R17,$20 ;mã lệnh=$20 RCALL OUT_LCD4 RET INIT_LCD4: CBI LCDPORT,RS ;RS=0 ghi l?nh
LDI R17,$28 ;Function set - giao tiep 4 bit, 1 dòng, font 5x8 RCALL OUT_LCD CBI LCDPORT,RS ;RS=0 ghi l?nh LDI R17,$01 ;Clear display RCALL OUT_LCD
LDI R16,20 ;ch? 2ms sau l?nh Clear display RCALL DELAY_US CBI LCDPORT,RS ;RS=0 ghi l?nh
LDI R17,$0C ;hiện màn hình, tắt con trỏ RCALL OUT_LCD CBI LCDPORT,RS ;RS=0 ghi l?nh
LDI R17,$06 ;con trỏ dịch phải sau mỗi lần đọc/ghi RCALL OUT_LCD RET NUM_DISP:
;nếu R17 là 1 BCD ko nén chỉ cần khúc dưới
ANDI R17,0X0F ;che lấy số BCD thấp
ORI R17,0X30 ;chuyển sang mã ASCII và tương tự SBI LCDPORT,RS LDI R16,1 RCALL DELAY_US RCALL OUT_LCD RET lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN MSG_DISP:
LPM R17,Z+ ;lấy mã ASCII ký tự từ Flash ROM
CPI R17, $00 ;kiểm tra ký tụ kết thúc lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
BREQ EXIT_MSG ;ký tự NULL thoát LDI R16,1 ;chờ 100us RCALL DELAY_US
SBI LCDPORT,RS ;RS=1 ghi data hiển thị LCD
RCALL OUT_LCD ;ghi mã ASCII ký tu ra
LCD RJMP MSG_DISP ;tiếp tục EXIT_MSG: RET
; INPUT:R16 Thơi gian delay = R16.100us
;------------------------------------------------------- DELAY_US:
MOV R15,R16 ;1MC n?p data cho R15 LDI R16,200 ;1MC s? d?ng R16
L1: MOV R14,R16 ;1MC n?p data cho R14 L2: DEC R14 ;1MC NOP ;1MC BRNE L2 ;2/1MC DEC R15 ;1MC BRNE L1 ;2/1MC RET ;4MC ;SO CAN CHUYEN:R17 ;NIBBLE CAO R17 ;NIBBLE THAP R16 CHUYENTHANHBCD: PUSH R15 CLR R15 LDI R16, 10 LP: SUB R17, R16 BRCS FINAL INC R15 RJMP LP FINAL: ADD R17, R16 MOV R16, R17 MOV R17, R15 POP R15 RET lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN ;SO BI CHIA :R17 ;SO CHIA: R16 ;THƯƠNG SO R17 ;DƯ R16 8DIV8: PUSH R15 CLR R15 LP: SUB R17, R16 BRCS FINAL INC R15 RJMP LP FINAL: ADD R17, R16 MOV R16, R17 MOV R17, R15 POP R15 RET
Bàn phím ma trận (Key pad)
- Quét từ cột C3C0 biến ếm R24
- Ở từng cột quét từ r0r3 bien ếm R23
Nếu không tìm thấy output = FF
Giá trị = hàng * 4 + cột lưu vào R24 lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
keypad_scan: ;OUTPUT R24:0-F NOTFOUND FF PUSH R20 PUSH R22 PUSH R23 ldi r20, 0b00001111 ; R3210
C3210 bits as output out DDRD, r20
ldi r20, 0b11111111 ; enable pull up resistor out PORTD, r20
ldi r22, 0b11110111 ; BAT DAU QUET TU
C3 ldi r23, 0 ; BAT DAU QUET TU R0 ldi r24,3 ; DEM COT DANG QUET
keypad_scan_loop: out PORTD, r22 ; scan
current col nop ;need to have 1us delay to stablize nop nop sbic PIND, 4 ; KIEM TRA RO rjmp keypad_scan_check_col2
rjmp keypad_scan_found ; HANG 0 DUOC NHAN
R23=0 keypad_scan_check_col2: sbic PIND, 5 ;
check row 1 rjmp keypad_scan_check_col3 ldi
r23, 1 ; HANNG 1 DUOC NHAN R23 =1 rjmp
keypad_scan_found keypad_scan_check_col3: sbic PIND, 6 ; check row 2 rjmp
keypad_scan_check_col4 ldi r23, 2 ; row 2 is
pressed rjmp keypad_scan_found
keypad_scan_check_col4: sbic PIND, 7 ; check
row 3 rjmp keypad_scan_next_row ldi r23, 3 ;
row 3 is pressed rjmp keypad_scan_found keypad_scan_next_row:
; check if all rows have been scanned cpi r24,0 breq keypad_scan_not_found
; DICH MAT NA SANG PHAI DE QUET HANG NHO HON ror r22 dec r24 ;DEcrease row index rjmp keypad_scan_loop keypad_scan_found:
; combine row and column to get key value (0-15) ;key code = row*4 + col
lsl r23 ; shift row value 4 bits to the left lsl r23
add r24, r23 ; add row value to column
value ret keypad_scan_not_found:
ldi r24, 0xFF ; no key pressed ret
In giá trị hex trong R17 ra LCD lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN HEX_DISP: PUSH R17 ;cất data
SWAP R17 ;đưa nibble cao ve thap
ANDI R17,0X0F ;che lây số hex byte cao
CPI R17, 0X0A ;SO SANH VƠI A NẾU LÀ CHỮ THÌ CỘNG 55 BRCC HEXCHU
ORI R17,0X30 ;chuyển sang mã ASCII cộng 0x30 RJMP XUATHEX1 HEXCHU:
SUBI R17, -55 ; VÌ A UNG VOI 65 XUATHEX1: SBI LCDPORT,RS ;RS=1 ghi data LDI R16,1 ;chờ 100us RCALL DELAY_US
RCALL OUT_LCD ;hiển thị giá trị POP R17 ;phục hồi data
; NẾU XUẤT 1 KY TU HEX BYTE THAP THI DUNG T ĐÂY
ANDI R17,0X0F ;che lây số hex byte THAP
CPI R17, 0X0A ;SO SANH VƠI A NẾU LÀ CHỮ THÌ CỘNG 55 BRCC HEXCHU2
ORI R17,0X30 ;chuyển sang mã ASCII cộng 0x30 RJMP XUATHEX2 HEXCHU2:
SUBI R17, -55 ; VÌ A UNG VOI 65 XUATHEX2: SBI LCDPORT,RS ;RS=1 ghi data LDI R16,1 ;chờ 100us RCALL DELAY_US
RCALL OUT_LCD ;hiển thị giá trị RET
BÀI 2: TIMER – LED 7 ĐOẠN – LED MA TRẬN TIMER: Các thanh ghi: lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
Timer 8bit timer 0, timer 2
Chọn chế ộ làm việc timer: TIMER0 OUT | 1,2 STS lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN Chọn nguồn clock timer:
Timer2 không có ếm sự kiện ngoài như timer0,1 thiết lập chia tần cũng khác lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
CHÂN ĐẾM SỰ KIỆN TIMER 0: PB0 Các cờ timer: Chế ộ NOR:
- Chọn MODE hoạt ộng và chưa cấp xung CLK(fTIMER=0) cho bộ Timer hoạt ộng.
WGM02, WGM01, WGM00=000 (NOR), Nạp vào các thanh ghi iều khiển TCCR0A, TCCR0B.
- Nạp giá trị ặt trước vào thanh ghi TCNT0. Cần ếm N xung thì nạp -N
- Chọn tần số CLK cho bộ timer và nạp vào thanh ghi TCCR0B: CS02, CS01,
CS00=??? Khi cấp CLK cho Timer thì bộ ếm bắt ầu hoạt ộng ếm lên từ giá trị ặt trong thanh ghi TCNT0.
- Liên tục kiểm tra cờ TOV0 bằng vòng lặp ể phát hiện khi nào TOV0=1 là Timer0
tràn, thoát khỏi vòng lặp.
- Ngừng Timer0 bằng cách nạp CS02:CS00=000.
- Xóa cờ TOV0 bằng cách ghi 1 vào bit TOV0, ể phát hiện lần tràn kế tiếp.
VD: Viết chương trình tạo 1 xung vuông 64 us sử dụng timer 0 ở chế ộ Normal mode.
Ngõ ra sử dụng chân OC0. Chế ộ CTC:
- Nạp giá trị ặt trước (n-1){ với n là số xung cần ếm} vào các thanh ghi ORC0A và
ORC0B.(giá trị TOP phải ặt trong ORC0A). lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
- Chọn MODE hoạt ộng và tần số CLK cho bộ timer nạp vào các thanh ghi iều khiển
TCCR0A và TCCR0B WGM02, WGM01, WGM00=010 (CTC) CS02, CS01, CS00=???
(phụ thuộc việc chọn hệ số chia tần N).
- Liên tục kiểm tra các cờ OCF0x bằng vòng lặp ể phát hiện khi nào OCF0x=1 là ạt kết
quả so sánh bằng, thoát khỏi vòng lặp.
- Xóa cờ OCF0x bằng cách ghi 1 vào bit OCF0x ể phát hiện lần báo kết quả so sánh bằng kế tiếp.
VD: Viết chương trình con delay 1 ms sử dụng timer 0. Sử dụng chương trình con này
ể tạo xung 500hz trên chân PA0. ;bai1 LDI R18, 0X01
OUT DDRA, R18 ;SET PA0 LA OUTPUT START: IN R19, PORTA EOR R19, R18 ; DAO BIT PA0 OUT PORTA, R19 CALL DELAY1MS RJMP START
;Tdelay = 1ms = 125. 125ns. 64 DELAY1MS:
LDI R16, 124 ;NAP n-1 VOI n LA SO XUNG CAN DEM
OUT OCR0A, R16 ;NAP GIA TRI TOP CHO OCR0A
LDI R16, 0b0000_0010 ;THIET LAP MODE CTC
OUT TCCR0A, R16 ;NAP CHO TCCR0A
LDI R16, 0b0000_0011 ;CHON THANG CLK CHIA 64 --> SAU 64MC(8us)THANH GHI DEM TANG 1
OUT TCCR0B, R16 ;NAP CHO TCCR0B XONG, TIMER BAT DAU CHAY LP1: IN R17, TIFR0
SBRS R17, OCF0A ;KIEM TRA CO OCF0A RJMP LP1 LDI R16, 0X00 OUT TCCR0B, R16 ; DUNG TIMER
OUT TIFR0, R17 ; XUAT 1 DE XOA CO RET
Ứng dụng tạo xung Timer: cần chỉnh DDR =1 cho port lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
VD: Viết chương trình thực hiện tạo xung vuông có chu kỳ 64 us sử dụng timer 0 ở chế ộ
CTC mode. Ngõ ra sử dụng chân OC0. ;bai2B:
SBI DDRB, 3 ;SET OCA LA OUTPUT ;32us = 256. 125ns. 1 ;KHONG CAN HIEU CHINH TIMER32US:
LDI R16, 255 ;NAP n-1 VOI n LA SO XUNG CAN DEM
OUT OCR0A, R16 ;LUU VAO OCR0A
LDI R16, 0b0100_0010 ;THIET LAP MODE CTC, OCA DAO BIT KHI OCR0A BANG GIA TRI BO DEM
OUT TCCR0A, R16 ;NAP CHO TCCR1A
LDI R16, 0b0000_0001 ;CHON THANG CLK CHIA 1 --> SAU 1MC(125ns)THANH GHI DEM TANG 1 OUT
TCCR0B, R16 ;NAP CHO TCCR1B XONG, TIMER BAT DAU CHAY LP: RJMP LP
Mode FPWM1: Khi ếm trở về BOTTOM, ngõ ra OcnA/B ược ặt lên 1 cùng lúc .org 00 call initTimer0 start: lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN rjmp start initTimer0:
// Set OC0A (PB3) and OC0B (PB4) pins as outputs
ldi r16, (1 << PB3) | (1 << PB4); out DDRB,r16
ldi r16, (1 << COM0B1)|(1 << COM0A1) | (1 << WGM00)|(1 << WGM01)
;Mode FPWM1 , Xoá OC0A, OC0B khi đại giá trị so sánh out TCCR0A,r16 // setup TCCR0A ldi r16, (1 << CS01)
out TCCR0B,r16 // setup TCCR0B ldi r16, 100 out OCR0A,r16 //OCRA = 100 ldi r16, 75 out OCR0B,r16 //OCRB = 75 ret Mode FPWM2 : 1) a.
Sử dụng mode FPWM2: khi timer ếm ến giá trị ặt trong OCR0B thì tín hiệu ngõ ra
OC0B bị xoá xuống 0(tuỳ chọn cài ặt COM), sau ó khi timer ếm ến giá trị top trong
OCR0A thì timer sẽ trở về bottom và OC0B ược ặt lên 1. b.
Giá trị ưa vào các thanh ghi của timer 0:
Giả sử fOSC=8MHz Tosc = 125ns / MC
F=1khz T = 1ms = n . Tosc . N = 125. 125ns. 64 + n: số lần ếm
+ Tosc thời gian 1 chu kỳ máy MC
+ N hệ số chia tần: 1, 8, 64, 256, 1024
Thiết lập mode FPWM2, hệ số chia tần 64 -TCCR0A = 0x23 -TCCR0B = 0x0B
Thiết lập chu kỳ 1ms cho xung -OCR0A = 124 (n-1) Thiết lập duty cycle 25% -OCR0B = 31 (25% cua 124) ;Bai5a:
;f=1khz--> T = 1ms = 125. 125ns. 64 .org 00 call initTimer0 start: lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN rjmp start initTimer0:
// Set OC0B (PB4) pins as outputs ldi r16, (1 << PB4); out DDRB,r16
ldi r16, (1 << COM0B1) | (1 << WGM00)|(1 << WGM01)
; XUAT 0 KHI DAT GIA TRI SO SANH, DAT 1 KHI DAT BOTTOM , MODE FPWM2 out TCCR0A,r16 // setup TCCR0A
ldi r16, (1 << CS01)|(1 << CS00)|(1 << WGM02) ;CHIA 64
out TCCR0B,r16 // setup TCCR0B ldi r16, 124 out OCR0A,r16 //OCRA = 124 (chu ky 1ms) ldi r16, 31 out OCR0B,r16 //OCRB = 31 (25% cua 124) ret lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN ;Bai5c:
;f=1khz--> T = 1ms = 125. 125ns. 64 .org 00 call initTimer0 ldi r19, 0 tang: ;tang dan duty cycle cpi r19, 124 breq giam subi r19, -1 out OCR0B,r19
rcall DELAY10MS ;su dung timer2 de delay rjmp tang giam: ;giam dan duty cycle cpi r19, 0 breq tang subi r19, 1 out OCR0B,r19 rcall DELAY10MS rjmp giam initTimer0:
// Set OC0B (PB4) pins as outputs ldi r16, (1 << PB4); out DDRB,r16
ldi r16, (1 << COM0B1) | (1 << WGM00)|(1 << WGM01)
; XUAT 0 KHI DAT GIA TRI SO SANH, DAT 1 KHI DAT BOTTOM , MODE FPWM2 out TCCR0A,r16 // setup TCCR0A
ldi r16, (1 << CS01)|(1 << CS00)|(1 << WGM02) ;CHIA 64 out TCCR0B,r16 // setup TCCR0B ldi r16, 124 out OCR0A,r16 //OCRA = 124 (chu ky 1ms) ldi r16, 0 out OCR0B,r16
//OCRB dieu chinh do rong xung ret DELAY10MS:
LDI R16, 77 ;NAP n-1 VOI n LA SO XUNG CAN DEM
STS OCR2A, R16 ;NAP GIA TRI TOP CHO OCR0A
LDI R16, 0b0000_0010 ;THIET LAP MODE CTC
STS TCCR2A, R16 ;NAP CHO TCCR0A
LDI R16, 0b0000_0101 ;CHON THANG CLK CHIA 1024
STS TCCR2B, R16 ;NAP CHO TCCR0B XONG, TIMER BAT DAU CHAY LP1: IN R17, TIFR2
SBRS R17, OCF2A ;KIEM TRA CO OCF0A RJMP LP1 LDI R16, 0X00 STS TCCR2B, R16 ; DUNG TIMER
OUT TIFR2, R17 ; XUAT 1 DE XOA CO RET lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN TIMER1
Hiển thị lên 1 led 7 oạn:
Có thể kết hợp delay hiển thị lần lượt các led tiếp theo 50HZ mỗi led delay 5ms lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN .EQU LED7PORT = PORTD .EQU LED7DDR = DDRD .EQU LACKPORT = PORTA .EQU LACKDDR = DDRA .EQU LE0 = 0 .EQU LE1 = 1 .ORG 0X00 RJMP MAIN .ORG 0X40 MAIN: RCALL led7portinit
LDI R26, 0 ;CHỌN LED0 (HANG DON VI)
LDI R27, 15 ; HIEN THI GIA TRI RCALL display_7seg WAIT: RJMP WAIT led7portinit: push R16
ldi R16, 0xFF ; SET led7seg PORT as output out LED7DDR, R16
in r16, LACKDDR ; read the Latch Port direction register ori r16, (1< lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN pop r16 ret
display_7seg: ;INPUT GIÁ TRỊ TRONG R27 ; VI TRI LED TRONG R26 (0-3) push r16
;BẢNG DATA ANNOT CHUNG --> 0 = ON
ldi zh,high(table_7seg_data<<1) ;
ldi zl,low(table_7seg_data<<1) ; clr r16 add r30, r27 ; TRA BẢNG adc r31,r16 lpm r16, z out LED7PORT, r16 sbi LACKPORT, LE0 nop nop cbi LACKPORT, LE0
ldi zh,high(table_7seg_control<<1) ; ldi
zl,low(table_7seg_control<<1) ; clr
r16 add r30, r26 adc r31,r16 lpm r16, z out LED7PORT,r16 sbi LACKPORT,LE1 nop nop cbi LACKPORT,LE1
pop r16 ; Restore the temporary register
ret ; Return from the function
; Lookup table for 7-segment codes
table_7seg_data: .DB $C0,$F9,$A4,$B0,$99,$92,$82,$F8,$80,$90,$88,$83,$C6,$A1,$86,$8E
; Lookup table for LED control
table_7seg_control: .DB 0b00001110,0b00001101, 0b00001011, 0b0000011
Quét led 7 oạn: cần 1 port data và 2 chân lack LE0, LE1 -
Tra bảng Led 7 oạn xuất data ra port
- Xung cạnh lên vào chốt LE0: LE0 = 1; nop nop; LE0 = 0
- Tra bảng iều kiển chọn led (xuất 0 led sáng) xuất data ra port
- Xung cạnh lên vào chốt LE1 - Delay, chuyển LED
VD: Đọc giá trị từ DIPSW, nhân 9, chuyển thành số BCD 4 chữ số lưu trong DRAM,
xuất ra 4 LED 7 oạn, sử dụng ngắt timer 1 tần số 50hz (mỗi 5ms tiến hành 1 lần) .EQU LED7PORT = PORTD .EQU LED7DDR = DDRD .EQU LACKPORT = PORTA .EQU LACKDDR = DDRA lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN .EQU LE0 = 0 .EQU LE1 = 1
;CHUYỂN DOI SO NHI PHAN 16 BIT TO BCD
.EQU BCD_BUF=0X200 ;đ/c đầu SRAM lưu số BCD (kq chuyển từ số 16 bit) SRAM
.DEF OPD1_L=R24 ;byte thấp của số nhị phân 16 bit
.DEF OPD1_H=R25 ;byte cao của số nhị phân 16 bit .DEF OPD2=R22 .DEF OPD3=R23 .DEF COUNT=R18 .ORG 0X0000 RJMP MAIN .ORG 0X001A JMP TIMER1_COMPA_ISR .ORG 0X0040 MAIN: RCALL led7portinit LDI R16, 0 OUT DDRB, R16 ;DIPSW LDI R16, 0XFF OUT PORTB, R16 RCALL initTimer1CTC LDI R16, 3
MOV R3, R16 ;BIẾN NHỚ VỊ TRÍ BAT DAU TU LED 3, CON TRO Y CHỈ BUFFER
LDI YL, LOW($201) ;BAT DAU TU HANG NGAN LDI YH, HIGH($201) LOOP: //IN R16, PINB ; ĐỌC DIPSW IN R16, PINB MOV R4, R16 CP R4, R5 BREQ LOOP MOV R5, R4 LDI R17, 9
MUL R16, R17 ; KET QUẢ R1:R0 MOVW R24, R0
RCALL BIN16_BCD5DG ;4 SỐ BCD TU $201- 204 DANG DUNG CON TRO X RJMP LOOP led7portinit: push R16
ldi R16, 0xFF ; SET led7seg PORT as output out LED7DDR, R16
in r16, LACKDDR ; read the Latch Port direction
register ori r16, (1<pop r16 ret
display_7seg: ;INPUT GIÁ TRỊ TRONG R27 ; VI TRI LED TRONG R26 (0-3) push r16
;BẢNG DATA ANNOT CHUNG --> 0 = ON ldi
zh,high(table_7seg_data<<1) ;
ldi zl,low(table_7seg_data<<1) ;
clr r16 add r30, r27 ; TRA BẢNG adc r31,r16 lpm r16, z lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN out LED7PORT, r16 sbi LACKPORT, LE0 RCALL DELAY1MS cbi LACKPORT, LE0
ldi zh,high(table_7seg_control<<1) ; ldi
zl,low(table_7seg_control<<1) ; clr
r16 add r30, r26 adc r31,r16 lpm r16, z out LED7PORT,r16 sbi
LACKPORT,LE1 RCALL DELAY1MS cbi LACKPORT,LE1
pop r16 ; Restore the temporary register
ret ; Return from the function
initTimer1CTC: ; NGẮT MỖI 5MS push r16
ldi r16, high(4999) ; Load the high Byte into the temporary register
sts OCR1AH, r16 ; Set the high byte of the timer 1 compare value ldi
r16, low(4999) ; Load the low byte into the temporary register sts
OCR1AL, r16 ; Set the low byte of the timer 1 compare value ldi r16,
(1 << CS10)| (1<< WGM12) ; 0b00000101, HE SO CHIA 8, MODE CTC1 sts TCCR1B, r16 ;
SEI ; CHO PHÉP NGẮT TOÀN CỤC
ldi r16, (1 << OCIE1A); KÍCH HOẠT NGẮT KHI CỜ OCF1A = 1
sts TIMSK1, r16 ; Enable the timer 1 compare A interrupt pop r16 ret
;BIN16_BCD5DG chuyển đổi số nhị phân 16 bit sang số BCD 5 digit
;Inputs: OPD1_H=R25:OPD1_L=R24 chứa số nhị phân 16 bit
;Outputs: BCD_BUF:BCD_BUF+4:địa chỉ SRAM chứa 5 digit BCD từ cao đến thấp
;Sử dụng R17,COUNT,X,ctc DIV16_8
;--------------------------------------------------------- BIN16_BCD5DG:
LDI XH,HIGH(BCD_BUF);X trỏ địa chỉ đầu buffer BCD LDI XL,LOW(BCD_BUF)
LDI COUNT,5 ;đếm số byte bộ nhớ
LDI R17,0X00 ;nạp giá trị 0
LOOP_CL:ST X+,R17 ;xóa buffer bộ nhớ
DEC COUNT ;đếm đủ 5 byte BRNE LOOP_CL
LDI OPD2,10 ;nạp số chia (SC) DIV_NXT:
RCALL DIV16_8 ;chia số nhị phân 16 bit cho số nhị phân 8 bit
ST -X,OPD3 ;cất số dư vào buffer
CPI OPD1_L,0 ;thương số=0?
BRNE DIV_NXT ;khác 0 chia tiếp RET
;---------------------------------------
;DIV16_8 chia số nhị phân 16 bit OPD1 cho 8 bit OPD2 (Xem giải thuật chia ở Chương 0)
;Input: OPD1_H,OPD1_L= SBC(GPR16-31) ; OPD2=SC(GPR0-31)
;Output:OPD1_H,OPD1_L=thương số ; OPD3=SD(GPR0-31) ;Sử dụng COUNT(GPR16-31) lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
;---------------------------------------
DIV16_8: LDI COUNT,16 ;COUNT=đếm 16 CLR OPD3 ;xóa dư số
SH_NXT: CLC ;C=0=bit thương số
LSL OPD1_L ;dịch trái SBC L,bit0=C=thương số
ROL OPD1_H ;quay trái SBC H,C=bit7
ROL OPD3 ;dịch bit7 SBC H vào dư số
BRCS OV_C ;tràn bit C=1,chia được
SUB OPD3,OPD2 ;trừ dư số với số chia BRCC GT_TH ;C=0 chia được
ADD OPD3,OPD2 ;C=1 không chia được,không trừ RJMP NEXT
OV_C: SUB OPD3,OPD2 ;trừ dư số với số chia
GT_TH: SBR OPD1_L,1 ;chia được,thương số=1
NEXT: DEC COUNT ;đếm số lần dịch SBC
BRNE SH_NXT ;chưa đủ tiếp tục dịch bit RET TIMER1_COMPA_ISR: PUSH R16
PUSH R26 ; R26,27 TRONG display_7seg PUSH R27 IN R2, SREG MOV R26, R3 LD R27, Y+ RCALL display_7seg TST R3 BREQ TROVELED3 DEC R3 RJMP DONE TROVELED3: LDI R16, 3
MOV R3, R16 ;BIẾN NHỚ VỊ TRÍ BAT DAU TU LED 3, CON TRO Y CHỈ BUFFER
LDI YL, LOW($201) ;BAT DAU TU HANG NGAN LDI YH, HIGH($201) DONE: OUT SREG, R2 POP R27 POP R26 POP R16 RETI DELAY1MS: PUSH R16 PUSH R17 LDI R16, 8 ;1MC LP1: LDI R17, 249 ;1MC LP2: DEC R17 ;1MC NOP ;1MC BRNE LP2 ;2/1MC DEC R16 ;1MC BRNE LP1 ;2/1MC POP R17 POP R16 lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN RET
; Lookup table for 7-segment codes
table_7seg_data: .DB $C0,$F9,$A4,$B0,$99,$92,$82,$F8,$80,$90,$88,$83,$C6,$A1,$86,$8E
; Lookup table for LED control
table_7seg_control: .DB 0b00001110,0b00001101, 0b00001011, 0b0000011 lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
.include "m324padef.inc" ; Include Atmega324pa definitions
;CHUYỂN DOI SO NHI PHAN 16 BIT TO BCD
.EQU BCD_BUF=0X200 ;đ/c đầu SRAM lưu số BCD (kq chuyển từ số 16 bit) SRAM
.DEF OPD1_L=R24 ;byte thấp của số nhị phân 16 bit
.DEF OPD1_H=R25 ;byte cao của số nhị phân 16 bit .DEF OPD2=R22 .DEF OPD3=R23 .DEF COUNT=R18
.org 0x0000 ; interrupt vector table rjmp reset_handler ; reset .org 0x001A rjmp timer1_COMP_ISR reset_handler: LDI R16, 0 OUT DDRB, R16 ;DIPSW LDI R16, 0XFF OUT PORTB, R16 ; initialize stack pointer ldi r16, high(RAMEND) out SPH, r16 ldi r16, low(RAMEND) out SPL, r16 ldi r16, (1<call initTimer1CTC call led7seg_portinit call Led7seg_buffer_init ; enable global interrupts sei LOOP: //IN R16, PINB ; ĐỌC DIPSW IN R16, PINB MOV R4, R16 CP R4, R5 BREQ LOOP MOV R5, R4 LDI R17, 9
MUL R16, R17 ; KET QUẢ R1:R0 MOVW R24, R0
RCALL BIN16_BCD5DG ;4 SỐ BCD TU $201- 204 DANG DUNG CON TRO X
LDI ZH, HIGH($201) ; TRO VI TRI NGUỒN LDI ZL, LOW($201) RCALL LED7UPDATE RJMP LOOP
; Lookup table for 7-segment codes
table_7seg_data: .DB $C0,$F9,$A4,$B0,$99,$92,$82,$F8,$80,$90,$88,$83,$C6,$A1,$86,$8E
; Lookup table for LED control table_7seg_control: lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
.DB 0b00001110,0b00001101, 0b00001011, 0b00000111 ; J34 connect to PORTD ; nLE0 connect to PB4 ; nLE1 connect to PB5 ; Output: None .equ LED7SEGPORT = PORTD .equ LED7SEGDIR = DDRD .equ LED7SEGLatchPORT = PORTB .equ LED7SEGLatchDIR = DDRB .equ nLE0Pin = 4 .equ nLE1Pin = 5 .dseg
.org SRAM_START ;starting address is 0x100
LED7segValue: .byte 4 ;store the BCD value to display LED7segIndex: .byte 1 .cseg .align 2 ;init the Led7seg buffer Led7seg_buffer_init: push r20 ldi r20,3 ;LED index start at 3 ldi r31,high(LED7segIndex) ldi r30,low(LED7segIndex) st z,r20 pop r20 ret led7seg_portinit: push r20
ldi r20, 0b11111111 ; SET led7seg PORT as output out LED7SEGDIR, r20
in r20, LED7SEGLatchDIR ; read the Latch Port direction
register ori r20, (1<LED7SEGLatchDIR,r20 pop r20 ret;
;Display a value on a 7-segment LED using a lookup table
; Input: R27 contains the value to display
; R26 contain the LED index (3..0) ; J34 connect to PORTD ; nLE0 connect to PB4 ; nLE1 connect to PB5 ; Output: None display_7seg:
push r16 ; Save the temporary register
; Look up the 7-segment code for the value in R18
; Note that this assumes a common anode display, where a HIGH output turns OFF the segment
; If using a common cathode display, invert the values in the table
above ldi zh,high(table_7seg_data<<1) ; ldi zl,low(table_7seg_data<<1) ;
clr r16 add r30, r27 adc r31,r16 lpm r16, z out LED7SEGPORT,r16 sbi LED7SEGLatchPORT,nLE0Pin lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN nop lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
cbi LED7SEGLatchPORT,nLE0Pin ldi
zh,high(table_7seg_control<<1) ldi
zl,low(table_7seg_control<<1) ; clr
r16 add r30, r26 adc r31,r16 lpm
r16, z out LED7SEGPORT,r16 sbi LED7SEGLatchPORT,nLE1Pin nop
cbi LED7SEGLatchPORT,nLE1Pin pop r16 ;
Restore the temporary register ret ;
Return from the function initTimer1CTC: push r16
ldi r16, high(10000) ; Load the high yte into the temporary register
sts OCR1AH, r16 ; Set the high byte of the timer 1 compare value ldi
r16, low(10000) ; Load the low byte into the temporary register sts
OCR1AL, r16 ; Set the low byte of the timer 1 compare value
ldi r16, (1 << CS10)| (1<< WGM12) ; Load the value 0b00000101 into the temporary register sts TCCR1B, r16 ;
ldi r16, (1 << OCIE1A); Load the value 0b00000010 into the temporary register
sts TIMSK1, r16 ; Enable the timer 1 compare A interrupt pop r16 ret
timer1_COMP_ISR: push r16 push r26 push r27 ldi r31,high(LED7segIndex) ldi r30,low(LED7segIndex) ld r16,z mov r26,r16 ldi r31,high(LED7segValue) ldi r30,low(LED7segValue) add r30,r16 clr r16 adc r31,r16 ld r27,z call display_7seg cpi r26,0 brne timer1_COMP_ISR_CONT ldi r26,4 ;if r16 = 0, reset to 3 timer1_COMP_ISR_CONT: dec r26 ;else, decrease ldi r31,high(LED7segIndex) ldi
r30,low(LED7segIndex) st z,r26 pop r27 pop r26 pop r16 reti
;BIN16_BCD5DG chuyển đổi số nhị phân 16 bit sang số BCD 5 digit
;Inputs: OPD1_H=R25:OPD1_L=R24 chứa số nhị phân 16 bit
;Outputs: BCD_BUF:BCD_BUF+4:địa chỉ SRAM chứa 5 digit BCD từ cao đến thấp lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
;Sử dụng R17,COUNT,X,ctc DIV16_8 lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
;--------------------------------------------------------- BIN16_BCD5DG:
LDI XH,HIGH(BCD_BUF);X trỏ địa chỉ đầu buffer BCD LDI XL,LOW(BCD_BUF)
LDI COUNT,5 ;đếm số byte bộ nhớ
LDI R17,0X00 ;nạp giá trị 0
LOOP_CL:ST X+,R17 ;xóa buffer bộ nhớ
DEC COUNT ;đếm đủ 5 byte BRNE LOOP_CL
LDI OPD2,10 ;nạp số chia (SC) DIV_NXT:
RCALL DIV16_8 ;chia số nhị phân 16 bit cho số nhị phân 8 bit ST
-X,OPD3 ;cất số dư vào buffer
CPI OPD1_L,0 ;thương số=0?
BRNE DIV_NXT ;khác 0 chia tiếp RET
;---------------------------------------
;DIV16_8 chia số nhị phân 16 bit OPD1 cho 8 bit OPD2 (Xem giải thuật chia ở Chương 0)
;Input: OPD1_H,OPD1_L= SBC(GPR16-31) ; OPD2=SC(GPR0-31)
;Output:OPD1_H,OPD1_L=thương số ; OPD3=DS(GPR0-31) ;Sử dụng COUNT(GPR16-31)
;---------------------------------------
DIV16_8: LDI COUNT,16 ;COUNT=đếm 16 CLR OPD3 ;xóa dư số
SH_NXT: CLC ;C=0=bit thương số
LSL OPD1_L ;dịch trái SBC L,bit0=C=thương số
ROL OPD1_H ;quay trái SBC H,C=bit7
ROL OPD3 ;dịch bit7 SBC H vào dư số
BRCS OV_C ;tràn bit C=1,chia được
SUB OPD3,OPD2 ;trừ dư số với số chia BRCC GT_TH ;C=0 chia được
ADD OPD3,OPD2 ;C=1 không chia được,không trừ RJMP NEXT
OV_C: SUB OPD3,OPD2 ;trừ dư số với số chia
GT_TH: SBR OPD1_L,1 ;chia được,thương số=1
NEXT: DEC COUNT ;đếm số lần dịch SBC
BRNE SH_NXT ;chưa đủ tiếp tục dịch bit RET
;CON TRO Z CẦN TRO TOI NGUON COPY LED7UPDATE: PUSH R20 PUSH R21
ldi r29,high(LED7segValue) ; Y register point to 4BYTE ĐƯỢC HIEN THI
ldi r28,low(LED7segValue) ldi r20,4 ;SO LUONG BYTE COPY
COPYLED7LOOP: ;copy font to display buffer
LD r21,z+ ;NẾU NGUỒN FLASH THÌ LPM st
y+,r21 dec r20 cpi r20,0 brne COPYLED7LOOP POP R20 POP R21 RET lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN LED MATRIX ;LEDMATRIX PORTD
;THANH GHI DỊCH LEDMATRIX PB0123
.include "m324padef.inc" ; Include Atmega324pa definitions .equ LEDMATRIXPORT = PORTD .equ LEDMATRIXDIR = DDRD
.equ clearSignalPort = PORTB ; Set clear signal port to PORTB
.equ clearSignalPin = 3 ; Set clear signal pin to pin 3 of PORTB
.equ shiftClockPort = PORTB ; Set shift clock port to PORTB
.equ shiftClockPin = 2 ; Set shift clock pin to pin 2 of PORTB
.equ latchPort = PORTB ; Set latch port to PORTB
.equ latchPin = 1 ; Set latch pin to pin 1 of PORTB
.equ shiftDataPort = PORTB ; Set shift data port to PORTB
.equ shiftDataPin = 0 ; Set shift data pin to pin 0 of PORTB
.org 0x0000 ; interrupt vector table rjmp reset_handler ; reset .org 0x001A rjmp timer1_COMP_ISR reset_handler: ; initialize stack pointer ldi r16, high(RAMEND) out SPH, r16 ldi r16, low(RAMEND) out SPL, r16 call shiftregister_initport call shiftregister_cleardata call initTimer1CTC
; enable global interrupts sei call ledmatrix_portinit
ldi r31,high(ledmatrix_Font_A << 1) ;Z register point to fontA
value ldi r30,low(ledmatrix_Font_A << 1) RCALL FONTUPDATE ;TRỎ Z VÀO VỊ TRÍ FONT SBI DDRA, 0 SBI PORTA, 0 MAIN:
SBIC PINA, 0 ; NHEU SW ON THI HIEN A Rjmp CHUA
ldi r31,high(ledmatrix_Font_B << 1) ;Z register point to fontA value
ldi r30,low(ledmatrix_Font_B << 1)
RCALL FONTUPDATE ;TRỎ Z VÀO VỊ TRÍ FONT RJMP MAIN CHUA:
ldi r31,high(ledmatrix_Font_A << 1) ;Z register point to fontA
value ldi r30,low(ledmatrix_Font_A << 1) RCALL FONTUPDATE ;TRỎ Z VÀO VỊ TRÍ FONT RJMP MAIN ; Initialize ports as outputs lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN shiftregister_initport: push r24 ldi r24,
(1<DDRB, r24 ; Set DDRB to output pop r24 ret shiftregister_cleardata: cbi
clearSignalPort, clearSignalPin ; Set clear signal pin to low ; Wait for a short time
sbi clearSignalPort, clearSignalPin ; Set clear signal pin to high ret ; Shift out data ;shift out R27 to bar led shiftregister_shiftoutdata: push r18
cbi shiftClockPort, shiftClockPin ; ldi r18, 8
; Shift 8 bits shiftloop: sbrc r27, 7 ; Check if the MSB of shiftData is 1
sbi shiftDataPort, shiftDataPin ; Set shift data pin to high
sbi shiftClockPort, shiftClockPin ; Set shift clock pin to high lsl r27 ; Shift left
cbi shiftClockPort, shiftClockPin ; Set shift clock pin to
low cbi shiftDataPort, shiftDataPin ; Set shift data pin to
low dec r18 brne shiftloop ; Latch data
sbi latchPort, latchPin ; Set latch pin to
high cbi latchPort, latchPin ; Set latch pin to low pop r18 ret
;Lookup table for collumn control
ledmatrix_col_control: .DB 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 ; Lookup table for font
ledmatrix_Font_A: .DB 0xFC,0xFE,0x13,0x13,0x13,0x13,0xFE,0xFC
ledmatrix_Font_B: .DB 0xFF,0xFF,0x00,0x76,0x76,0x89,0xFF,0xFF .dseg
.org SRAM_START ;starting address is 0x100 LedMatrixBuffer : .byte 8 LedMatrixColIndex : .byte 1 .cseg .align 2 ledmatrix_portinit: push r20 push r21
ldi r20, 0b11111111 ; SET port as
output out LEDMATRIXDIR, r20 ldi r20,0 ;col index start at 0 ldi
r31,high(LedMatrixColIndex) ldi
r30,low(LedMatrixColIndex) st z,r20 ldi r20,0 pop r21 lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN pop r20 ret FONTUPDATE: PUSH R20 PUSH R21
ldi r29,high(LedMatrixBuffer) ; Y register point to fontA value ldi r28,low(LedMatrixBuffer) ldi r20,8
COPYFONTLOOP: ;copy font to display
buffer lpm r21,z+ st y+,r21 dec r20 cpi r20,0 brne COPYFONTLOOP POP R20 POP R21 RET
; Display a Collumn of Led Matrix
; Input: R27 contains the value to display
; R26 contain the Col index (3..0)
; Output: None ledmatrix_display_col: push r16 ; Save the temporary register push r27 clr r16 out LEDMATRIXPORT,r16 call
shiftregister_shiftoutdata ldi
r31,high(ledmatrix_col_control << 1)
ldi r30,low(ledmatrix_col_control << 1)
clr r16 add r30,r26 adc r31,r16 lpm r27,z out LEDMATRIXPORT,r27 pop r27
pop r16 ; Restore the temporary register
ret ; Return from the function initTimer1CTC: push r16
ldi r16, high(5000) ; Load the high yte into the temporary register
sts OCR1AH, r16 ; Set the high byte of the timer 1 compare value ldi
r16, low(5000) ; Load the low byte into the temporary register sts
OCR1AL, r16 ; Set the low byte of the timer 1 compare value
ldi r16, (1 << CS10)| (1<< WGM12) ; Load the value 0b00000101 into the
temporary register sts TCCR1B, r16 ;
ldi r16, (1 << OCIE1A); Load the value 0b00000010 into the temporary
register sts TIMSK1, r16 ; Enable the timer 1 compare A interrupt pop r16
ret timer1_COMP_ISR: push r16 push r26 push r27 lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN PUSH R30 PUSH R31 ldi r31,high(LedMatrixColIndex)
ldi r30,low(LedMatrixColIndex) ld r16,z mov r26,r16 ldi r31,high(LedMatrixBuffer) ldi r30,low(LedMatrixBuffer) add r30,r16 clr r16 adc r31,r16 ld r27,z call ledmatrix_display_col inc r26 cpi r26,8 brne timer1_COMP_ISR_CONT ldi r26,0 ;if r26 = 8, reset to 0 timer1_COMP_ISR_CONT:
ldi r31,high(LedMatrixColIndex)
ldi r30,low(LedMatrixColIndex) st z,r26 POP R31 POP R30 pop r27 pop r26 pop r16 reti
BÀI 3: Serial Port + RTC + EEPROM Các cổng giao tiếp: lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN Giao tiếp USART: Khởi ộng USART: USART_INIT:
; Set baud rate to 9600 bps with 8 MHz clock
ldi r16, 51 ; 1MHz nạp 12|8MHz nạp 51 baud khác tra bảng
sts UBRR0L, r16; nhỏ hơn 255 thì chỉ cần nạp vào low ; set double speed ldi r16, 0 ; off sts UCSR0A, r16
; chọn khung truyền: 8 data bits, no parity, 1 stop bit
// parity chẵn thì thêm (1<(1<sts UCSR0C, r16
; Enable transmitter and receiver
ldi r16, (1 << RXEN0) | (1 << TXEN0) lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN sts UCSR0B, r16 ret
Các port RX0 (PD0) và TX0(PD1) tự ộng ược set ddr
Truyền dữ liệu usart:
-Kiểm tra cờ UDRE0 trong thanh ghi UCSR0A
+ =1 thì ang rảnh | =0 thì phải chờ
-Nạp data vào UDR0 ể truyền i (cờ UDRE0 tự ộng bật 0)
USART_SendChar: ;truyền Data trông R16 đi push r17
; Wait for the transmitter to be ready USART_SendChar_Wait: lds r17, UCSR0A
sbrs r17, UDRE0 ;check USART Data Register Empty
bit rjmp USART_SendChar_Wait sts UDR0, r16 ;send out pop r17 ret
Nhận dữ liệu usart:
USART_ReceiveChar:;Nhận data lưu vào R16 push r17
; Wait for the transmitter to be ready USART_ReceiveChar_Wait: lds r17, UCSR0A
sbrs r17, RXC0 ;check USART Receive Complete
bit rjmp USART_ReceiveChar_Wait lds r16, UDR0 ;get data pop r17 ret
VD: Nhận 1 byte dữ liệu từ máy tính và gửi lại máy tính byte ó .include "m324padef.inc"
; Replace with your application code call USART_Init start:
call USART_ReceiveChar ; nhận dữ liệu
call USART_SendChar ; phát lại dữ liệu rjmp start USART_Init:
; Set baud rate to 9600 bps with 8 MHz clock lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
ldi r16, 51 ; 1MHz nạp 12|8MHz nạp 51
sts UBRR0L, r16; nhỏ hơn 255 thì chỉ cần nạp vào low ; set double speed ldi r16, 0 ; off sts UCSR0A, r16
; chọn khung truyền: 8 data bits, no parity, 1 stop bit
// parity chẵn thì thêm (1<(1<sts UCSR0C, r16
; Enable transmitter and receiver
ldi r16, (1 << RXEN0) | (1 << TXEN0) sts UCSR0B, r16 ret
USART_SendChar: ;truyền Data trông R16 đi push r17
; Wait for the transmitter to be ready USART_SendChar_Wait: lds r17, UCSR0A
sbrs r17, UDRE0 ;check USART Data Register Empty
bit rjmp USART_SendChar_Wait sts UDR0, r16 ;send out pop r17 ret
USART_ReceiveChar:;Nhận data lưu vào R16 push r17
; Wait for the transmitter to be ready USART_ReceiveChar_Wait: lds r17, UCSR0A
sbrs r17, RXC0 ;check USART Receive Complete
bit rjmp USART_ReceiveChar_Wait lds r16, UDR0 ;get data pop r17 ret Giao thức SPI lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
SPI phải khai báo DDR cho port còn usart thì tự ộng
VD: Nhận data từ máy tính qua USART0 phản hồi ngược lại data ó về máy tính, truyền data
ó vào thanh ghi dịch thông qua SPI, hiển thị thanh ghi dịch ra barled. ;BAI 3 .EQU SPI_PORT=PORTB .EQU SPI_PORT_DDR=DDRB
.EQU MR=3 ;XOÁ THANH GHI DỊCH NẾU PB3 = 0
; khong cần tín hiệu SS (slave select) vì thanh ghi dịch on sẵn
.EQU SS = 4 ;COI SS LÀ LACK THANH GHI DỊCH .EQU MOSI=5 .EQU MISO=6 .EQU SCK=7 .ORG 0 RCALL SPI_INIT RCALL USART_Init SBI DDRB, MR ;
SBI PORTB, MR ;KÉO LÊN MỨC CAO
LOOP: rcall USART_ReceiveChar ; NHẬN DATA TRONG R16 RCALL USART_SendChar
RCALL SPI_TRANS ; PHAT DATA TRONG R16 ĐI NHẬN LẠI TRONG R17
SBI SPI_PORT,SS ; TẠO XUNG CẠNH LÊN ĐỂ LACK RA BARLED CBI SPI_PORT,SS ; RJMP LOOP SPI_INIT:
LDI R16,(1<OUT SPI_PORT_DDR, R16 ; Output pins
LDI R16,(1<OUT SPCR0, R16 ; Enable spi, CHẾ ĐỘ master, MSB first LDI R16,(1<STS SPSR0,R16 RET
SPI_TRANS: ;TRUYỀN DATA TRONG R16 ĐI NHẬN LẠI DATA TRONG R17
PUSH R18 ; TRUNG GIAN TRẠNG THÁI CBI PORTB, MR
SBI PORTB, MR ;XOÁ DATA CŨ THANH GHI DỊCH OUT SPDR0, R16 ;ghi data ra SPI WAIT_SPI: IN R18,SPSR0 ; SPIF0
SBRS R18,SPIF0 ;cờ SPIF0=1 truyền SPI xong
RJMP WAIT_SPI ;chờ cờ SPIF0=1 IN R17,SPDR0 POP R18 RET USART_Init:
; Set baud rate to 9600 bps with 8 MHz clock
ldi r16, 51 ; 1MHz nạp 12|8MHz nạp 51
sts UBRR0L, r16; nhỏ hơn 255 thì chỉ cần nạp vào low lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN ; set double speed ldi r16, 0 ; off lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN sts UCSR0A, r16
; chọn khung truyền: 8 data bits, no parity, 1 stop bit
// parity chẵn thì thêm (1<(1<sts UCSR0C, r16
; Enable transmitter and receiver
ldi r16, (1 << RXEN0) | (1 << TXEN0) sts UCSR0B, r16 ret
USART_SendChar: ;truyền Data trong R16 đi push r17
; Wait for the transmitter to be ready USART_SendChar_Wait: lds r17, UCSR0A
sbrs r17, UDRE0 ;check USART Data Register Empty
bit rjmp USART_SendChar_Wait sts UDR0, r16 ;send out pop r17 ret
USART_ReceiveChar:;Nhận data lưu vào R16 push r17
; Wait for the transmitter to be ready USART_ReceiveChar_Wait: lds r17, UCSR0A
sbrs r17, RXC0 ;check USART Receive Complete
bit rjmp USART_ReceiveChar_Wait lds r16, UDR0 ;get data pop r17 ret
VD: ếm số ký tự nhận từ USART, hiển thị giá trị ếm ược ra barled ,lưu giá trị ếm ược
vào EEPROM, khi mất iện thì khôi phục lại. Dùng module 25AA1024 ;BAI 4 .EQU SPI_PORT=PORTB .EQU SPI_PORT_DDR=DDRB
.EQU SS=4 ;4 chân c?a giao th?c PSI .EQU MOSI=5 .EQU MISO=6 .EQU SCK=7
.EQU WIP=0 ;bit báo bộ nhớ bận
.EQU PE=$42 ;mã lệnh xoá 1 page data
.EQU WREN=$06 ;cho phép ghi bộ nhớ
.EQU WRDI=$04 ;không cho phép ghi
.EQU RDSR=$05 ;mã lệnh đọc trạng thái bộ nhớ
.EQU WRSR=$01 ;mã lệnh ghi trạng thái bộ nhớ
.EQU SPI_RD=$03 ;mã lệnh đọc bộ nhớ
.EQU SPI_WR=$02 ;mã lệnh ghi bộ nhớ
.EQU MEM_BYTE3=0X00 ;địa chỉ bộ nhớ byte3 bit 23-16 .EQU MEM_BYTE2=0X01 ;15-8 lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN .EQU MEM_BYTE1=0X00 ;7-0 .ORG 0 RCALL SPI_INIT ;THIET LAP SPI
RCALL USART_INIT ;THIET LAP USART LDI R16,$FF OUT DDRA,R16 ;PORTA:BARLED
CBI PORTB,SS ;CHO PHEP GHI EEPROM
RCALL EEPROM_READ ;SAU KHI RESET DOC EEPROM LAY DATA LUU R20 RCALL DELAY1MS RCALL DELAY1MS RCALL DELAY1MS RCALL DELAY1MS
MOV R19, R20 ;KHOI PHUC DU LIEU CHO CHO BIEN DEM R19
OUT PORTA, R19 ;XUAT R19 RA PORTA
//RCALL EEPROM_ERASE ;LAN DAU CHAY XOA EEPROM VA CHO R19 = 0
//LDI R19, 0 ; LAN SAU CHAY THI XOA 2 LENH NAY DI
OUT PORTA, R19 ;XUAT R19 RA PORTA LOOP: ;VONG LAP
RCALL USART_RECEIVER_CHAR ;CHO NHAN BYTE DATA INC R19 ; TANG R19 LEN 1
OUT PORTA, R19 ;XUAT R19 RA PORTA
RCALL EEPROM_ERASE ;XOA DATA EEPROM
RCALL EEPROM_WRITE ;GHI DATA MOI RCALL DELAY1MS RCALL DELAY1MS RCALL DELAY1MS RCALL DELAY1MS RCALL DELAY1MS RCALL EEPROM_READ RJMP LOOP
USART_INIT: ; THIET LAP USART CHỈ ĐỌC LDI R16, $00 STS UBRR0H, R16 LDI R16, 51 STS UBRR0L, R16
LDI R16, (1<STS UCSR0B, R16
LDI R16, (1<STS UCSR0C, R16 RET
USART_RECEIVER_CHAR: ;NHAN KY TU LUU VAO R18 PUSH R17 WAIT_UART_RECEIVE: LDS R17, UCSR0A SBRS R17, RXC0 RJMP WAIT_UART_RECEIVE LDS R18, UDR0 POP R17 RET
EEPROM_READ: ; DOC DATA VI TRI 0X00100 EEPROM LUU VAO R20 lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN LDI R16,SPI_RD CBI PORTB,SS RCALL SPI_TRANS
LDI R16,MEM_BYTE3 ; THIET LAP VI TRI 0X00100 RCALL SPI_TRANS lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN LDI R16,MEM_BYTE2 RCALL SPI_TRANS LDI R16,MEM_BYTE1 RCALL SPI_TRANS
LDI R16,$FF ;DAT DATA GIA TRUYEN SPI
RCALL SPI_TRANS ;OUT R16 IN R17 SBI PORTB,SS MOV R20,R17 RET
EEPROM_ERASE: ;XOA DATA EEPROM LDI R16,WREN CBI SPI_PORT,SS RCALL SPI_TRANS SBI PORTB,SS LDI R16,PE CBI PORTB,SS RCALL SPI_TRANS LDI R16,MEM_BYTE3 RCALL SPI_TRANS LDI R16,MEM_BYTE2 RCALL SPI_TRANS LDI R16,MEM_BYTE1 RCALL SPI_TRANS SBI SPI_PORT,SS WR_FIN: LDI R16,RDSR CBI SPI_PORT,SS RCALL SPI_TRANS SBRC R17,WIP RJMP WR_FIN SBI SPI_PORT,SS RET
EEPROM_WRITE: ;GHI NOI DUNG TRONG R19 VAO VI TRI 0X00100 EEPROM
LDI R16,WREN ;LUU LENH CHO PHEP SHI VAO R16
CBI SPI_PORT,SS ; CHO PHEP TRUYEN SPI
RCALL SPI_TRANS ;TRUYEN L?NH RA EEPROM
SBI PORTB,SS ; KHONG CHO PHEP TRUYEN SPI
LDI R16,SPI_WR ;LENH GHI BO NHO CBI PORTB,SS RCALL SPI_TRANS
LDI R16,MEM_BYTE3 ; NAP ?IA CHI BYTE 3,2,1 BO NHO RCALL SPI_TRANS
LDI R16,MEM_BYTE2 ; BAT DAU TU VI TRI 0X00100 RCALL SPI_TRANS LDI R16,MEM_BYTE1 RCALL SPI_TRANS
MOV R16,R19 ;NOI DUNG CAN TRUYEN LUU TRONG R19
RCALL SPI_TRANS ;NEU TRUYEN TIEP DATA EEPROM TU DICH VI TRI +1 SBI SPI_PORT,SS
WR_FIN0: ;CHO DEN KHI TRUYEN XONG LDI R16,RDSR lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN CBI SPI_PORT,SS RCALL SPI_TRANS SBRC R17,WIP RJMP WR_FIN0 SBI SPI_PORT,SS lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN RET SPI_INIT:
LDI R16,(1<OUT SPI_PORT_DDR, R16
SBI SPI_PORT,SS ;DUNG TRUYEN SPI LDI R16,(1<OUT SPCR0, R16
LDI R16,(1<STS SPSR0,R16 ;FOSC/8 RET
SPI_TRANS: ;DATA TRUYEN:R16 DATA NHAN LAI:R17 OUT SPDR0,R16
WAIT_SPI: ;CHO DEN KHI TRUYEN XONG IN R16,SPSR0 SBRS R16,SPIF0 RJMP WAIT_SPI IN R17,SPDR0 RET DELAY1MS: LDI R16,0 OUT TCNT0,R16 LDI R16,$00 OUT TCCR0A,R16 LDI R16,$05 OUT TCCR0B,R16 AGAIN: SBIS TIFR0,TOV0 RJMP AGAIN SBI TIFR0,TOV0 LDI R16,$00 OUT TCCR0B,R16 RET Dùng EEPROM nội: ;BAI5 .DEF COUNTER = R18 .ORG 0 MAIN: ; SET STACK LDI R16, HIGH(RAMEND) OUT SPH, R16 LDI R16, LOW(RAMEND) OUT SPL, R16 CLR COUNTER ; CLR BIEN DEM LDI R16,0XFF ; SET UP DDRA OUT DDRA, R16
LDI R20, $01 ;VI TRI LUU EEPROM LDI R21, $00 RCALL USART_INIT
RCALL READ_FROM_EEPROM ;KHOI PHUC COUNTER START: lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN OUT PORTA, COUNTER RCALL USART_RECEIVER_CHAR INC COUNTER ; TANG BIEN DEM lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
RCALL WRITE_TO_EEPROM ; LUU GIA TRI MOI VAO EEPROM RJMP START
USART_INIT: ;Chế độ chỉ nhận LDI R16, $00 STS UBRR0H, R16 LDI R16, 51
STS UBRR0L, R16 ; SET BAUD = 9600 , ... VI DU 1
LDI R16, (1<STS UCSR0B, R16 LDI R16, (1<UCSR0C, R16 RET USART_RECEIVER_CHAR: PUSH R17 ; CAT R17 WAIT_UART_RECEIVE: LDS R17, UCSR0A
SBRS R17, RXC0 ; CHO CO RXC0 = 1 RJMP WAIT_UART_RECEIVE LDS R19, UDR0 POP R17 ; LAY R17 RET WRITE_TO_EEPROM: WAIT_ENABLE_WRITE:
SBIC EECR, EEPE ; CHO ENABLE = 0 RJMP WAIT_ENABLE_WRITE
OUT EEARH, R21 ; DAY DIA CHI EEPROM HIGH
OUT EEARL, R20 ; DAY DIA CHI EEPROM LOW
OUT EEDR, COUNTER ; luu GIA TRI R18 vao THANH GHI DATA
SBI EECR, EEMPE ; BIT CHO PHEP GHI DU LIEU MOI VAO EEPROM
SBI EECR, EEPE ; BIT CHO PHEP GHI DU LIEU MOI VAO EEPROM , THIET LAP CHE DO HOAT DONG XONG RCALL DELAY_5MS ;DELAY 5MS RET READ_FROM_EEPROM: WAIT_READ:
SBIC EECR, EEPE ;CHO ENALBE = 0 RJMP WAIT_READ ; TIEP TUC CHO
OUT EEARH, R21 ; LUU DIA CHI BO NHO EEPROM
OUT EEARL, R20 ; LUU DIA CHI BO NHO EEPROM
SBI EECR, EERE ; CHO PHEP DOC EERE = 1
IN COUNTER, EEDR ;LUU DU LIEU DATA VE R18 RET
DELAY_5MS: ; CHUONG TRINH CON DELAY 5MS LDI R20, 5 LP2: LDI R21, 250 LP1: NOP DEC R21 BRNE LP1 lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN DEC R20 BRNE LP2 RET lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN RTC VD:
a) Kết nối các tín hiệu SDA (PC1) và SCL (PC0) của AVR vào các tín hiệu tương ứng trên module RTC.
Kết nối 1 chân port vào tín hiệu MFP (). Kết nối LCD 16x2 vào 1 port của AVR
b) Viết chương trình con khởi ộng RTC với thời gian hiện hành, cấu hình xung MFP tần số 1Hz. Sau ó cứ
mỗi cạnh lên của MFP, ọc các giá trị ngày tháng năm giờ phút giây của RTC và cập nhật lên LCD LCD : PORTA – hiển thị SW1 : PIND0 - điều khiển SW2 : PIND1 - điều khiển SCL : PC0 SDA : PC1
.DEF REG_FLAG=R19 ;REG_FLAG chứa các cờ báo .DEF COUNT=R20 ;biến đếm
.DEF NUM_MAX=R21 ;biến đặt giá trị MAX
.DEF NUM_MIN=R22 ;biến đặt giá trị MIN
.DEF POS_CRS=R23 ;biến đặt vị trí con trỏ hiển thị
.EQU LCD=PORTA ;PORTA hiển thị .EQU LCD_DR=DDRA
.EQU CONT=PORTD ;PORTD điều khiển .EQU CONT_DR=DDRD ; .EQU CONT_IN=PIND ; .EQU SW_FLG=0 .EQU RS=0 ;bit RS .EQU RW=1 ;bit RW .EQU E=2 ;bit E
.EQU SCL=0 ;ký hiệu chân SCL
.EQU SDA=1 ;ký hiệu chân SDA
.EQU SW1=0 ;ký hiệu chân SW1
.EQU SW2=1 ;ký hiệu chân SW2
.EQU STO=7 ;bit cho phép OSC RTC
.EQU VBATEN=3 ;bit cho phép nguồn dự phòng
.EQU NULL=$00 ;mã kết thúc chuỗi ký tự
.EQU CTL_BYTE=0B11011110 ;byte điều khiển truy xuất .EQU RTC_BUF=0X200 .ORG 0 RJMP MAIN .ORG 0X40
MAIN: LDI R16,HIGH(RAMEND) ;đưa stack lên vùng đ/c cao OUT SPH,R16 LDI R16,LOW(RAMEND) OUT SPL,R16 LDI R16,0XFF OUT LCD_DR,R16 LDI R16,0X00 OUT LCD,R16
CBI CONT_DR,SW1 ;chân SW1 input lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
SBI CONT,SW1 ;điện trở kéo lên chân SW1 lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
CBI CONT_DR,SW2 ;chân SW2 input
SBI CONT,SW2 ;điện trở kéo lên chân SW2 LDI R16,250 ;delay 25ms
RCALL DELAY_US ;ctc delay 100μsxR16 LDI R16,250 ;delay 25ms
RCALL DELAY_US ;ctc delay 100μsxR16 CBI LCD,RS ;RS=0 ghi lệnh
LDI R17,$30 ;mã lệnh=$30 lần 1,RS=RW=E=0
RCALL OUT_LCD4 ;ctc ghi ra LCD chọn RS 0/1 trước LDI R16,42 ;delay 4.2ms RCALL DELAY_US CBI LCD,RS
LDI R17,$30 ;mã lệnh=$30 lần 2 RCALL OUT_LCD4 LDI R16,2 ;delay 200μs RCALL DELAY_US CBI LCD,RS
LDI R17,$30 ;mã lệnh=$30 lần 3 RCALL OUT_LCD4 LDI R16,1 ;delay 100μs RCALL DELAY_US CBI LCD,RS LDI R17,$20 ;mã lệnh=$20 RCALL OUT_LCD4
LDI R18,$28 ;Function set 2 dòng font 5x8,mode 4 bit LDI R19,$01 ;Clear display
LDI R20,$0C ;display on,con trỏ off
LDI R21,$06 ;Entry mode set dịch phải con trỏ,DDRAM tăng 1 đ/c
;khi nhập ký tự,màn hình không dịch
RCALL INIT_LCD4 ;ctc khởi động LCD 4 bit RCALL TWI_INIT START:
LDI REG_FLAG,0 ;xóa các cờ báo LDI R16,1 ;chờ 100μs RCALL DELAY_US CBI LCD,RS ;RS=0 ghi lệnh LDI R17,$01 ;xóa màn hình RCALL OUT_LCD
LDI R16,20 ;chờ 2ms sau lệnh Clear display RCALL DELAY_US
LDI R17,$80 ;con trỏ bắt đầu ở đầu dòng 1
RCALL CURS_POS ;xuất lệnh ra LCD
LDI ZH,HIGH(MSG1<<1);Z trỏ địa chỉ đầu bảng MSG1 trong Flash ROM LDI ZL,LOW(MSG1<<1)
RCALL MSG_DISP ;ghi MSG1 ra LCD
LDI R17,$C0 ;con trỏ bắt đầu ở đầu dòng 2
RCALL CURS_POS ;xuất lệnh ra LCD
LDI ZH,HIGH(MSG2<<1);Z trỏ đầu bảng tra MSG2 LDI ZL,LOW(MSG2<<1)
RCALL MSG_DISP ;ghi MSG2 ra LCD
;---------------------------------------------------------
;Đặt bit SQWEN=1,RS2:0=000 cho dao động 1Hz ;xuất ra chân MFP
;--------------------------------------------------------- lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
RCALL TWI_START ;phát xung START
LDI R17,(CTL_BYTE|0X00);truy xuất ghi RTC_TCCR RCALL TWI_WRITE ;ghi RTC+W
LDI R17,0X07 ;địa chỉ thanh ghi Control RCALL TWI_WRITE
LDI R17,0B01000000 ;MFP xuất xung 1Hz RCALL TWI_WRITE RCALL TWI_STOP
;--------------------------------------------------------
;Đọc các thanh ghi 0x00-0x06 RTC
;--------------------------------------------------------- START1:
LDI XH,HIGH(RTC_BUF);X trỏ đầu buffer RTC LDI XL,LOW(RTC_BUF) LDI COUNT,7
RCALL TWI_START ;phát xung START
LDI R17,(CTL_BYTE|0X00);truy xuất ghi RTC_TCCR RCALL TWI_WRITE ;ghi RTC+W
LDI R17,0X00 ;địa chỉ thanh ghi 0x00 RCALL TWI_WRITE
RCALL TWI_START ;phát xung START
LDI R17,(CTL_BYTE|0X01);truy xuất đọc RTC_TCCR RCALL TWI_WRITE ;ghi RTC+R RTC_RD: RCALL TWI_READ ST X+,R17 DEC COUNT BRNE RTC_RD RCALL TWI_NAK RCALL TWI_STOP
;------------------------------------------------------------------
;Hiền thị thứ giờ:phút:giây
;------------------------------------------------------------------ START2: LDI R17,$0C ;xóa con trỏ
CBI LCD,RS ;RS=0 truy xuat lenh LDI R16,1 ;chờ 100μs RCALL DELAY_US RCALL OUT_LCD
LDI XH,HIGH(RTC_BUF+3);X trỏ buffer RTC thứ LDI XL,LOW(RTC_BUF+3)
LDI R17,$84 ;con trỏ bắt đầu ở dòng 1 vị trí thứ
RCALL CURS_POS ;xuất lệnh ra LCD LD R17,X ;lấy data thứ ANDI R17,0X07
LDI R18,0X30 ;chuyển sang mã ASCII ADD R17,R18 SBI LCD,RS LDI R16,1 ;chờ 100μs RCALL DELAY_US
RCALL OUT_LCD ;hiển thị ra LCD
LDI R17,0X20 ; khoảng trắng SBI LCD,RS LDI R16,1 ;chờ 100μs lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN RCALL DELAY_US
RCALL OUT_LCD ;hiển thị ra LCD LDI COUNT,3
LDI R17,$86 ;con trỏ bắt đầu ở dòng 1 vị trí giờ
RCALL CURS_POS ;xuất lệnh ra LCD DISP_NXT1: LD R17,-X ;lấy data CPI COUNT,1 ;data=sec
BRNE D_NXT ;khác,hiển thị tiếp CBR R17,(1<D_NXT: RCALL NUM_DISP DEC COUNT BREQ QUIT1 LDI R17,':' SBI LCD,RS LDI R16,1 ;chờ 100μs RCALL DELAY_US
RCALL OUT_LCD ;hiển thị ra LCD RJMP DISP_NXT1
;----------------------------------------------------
;Hiển thị ngày/tháng/năm
;---------------------------------------------------- QUIT1:
LDI XH,HIGH(RTC_BUF+4);X trỏ buffer RTC ngày LDI XL,LOW(RTC_BUF+4) LDI COUNT,3
LDI R17,$C6 ;con trỏ bắt đầu ở dòng 2 vị trí ngày
RCALL CURS_POS ;xuất lệnh ra LCD DISP_NXT2: LD R17,X+ RCALL NUM_DISP DEC COUNT BREQ SW_CHK LDI R17,'/' SBI LCD,RS LDI R16,1 ;chờ 100μs RCALL DELAY_US
RCALL OUT_LCD ;hiển thị ra LCD RJMP DISP_NXT2
;------------------------------------------------------------------ ;Đặt lại RTC
;------------------------------------------------------------------ SW_CHK:
RCALL GET_SW ;đọc SW chờ SW nhấn SBRS REG_FLAG,SW_FLG RJMP START1 CPI R17,1 BRNE SW_CHK
LDI R17,$0E ;hiển thị con trỏ CBI LCD,RS LDI R16,1 ;chờ 100μs RCALL DELAY_US
RCALL OUT_LCD ;xuất lệnh ra LCD RTC_SET: lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
CPI COUNT,0 ;cài đặt thứ?
BRNE HR_CHK ;khác,kiểm tra giờ
LDI XH,HIGH(RTC_BUF+3);X trỏ buffer RTC thứ LDI XL,LOW(RTC_BUF+3) LDI NUM_MAX,7 LDI NUM_MIN,1
LDI POS_CRS,$84 ;đặt con trỏ vị trí thứ
RCALL SET_NUM ;đặt và hiển thị thứ LD R17,X SBR R17,(1<ST X,R17 RJMP RTC_SET HR_CHK:
CPI COUNT,1 ;cài đặt giờ?
BRNE MI_CHK ;khác,kiểm tra phút
LDI XH,HIGH(RTC_BUF+2);X trỏ buffer RTC giờ LDI XL,LOW(RTC_BUF+2) LDI NUM_MAX,0X23 LDI NUM_MIN,0
LDI POS_CRS,$86 ;đặt con trỏ vị trí giờ RCALL SET_NUM RJMP RTC_SET MI_CHK:
CPI COUNT,2 ;cài đặt phút?
BRNE SEC_CHK ;khác,kiểm tra giây
LDI XH,HIGH(RTC_BUF+1);X trỏ buffer RTC phút LDI XL,LOW(RTC_BUF+1) LDI NUM_MAX,0X59 LDI NUM_MIN,0
LDI POS_CRS,$89 ;đặt con trỏ vị trí phút RCALL SET_NUM RJMP RTC_SET SEC_CHK:
CPI COUNT,3 ;cài đặt giây?
BRNE DAT_CHK ;kiểm tra ngày
LDI XH,HIGH(RTC_BUF);X trỏ buffer RTC giây LDI XL,LOW(RTC_BUF) LDI NUM_MAX,0X59 LDI NUM_MIN,0
LDI POS_CRS,$8C ;đặt con trỏ vị trí giây RCALL SET_NUM LD R17,X SBR R17,(1<ST X,R17 RJMP RTC_SET DAT_CHK:
CPI COUNT,4 ;cài đặt ngày?
BRNE MO_CHK ;khác,kiểm tra tháng
LDI XH,HIGH(RTC_BUF+4);X trỏ buffer RTC ngày LDI XL,LOW(RTC_BUF+4) LDI NUM_MAX,0X31 LDI NUM_MIN,1
LDI POS_CRS,$C6 ;con trỏ vị trí ngày RCALL SET_NUM RJMP RTC_SET lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN MO_CHK:
CPI COUNT,5 ;cài đặt tháng?
BRNE YEA_CHK ;khác,kiểm tra năm
LDI XH,HIGH(RTC_BUF+5);X trỏ buffer RTC tháng LDI XL,LOW(RTC_BUF+5) LDI NUM_MAX,0X12 LDI NUM_MIN,1
LDI POS_CRS,$C9 ;con trỏ vị trí tháng RCALL SET_NUM YEA_CHK:
CPI COUNT,6 ;cài đặt năm? BRNE EXIT_CHK ;khác,thoát
LDI XH,HIGH(RTC_BUF+6);X trỏ buffer RTC năm LDI XL,LOW(RTC_BUF+6) LDI NUM_MAX,0X99 LDI NUM_MIN,1
LDI POS_CRS,$CC ;con trỏ vị trí năm RCALL SET_NUM RJMP RTC_SET
;-----------------------------------------------------
;Lưu các giá trị cài đặt vào RTCC
;----------------------------------------------------- EXIT_CHK: LDI COUNT,7 ;lưu vào RTCC
LDI XH,HIGH(RTC_BUF);X trỏ buffer RTC LDI XL,LOW(RTC_BUF)
RCALL TWI_START ;phát xung START
LDI R17,(CTL_BYTE|0X00);truy xuất ghi RTC RCALL TWI_WRITE ;ghi RTC+W
LDI R17,0X00 ;địa chỉ thanh ghi giây
RCALL TWI_WRITE ;ghi địa chỉ TCCR WR_RTC: LD R17,X+ RCALL TWI_WRITE ;ghi TCCR DEC COUNT BRNE WR_RTC RCALL TWI_STOP RJMP START1
;------------------------------------------------------
;GET_SW đọc trạng thái SW1,SW2 có chống rung
;Trả về mã SW1=1 hoặc mã SW2=2 và cờ SW_FLG=1 nếu có SW nhấn
;Trả về cờ SW_FLG=0 nếu không có SW nhấn
;Sử dụng R16,R17,cờ SW_FLG thuộc thanh ghi FLAG_REG
;------------------------------------------------------------------------- - GET_SW: CBR REG_FLAG,(1<BACK0:
LDI R16,50 ;kiểm tra SW nhấn 50 lần liên tục WAIT0: IN R17,CONT_IN
ANDI R17,(1<CPI R17,(1<BREQ EXIT_SW ;không nhấn thoát
DEC R16 ;có nhấn tiếp tục lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN BRNE WAIT0 ; PUSH R17 ;cất mã SW BACK1:
LDI R16,50 ;kiểm tra sw nhả 50 lần liên tục WAIT1: IN R17,CONT_IN
ANDI R17,(1<CPI R17,(1<BRNE BACK1 ;chờ nhả SW DEC R16 BRNE WAIT1 POP R17 ;phục hồi mã SW
CPI R17,(1<BRNE SW2_CODE ;không phải kiểm tra mã SW2
LDI R17,1 ;gán giá trị mã SW1
RJMP SET_FLG ;báo cờ nhấn SW SW2_CODE:
CPI R17,(1<BRNE EXIT_SW ;không phải thoát
LDI R17,2 ;gán giá trị mã SW2 SET_FLG: SBR REG_FLAG,(1<EXIT_SW: RET
;----------------------------------------------------------------
;SET_NUM cài đặt các giá trị thời gian chọn qua biến COUNT ;Nhấn/nhả SW1 thoát
;Nhấn/nhả SW2 cài đặt giá trị
;Sử dụng R17,R18,ctc CURS_POS,GET_SW
;---------------------------------------------------------------- SET_NUM:
MOV R17,POS_CRS ;đặt vị trí con trỏ đúng vị trí cài đặt RCALL CURS_POS SW_CHK1: RCALL GET_SW ;đọc SW
SBRS REG_FLAG,SW_FLG;có SW nhấn RJMP SW_CHK1 ;chờ nhấn SW CPI R17,1 ;SW1 nhấn? BREQ EXIT_NUM ;đúng,thoát CPI R17,2 ;SW2 nhấn?
BRNE SW_CHK1 ;khác,đọc lại SW
LD R17,X ;nạp giá trị cài đặt
CPI COUNT,3 ;cài đặt giây?
BRNE DAY_CHK ;khác,kiểm tra ngày
CBR R17,(1<RJMP PRESET ;tiến hành đặt DAY_CHK:
CPI COUNT,0 ;cài đặt ngày?
BRNE PRESET ;khác,tiến hành đặt
ANDI R17,0X07 ;lọc lấy data ngày PRESET:
INC R17 ;tăng giá trị thêm 1
MOV R18,R17 ;cất giá trị đặt
ANDI R17,$0F ;che lấy 4 bit thấp CPI R17,$0A ;giá trị<10 lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
BRCS NON_CR ;đúng,không tràn
LDI R17,$06 ;hiệu đính BCD ADD R18,R17 NON_CR:
MOV R17,R18 ;trả số BCD đặt về R17
CP R17,NUM_MAX ;so sánh giới hạn MAX
BRCS DISP ;nhỏ hơn,hiển thị
BREQ DISP ;bằng,hiển thị
MOV R17,NUM_MIN ;lớn hơn,trả về giới hạn MIN
DISP: ST X,R17 ;cất số BCD đặt vào buffer
RCALL NUM_DISP ;hiển thị số BCD đặt
RJMP SET_NUM ;tiếp tục đặt EXIT_NUM:
INC COUNT ;tăng biến đếm vị trí cài đặt RET
;--------------------------------------------------------------- NUM_DISP: PUSH R17 ;cất data
SWAP R17 ;hoán vị 4 bitthấp/cao
ANDI R17,0X0F ;che lấy số BCD cao
ORI R17,0X30 ;chuyển sang mã ASCII SBI LCD,RS LDI R16,1 ;chờ 100μs RCALL DELAY_US
RCALL OUT_LCD ;hiển thị giá trị POP R17 ;phục hồi data
ANDI R17,0X0F ;che lấy số BCD thấp
ORI R17,0X30 ;chuyển sang mã ASCII SBI LCD,RS LDI R16,1 ;chờ 100μs RCALL DELAY_US
RCALL OUT_LCD ;hiển thị giá trị RET
;-----------------------------------------------------------------
;MSG_DISP hiển thị chuỗi ký tự kết thúc bằng mã NULL đặt trong Flash ROM
;Input: Z chứa địa chỉ đầu chuỗi ký tự
;Output: hiển thị chuỗi ký tự ra LCD tại vị trí con trỏ hiện hành
;Sử dụng R16,R17,ctc DELAY_US,OUT_LCD
;------------------------------------------------------------------ MSG_DISP:
LPM R17,Z+ ;lấy mã ASCII ký tự từ Flash ROM
CPI R17,NULL ;kiểm tra ký tự kết thúc
BREQ EXIT_MSG ;ký tự NULL thoát LDI R16,1 ;chờ 100μs RCALL DELAY_US
SBI LCD,RS ;RS=1 ghi data hiển thị LCD
RCALL OUT_LCD ;ghi mã ASCII ký tự ra LCD
RJMP MSG_DISP ;tiếp tục hiển thị ký tự EXIT_MSG: RET
;----------------------------------------------------------
;CURS_POS đặt con trỏ tại vị trí có địa chỉ trong R17
;Input: R17=$80 -$8F dòng 1,$C0-$CF dòng 2
; R17= địa chỉ vị trí con trỏ lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
;Sử dụng R16,ctc DELAY_US,OUT_LCD
;---------------------------------------------------------- CURS_POS: LDI R16,1 ;chờ 100μs RCALL DELAY_US CBI LCD,RS ;RS=0 ghi lệnh RCALL OUT_LCD RET
;-----------------------------------------------------------------
;INIT_LCD4 khởi động LCD ghi 4 byte mã lệnh theo giao tiếp 4 bit
;Function set:R18=$28 2 dòng font 5x8 giao tiếp 4 bit
;Clear display:R19=$01 xóa màn hình
;Display on/off LCDrol:R20=$0C màn hình on,con trỏ off
;Entry mode set:R21=$06 dịch phải con trỏ ,đ/c DDRAM tăng 1 khi ghi data ;RS=bit0=0,RW=bit1=0
;---------------------------------------------------------------- INIT_LCD4: CBI LCD,RS ;RS=0: ghi lệnh MOV R17,R18 ;R18=Function set
RCALL OUT_LCD ;ghi 1 byte data ra LCD
MOV R17,R19 ;R19=Clear display RCALL OUT_LCD
LDI R16,20 ;chờ 2ms sau lệnh Clear display RCALL DELAY_US
MOV R17,R20 ;R20=Display LCDrol on/off RCALL OUT_LCD
MOV R17,R21 ;R21=Entry mode set RCALL OUT_LCD RET
;--------------------------------------------------
;OUT_LCD4 ghi mã lệnh/data ra LCD
;Input: R17 chứa mã lệnh/data 4 bit cao
;-------------------------------------------------- OUT_LCD4: OUT LCD,R17 SBI LCD,E CBI LCD,E RET
;------------------------------------------------------
;OUT_LCD ghi 1 byte mã lệnh/data ra LCD ;chia làm 2 lần ghi 4bit
;Input: R17 chứa mã lệnh/data,R16
;bit RS=0/1:lệnh/data,bit RW=0:ghi ;Sử dụng ctc OUT_LCD4
;------------------------------------------------------ OUT_LCD: LDI R16,1 ;chờ 100us RCALL DELAY_US IN R16,LCD ;đọc PORT LCD
ANDI R16,(1<PUSH R16 ;cất R16 PUSH R17 ;cất R17 ANDI R17,$F0 ;lấy 4 bit cao OR R17,R16 ;ghép bit RS lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN RCALL OUT_LCD4 ;ghi ra LCD LDI R16,1 ;chờ 100us RCALL DELAY_US POP R17 ;phục hồi R17 POP R16 ;phục hồi R16 SWAP R17 ;đảo 4 bit
ANDI R17,$F0 ;lấy 4 bit thấp chuyển thành cao OR R17,R16 ;ghép bit RS RCALL OUT_LCD4 ;ghi ra LCD RET
;-------------------------------------------------------
;DELAY_US tạo thời gian trễ =R16x100μs(Fosc=8Mhz)
;Input:R16 hệ số nhân thời gian trễ 1 đến 255
;------------------------------------------------------- DELAY_US:
MOV R15,R16 ;1MC nạp data cho R15
LDI R16,200 ;1MC sử dụng R16
L1: MOV R14,R16 ;1MC nạp data cho R14 L2: DEC R14 ;1MC NOP ;1MC BRNE L2 ;2/1MC DEC R15 ;1MC BRNE L1 ;2/1MC RET ;4MC
;---------------------------------------------------------
;TWI_INIT khởi động cổng TWI
;Đặt tốc độ tuyền=100Khz
;--------------------------------------------------------- TWI_INIT: lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
LDI R17,8 ;tốc độ truyền SCL=100Khz STS TWBR,R17 LDI R17,1
STS TWSR,R17 ;hệ số đặt trước=4 LDI R17,(1<STS TWCR,R17 RET
;---------------------------------------------------------- TWI_START: LDI R17,(1<TWCR,R17 WAIT_STA:
LDS R17,TWCR ;đọc cờ TWINT
SBRS R17,TWINT ;chờ cờ TWINT=1 báo truyền xong RJMP WAIT_STA RET
;---------------------------------------------------------- TWI_WRITE: STS TWDR,R17 ;ghi data LDI R17,(1<TWCR,R17 WAIT_WR:
LDS R17,TWCR ;chờ cờ TWINT=1 báo truyền xong SBRS R17,TWINT RJMP WAIT_WR RET
;---------------------------------------------------------- TWI_READ: LDI R17,(1<TWCR,R17 WAIT_RD:
LDS R17,TWCR ;chờ cờ TWINT=1 báo truyền xong SBRS R17,TWINT RJMP WAIT_RD
LDS R17,TWDR ;đọc data thu được RET
;-------------------------------------------------- TWI_NAK: LDI R17,(1<TWCR,R17 WAIT_NAK:
LDS R17,TWCR ;chờ cờ TWINT=1 báo truyền xong SBRS R17,TWINT RJMP WAIT_NAK RET
;---------------------------------------------------------- TWI_STOP: LDI R17,(1<TWCR,R17 RET
;--------------------------------------------------------- .ORG 0X200 MSG1: .DB “THU”,$00 MSG2: .BD “NGAY”,$00 lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN BÀI 4: Interrupt Bảng vector ngắt: lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN Ngắt Timer Thanh ghi ngắt timer: lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
VD: Cấu trúc ngắt TIMER2_COMPA_ISR mỗi 5ms: .ORG 0x00 RJMP MAIN .ORG 0X0020 RJMP TIMER0_COMPA_ISR MAIN: RCALL TIMER0_5MS_IRS_INIT LOOP: ... RJMP LOOP ;5MS = 39 * 125nS *1024 ;MOD CTC TIMER0_5MS_IRS_INIT: ldi r16, 38 out OCR0A,r16 //OCRA = 39-1 (chu ky 5ms) LDI R16, (1 << OCIE0A)
STS TIMSK0, R16 ;BAT NGAT COMPA0 SEI ;CHO PHEP NGAT TOAN CUC ldi r16, (1 << WGM01) out TCCR0A,r16 // setup TCCR0A MODE CTC
ldi r16, (1 << CS02)|(1 << CS00) ;CHIA 1024 out TCCR0B,r16
// setup TCCR0B, BẮT ĐẦU ĐẾM ret TIMER0_COMPA_ISR: PUSH R2 IN R2, SREG ... OUT SREG, R2 POP R2 RETI
VD: ledmatrix dùng ngắt timer0, 125Hz (ngắt 1ms/led) lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
;LEDMATRIX PORTD 125HZ 1ms / LED
;THANH GHI D?CH LEDMATRIX PB0123 ;SW CHUYEN FONT PA0
.include "m324padef.inc" ; Include Atmega324pa definitions .equ LEDMATRIXPORT = PORTD .equ LEDMATRIXDIR = DDRD
.equ clearSignalPort = PORTB ; Set clear signal port to PORTB
.equ clearSignalPin = 3 ; Set clear signal pin to pin 3 of PORTB
.equ shiftClockPort = PORTB ; Set shift clock port to PORTB
.equ shiftClockPin = 2 ; Set shift clock pin to pin 2 of PORTB
.equ latchPort = PORTB ; Set latch port to PORTB
.equ latchPin = 1 ; Set latch pin to pin 1 of PORTB
.equ shiftDataPort = PORTB ; Set shift data port to PORTB
.equ shiftDataPin = 0 ; Set shift data pin to pin 0 of PORTB
.org 0x0000 ; interrupt vector table rjmp reset_handler ; reset .ORG 0X0020 RJMP TIMER0_COMPAISR reset_handler: ; initialize stack pointer ldi r16, high(RAMEND) out SPH, r16 ldi r16, low(RAMEND) out SPL, r16 call shiftregister_initport call shiftregister_cleardata call TIMER0_1MS_IRS_INIT ; enable global interrupts sei call ledmatrix_portinit
ldi r31,high(ledmatrix_Font_A << 1) ;Z register point to fontA
value ldi r30,low(ledmatrix_Font_A << 1) RCALL FONTUPDATE ;TR? Z VÀO V? TRÍ FONT SBI DDRA, 0 SBI PORTA, 0 MAIN:
SBIC PINA, 0 ; NHEU SW ON THI HIEN A lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN Rjmp CHUA
ldi r31,high(ledmatrix_Font_B << 1) ;Z register point to fontA value
ldi r30,low(ledmatrix_Font_B << 1)
RCALL FONTUPDATE ;TR? Z VÀO V? TRÍ FONT RJMP MAIN
CHUA: ldi r31,high(ledmatrix_Font_A << 1) ;Z register point to
fontA value ldi r30,low(ledmatrix_Font_A << 1) RCALL FONTUPDATE
;TR? Z VÀO V? TRÍ FONT RJMP MAIN ; Initialize ports as outputs shiftregister_initport: push r24 ldi r24,
(1<DDRB, r24 ; Set DDRB to output pop r24 ret shiftregister_cleardata: cbi
clearSignalPort, clearSignalPin ; Set clear signal pin to low ; Wait for a short time
sbi clearSignalPort, clearSignalPin ; Set clear signal pin to high ret ; Shift out data ;shift out R27 to bar led shiftregister_shiftoutdata: push r18
cbi shiftClockPort, shiftClockPin ; ldi r18, 8
; Shift 8 bits shiftloop: sbrc r27, 7 ; Check if the MSB of shiftData is 1
sbi shiftDataPort, shiftDataPin ; Set shift data pin to high
sbi shiftClockPort, shiftClockPin ; Set shift clock pin to high lsl r27 ; Shift left
cbi shiftClockPort, shiftClockPin ; Set shift clock pin to
low cbi shiftDataPort, shiftDataPin ; Set shift data pin to
low dec r18 brne shiftloop ; Latch data
sbi latchPort, latchPin ; Set latch pin to
high cbi latchPort, latchPin ; Set latch pin to low pop r18 ret
;Lookup table for collumn control
ledmatrix_col_control: .DB 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 ; Lookup table for font
ledmatrix_Font_A: .DB 0xFC,0xFE,0x13,0x13,0x13,0x13,0xFE,0xFC
ledmatrix_Font_B: .DB 0xFF,0xFF,0x00,0x76,0x76,0x89,0xFF,0xFF .dseg
.org SRAM_START ;starting address is 0x100 LedMatrixBuffer : .byte 8 LedMatrixColIndex : .byte 1 .cseg lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN .align 2 ledmatrix_portinit: push r20 push r21
ldi r20, 0b11111111 ; SET port as output
out LEDMATRIXDIR, r20 ldi r20,0 ;col index start at 0 ldi
r31,high(LedMatrixColIndex) ldi
r30,low(LedMatrixColIndex) st z,r20 ldi r20,0 pop r21 pop r20 ret FONTUPDATE: PUSH R20 PUSH R21
ldi r29,high(LedMatrixBuffer) ; Y register point to fontA value ldi r28,low(LedMatrixBuffer) ldi r20,8
COPYFONTLOOP: ;copy font to display
buffer lpm r21,z+ st y+,r21 dec r20 cpi r20,0 brne COPYFONTLOOP POP R20 POP R21 RET
; Display a Collumn of Led Matrix
; Input: R27 contains the value to display
; R26 contain the Col index (3..0)
; Output: None ledmatrix_display_col: push r16 ; Save the temporary register push r27 clr r16 out LEDMATRIXPORT,r16 call
shiftregister_shiftoutdata ldi
r31,high(ledmatrix_col_control << 1)
ldi r30,low(ledmatrix_col_control << 1)
clr r16 add r30,r26 adc r31,r16 lpm r27,z out LEDMATRIXPORT,r27 pop r27
pop r16 ; Restore the temporary register ret ; Return from the function TIMER0_1MS_IRS_INIT: push r16 ldi r16, 124 out OCR0A, r16 //OCRA = 125- 1 (chu ky 1ms) lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
LDI R16, (1 << OCIE0A)
STS TIMSK0, R16 ;BAT NGAT COMPA0 //SEI ;CHO PHEP NGAT TOAN CUC ldi r16, (1 << WGM01) out TCCR0A,r16 // setup TCCR0A MODE CTC
ldi r16, (1 << CS01)|(1 << CS00) ;CHIA 64 out TCCR0B,r16
// setup TCCR0B, BẮT ĐẦU ĐẾM POP R16 ret TIMER0_COMPAISR: push r16 push r26 push r27 PUSH R30 PUSH R31 ldi r31,high(LedMatrixColIndex)
ldi r30,low(LedMatrixColIndex) ld r16,z mov r26,r16 ldi r31,high(LedMatrixBuffer) ldi r30,low(LedMatrixBuffer) add r30,r16 clr r16 adc r31,r16 ld r27,z call ledmatrix_display_col inc r26 cpi r26,8 brne timer0_COMP_ISR_CONT ldi r26,0 ;if r26 = 8, reset to 0 timer0_COMP_ISR_CONT: ldi
r31,high(LedMatrixColIndex) ldi r30,low(LedMatrixColIndex) st z,r26 POP R31 POP R30 pop r27 pop r26 pop r16 reti Ngắt USART 0,1
Chương trình con USART_ReceiveChar sẽ có vòng lặp chờ cho ến khi cờ RXC = 1 ể
phát hiện nhận xong data. dùng ngắt ể không phải chờ Thanh ghi ngắt usart: lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
Ngắt RXC = 1: kích hoạt mỗi khi nhận ược data; ngắt UDRE =1 kích hoạt khi bộ phát trống.
VD: ếm số ký tự nhận ược từ USART hiển thị ra barled, nếu vượt quá 15 thì reset về 0 .include "m324padef.inc"
; Replace with your application code .DEF COUNT = R20 .ORG 0X00 RJMP MAIN .ORG 0X28 RJMP USART0_RX_ISR .ORG 0X40 MAIN: LDI R16, $FF OUT DDRB, R16 ;PORTB BARLED RCALL USART_ISR_INIT SEI ;CHO PHEP NGAT TOAN CUC LOOP: RJMP LOOP USART_ISR_INIT:
; Set baud rate to 9600 bps with 8 MHz clock
ldi r16, 51 ; 1MHz nạp 12|8MHz nạp 51
sts UBRR0L, r16; nhỏ hơn 255 thì chỉ cần nạp vào low ; set double speed ldi r16, 0 ; off sts UCSR0A, r16
; chọn khung truyền: 8 data bits, no parity, 1 stop bit lOMoAR cPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
// parity chẵn thì thêm (1<r16, (1 << UCSZ01) | (1 << UCSZ00) lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN sts UCSR0C, r16
; Enable transmitter and receiver
ldi r16, (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0) ; CHO PHEP NGAT rxc sts UCSR0B, r16 ret
USART_SendChar: ;truyền Data trông R16 đi push r17
; Wait for the transmitter to be ready USART_SendChar_Wait: lds r17, UCSR0A
sbrs r17, UDRE0 ;check USART Data Register Empty
bit rjmp USART_SendChar_Wait sts UDR0, r16 ;send out pop r17 ret
USART_ReceiveChar:;Nhận data lưu vào R16 push r17
; Wait for the transmitter to be ready USART_ReceiveChar_Wait: lds r17, UCSR0A
sbrs r17, RXC0 ;check USART Receive Complete
bit rjmp USART_ReceiveChar_Wait lds r16, UDR0 ;get data pop r17 ret USART0_RX_ISR: INC COUNT ; TANG BIEN DEM R3
OUT PORTB, COUNT ;OUT RA BARLED
LDS R16, UDR0 ; DOC DE XOA CO NGAT
RCALL USART_SendChar ;PHAT LAI PC CPI COUNT, 0x0F BRCC RESETCOUNT RJMP RXDONE RESETCOUNT:
CLR COUNT ;XOÁ BIEN DEM VE 0 RXDONE: RETI
Ngắt NGOÀI INT 0,1,2 Thanh ghi ngắt ngoài: lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
Ngắt ngoài không cần khai báo DDR
VD: ngắt cạnh xuống INT0 .ORG 0x00 RJMP MAIN .ORG 0X0002 RJMP INT0_ISR MAIN: RCALL INT0_ISR_INIT SEI LOOP: ... RJMP LOOP lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN INT0_ISR_INIT: LDI R16, (1<STS EICRA, R16 LDI R16, (1<STS EIMSK, R16 RET INT0_ISR: PUSH R2 IN R2, SREG ... OUT SREG, R2 POP R2 RETI
Điều khiển ộng cơ = PWM LAD4-2 ;Bai1:
;f=1khz--> T = 1ms = 125. 125ns. 64 ;timer2 tao xung pwm PD6 ;timer0 dem xung PD0 ;timer1 ngat 1s ;PORTA DIEU KHIEN + CHB(PA6) ;PORTC LCD .include "m324padef.inc"
.EQU PORT = PORTA ;port dieu khien .EQU PIN = PINA .EQU DDRPORT = DDRA
.EQU DIPSW1 = 0 ;DIEU KHIEN CHIEU .EQU DIPSW2 = 1 .EQU SW1 = 2 ;TANG TOC .EQU SW2 = 3 ;GIAM TOC .EQU CTR1 = 4 ;OUTPUT
.EQU CTR2 = 5 ;CHAN EN TIMER2 PD6
.EQU CHB = 6 ;PA6 DO CHIEU QUAY
.DEF COUNT0 = R26 ; DEM SO LAN NGAT TIMER0
.DEF CHIEU = R20 ; GHI NHAN CHIEU QUAY
.DEF OPD1_L=R24 ;byte thấp của số nhị phân 16 bit
.DEF OPD1_H=R25 ;byte cao của số nhị phân 16 bit .DEF OPD2=R22 .DEF OPD3=R23 .DEF COUNT=R18
.EQU BCD_BUF=0X200 ;LUU BCD 5DG
.equ LCDPORT = PORTC ; Set signal port reg to PORTA
.equ LCDDDR = DDRC ; Set signal port dir reg to PORTA
.equ LCDPIN = PINC ; Set clear signal port pin reg to PORTA .equ RS = 0 ;PB0 DEM SU KIEN .equ RW = 1 .equ EN = 2 lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN .ORG 0 RJMP MAIN .ORG 0x001A RJMP TIMER1_1S_ISR .ORG 0x0020 RJMP TIMER0_ISR
.ORG 0x40; ch?a ch? cho ng?t MAIN: RCALL PORT_INIT RCALL RESET_LCD RCALL INIT_LCD4 RCALL TIMER2_INIT ; TAO PWM
RCALL TIMER0_IRS_INIT ; DEM CANH LEN ENCODER RCALL TIMER1_INIT ;NGAT 1S
ldi r19, 0 ;BIEN DIEU CHINH DUTYCYCLE
SEI ; NGĂT TOAN CUC BAT READ:
SBIS PIN, DIPSW1 ;IF SIPSW1 ON (=0) --> CTR1= 1 ELSE = 0 RJMP DSW1ON CBI PORT, CTR1 RJMP CHECKDIPSW2 DSW1ON: SBI PORT, CTR1 CHECKDIPSW2:
SBIS PIN, DIPSW2 ;IF SIPSW2 ON --> CTR2= 1 ELSE = 0 RJMP DSW2ON CBI PORT, CTR2 RJMP CHECKSW1 DSW2ON: SBI PORT, CTR2 CHECKSW1:
SBIC PIN, SW1 ;NEU SW1 KO DC NHAN RJMP CHECKSW2 WAITSW1: SBIS PIN, SW1 RJMP WAITSW1 RCALL TANG CHECKSW2:
SBIC PIN, SW2 ;NEU SW2 KO DC NHAN RJMP READ ; DOC SW LAI TU DAU WAITSW2: SBIS PIN, SW2 RJMP WAITSW2 RCALL GIAM RJMP READ ; LAP LAI
;KIEM TRA GIA TRI R19 NEU R19 > MAX THI =
MAX tang: ;tang dan duty cycle subi r19, -6 ;TANG 5% cpi r19, 124 ;KIEM TRA BRCS CHUAMAX LDI R19, 124 CHUAMAX: STS OCR2B,r19 lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN RET
;KIEM TRA GIA TRI R19 NEU R19 < MIN THI = MIN GIAM: ;tang dan duty cycle subi r19, 6 ;GIAM 5% BRCC CHUAMIN LDI R19, 0 CHUAMIN: STS OCR2B,r19 RET TIMER2_INIT:
// Set OC2B (PD6) pins as outputs ldi r16, (1 << PD6); out DDRD,r16
ldi r16, (1 << COM2B1) | (1 << WGM20)|(1 << WGM21)
; XUAT 0 KHI DAT GIA TRI SO SANH, DAT 1 KHI DAT BOTTOM , MODE FPWM2 STS TCCR2A,r16 // setup TCCR0A
ldi r16, (1 << CS22)|(1 << WGM22) ;CHIA 64 khac voi timer0,1
STS TCCR2B,r16 // setup TCCR0B ldi r16, 124 STS OCR2A,r16 //OCRA = 124 (chu ky 1ms) ldi r16, 0 STS OCR2B,r16
//OCRB dieu chinh do rong xung ret PORT_INIT:
ldi r16, (1 << CTR1) | (1 << CTR2) OUT DDRPORT, R16
LDI R16, (1 << DIPSW1) | (1 << DIPSW2) |(1 << SW1) |(1 << SW2) | (1 << CHB) OUT PORT, R16 RET
TIMER0_IRS_INIT: ;ĐẾM XUNG CẠNH LÊN ldi r16, 249 out OCR0A,r16 //OCRA = 250-1 LDI R16, (1 << OCIE0A)
STS TIMSK0, R16 ;BAT NGAT COMPA0 ldi r16, (1 << WGM01) out TCCR0A,r16 // setup TCCR0A MODE CTC
ldi r16, (1 << CS02)|(1 << CS01)|(1 << CS00) ;DEM CANH LEN out TCCR0B,r16
// setup TCCR0B, BẮT ĐẦU ĐẾM ret
TIMER1_INIT: ; NGẮT MỖI 1S MODE CTC push r16
ldi r16, high(31249) ; Load the high Byte into the temporary register
sts OCR1AH, r16 ; Set the high byte of the timer 1 compare value ldi
r16, low(31249) ; Load the low byte into the temporary register sts
OCR1AL, r16 ; Set the low byte of the timer 1 compare value ldi r16, (1
<< CS12)| (1<< WGM12) ; 0b00000101, HE SO CHIA 256, MODE CTC1 sts TCCR1B, r16 ;
ldi r16, (1 << OCIE1A); KÍCH HOẠT NGẮT KHI CỜ OCF1A = 1
sts TIMSK1, r16 ; Enable the timer 1 compare A interrupt pop r16 ret lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
TIMER0_ISR: ;NGẮT MỖI 250 XUNG PUSH R15 IN R15, SREG
SER CHIEU; MAC DINH CHIEU THUAN FF
SBIC PIN, CHB ;NEU CHB = 0 THI BO QUA CLR CHIEU ; CHIEU NGHICH 00 INC COUNT0 ;TANG BIEN DEM OUT SREG, R15 POP R15 RETI TIMER1_1S_ISR: ;NGAT MOI 1S PUSH R15 IN R15, SREG PUSH R16 PUSH R17 PUSH R18 PUSH R22 PUSH R23 PUSH R24 PUSH R25
LDI R16, 250 ; TINH SO XUNG DEM DC MUL COUNT0, R16 LDI R17, 0 IN R16, TCNT0 ADD R0, R16
ADC R1, R17 ; CONG TRAN NEU CO RCALL SHIFT_L1 ;NHÂN 2 MOVW R24, R0 ; SBC R25:R24 LDI R22, 11 ; SO CHIA
RCALL DIV16_8 ; CHIA 11 RA SO RPM
RCALL BIN16_BCD5DG ;CHUYEN THANH BCD 201-204 CBI LCDPORT, RS LDI R16,1 ;chờ 100us RCALL DELAY_US LDI R17, $01 RCALL OUT_LCD LDI R16, 200 RCALL DELAY_US ;XOA MAN HINH TST CHIEU BREQ NGHICH
ldi ZH, high(line1<<1) ; point to the information that is to be displayed ldi ZL, low(line1<<1) RJMP TIEPTUC NGHICH:
ldi ZH, high(line2<<1) ; point to the information that is to be
displayed ldi ZL, low(line2<<1) TIEPTUC: RCALL MSG_DISP CBI LCDPORT, RS LDI R16,1 ;chờ 100us RCALL DELAY_US lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN LDI R17, $C0 ; GIUA DONG 2 RCALL OUT_LCD LDS R17, $201 RCALL NUM_DISP LDS R17, $202 RCALL NUM_DISP LDS R17, $203 RCALL NUM_DISP LDS R17, $204 RCALL NUM_DISP
ldi ZH, high(line3<<1) ; point to the information that is to be displayed ldi ZL, low(line3<<1) RCALL MSG_DISP LDI R16, 0 OUT TCNT0, R16 ;XOA BO DEM CLR COUNT0 POP R25 POP R24 POP R23 POP R22 POP R18 POP R17 POP R16 OUT SREG, R15 POP R15 RETI
;DIV16_8 chia số nhị phân 16 bit OPD1 cho 8 bit OPD2 (Xem giải thuật chia ở Chương 0)
;Input: OPD1_H,OPD1_L= SBC(GPR16-31) R25:24 ; OPD2=SC(GPR0-31) R22
;Output:OPD1_H,OPD1_L=thương số ; OPD3=SD(GPR0-31) R23
;Sử dụng COUNT(GPR16-31) R18
;--------------------------------------- DIV16_8: LDI COUNT,16 ;COUNT=đếm 16 CLR OPD3 ;xóa dư số
SH_NXT: CLC ;C=0=bit thương số
LSL OPD1_L ;dịch trái SBC L,bit0=C=thương số
ROL OPD1_H ;quay trái SBC H,C=bit7
ROL OPD3 ;dịch bit7 SBC H vào dư số
BRCS OV_C ;tràn bit C=1,chia được
SUB OPD3,OPD2 ;trừ dư số với số chia BRCC GT_TH ;C=0 chia được
ADD OPD3,OPD2 ;C=1 không chia được,không trừ RJMP NEXT
OV_C: SUB OPD3,OPD2 ;trừ dư số với số chia
GT_TH: SBR OPD1_L,1 ;chia được,thương số=1
NEXT: DEC COUNT ;đếm số lần dịch SBC
BRNE SH_NXT ;chưa đủ tiếp tục dịch bit RET lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN SHIFT_L1: LSL R1 BST R0,7 BLD R1,0
LSL R0 ;dịch TRÁI số 16bit 1 lần RET
;BIN16_BCD5DG chuyển đổi số nhị phân 16 bit sang số BCD 5 digit
;Inputs: OPD1_H=R25:OPD1_L=R24 chứa số nhị phân 16 bit
;Outputs: BCD_BUF:BCD_BUF+4:địa chỉ SRAM chứa 5 digit BCD từ cao đến thấp
;Sử dụng R17,COUNT,X,ctc DIV16_8
;--------------------------------------------------------- BIN16_BCD5DG:
LDI XH,HIGH(BCD_BUF);X trỏ địa chỉ đầu buffer BCD LDI XL,LOW(BCD_BUF)
LDI COUNT,5 ;đếm số byte bộ nhớ
LDI R17,0X00 ;nạp giá trị 0
LOOP_CL:ST X+,R17 ;xóa buffer bộ nhớ
DEC COUNT ;đếm đủ 5 byte BRNE LOOP_CL
LDI OPD2,10 ;nạp số chia (SC) DIV_NXT:
RCALL DIV16_8 ;chia số nhị phân 16 bit cho số nhị phân 8 bit
ST -X,OPD3 ;cất số dư vào buffer
CPI OPD1_L,0 ;thương số=0?
BRNE DIV_NXT ;khác 0 chia tiếp RET
;RS=0-> lenh| =1 -> data
;Input: R17 chứa mã lệnh/data 4 bit cao
;-------------------------------------------------- OUT_LCD4: OUT LCDPORT,R17 SBI LCDPORT,EN CBI LCDPORT,EN RET OUT_LCD: LDI R16,1 ;chờ 100us RCALL DELAY_US
IN R16,LCDPORT ;đọc PORT LCD
ANDI R16,(1<PUSH R16 ;cât R16 PUSH R17 ;cất R17 ANDI R17,$F0 ;lấy 4 bit cao OR R17,R16 ;ghép bit RS RCALL OUT_LCD4 ;ghi ra LCD LDI R16,1 ;chờ 100us RCALL DELAY_US POP R17 ;phuc hôi R17, r16 POP R16
SWAP R17 ;đảo byte thấp lệnh lên
ANDI R17,$F0 ;l?y 4 bit th?p chuy?n thành cao OR R17,R16 ;ghép bit RS lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN RCALL OUT_LCD4 ;ghi ra LCD RET RESET_LCD: LDI R16,250 ;delay 25ms
RCALL DELAY_US ;ctc delay 100usxR16 LDI R16,250 ;delay 25ms RCALL DELAY_US
LDI R16, 0XFF ;SET OUTPUT CHO PORTLCD OUT LCDDDR, R16
CBI LCDPORT, RS ;RS=0 ghi l?nh
LDI R17,$30 ;mã lênh=$30 lần 1 RCALL OUT_LCD4 LDI R16,42 ;delay 4.2ms RCALL DELAY_US CBI LCDPORT,RS
LDI R17,$30 ;mã lệnh=$30 lần 2 RCALL OUT_LCD4 LDI R16,2 ;delay 200us RCALL DELAY_US CBI LCDPORT,RS LDI R17,$20 ;mã lệnh=$20 RCALL OUT_LCD4 RET INIT_LCD4: CBI LCDPORT,RS ;RS=0 ghi l?nh
LDI R17,$28 ;Function set - giao tiep 4 bit, 1 dòng, font 5x8 RCALL OUT_LCD CBI LCDPORT,RS ;RS=0 ghi l?nh LDI R17,$01 ;Clear display RCALL OUT_LCD
LDI R16,20 ;ch? 2ms sau l?nh Clear display RCALL DELAY_US CBI LCDPORT,RS ;RS=0 ghi l?nh
LDI R17,$0C ;hiện màn hình, tắt con trỏ RCALL OUT_LCD CBI LCDPORT,RS ;RS=0 ghi l?nh
LDI R17,$06 ;con trỏ dịch phải sau mỗi lần đọc/ghi RCALL OUT_LCD lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN RET NUM_DISP : PUSH R16
;nếu R17 là 1 BCD ko nén chỉ cần khúc dưới
ANDI R17,0X0F ;che lấy số BCD thấp
ORI R17,0X30 ;chuyển sang mã ASCII và tương tự SBI LCDPORT,RS LDI R16,1 RCALL DELAY_US RCALL OUT_LCD POP R16 RET MSG_DISP:
LPM R17,Z+ ;lấy mã ASCII ký tự từ Flash ROM
CPI R17, $00 ;kiểm tra ký tụ kết thúc
BREQ EXIT_MSG ;ký tự NULL thoát LDI R16,1 ;chờ 100us RCALL DELAY_US
SBI LCDPORT,RS ;RS=1 ghi data hiển thị LCD
RCALL OUT_LCD ;ghi mã ASCII ký tu ra
LCD RJMP MSG_DISP ;tiếp tục EXIT_MSG: RET
; INPUT:R16 Thơi gian delay = R16.100us lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
;------------------------------------------------------- DELAY_US: PUSH R15 PUSH R16
MOV R15,R16 ;1MC n?p data cho R15 LDI R16,200 ;1MC s? d?ng R16
L1: MOV R14,R16 ;1MC n?p data cho R14 L2: DEC R14 ;1MC NOP ;1MC BRNE L2 ;2/1MC DEC R15 ;1MC BRNE L1 ;2/1MC POP R16 POP R15 RET ;4MC .org 0x200 line1: .db "CHIEU THUAN",0 line2: .db "CHIEU NGHICH ",0 line3: .db "RPM",0 Bài 5 : ADC Các thanh ghi ADC: lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN ADEN : bật ADC
ADCS : bắt ầu chuyển ổi ADC trong mô thức chạy 1 lần, mỗi lần chạy phải bật lên 1.
Mô thức tự chạy (free run) chỉ cần bật lên 1 lần ầu cùng lúc hoặc sau ADEN
ADATE : bật mô thức tự kích sau ó chọn nguồn bằng thanh ghi ADCSRB (free run mặc ịnh khỏi chọn)
ADIF : cờ báo chuyển ổi xong, bình thường phải ghi 1 ể xoá cờ sẵn sàng cho lần tiếp
theo nếu bật interupt thì xoá tự ộng mỗi lần ngắt
ADIE : bật ngắt ADC lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
ADATE = 1 thì chọn nguồn kích
ADC không cần khai báo DDR ADC ngõ vào ơn: lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN 𝐴𝐷𝐶𝑎𝑙.5
Vref = Avcc = 5V; 𝑉𝐼𝑁 =
1024 (ộ phân giải chọn = 10)
Ta muốn hiển thị 2 số sau dấu chấm thập phân, ta phải tính giá trị hiển thị theo công thức: 100. 𝐴𝐷𝐶𝑎𝑙. 5 𝐴𝐷𝐶𝑎𝑙. 250 𝑉𝐼𝑁. 100 = 1024 = 29
VREF=2.56V, 4 chữ số thập phân:
10000.𝐴𝐷𝐶𝑎𝑙. 2.56 𝑉𝐼𝑁.10000 = = 25. 𝐴𝐷𝐶𝑎𝑙 1024
VD: Đo ADC, Vref = Avcc = 5V, hiện ADCal ra usart0 mỗi 1s, hiện kết quả tính toán ra LCD liên tục lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN ;BAI Vref = Vcc = 5V .EQU ADC_PORT=PORTA .EQU ADC_DR=DDRA .EQU ADC_IN=PINA
.DEF OPD1_L=R24 ;byte thấp của số nhị phân 16 bit
.DEF OPD1_H=R25 ;byte cao của số nhị phân 16 bit .DEF OPD2=R22 .DEF OPD3=R23 .DEF COUNT=R18
.EQU BCD_BUF=0X200 ;LUU BCD 5DG
.equ LCDPORT = PORTC ; Set signal port reg to PORTA
.equ LCDDDR = DDRC ; Set signal port dir reg to PORTA
.equ LCDPIN = PINC ; Set clear signal port pin reg to PORTA .equ RS = 0 ;PB0 DEM SU KIEN .equ RW = 1 .equ EN = 2 .ORG 0 RJMP MAIN .ORG 0x001A JMP TIMER1_1S_ISR .ORG 0x40 MAIN: LDI R16, HIGH(RAMEND) OUT SPH, R16 LDI R16, LOW(RAMEND) OUT SPL, R16 RCALL USART_INIT RCALL RESET_LCD RCALL INIT_LCD4 RCALL ADC_DON_INIT lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN RCALL TIMER1_INIT ;NGAT 1S SEI ; NGĂT TOAN CUC BAT LOOP:
RJMP LOOP ;ti?p t?c chuy?n ??i MUL_MATCH: ;NHAN 250 LDI R20,250 MUL R16,R20 MOV R10,R0 MOV R11,R1 MUL R17,R20 MOV R12,R0 MOV R13,R1 ADD R12,R11 CLR R0 ADC R13,R0 ;R13:R12:R10 RET SHIFT_R: ;DICH PHAI 10 LAN LSR R12 BST R13,0 BLD R12,7 LSR R13 MOV R24,R12 MOV R25,R13 RET USART_INIT:
; Set baud rate to 9600 bps with 8 MHz clock ldi r16,
51 ; 1MHz nạp 12|8MHz nạp 51 baud khác tra bảng sts
UBRR0L, r16; nhỏ hơn 255 thì chỉ cần nạp vào low ; set double speed ldi r16, 0 ; off sts UCSR0A, r16
; chọn khung truyền: 8 data bits, no parity, 1 stop bit //
parity chẵn thì thêm (1<ldi r16, (1 << UCSZ01) | (1 << UCSZ00) sts UCSR0C, r16
; Enable transmitter and receiver
ldi r16, (1 << RXEN0) | (1 << TXEN0) sts UCSR0B, r16 ret
USART_SendChar: ;truyền Data trong R16 đi push r17
; Wait for the transmitter to be ready USART_SendChar_Wait: lds r17, UCSR0A
sbrs r17, UDRE0 ;check USART Data Register Empty
bit rjmp USART_SendChar_Wait sts UDR0, r16 ;send out pop r17 ret ADC_DON_INIT:
LDI R16, 0b01000000 ;Vref=AVcc=5V, SE ADC0 STS ADMUX, R16 ; x1,dich phai
LDI R16, 0b10000110 ;cho phép ADC,mode 1 lan. lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
STS ADCSRA, R16 ;f(ADC)=fosc/64=125Khz RET
TIMER1_INIT: ; NGẮT MỖI 1S MODE CTC push r16
ldi r16, high(31249) ; Load the high Byte into the temporary register
sts OCR1AH, r16 ; Set the high byte of the timer 1 compare value ldi
r16, low(31249) ; Load the low byte into the temporary register sts
OCR1AL, r16 ; Set the low byte of the timer 1 compare value ldi r16, (1
<< CS12)| (1<< WGM12) ; 0b00000101, HE SO CHIA 256, MODE CTC1 sts TCCR1B, r16 ;
ldi r16, (1 << OCIE1A); KÍCH HOẠT NGẮT KHI CỜ OCF1A = 1
sts TIMSK1, r16 ; Enable the timer 1 compare A interrupt pop r16 ret
;DIV16_8 chia số nhị phân 16 bit OPD1 cho 8 bit OPD2 (Xem giải thuật chia ở Chương 0)
;Input: OPD1_H,OPD1_L= SBC(GPR16-31) R25:24 ; OPD2=SC(GPR0-31) R22
;Output:OPD1_H,OPD1_L=thương số ; OPD3=SD(GPR0-31) R23
;Sử dụng COUNT(GPR16-31) R18
;--------------------------------------- DIV16_8: LDI COUNT,16 ;COUNT=đếm 16 CLR OPD3 ;xóa dư số
SH_NXT: CLC ;C=0=bit thương số
LSL OPD1_L ;dịch trái SBC L,bit0=C=thương số
ROL OPD1_H ;quay trái SBC H,C=bit7
ROL OPD3 ;dịch bit7 SBC H vào dư số
BRCS OV_C ;tràn bit C=1,chia được
SUB OPD3,OPD2 ;trừ dư số với số chia BRCC GT_TH ;C=0 chia được
ADD OPD3,OPD2 ;C=1 không chia được,không trừ RJMP NEXT
OV_C: SUB OPD3,OPD2 ;trừ dư số với số chia
GT_TH: SBR OPD1_L,1 ;chia được,thương số=1
NEXT: DEC COUNT ;đếm số lần dịch SBC
BRNE SH_NXT ;chưa đủ tiếp tục dịch bit RET
;BIN16_BCD5DG chuyển đổi số nhị phân 16 bit sang số BCD 5 digit
;Inputs: OPD1_H=R25:OPD1_L=R24 chứa số nhị phân 16 bit
;Outputs: BCD_BUF:BCD_BUF+4:địa chỉ SRAM chứa 5 digit BCD từ cao đến thấp
;Sử dụng R17,COUNT,X,ctc DIV16_8
;--------------------------------------------------------- BIN16_BCD5DG:
LDI XH,HIGH(BCD_BUF);X trỏ địa chỉ đầu buffer BCD LDI XL,LOW(BCD_BUF)
LDI COUNT,5 ;đếm số byte bộ nhớ
LDI R17,0X00 ;nạp giá trị 0
LOOP_CL:ST X+,R17 ;xóa buffer bộ nhớ
DEC COUNT ;đếm đủ 5 byte BRNE LOOP_CL
LDI OPD2,10 ;nạp số chia (SC) lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN DIV_NXT:
RCALL DIV16_8 ;chia số nhị phân 16 bit cho số nhị phân 8 bit
ST -X,OPD3 ;cất số dư vào buffer
CPI OPD1_L,0 ;thương số=0?
BRNE DIV_NXT ;khác 0 chia tiếp RET
;RS=0-> lenh| =1 -> data
;Input: R17 chứa mã lệnh/data 4 bit cao
;-------------------------------------------------- OUT_LCD4: OUT LCDPORT,R17 SBI LCDPORT,EN CBI LCDPORT,EN RET OUT_LCD: LDI R16,1 ;chờ 100us RCALL DELAY_US
IN R16,LCDPORT ;đọc PORT LCD
ANDI R16,(1<PUSH R16 ;cât R16 PUSH R17 ;cất R17 ANDI R17,$F0 ;lấy 4 bit cao OR R17,R16 ;ghép bit RS RCALL OUT_LCD4 ;ghi ra LCD LDI R16,1 ;chờ 100us RCALL DELAY_US POP R17 ;phuc hôi R17, r16 POP R16
SWAP R17 ;đảo byte thấp lệnh lên
ANDI R17,$F0 ;l?y 4 bit th?p chuy?n thành cao OR R17,R16 ;ghép bit RS RCALL OUT_LCD4 ;ghi ra LCD lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN RET RESET_LCD : LDI R16,250 ;delay 25ms
RCALL DELAY_US ;ctc delay 100usxR16 LDI R16,250 ;delay 25ms RCALL DELAY_US
LDI R16, 0XFF ;SET OUTPUT CHO PORTLCD OUT LCDDDR, R16
CBI LCDPORT, RS ;RS=0 ghi l?nh
LDI R17,$30 ;mã lênh=$30 lần 1 RCALL OUT_LCD4 LDI R16,42 ;delay 4.2ms RCALL DELAY_US CBI LCDPORT,RS
LDI R17,$30 ;mã lệnh=$30 lần 2 RCALL OUT_LCD4 LDI R16,2 ;delay 200us RCALL DELAY_US CBI LCDPORT,RS LDI R17,$20 ;mã lệnh=$20 RCALL OUT_LCD4 RET INIT_LCD4 : CBI LCDPORT,RS ;RS=0 ghi l?nh
LDI R17,$28 ;Function set - giao tiep 4 bit, 1 dòng, font 5x8 RCALL OUT_LCD CBI LCDPORT,RS ;RS=0 ghi l?nh LDI R17,$01 ;Clear display RCALL OUT_LCD
LDI R16,20 ;ch? 2ms sau l?nh Clear display RCALL DELAY_US CBI LCDPORT,RS ;RS=0 ghi l?nh
LDI R17,$0C ;hiện màn hình, tắt con trỏ RCALL OUT_LCD CBI LCDPORT,RS ;RS=0 ghi l?nh
LDI R17,$06 ;con trỏ dịch phải sau mỗi lần đọc/ghi RCALL OUT_LCD RET NUM_DISP : PUSH R16
;nếu R17 là 1 BCD ko nén chỉ cần khúc dưới
ANDI R17,0X0F ;che lấy số BCD thấp
ORI R17,0X30 ;chuyển sang mã ASCII và tương tự SBI LCDPORT,RS LDI R16,1 RCALL DELAY_US RCALL OUT_LCD POP R16 RET lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN MSG_DISP:
LPM R17,Z+ ;lấy mã ASCII ký tự từ Flash ROM
CPI R17, $00 ;kiểm tra ký tụ kết thúc
BREQ EXIT_MSG ;ký tự NULL thoát LDI R16,1 ;chờ 100us RCALL DELAY_US
SBI LCDPORT,RS ;RS=1 ghi data hiển thị LCD
RCALL OUT_LCD ;ghi mã ASCII ký tu ra
LCD RJMP MSG_DISP ;tiếp tục EXIT_MSG: RET
; INPUT:R16 Thơi gian delay = R16.100us
;------------------------------------------------------- DELAY_US: PUSH R15 PUSH R16
MOV R15,R16 ;1MC n?p data cho R15 LDI R16,200 ;1MC s? d?ng R16
L1: MOV R14,R16 ;1MC n?p data cho R14 L2: DEC R14 ;1MC NOP ;1MC BRNE L2 ;2/1MC DEC R15 ;1MC BRNE L1 ;2/1MC POP R16 POP R15 RET ;4MC
READ_ADC: ;CHO DOC ADC LUU VAO R1:R0 LDS R16, ADCSRA ;DOC CO ADIF
SBRS R16, ADIF ;CHỜ ADIF=1 CHUYEN DOI XONG RJMP READ_ADC
LDS R0, ADCL ;DOC BYTE THAP ADC
LDS R1, ADCH ;DOC BYTE CAO ADC STS ADCSRA, R16 ;xóa cO ADIF RET TIMER1_1S_ISR: PUSH R2 IN R2, SREG PUSH R15 PUSH R16 PUSH R17 LDS R16, ADCSRA
ORI R16, (1<STS ADCSRA, R16
RCALL READ_ADC ; KET QUA LUU VAO R1:R0 ;xuat usart MOV R16,R1
RCALL USART_SendChar ;truyền Data trong R16 đi lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN MOV R16,R0 RCALL USART_SendChar MOVW R16,R0 RCALL MUL_MATCH ;TÍNH TOÁN RCALL SHIFT_R RCALL BIN16_BCD5DG XUAT_LCD: CBI LCDPORT, RS LDI R17, $01 RCALL OUT_LCD LDI R16, 200 RCALL DELAY_US ;XOA MAN HINH
CBI LCDPORT, RS ;RS=0 ghi lenh
LDI R17, $84 ;con tr? b?t ??u ? dòng 1 v? trí th? 1 RCALL OUT_LCD LDI R17,'V' SBI LCDPORT, RS RCALL OUT_LCD LDI R17,'=' SBI LCDPORT, RS RCALL OUT_LCD SBI LCDPORT, RS LDI R17,' '
LDS R17, $202 ; XUAT HANG TRAM RCALL NUM_DISP LDI R17, 44 ;xuat ',' lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN SBI LCDPORT, RS RCALL OUT_LCD
LDS R17, $203 ; XUAT HANG CHUC RCALL NUM_DISP
LDS R17, $204 ; XUAT HANG DON VI RCALL NUM_DISP LDI R17,'V' SBI LCDPORT, RS RCALL OUT_LCD POP R17 POP R16 POP R15 OUT SREG, R2 POP R2 RETI Vref = 2.56V ADC_DON_INIT:
LDI R16, 0b11000000 ;Vref=AVcc=2.56V, SE ADC0 STS ADMUX, R16 ; x1,dich phai
LDI R16, 0b10000110 ;cho phép ADC,mode 1 lan.
STS ADCSRA, R16 ;f(ADC)=fosc/64=125Khz RET MOVW R16,R0
RCALL MUL_MATCH ;TÍNH TOÁN NHAN 25 RCALL BIN16_BCD5DG MUL_MATCH: ;NHAN 25 LDI R20,25 MUL R16,R20 MOV R10,R0 MOV R11,R1 MUL R17,R20 MOV R12,R0 MOV R13,R1 ADD R12,R11 CLR R0 ADC R13,R0 ;R13:R12:R10
MOV R24,R10 ;max =3FF nen chi can lay r12:r10 MOV R25,R12 RET
LDS R17, $200 ; XUAT HANG CHUC NGAN RCALL NUM_DISP lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN LDI R17, 44 ;xuat ',' SBI LCDPORT, RS RCALL OUT_LCD
LDS R17, $201 ; XUAT HANG NGAN RCALL NUM_DISP
LDS R17, $202 ; XUAT HANG TRAM RCALL NUM_DISP ADC vi sai:
Vref phải lớn hơn 2 và nhỏ hơn 4.5V chọn 2.56
Kết quả ADC sẽ ở dạng số có dấu bù 2, 10 bit từ 0x200 (-512) ến 0x1FF (+511)
(𝑉𝑃 − 𝑉𝑁) ⋅ 𝐺𝑎𝑖𝑛 ⋅ 512 𝐴𝐷𝐶 = 𝑉𝑟𝑒𝑓
Chọn ADC1(PA1) – ADC0(PA0), Gain x10, Vref = 2.56V
ADC = dv * 2000 => dv = ADC/2 (mV) .DEF AM = R19 ;CO BAO AM ADC_VISAI_INIT:
LDI R16, 0b11001001 ;Vref=2.56V, VISAI ADC1- ADC0 X10 STS ADMUX, R16 ; dich phai
LDI R16, 0b10000110 ;cho phép ADC,mode 1 lan.
STS ADCSRA, R16 ;f(ADC)=fosc/64=125Khz RET MOVW R16,R0
RCALL MUL_MATCH ;TÍNH TOÁN KHIEM TRA AM DUONG, CHYEN DOI, CHIA 2 lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN RCALL BIN16_BCD5DG ;KIEM TRA BIT 9 XEM 0+ HAY 1-
;NEU AM THI MO RONG BIT, LAY NOT, +1 ,CO AM = FF
MUL_MATCH: ;ADC R17;R16 OUT R25:R24
CLR AM ; MAC DINH LA SO DUONG, AM = 0
MOVW R24,R16 ;chuyen sang r25:24
SBRS R17, 1 ;NEU AM THI BO QUA RJMP DUONG SER AM ; BAT CO AM
ORI R17, 0B11111100 ;MO RONG BIT
MOVW R24,R16 ;CHUYEN SANG CHO R25:R24 COM R25 COM R24 LDI R16, 1 LDI R17, 0 ADD R24, R16 ADC R25, R17 ; LAY BU 2 DUONG: ; CHIA 2 LSR R24 BST R25,0 BLD R24,7 LSR R25 RET LDI R17,'d' SBI LCDPORT, RS RCALL OUT_LCD LDI R17,'V' SBI LCDPORT, RS RCALL OUT_LCD LDI R17,'=' SBI LCDPORT, RS RCALL OUT_LCD SBI LCDPORT, RS LDI R17,' ' RCALL OUT_LCD TST AM ; KHIEM TRA CO AM BREQ TIEPTUC SBI LCDPORT, RS LDI R17,'-' RCALL OUT_LCD TIEPTUC:
LDS R17, $202 ; XUAT HANG TRAM RCALL NUM_DISP
LDS R17, $203 ; XUAT HANG CHUC lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN RCALL NUM_DISP
LDS R17, $204 ; XUAT HANG DV RCALL NUM_DISP LDI R17,'m' SBI LCDPORT, RS RCALL OUT_LCD LDI R17,'V' SBI LCDPORT, RS RCALL OUT_LCD
Cảm biến nhiệt ộ MCP9701
Chọn chế ộ o ADC0, Vref = 2.56V, Dt=(Dout – D0 ộ) / 8 V0 ộ = 400mV, D0 ộ = 160 19.5mV = 8
;BAI Vref = Vcc = 2.56 do nhiet do .EQU ADC_PORT=PORTA .EQU ADC_DR=DDRA .EQU ADC_IN=PINA
.DEF OPD1_L=R24 ;byte thấp của số nhị phân 16 bit
.DEF OPD1_H=R25 ;byte cao của số nhị phân 16 bit .DEF OPD2=R22 .DEF OPD3=R23 .DEF COUNT=R18
.EQU BCD_BUF=0X200 ;LUU BCD 5DG
.equ LCDPORT = PORTC ; Set signal port reg to PORTA
.equ LCDDDR = DDRC ; Set signal port dir reg to PORTA
.equ LCDPIN = PINC ; Set clear signal port pin reg to PORTA .equ RS = 0 ;PB0 DEM SU KIEN .equ RW = 1 .equ EN = 2 .ORG 0 RJMP MAIN .ORG 0x001A JMP TIMER1_1S_ISR .ORG 0x40 MAIN: LDI R16, HIGH(RAMEND) OUT SPH, R16 LDI R16, LOW(RAMEND) OUT SPL, R16 RCALL USART_INIT lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN RCALL RESET_LCD RCALL INIT_LCD4 lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN RCALL ADC_DON_INIT RCALL TIMER1_INIT ;NGAT 1S SEI ; NGĂT TOAN CUC BAT LOOP:
RJMP LOOP ;ti?p t?c chuy?n ??i MUL_MATCH: ;NHAN 25 LDI R20,25 MUL R16,R20 MOV R10,R0 MOV R11,R1 MUL R17,R20 MOV R12,R0 MOV R13,R1 ADD R12,R11 CLR R0 ADC R13,R0 ;R13:R12:R10
MOV R24,R10 ;max =3FF nen chi can lay r12:r10 MOV R25,R12 RET USART_INIT:
; Set baud rate to 9600 bps with 8 MHz clock ldi r16,
51 ; 1MHz nạp 12|8MHz nạp 51 baud khác tra bảng sts
UBRR0L, r16; nhỏ hơn 255 thì chỉ cần nạp vào low ; set double speed ldi r16, 0 ; off sts UCSR0A, r16
; chọn khung truyền: 8 data bits, no parity, 1 stop bit //
parity chẵn thì thêm (1<ldi r16, (1 << UCSZ01) | (1 << UCSZ00) sts UCSR0C, r16
; Enable transmitter and receiver
ldi r16, (1 << RXEN0) | (1 << TXEN0) sts UCSR0B, r16 ret
USART_SendChar: ;truyền Data trong R16 đi push r17
; Wait for the transmitter to be ready USART_SendChar_Wait: lds r17, UCSR0A
sbrs r17, UDRE0 ;check USART Data Register Empty
bit rjmp USART_SendChar_Wait sts UDR0, r16 ;send out pop r17 ret ADC_DON_INIT:
LDI R16, 0b11000000 ;Vref=AVcc=2.56V, SE ADC0 STS ADMUX, R16 ; x1,dich phai
LDI R16, 0b10000110 ;cho phép ADC,mode 1 lan.
STS ADCSRA, R16 ;f(ADC)=fosc/64=125Khz RET lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
TIMER1_INIT: ; NGẮT MỖI 1S MODE CTC push r16
ldi r16, high(31249) ; Load the high Byte into the temporary register
sts OCR1AH, r16 ; Set the high byte of the timer 1 compare value ldi
r16, low(31249) ; Load the low byte into the temporary register sts
OCR1AL, r16 ; Set the low byte of the timer 1 compare value ldi r16, (1
<< CS12)| (1<< WGM12) ; 0b00000101, HE SO CHIA 256, MODE CTC1 sts TCCR1B, r16 ;
ldi r16, (1 << OCIE1A); KÍCH HOẠT NGẮT KHI CỜ OCF1A = 1
sts TIMSK1, r16 ; Enable the timer 1 compare A interrupt pop r16 ret
;DIV16_8 chia số nhị phân 16 bit OPD1 cho 8 bit OPD2 (Xem giải thuật chia ở Chương 0)
;Input: OPD1_H,OPD1_L= SBC(GPR16-31) R25:24 ; OPD2=SC(GPR0-31) R22
;Output:OPD1_H,OPD1_L=thương số ; OPD3=SD(GPR0-31) R23
;Sử dụng COUNT(GPR16-31) R18
;--------------------------------------- DIV16_8: LDI COUNT,16 ;COUNT=đếm 16 CLR OPD3 ;xóa dư số
SH_NXT: CLC ;C=0=bit thương số
LSL OPD1_L ;dịch trái SBC L,bit0=C=thương số
ROL OPD1_H ;quay trái SBC H,C=bit7
ROL OPD3 ;dịch bit7 SBC H vào dư số
BRCS OV_C ;tràn bit C=1,chia được
SUB OPD3,OPD2 ;trừ dư số với số chia BRCC GT_TH ;C=0 chia được
ADD OPD3,OPD2 ;C=1 không chia được,không trừ RJMP NEXT
OV_C: SUB OPD3,OPD2 ;trừ dư số với số chia
GT_TH: SBR OPD1_L,1 ;chia được,thương số=1
NEXT: DEC COUNT ;đếm số lần dịch SBC
BRNE SH_NXT ;chưa đủ tiếp tục dịch bit RET
;BIN16_BCD5DG chuyển đổi số nhị phân 16 bit sang số BCD 5 digit
;Inputs: OPD1_H=R25:OPD1_L=R24 chứa số nhị phân 16 bit
;Outputs: BCD_BUF:BCD_BUF+4:địa chỉ SRAM chứa 5 digit BCD từ cao đến thấp
;Sử dụng R17,COUNT,X,ctc DIV16_8
;--------------------------------------------------------- BIN16_BCD5DG:
LDI XH,HIGH(BCD_BUF);X trỏ địa chỉ đầu buffer BCD LDI XL,LOW(BCD_BUF)
LDI COUNT,5 ;đếm số byte bộ nhớ
LDI R17,0X00 ;nạp giá trị 0
LOOP_CL:ST X+,R17 ;xóa buffer bộ nhớ
DEC COUNT ;đếm đủ 5 byte BRNE LOOP_CL
LDI OPD2,10 ;nạp số chia (SC) DIV_NXT:
RCALL DIV16_8 ;chia số nhị phân 16 bit cho số nhị phân 8 bit
ST -X,OPD3 ;cất số dư vào buffer lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
CPI OPD1_L,0 ;thương số=0?
BRNE DIV_NXT ;khác 0 chia tiếp RET
;RS=0-> lenh| =1 -> data
;Input: R17 chứa mã lệnh/data 4 bit cao
;-------------------------------------------------- OUT_LCD4: OUT LCDPORT,R17 SBI LCDPORT,EN CBI LCDPORT,EN RET OUT_LCD: LDI R16,1 ;chờ 100us RCALL DELAY_US
IN R16,LCDPORT ;đọc PORT LCD
ANDI R16,(1<PUSH R16 ;cât R16 PUSH R17 ;cất R17 ANDI R17,$F0 ;lấy 4 bit cao OR R17,R16 ;ghép bit RS RCALL OUT_LCD4 ;ghi ra LCD LDI R16,1 ;chờ 100us RCALL DELAY_US POP R17 ;phuc hôi R17, r16 POP R16
SWAP R17 ;đảo byte thấp lệnh lên
ANDI R17,$F0 ;l?y 4 bit th?p chuy?n thành cao OR R17,R16 ;ghép bit RS RCALL OUT_LCD4 ;ghi ra LCD RET RESET_LCD: LDI R16,250 ;delay 25ms
RCALL DELAY_US ;ctc delay 100usxR16 LDI R16,250 ;delay 25ms RCALL DELAY_US
LDI R16, 0XFF ;SET OUTPUT CHO PORTLCD OUT LCDDDR, R16
CBI LCDPORT, RS ;RS=0 ghi l?nh
LDI R17,$30 ;mã lênh=$30 lần 1 RCALL OUT_LCD4 LDI R16,42 ;delay 4.2ms RCALL DELAY_US CBI LCDPORT,RS
LDI R17,$30 ;mã lệnh=$30 lần 2 RCALL OUT_LCD4 LDI R16,2 ;delay 200us RCALL DELAY_US CBI LCDPORT,RS LDI R17,$20 ;mã lệnh=$20 RCALL OUT_LCD4 RET INIT_LCD4: lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN CBI LCDPORT,RS ;RS=0 ghi l?nh
LDI R17,$28 ;Function set - giao tiep 4 bit, 1 dòng, font 5x8 RCALL OUT_LCD CBI LCDPORT,RS ;RS=0 ghi l?nh
LDI R17,$01 ;Clear display RCALL OUT_LCD
LDI R16,20 ;ch? 2ms sau l?nh Clear display RCALL DELAY_US CBI LCDPORT,RS ;RS=0 ghi l?nh
LDI R17,$0C ;hiện màn hình, tắt con trỏ RCALL OUT_LCD CBI LCDPORT,RS ;RS=0 ghi l?nh
LDI R17,$06 ;con trỏ dịch phải sau mỗi lần đọc/ghi RCALL OUT_LCD RET NUM_DISP : PUSH R16
;nếu R17 là 1 BCD ko nén chỉ cần khúc dưới
ANDI R17,0X0F ;che lấy số BCD thấp
ORI R17,0X30 ;chuyển sang mã ASCII và tương tự SBI LCDPORT,RS LDI R16,1 RCALL DELAY_US RCALL OUT_LCD POP R16 RET MSG_DISP:
LPM R17,Z+ ;lấy mã ASCII ký tự từ Flash ROM
CPI R17, $00 ;kiểm tra ký tụ kết thúc
BREQ EXIT_MSG ;ký tự NULL thoát lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN LDI R16,1 ;chờ 100us RCALL DELAY_US
SBI LCDPORT,RS ;RS=1 ghi data hiển thị LCD
RCALL OUT_LCD ;ghi mã ASCII ký tu ra
LCD RJMP MSG_DISP ;tiếp tục EXIT_MSG: RET
; INPUT:R16 Thơi gian delay = R16.100us
;------------------------------------------------------- DELAY_US: PUSH R15 PUSH R16
MOV R15,R16 ;1MC n?p data cho R15 LDI R16,200 ;1MC s? d?ng R16
L1: MOV R14,R16 ;1MC n?p data cho R14 L2: DEC R14 ;1MC NOP ;1MC BRNE L2 ;2/1MC DEC R15 ;1MC BRNE L1 ;2/1MC POP R16 POP R15 RET ;4MC
READ_ADC: ;CHO DOC ADC LUU VAO R1:R0 LDS R16, ADCSRA ;DOC CO ADIF
SBRS R16, ADIF ;CHỜ ADIF=1 CHUYEN DOI XONG RJMP READ_ADC
LDS R0, ADCL ;DOC BYTE THAP ADC
LDS R1, ADCH ;DOC BYTE CAO ADC STS ADCSRA, R16 ;xóa cO ADIF RET TIMER1_1S_ISR: PUSH R2 IN R2, SREG PUSH R15 PUSH R16 PUSH R17 LDS R16, ADCSRA
ORI R16, (1<STS ADCSRA, R16
RCALL READ_ADC ; KET QUA LUU VAO R1:R0 ;xuat usart MOV R16,R1
RCALL USART_SendChar ;truyền Data trong R16 đi MOV R16,R0 RCALL USART_SendChar lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN MOVW R16,R0
PUSH R16 ; LUU LAI DE TINH DO C PUSH R17
RCALL MUL_MATCH ;TÍNH TOÁN NHAN
25 RCALL BIN16_BCD5DG XUAT_LCD: CBI LCDPORT, RS LDI R17, $01 RCALL OUT_LCD LDI R16, 200 RCALL DELAY_US ;XOA MAN HINH
CBI LCDPORT, RS ;RS=0 ghi lenh
LDI R17, $84 ;con tr? b?t ??u ? dòng 1 v? trí th? 1 RCALL OUT_LCD LDI R17,'V' SBI LCDPORT, RS RCALL OUT_LCD LDI R17,'=' SBI LCDPORT, RS RCALL OUT_LCD SBI LCDPORT, RS LDI R17,' '
LDS R17, $200 ; XUAT HANG CHUC NGAN RCALL NUM_DISP LDI R17, 44 ;xuat ',' SBI LCDPORT, RS RCALL OUT_LCD
LDS R17, $201 ; XUAT HANG NGAN RCALL NUM_DISP
LDS R17, $202 ; XUAT HANG TRAM RCALL NUM_DISP LDI R17,'V' SBI LCDPORT, RS RCALL OUT_LCD
CBI LCDPORT, RS ;RS=0 ghi lenh
LDI R17, $C4 ;con tr? b?t ??u ? dòng 1 v? trí th? 1 RCALL OUT_LCD LDI R17,'T' SBI LCDPORT, RS RCALL OUT_LCD lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN LDI R17,'=' SBI LCDPORT, RS RCALL OUT_LCD POP R17 ; LAY LAI GIA TRI D POP R16
RCALL TRU16_16 ;TRU CHO GIA TRI TAI 0 DO RCALL SHIFT_R3 ; CHIA 8 RCALL BIN16_BCD5DG
LDS R17, $203 ; XUAT HANG CHUC RCALL NUM_DISP LDS R17, $204 ; XUAT HANG DV RCALL NUM_DISP LDI R17,'o' SBI LCDPORT, RS RCALL OUT_LCD LDI R17,'C' SBI LCDPORT, RS RCALL OUT_LCD POP R17 POP R16 POP R15 OUT SREG, R2 POP R2 RETI TRU16_16: ;OUTPUT R17:R16 push r21 lOMoARcPSD| 36991220
BY ÔNG ANH KHOA ĐIỆN
ldi r21,high($A1) ;gia tri tai 0 do
C mov r7,r21 ldi r21,low($A1) mov
r6,r21 sub r16,r6 sbc r17,r7 pop r21 ret SHIFT_R3: LDI R19, 3 SHIFT_LOOP: LSR R16 BST R17,0 BLD R16,7 LSR R17 DEC R19 BRNE SHIFT_LOOP MOVW R24,R16 RET