Tài liệu Bài giảng Vào / ra (input / output): BÀI 2: VÀO / RA (Input / Output)
Ví dụ 1: Đặt P3.0 hoặc P3.1 xuống mức “0” sẽ làm mất kết nối giữa bo với máy tính
***************************************************
ORG 00H ;Reset
LJMP MAIN
ORG 0003H ;INT0
RETI ;do nothing
ORG 0013H ;Timer 0
RETI ;do nothing
ORG 0013H ;INT1
RETI ;do nothing
ORG 001BH ;Timer 1
RETI ;do nothing
ORG 0023H ;serial port
JNB SCON.0,SerialIntExit
SerialIntExit:
RETI ;do nothing
****************************************************
ORG 40H ;start of program
MAIN:
MOV P0,#0FFH
MOV P1,#0FFH
MOV P2,#0FFH
MOV P3,#0FFH
SJMP $
END
Câu hỏi 1: Khi đặt các swicth ở vị trí ON thì mức logic ngõ ra tương ứng sẽ là cao (High) hay thấp (Low)?
Trả lời: Khi đặt các swicth ở vị trí ON thì mức logic ngõ ra tương ứng sẽ là LOW
Câu hỏi 2: Tác dụng của những dòng lệnh trước phần chương trình chính (MAIN) là để làm gì?
Trả lời: Dùng để kích hoat ngắt cho các port
Câu hỏi 3: Viết chương trình để bật sáng lần lượt, sau đó tắt lầ...
51 trang |
Chia sẻ: hunglv | Lượt xem: 1404 | Lượt tải: 0
Bạn đang xem trước 20 trang mẫu tài liệu Bài giảng Vào / ra (input / output), để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
BÀI 2: VÀO / RA (Input / Output)
Ví dụ 1: Đặt P3.0 hoặc P3.1 xuống mức “0” sẽ làm mất kết nối giữa bo với máy tính
***************************************************
ORG 00H ;Reset
LJMP MAIN
ORG 0003H ;INT0
RETI ;do nothing
ORG 0013H ;Timer 0
RETI ;do nothing
ORG 0013H ;INT1
RETI ;do nothing
ORG 001BH ;Timer 1
RETI ;do nothing
ORG 0023H ;serial port
JNB SCON.0,SerialIntExit
SerialIntExit:
RETI ;do nothing
****************************************************
ORG 40H ;start of program
MAIN:
MOV P0,#0FFH
MOV P1,#0FFH
MOV P2,#0FFH
MOV P3,#0FFH
SJMP $
END
Câu hỏi 1: Khi đặt các swicth ở vị trí ON thì mức logic ngõ ra tương ứng sẽ là cao (High) hay thấp (Low)?
Trả lời: Khi đặt các swicth ở vị trí ON thì mức logic ngõ ra tương ứng sẽ là LOW
Câu hỏi 2: Tác dụng của những dòng lệnh trước phần chương trình chính (MAIN) là để làm gì?
Trả lời: Dùng để kích hoat ngắt cho các port
Câu hỏi 3: Viết chương trình để bật sáng lần lượt, sau đó tắt lần lượt các đèn led ở Port 2, Port 3
Trả lời:
Cách 1: (thủ công: viết lệnh cho từng led)
************************
ORG 00H ;Reset
LJMP MAIN
ORG 03H ;INTO
RETI ;do nothing
ORG 0BH ;Timer0
RETI ;do nothing
ORG 13H ;INT1
RETI ;do nothing
ORG 1BH ;Timer 1
RETI ;do nothing
ORG 23H ;Serial port
JNB SCON.0,SeriallntExit
SeriallntExit:
RETI ;do nothing
*************************************
ORG 60H ;start of program
MAIN:
MOV P2,#0H
MOV P3,#0H
LCALL DELAY_10S ;wait for a second
SETB P2.0 ;red led:off
LCALL DELAY_10S ;wait for a second
SETB P2.1 ;red led:off
LCALL DELAY_10S ;wait for a second
SETB P2.2 ;red led:off
LCALL DELAY_10S ;wait for a second
SETB P2.3 ;red led:off
LCALL DELAY_10S ;wait for a second
SETB P2.4 ;red led:off
LCALL DELAY_10S ;wait for a second
SETB P2.5 ;red led:off
LCALL DELAY_10S ;wait for a second
SETB P2.6 ;yellow led:off
LCALL DELAY_10S ;wait for a second
SETB P2.7 ;green led:off
LCALL DELAY_10S ;wait for a second
LCALL DELAY_10S ;wait for a second
CLR P2.0 ;red led:off
LCALL DELAY_10S ;wait for a second
CLR P2.1 ;red led:off
LCALL DELAY_10S ;wait for a second
CLR P2.2 ;red led:off
LCALL DELAY_10S ;wait for a second
CLR P2.3 ;red led:off
LCALL DELAY_10S ;wait for a second
CLR P2.4 ;red led:off
LCALL DELAY_10S ;wait for a second
CLR P2.5 ;red led:off
LCALL DELAY_10S ;wait for a second
CLR P2.6 ;yellow led:off
LCALL DELAY_10S ;wait for a second
CLR P2.7 ;green led:off
LCALL DELAY_10S ;wait for a second
SJMP MAIN
DELAY_10S:
MOV R1,#10
ACALL DELAY
RET
DELAY:
LOOP1_1:
MOV R2,#100
LOOP1_2:
MOV R3,#100
LOOP1_3:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R3,LOOP1_3
DJNZ R2,LOOP1_2
DJNZ R1,LOOP1_1
RET
END
Cách 2: ( sử dụng dịch phải_RR)
************************
ORG 00H ;Reset
LJMP MAIN
ORG 03H ;INTO
RETI ;do nothing
ORG 0BH ;Timer0
RETI ;do nothing
ORG 13H ;INT1
RETI ;do nothing
ORG 1BH ;Timer 1
RETI ;do nothing
ORG 23H ;Serial port
JNB SCON.0,SeriallntExit
SeriallntExit:
RETI ;do nothing
*************************************
ORG 60H ;start of program
MAIN:
MOV A,#0000 0010 B
LOOP: RR A
MOVE P3, A
ACALL DELAY_1S ;wait for a second
SJMP LOOP
DELAY_1S:
MOV R1,#30
ACALL DELAY
RET
DELAY:
LOOP1_1:
MOV R2,#100
LOOP1_2:
MOV R3,#100
LOOP1_3:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R3,LOOP1_3
DJNZ R2,LOOP1_2
DJNZ R1,LOOP1_1
RET
END
Câu hỏi 4: Thay đổi chương trình để xuất dữ liệu của P1 lần lượt là 0x0FH, 0x1FH, 0x2FH, ….0xFFH. Thống kê lại kết quả vào bảng sau và rút ra kết luận
STT
DỮ LIỆU YÊU CẦU XUẤT RA P1
TRẠNG THÁI MSB CỦA P1 TƯƠNG ỨNG
ĐÁP ỨNG ĐÚNG?
( CÓ / KHÔNG)
BIT 1
BIT2
BIT3
BIT4
1
0x0FH
L
L
L
L
2
0x1FH
H
L
L
L
3
0x2FH
L
H
L
L
4
0x3FH
H
H
L
L
5
0x4FH
L
L
H
L
6
0x5FH
H
L
H
L
7
0x6FH
L
H
H
L
8
0x7FH
H
H
H
L
9
0x8FH
L
L
L
H
10
0x9FH
H
L
L
H
11
0xAFH
L
H
L
H
12
0xBFH
H
H
L
H
13
0xCFH
L
L
H
H
14
0xDFH
H
L
H
H
15
0xEFH
L
H
H
H
16
0xFFH
H
H
H
H
BÀI 3: ĐÈN GIAO THÔNG
Bài tập 1: Ban đầu bật từng LED sáng tắt mà không có tác động của các công tắc. Viết chương trình để:
Bật sáng LED đỏ chỉ trong một khoảng thời gian ngắn và sau đó tắt đi.
Bật sáng LED xanh chỉ trong một khoảng thời gian ngắn và sau đó tắt đi
Bật sáng LED vàng chỉ trong một khoảng thời gian ngắn và sau đó tắt đi
Nhấp nháy LED đỏ
Nhấp nháy cả 3 LED
Chương trình mẫu:
********************************
ORG 0000H ;Reset
LJMP MAIN
ORG 0003H ;INT0
RETI ;do nothing
ORG 000BH ;Timer 0
RETI ;do nothing
ORG 0013H ;INT1
RETI ;do nothing
ORG 001BH ;Timer 1
RETI ;do nothing
ORG 0023H ;Serial port
JNB SCON.SerialIntExit
SerialIntExit:
RETI ;do nothing
***********************************
ORG 60H ;start of program
MAIN:
CLR P1.3 ;red led: on
LCALL DELAY_10S ;wait for a second
SETB P1.3 ;red led: off
CLR P1.0 ;green led: on
LCALL DELAY_10S ;wait for a second
SETB P1.0 ;green led: off
CLR P1.1 ;yellow led: on
LCALL DELAY_10S ;wait for a second
SETB P1.1 ;yellow led: off
MOV R0,#5 ;set times you want to repeat
LCALL NHAY_LED_DO ;run a sub program
MOV R0,#5 ;set times you want to repeat
LCALL NHAY_BA_LED ;run a sub program
ACALL MAIN ;enable if you want repeat
SJMP $ ;finish program and do nothing
NHAY_LED_DO:
CLR P1.3
LCALL DELAY_1S
SETB P1.3
LCALL DEALY_1S
DJNZ R0,NHAY_LED_DO
RET
NHAY_BA_LED:
MOV P1,#11110100B
LCALL DELAY_1S
MOV P1,#11111111b
LCALL DELAY_1S
DJNZ R0,NHAY_BA_LED
RET
DELAY_10S:
MOV R1,#10
ACALL DELAY
RET
DELAY:
LOOP1_1:
MOV R2,#100
LOOP1_2:
MOV R3,#100
LOOP1_3:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R3,LOOP1_3
DJNZ R2,LOOP1_2
DJNZ R1,LOOP1_1
RET
END
Sơ đồ giải thuật chương trình :
Đặt thời gian nhấp nháy LED đỏ
Khởi động chương trình
Clear P1.3 : bật LED đỏ
Gọi hàm con DELAY_1S
Set P1.3 : tắt LED đỏ
Clear P1.0 : bật LED xanh
Gọi hàm con DELAY_1S
Set P1.0 : tắt LED xanh
Clear P1.1 : bật LED vàng
Gọi hàm con DELAY_1S
Set P1.1 : tắt LED vàng
Gọi hàm con NHAY_LED_DO
Đặt thời gian nhấp nháy 3 LED
Gọi hàm con NHAY_3_LED
Kết thúc
Bài tập 2: Bây giờ bạn có thể điều khiển nhiều hơn một ngõ ra. Bước tiếp theo là đọc một ngõ vào. Khi công tắc không tích cực, đường tương ứng ỡ mức cao, và LED sẽ sáng. Khicông tắc được tích cực, nhấp nháy một LED. Viết chương trình để:
Bật sáng LED đỏ nếu công tắc 1 không tích cực.
Bật sáng LED xanh nếu công tắc 2 không tích cực
Nhấp nháy LED đỏ chừng nào mà công tắc 1 còn tích cực, bật LED đỏ khi công tắc 1 không tích cực.
Nhấp nháy LED vàng chừng nào mà công tắc 2 còn tích cực, bật LED vàng khi công tắc 2 không tích cực.
Chương trình mẫu:
*****************************
ORG 0000H ;reset
LJMP MAIN
ORG 0030H ;INT0
RETI ;do nothing
ORG 000BH ;timer 0
RETI ;do nothing
ORG 0013H ;INT1
RETI ;do nothing
ORG 001BH ;timer 1
RETI ;do nothing
ORG 0023H ;serial port
JNB SCON.0,SerialIntExit
SerialIntExit:
RETI ;do nothing
*******************************
ORG 60H
MAIN:
CLR P1.3
CLR P1.1
JNB P3.2,FLASH_RED
TT:
JNB P3.3,FLASH_YELLOW
SJMP MAIN
FLASH_RED:
SETB P1.3
LCALL DELAY_1S
CLR P1.3
LCALL DELAY_1S
SJMP TT
FLASH_YELLOW:
SETB P1.1
LCALL DELAY_1S
CLR P1.1
LCALL DELAY_1S
SJMP MAIN
DELAY_1S:
MOV R1,#10
LOOP1_1:
MOV R2,#100
LOOP1_2:
MOV R3,#100
LOOP1_3:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R3,LOOP1_3
DJNZ R2,LOOP1_2
DJNZ R1,LOOP1_1
RET
END
Sơ đồ giải thuật chương trình :
Không tich cưc =0
Tích cực=1
Không tich cưc =0
Tích cực=1
Khởi động chương trình
Clear P1.3 : bật LED đỏ
Clear P1.1 : bật LED vàng
P3.2 = 0?
Gọi hàm con NHAY_LED_DO
Gọi hàm con NHAY_LED_DO
Gọi hàm con NHAY_LED_VANG
P3.3 = 0?
Bài tập 3: Viết chương trình cho bộ điều khiển đèn giao thông theo các yêu cầu sau:
Công tắc 1
Công tắc 2
LED đỏ
LED vàng
LED xanh
Hở
Hở
OFF
OFF
ON
Hở
Đóng
ON
ON
OFF
Đóng
Hở
OFF
OFF
ON
Đóng
Đóng
OFF
OFF
OFF
Xây dựng chương trình và nạp vào kit thí nghiệm. Theo dõi chương trình và quan sát các LED khi cho chạy từng bước mỗi một câu lệnh. Đóng / mở sw1 và 2 để thay đổi trang thái LED để chắc rằng chương trình đúng trường hợp.
Chương trình mẫu:
*****************************************************
ORG 0000H ;reset
LJMP MAIN
ORG 0030H ;INT0
RETI ;do nothing
ORG 000BH ;timer 0
RETI ;do nothing
ORG 0013H ;INT1
RETI ;do nothing
ORG 001BH ;timer 1
RETI ;do nothing
ORG 0023H ;serial port
JNB SCON.0,SerialIntExit
SerialIntExit:
RETI ;do nothing
*****************************************************
ORG 60H ;start of program
MAIN:
MOV A,P3
CJNE A,#11110111B,TT0 ;SW1:0FF AND SW2:ON
MOV P1,#11110101B ;RED AND YELLOW
TT0: CJNE A,#11111011B,TT1 ;SW1:0N AND SW2:OFF
MOV P1,#11111110B ;GREEN
TT1: CJNE A,#11110011B,TT2 ;SW1:ON AND SW2:ON
MOV P1,#11111111B ;ALL LED OFF
TT2: CJNE A,#11111111B,MAIN ;ALL SWITCHS OFF
MOV P1,#11111110B ;GREEN
SJMP MAIN
END
Sơ đồ giải thuật chương trình :
SĐ
SĐ
Đ
Đ
SĐ
Khởi động chương trình
Ghi (P3) vào A
A=11110111B
A=11110011B
Ghi 11110111B vào P1
(sw1:ON, sw2:ON)
Ghi 11110111B vào P1
(sw1:ON,sw2:OFF)
A=11111111B
Ghi 11111111B vào P1
(sw1:OFF,sw2:OFF)
Đ
Kết thúc
Câu hỏi 2: Có thể viết lại chương trình câu 2 theo dạng câu 3 được không? Hãy viết lại để kiểm chứng?
**************************
ORG 00H
LJMP MAIN
ORG 03H
RETI
ORG 0BH
RETI
ORG 13H
RETI
ORG 1BH
RETI
ORG 23H
JNB SCON.0,SeriallntExit
SeriallntExit:
RETI
******************************
ORG 60H
MAIN:
MOV A,P3
CJNE A,#11111111B,TT0
MOV P1,#11110101B
TT0:
CJNE A,#11111011B,TT1
SETB P1.3
LCALL DELAY_1S
CLR P1.3
LCALL DELAY_1S
SJMP TT1
TT1:
CJNE A,#11110111B,MAIN
SETB P1.1
LCALL DELAY_1S
CLR P1.1
LCALL DELAY_1S
SJMP MAIN
DELAY_1S:
MOV R1,#10
ACALL DELAY
RET
DELAY:
LOOP1_1:
MOV R2,#10
LOOP1_2:
MOV R3,#100
LOOP1_3:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R3,LOOP1_3
DJNZ R2,LOOP1_2
DJNZ R1,LOOP1_1
RET
SJMP MAIN
END
Kết luận:BÀI 4: BIẾN ĐỔI A/D TRÊN BOARD TB-1
Bài tập : Viết một chương trình Assembler sử dụng bộ biến đổi A/D ở chế độ single-ended với biến trở nối vào kênh 0 ( tức chân 3) trên chip A/D thông qua khối đầu cuối ( terminal block) trên bo TB-1. Thay đổi điện áp vào tương tự và hiển thị giá trị của nó. Nối biến trở vào kênh 0 , sau đó hiển thị đồng thời ca hai giá trị đó ra P0, P2. Thay đổi các giá trị điện áp vào tương tự và quan sát các kết quả.
Chương trình mẫu:
***************DEFINITION**********
ADCCS BIT P3.7
ADCCLK BIT P1.6
ADCDIN BIT P1.4
ADCDOUT EQU P1
****************INTERRUPT HANDLERS********
ORG 00H ;reset
LJMP MAIN
ORG 03H ;INTO
RETI ;do nothing
ORG 0BH ;timer 0
RETI ;do nothing
ORG 13H ;INT1
RETI ;do nothing
ORG 1BH ;timer 1
RETI ;do nothing
ORG 23H ;serial port
RETI ;do nothing
**********************************
ORG 4BH ;data & subrountines
******************************************
MAIN:
MOV B,#0 ;select channel_0
ACALL CONVERT
MOV P2,A ;send channel_0 to port_2
*******************************
MOV B,#1 ;select channel_1
ACALL CONVERT
MOV P0,A ;send channel_1 to port_0
***************************************
SJMP MAIN
CONVERT:
*************RESET ADC *************************
SETB ADCCS
CLR ADCCLK
SETB ADCDIN
************ START CONVERSION **********
CLR ADCCS
ACALL DELAY
************ START BIT ********
SETB ADCDIN
ACALL CLOCK
************** SGL/DIF BIT ************
SETB ADCDIN
ACALL CLOCK
ACALL ODD_SIGH
ACALL SELECT
ACALL READ_ADC
RET
************** ODD/SIGH BIT ************
ODD_SIGH:
JNB B.0,ELSE
SETB ADCDIN
AJMP CLOCK
ELSE:
CLR ADCDIN
QUIT:
ACALL CLOCK
RET
****************** SELECT BIT **********
SELECT:
JNB B.1,ELSE1
SETB ADCDIN
AJMP QUIT1
ELSE1:
CLR ADCDIN
QUIT1:
ACALL CLOCK
RET
************** READ_ADC****************
READ_ADC:
SETB ADCDIN
MOV R0,#8
MOV A,#0
ACALL CLOCK
LOOP3:
MOV R7,ADCDOUT
CJNE R7,#0AFH,ELSE2
CLR C
RLC A
ACALL CLOCK
DJNZ R0,LOOP3
AJMP EXIT1
ELSE2:
SETB C
RLC A
ACALL CLOCK
DJNZ R0,LOOP3
EXIT1:
RET
****************************************
CLOCK:
SETB ADCCLK
CLR ADCCLK
RET
*************************************
DELAY:
MOV R0,#1
LOOP0:
MOV R1,#100
LOOP1:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R1,LOOP1
DJNZ R0,LOOP0
RET
END
Sơ đồ giải thuật chương trình :
Khởi động chương trình
Ghi 0 vào B (chọn kênh 0)
Kết thúc
Gọi hàm con CONVERT
Ghi 1 vào B (chọn kênh 1)
Ghi A vào P2 (gửi kênh 0 ra P2)
Gọi hàm con CONVERT
Ghi A vào P0 (gửi kênh 1 ra P0)
Câu hỏi 2: Điện áp ngõ vào là bao nhiêu để ADC đọc giá trị 0x0FFH?
Trả lời: điện áp ngõ ra đo được là 2,5V
Câu hỏi 4: Tại sao khi tăng giá trị điện áp ngõ vào kênh 0 thì giá trị ADC của kênh 1 có xu hướng tăng theo?
Trả lời: kênh 1 chưa được nối mass nên sẽ chịu ảnh hưởng của nhiễu.
Câu hỏi 5: Sửa lại chương trình để đọc ADC kênh 2, 3 thay cho kênh 0, 1 như lúc đầu. Chạy thử chương trình và thay đổi điện áp ngõ vào kênh 0. Tại sao giá trị điện áp của kênh 0 cũng chịu ảnh hưởng đến kết quả đọc ADC của kênh 2 và 3.
***************DEFINITION**********
ADCCS BIT P3.7
ADCCLK BIT P1.6
ADCDIN BIT P1.4
ADCDOUT EQU P1
****************INTERRUPT HANDLERS********
ORG 00H ;reset
LJMP MAIN
ORG 03H ;INTO
RETI ;do nothing
ORG 0BH ;timer 0
RETI ;do nothing
ORG 13H ;INT1
RETI ;do nothing
ORG 1BH ;timer 1
RETI ;do nothing
ORG 23H ;serial port
RETI ;do nothing
**********************************
ORG 4BH ;data & subrountines
******************************************
MAIN:
MOV B,#2 ;select channel_0
ACALL CONVERT
MOV P2,A ;send channel_0 to port_2
*******************************
MOV B,#3 ;select channel_1
ACALL CONVERT
MOV P0,A ;send channel_1 to port_0
***************************************
SJMP MAIN
CONVERT:
*************RESET ADC *************************
SETB ADCCS
CLR ADCCLK
SETB ADCDIN
************ START CONVERSION **********
CLR ADCCS
ACALL DELAY
************ START BIT ********
SETB ADCDIN
ACALL CLOCK
************** SGL/DIF BIT ************
SETB ADCDIN
ACALL CLOCK
ACALL ODD_SIGH
ACALL SELECT
ACALL READ_ADC
RET
************** ODD/SIGH BIT ************
ODD_SIGH:
JNB B.0,ELSE
SETB ADCDIN
AJMP CLOCK
ELSE:
CLR ADCDIN
QUIT:
ACALL CLOCK
RET
****************** SELECT BIT **********
SELECT:
JNB B.1,ELSE1
SETB ADCDIN
AJMP QUIT1
ELSE1:
CLR ADCDIN
QUIT1:
ACALL CLOCK
RET
************** READ_ADC****************
READ_ADC:
SETB ADCDIN
MOV R0,#8
MOV A,#0
ACALL CLOCK
LOOP3:
MOV R7,ADCDOUT
CJNE R7,#0AFH,ELSE2
CLR C
RLC A
ACALL CLOCK
DJNZ R0,LOOP3
AJMP EXIT1
ELSE2:
SETB C
RLC A
ACALL CLOCK
DJNZ R0,LOOP3
EXIT1:
RET
****************************************
CLOCK:
SETB ADCCLK
CLR ADCCLK
RET
*************************************
DELAY:
MOV R0,#1
LOOP0:
MOV R1,#100
LOOP1:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R1,LOOP1
DJNZ R0,LOOP0
RET
END
Kết luận:
BÀI 5: HOẠT ĐỘNG ĐỊNH THỜI VÀ HOẠT ĐỘNG NGẮT
Bài tập : Viết chương trình đèn giao thông thực tế có sử dụng timer và ngắt ngoài theo yêu cầu sau:
Khi không có ngắt, điều khiển đèn sáng luân phiên: xanh – đỏ (0,5s), đỏ - vàng (0,5s), vàng – xanh (0,5s), và lặp lại….giống như đèn giao thông.
Khi có ngắt ngoài, điều khiển chớp tắt cả ba đèn cùng lúc cho đến khi có tác động ngắt ngoài lần nữa thì trở lại chương trình đèn giao thông.
Chương trình mẫu:
****************************************
;timer0 should gennerate interrupts 0.001 seconds
;timer0 overflow time is calculated as follows:
;0.01 seconds=(timer count value)*(1/22118400Hz)*12
;because our clock speed is 22.184MHz and timer is advanced by one count every
;12 clock cycles.Therefore,the timer count value is calculated as 18432 .Timer
;starts from its reload value and counts upwards until it overflows at 65536
;timer reload value is calculated as:
;timer reload value=65536-timer count value
;timer reload value=65536-18432=47104
t10ms equ 47104
;period of blinking/running(*0.01sek.)
period equ 50
;pins,assigned to LEDs
led1 equ P1.3
led2 equ P1.1
led3 equ P1.0
;switch 1 connected to INT0 pin
sw1 equ P3.2
;TCON bits:
TF1 equ TCON.7
TR1 equ TCON.6
TF0 equ TCON.5
TR0 equ TCON.4
IE1 equ TCON.3
IT1 equ TCON.2
IE0 equ TCON.2
IT0 equ TCON.0
;IE bits
EA equ IE.7
ET2 equ IE.5
ES equ IE.4
ET1 equ IE.3
EX1 equ IE.2
ET0 equ IE.1
EX0 equ IE.0
;8051 stack
stack equ $60
;counts 0-20(*0.025) to generate 0.5 seconds
counter1 equ $30
;timer of INT0 disable
counter2 equ $31
;LEDs status
LEDs equ $32
DisableINT0 bit $20.0
;run/blinking together
mode bit $20.1
odd_tact bit $20.2
;jump to main body of the program
ajmp prog
;INT0 interrupt
org 3
ajmp int0_sr
;TIMER0 interrupt
org 0bh
ajmp t0_int
;INT1 interrupt( not used)
org 13h
reti
;TIMER1 interrupt( not used)
org 1bh
reti
;UART( serial port)interrupt( not used)
org 23h
reti
************* Main program********************
;set stack pointer
prog: mov SP,#stack
;TIMER0-16 bit timer mode1
mov a,TMOD
anl a,#11110000b
orl a,#00000001b
mov TMOD,a
;Run TIMER0
setb TR0
;INT0 low level activated
clr IT0
;Enable both TIMER0 and INT0
mov IE,#00000011b
;TIMER0-high priority
mov IP,#00000010B
mov counter1,#period
mov LEDs,#00000001b
;Global interrupts enable
setb EA
m001:
;Set idle mode,loop forever until interrupted
mov a,pcon
orl a,#10000000b
mov pcon,a
sjmp m001
****************TIMER0 interrupt service routine**************
t0_int: push psw
push acc
;clear interrupt flag
clr TF0
;Load TIMER0 for next 0.01 sek
mov TL0,#t10ms
mov TH0,#=t10ms
;suppress swich contacts bouncing:
;INT0 will remain disabled till SW1 will
;relised and 0.1 sek more
jnb sw1,ti01
;if INT0 is temporary disabled count time
;and exit i.s.r.
jnb DisableINT0,ti01
djnz counter2,ti01
;re-enable INT0
clr DisableINT0
setb ex0
;Drive LEDs
;count 0.01 sek.intervals and exits i.s.r.
ti01: djnz counter1,ti02
;reload counter
mov counter1,#period
;mode=1-all LEDs are blinking
;mode=0-LEDs are running
jb mode,ti03
;rotate LEDs 1 position left
mov a,LEDs
mov c,acc.2
rlc a
mov LEDs,a
;drive LED pins
ti05: mov c,acc.0
mov led1,c
mov c,acc.1
mov led2,c
mov c,acc.2
mov led3,c
sjmp ti02
;LEDs are blinking
ti03: cpl odd_tact
jb odd_tact,ti04
;at even tacts will turn LEDs OFF
mov a,#0
sjmp ti05
;at odd tacts will turn them ON
ti04: mov a,#00000111b
sjmp i05
ti02: pop acc
pop psw
reti
************** External interrupt0 service rountine*********
int0_sr:
;clear interrupt flag
clr ie0
; to prevent multiple interrupts due to the bouncing of
;switch contacts, disable it for 0.1 seconds
clr ex0
;load counter for 0.1 seconds
mov counter2,#10
setb disableINT0
;change mode from blinking to shift or vice versa
cpl mode
mov LEDs,#00000001b
reti
BÀI 6: BÀN PHÍM MA TRẬN 4X4
Bài tập : Xác định sơ đồ chân và cách bố trí ma trận của bàn phím sử dụng chức năng đo điện trở của máy đo vạn năng. Viết một chương trình Assembler để hiện thị lên màn hình giá tri của phím được nhấn trên bàn phím.
Chương trình mẫu:
;***********DIFINITIONS**********
;-------------R0,R7 REGISTERS------------
;R0-
;R1-
;R2-
;R3-
;R4-key index
;R5-row counter
;R6-counter for delay
;R7-counter for delay
;-------------LOWER BANK RAM------------------
FLAGS EQU 20H ;REGISTER OF EVENTS
MAX_ROW EQU 4 ;KEYPAD DEFINITIONS
COL1 BIT P2.4
COL2 BIT P2.5
COL3 BIT P2.6
COL4 BIT P2.7
ON_FLAG BIT FLAGS.0 ;=1if any pressed key was found
TI BIT SCON.1
TR1 BIT TCON.6
CR EQU 0DH
;-------------INTERRUPT HANDLERS-----------
ORG 00H
LJMP MAIN
ORG 03H
RETI
ORG 0BH
RETI
ORG 13H
RETI
ORG 1BH
RETI
ORG 23H
RETI
;**********************************
ORG 4BH
;*********************************
RowSEL: DB 0FEH
DB 0FDH
DB 0FBH
DB 0F7H
KeyTBL:
DB '1','2','3','A'
DB '4','5','6','B'
DB '7','8','9','C'
DB '*','0','#','D'
;**********************************
DELAY:
DLY0: MOV R6,#0FFH
DLY1: MOV R7,#0FFH
DLY2: NOP
NOP
NOP
DJNZ R7,DLY2
DJNZ R6,DLY1
RET
;**********************************
SCAN_KEYPAD:
MOV DPTR,#RowSEL
MOV R5,#MAX_ROW
MOV R4,#0
CLR ON_FLAG
SCAN0:
CLR A
MOVC A,@A+DPTR
MOV P2,A
JNB COL1,SCAN1
INC R4
JNB COL2,SCAN1
INC R4
JNB COL3,SCAN1
INC R4
JNB COL4,SCAN1
INC R4
INC DPTR
DJNZ R5,SCAN0
RET
SCAN1:
SETB ON_FLAG
MOV DPTR,#KeyTBL
MOV A,R4
MOVC A,@A+DPTR
RET
;**********************************
MAIN:
MOV SCON,#%01010000
MOV TMOD,#20H
MOV TH1,#0FDH
MOV TL1,#0FDH
MOV TCON,#%01001001
MOV DPTR,#MESSAGE
ACALL SEND_MESSAGE
LOOP:
LCALL DELAY
LCALL SCAN_KEYPAD
JNB ON_FLAG,LOOP
ACALL SEND_CHAR
MOV A,#CR
ACALL SEND_CHAR
AJMP LOOP
SEND_CHAR:
MOV SBUF,A
JNB TI,$
CLR TI
RET
SEND_MESSAGE:
CLR A
MOVC A,@A+DPTR
JZ EXIT
ACALL SEND_CHAR
INC DPTR
AJMP SEND_MESSAGE
;**********************************
EXIT: RET
;**********************************
MESSAGE STR "4*4 KEYPAD"
DB CR,0
;**********************************
END
Sơ đồ giải thuật chương trình :
=1
=0
Quay lại
=1
=0
=0
Tạo vòng LOOP
Ghi 0101000 vào SCON
Ghi 20H vào TMOD (timer1)
Ghi 0FDh vào TH1
Ghi 01001001 vào TCON
Ghi nội dung hàm MESSENGE vào DPTR
Gọi hàm con SEND_MESSENGE
Gọi hàm con DELAY
Gọi hàm con SCAN_KEYPAD
Ghi (CR) vào A
Kết thúc
Kiểm tra hàm ON_FLAG=0?
Gọi hàm con SEND_CHAR
Gọi hàm con SEND_CHAR
Xóa A
Ghi (A+DPTR) vào A
A = 0?
EXIT
Gọi hàm con SEND_CHAR
Tăng DPTR
Ghi A vào bộ nhớ đệm
TI = 0 ?
Không làm gì cả
Xóa cờ TI
Kết thúc hàm con SEND_CHAR
Nội dung cần xuất ra màn hình
Câu hỏi 2: Mở rộng chương trình trên sao cho khi có phím nhấn thì giá trị nhị phân tương ứng sẽ được thể hiện trên 4 bit thấp của P0 cho đến khi phím khác được nhấn?
;***********DIFINITIONS**********
;-------------R0,R7 REGISTERS------------
;R0-
;R1-
;R2-
;R3-
;R4-key index
;R5-row counter
;R6-counter for delay
;R7-counter for delay
;-------------LOWER BANK RAM------------------
FLAGS EQU 20H ;REGISTER OF EVENTS
MAX_ROW EQU 4 ;KEYPAD DEFINITIONS
COL1 BIT P2.4
COL2 BIT P2.5
COL3 BIT P2.6
COL4 BIT P2.7
ON_FLAG BIT FLAGS.0 ;=1if any pressed key was found
TI BIT SCON.1
TR1 BIT TCON.6
CR EQU 0DH
;-------------INTERRUPT HANDLERS-----------
ORG 00H
LJMP MAIN
ORG 03H
RETI
ORG 0BH
RETI
ORG 13H
RETI
ORG 1BH
RETI
ORG 23H
RETI
;**********************************
ORG 4BH
;*********************************
RowSEL: DB 0FEH
DB 0FDH
DB 0FBH
DB 0F7H
KeyTBL:
DB '1','2','3','A'
DB '4','5','6','B'
DB '7','8','9','C'
DB '*','0','#','D'
;**********************************
DELAY:
DLY0: MOV R6,#0FFH
DLY1: MOV R7,#0FFH
DLY2: NOP
NOP
NOP
DJNZ R7,DLY2
DJNZ R6,DLY1
RET
;**********************************
SCAN_KEYPAD:
MOV DPTR,#RowSEL
MOV R5,#MAX_ROW
MOV R4,#0
CLR ON_FLAG
SCAN0:
CLR A
MOVC A,@A+DPTR
MOV P2,A
JNB COL1,SCAN1
INC R4
JNB COL2,SCAN1
INC R4
JNB COL3,SCAN1
INC R4
JNB COL4,SCAN1
INC R4
INC DPTR
DJNZ R5,SCAN0
RET
SCAN1:
SETB ON_FLAG
MOV DPTR,#KeyTBL
MOV A,R4
MOVC A,@A+DPTR
RET
;**********************************
MAIN:
MOV SCON,#%01010000
MOV TMOD,#20H
MOV TH1,#0FDH
MOV TL1,#0FDH
MOV TCON,#%01001001
MOV DPTR,#MESSAGE
ACALL SEND_MESSAGE
LOOP:
LCALL DELAY
LCALL SCAN_KEYPAD
MOV P0,P2
JNB ON_FLAG,LOOP
ACALL SEND_CHAR
MOV A,#CR
ACALL SEND_CHAR
AJMP LOOP
SEND_CHAR:
MOV SBUF,A
JNB TI,$
CLR TI
RET
SEND_MESSAGE:
CLR A
MOVC A,@A+DPTR
JZ EXIT
ACALL SEND_CHAR
INC DPTR
AJMP SEND_MESSAGE
;**********************************
EXIT: RET
;**********************************
MESSAGE STR "4*4 KEYPAD"
DB CR,0
;**********************************
END
BÀI 7: MÀN HÌNH TINH THỂ LỎNG LCD
Bài tập : Sử dụng bảng đặc tính (datasheet) của LCD, viết chương trình Assembler để hiển thị dòng ký tự “ Hello World” lên hàng đầu của LCD. Sau đó, hiểu thị dòng ký tự ở hàng thứ hai của LCD.
;**************************************************************************
;
; This module is presented here only to serve as a sample for
; 8051 program development on the MINI-MAX/51 or PRO-MAX/51 system.
; BiPOM Electronics does not guarantee its functionality
; with other micro-controller systems.
; Please e-mail any questions and suggestions to info@bipom.com.
; Visit BiPOM Electronics webpage at www.bipom.com for 8051 code examples.
;
; Module: LCDASM.ASM
;
; Revision: 1.01
;
; Description: Subroutines to access an alphanumeric LCD
;
; InitLCD : Initializes the LCD
; WriteData : Writes the value to the data register
; WriteCtrl : Writes the value to the control register
; _MM51C_PWM : Sets a new level of Vee (LCD contrast)
;
;
; NOTE: The LCD is accessed in 4-bit mode to save port pins.
;
;*************************************************************************
CTRL EQU P0.0 ;CONTROL BIT (CONTROL=RESET & DATA=SET)
READ EQU P0.1 ;READ=SET & WRITE=RESET
STROBE EQU P0.2 ;DATA STROBE (ENABLE)
DATAPORT EQU P0 ;LCD DATA ( ONLY LOWER 4 BITS ARE USED )
;*************** INTERRUPT HANDLERS ***************************************
ORG 0H ;Reset vector
SJMP main
;**************************************************************************
; Function: Main
;
; Description: Main program.
; Serves as an example of how to access peripherals
; on MINI-MAX/51.
; Never returns.
;**************************************************************************
main:
MOV R7,#40
ACALL InitLCD ;Initialize LCD
MOV DPTR,#LCD_MESSAGE0 ;Assign pointer to LCD message
PRINT:
CLR A ;Clear offset
MOVC A,@A+DPTR ;Read next char from string
JZ EXIT ;If == 0 then exit
ACALL WriteData ;Write next char to LCD
INC DPTR ;Increase pointer
;SJMP PRINT ;Go to next char
DJNZ R7,PRINT
MOV DPTR,#LCD_MESSAGE1 ;Assign pointer to LCD message
PRINT1:
CLR A ;Clear offset
MOVC A,@A+DPTR ;Read next char from string
JZ EXIT ;If == 0 then exit
ACALL WriteData ;Write next char to LCD
INC DPTR ;Increase pointer
SJMP PRINT1 ;Go to next char
EXIT:
SJMP $ ;Loop forever
LCD_MESSAGE0:
STRZ 'HELLO WORLD! '
LCD_MESSAGE1:
STRZ 'TON DUC THANG UNIVERSITY'
;**************************************************************************
; Function: InitLCD
;
; Description: Initializes the LCD
;
; Inputs: None
;
; Returns: None
;
;**************************************************************************
InitLCD:
;CTRL = READ = STROBE = 1
MOV P0,#7
;Initialize the LCD to 4-bit mode
MOV A,#3
ACALL WriteCtrl ;WriteCtrl(3)
MOV R3,#50
MOV R4,#0
ACALL Delay ;delay(50);
;
MOV A,#3
ACALL WriteCtrl ;WriteCtrl(3);
ACALL Delay10ms ;delay(10);
;
MOV A,#3
ACALL WriteCtrl ;WriteCtrl(3);
ACALL Delay10ms ;delay(10);
;
MOV A,#2
ACALL WriteCtrl ;WriteCtrl(2);
ACALL Delay10ms ;delay(10);
;
; Function Set
MOV A,#2
ACALL WriteCtrl ;WriteCtrl(2);
ACALL Delay10ms ;delay(10);
;
MOV A,#8
ACALL WriteCtrl ;WriteCtrl(8);
ACALL Delay10ms ;delay(10);
;
; Display OFF
CLR A
ACALL WriteCtrl ;WriteCtrl(0);
ACALL Delay10ms ;delay(10);
;
MOV A,#8
ACALL WriteCtrl ;WriteCtrl(8);
ACALL Delay10ms ;delay(10);
;
; Display ON
CLR A
ACALL WriteCtrl ;WriteCtrl(0);
ACALL Delay10ms ;delay(10);
;
MOV A,#0FH
ACALL WriteCtrl ;WriteCtrl(0x0F);
ACALL Delay10ms ;delay(10);
;
; Entry mode
CLR A
ACALL WriteCtrl ;WriteCtrl(0);
ACALL Delay10ms ;delay(10);
;
MOV A,#6
ACALL WriteCtrl ;WriteCtrl(6);
ACALL Delay10ms ;delay(10);
;
; Clear Screen
CLR A
ACALL WriteCtrl ;WriteCtrl(0);
ACALL Delay10ms ;delay(10);
;
MOV A,#1
ACALL WriteCtrl ;WriteCtrl(1);
MOV R3,#100
MOV R4,#0
ACALL Delay ;delay(100);
;
; Cursor home
CLR A
ACALL WriteCtrl ;WriteCtrl(0);
ACALL Delay10ms ;delay(10);
;
MOV A,#2
ACALL WriteCtrl ;WriteCtrl(2);
MOV R3,#100
MOV R4,#0
ACALL Delay ;delay(100);
;
RET
;***************************************************************************
; Function: WriteCtrl
;
; Description: Writes the value to the control register
;
; Inputs: ACC = value
;
; Returns: None
;
;***************************************************************************
WriteCtrl:
CLR CTRL ;select control register
ACALL WriteCommon ;write value to control register
RET
;***************************************************************************
; Function: WriteData
;
; Description: Writes the value to the data register
;
; Inputs: ACC = value
;
; Returns: None
;
;***************************************************************************
WriteData:
SETB CTRL ;select data register
PUSH ACC ;store 4 low bits
SWAP A ;ACC = value >> 4
ACALL WriteCommon ;write data to LCD
POP ACC ;ACC = value
ACALL WriteCommon ;write data to LCD
RET
;***************************************************************************
; Function: WriteCommon
;
; Description: Writes the value to LCD
;
; Inputs: ACC = value
;
; Returns: None
;
;**************************************************************************
WriteCommon:
CLR READ ;clrbit (READ);
SWAP A
ANL A,#0F0H ;value=value<<4;
ANL P0,#7 ;P0&=0x07;
ORL P0,A ;P0|=value;
ACALL Delay1ms ;delay(1);
SETB STROBE ;setbit(STROBE);
ACALL Delay1ms ;delay(1);
CLR STROBE ;clrbit(STROBE);
ACALL Delay1ms ;delay(1);
SETB READ ;setbit(READ);
ACALL Delay1ms ;delay(1);
RET
;*********************************************************************
;
; Routine: _MM51C_WDT
;
; Description: Sets a new WDT period
;
; Inputs: Accumulator contains new WDT period
; 0 - disables WDT
; 1..127 - specifies WDT period (in seconds)
;
; Returns: None
;
;*********************************************************************
;*********************************************************************
;
; Routine: _MM51C_PWM
;
; Description: Sets a new level of Vee (LCD contrast)
;
; Inputs: Accumulator contains new setting
; 0..15 - specifies Vee level
;
; Returns: None
;
;*********************************************************************
;*********************************************************************
;
; Routine: _MM51C
;
; Description: Services I2C communication to on-board PIC
;
; Inputs: Accumulator contains a value to be sent to PIC
;
; Returns: None
;
;*********************************************************************
;***************************************************************
; Function: _MM51C_TRANSMIT
;
; Description: Transmits a byte to I2C device with
; most significant bit first.
;
; Inputs: A - Contains the byte to be transmitted.
; SCL and SDA should be low on entry.
;
; Returns: - Carry is set if I2C device can not acknowledge.
; - A is modified.
;
;****************************************************************
;*****************************************************************************
; Function: _MM51C_START
;
; Description: Signals a Start which is defined as negative going
; transition of SDA while SCL is high.
;
; Inputs: None
;
; Returns: - Carry is set if bus is not available.
; - Carry is reset if success.
; - SCL and SDA are reset upon return.
;
;******************************************************************************
;****************************************************************************
; Function: _MM51C_STOP
;
; Description: Signals a Stop which is defined as positive going
; transition of SDA while SCL is high.
;
; Inputs: SCL should be reset on entry
;
; Returns: SCL and SDA are set upon return.
;
;****************************************************************************
;***************************************************************************
;
; Function: _MM51C_DELAY
;
; Description: Produces very small delay
:
; Inputs: None
;
; Returns: None
;
;***************************************************************************
;***************************************************************************
;
; Function: Delay1ms
;
; Description: Produces 1ms delay
;
; Inputs: None
;
; Returns: None
;
;***************************************************************************
Delay1ms:
MOV R3,#2
SJMP DelayEntry
;***************************************************************************
;
; Function: Delay10ms
;
; Description: Produces 10ms delay
;
; Inputs: None
;
; Returns: None
;***************************************************************************
Delay10ms:
MOV R3,#20
DelayEntry:
MOV R4,#0
SJMP Delay
;***************************************************************************
;
; Function: Delay
;
; Desription: Produces a delay via software timing loop
; R2 count is calculated as: (crystal-72000)/48000
;
; Inputs: R3 - Low Counter
; R4 - High Counter
;
; Returns: None
;
;***************************************************************************
Delay CJNE R3,#0,Delay_0 ; Not zero
CJNE R4,#0,Delay_0 ; Not zero
RET
Delay_0
MOV R2,#229 ; 1ms at 11059200Hz
Delay_1ms
NOP
NOP ; Waste 2 cycles
DJNZ R2,Delay_1ms ; Loop for 1-ms
DEC R3 ; Reduce count
CJNE R3,#-1,Delay ; No carry
DEC R4 ; Reduce high
SJMP Delay_0 ; And proceed
;***************************************************************************
END
Câu hỏi 2: Nếu chuỗi ký tự muốn hiển thị dài hơn 24 ký tự thì điều gì sẽ xảy ra?
Trả lời: ký tự thứ 25 trở đi không hiển thị ra màn hình LCD
Câu hỏi 3: Thay chuổi LCD_MESSENGER0 bằng chuỗi LCD_MESSENGER1 và nạp lại chương trình. Từ đó rút ra kết luận đầy đủ cho câu 2.
Trả lời: ký tự thứ 25 tới ký tự thứ 40 sẽ không hiển thị ra màn hình LCD. Màn hình LCD chỉ hiện thị 24 ký tự ở hàng đầu tiên
Một hàng của LCD chứa tối đa 40 ký tự và chỉ hiện thị ký tự thứ 1 đến ký tự thứ 24, ký tự 25 tới 40 sẽ không hiển thị.
Ký tự thứ 41 trở đi sẽ xuất hiện ở hàng 2 của LCD, và hàng 2 của LCD cũng chỉ hiện thị 24 ký tự ( tức là ký tự 41 đến ký tự 64 của hàng 1)
Câu hỏi 4: Lệnh MOV R2,#229 ở nhãn DELAY_0 dùng để tạo trễ 1ms. Thực tế có đúng không?
Tại sao?
Trả lời:
Câu hỏi 5: Viết lại chương trình hiển thị chuỗi “TON DUC THANG UNIVERSITY HAVE GOOD DAY!...”trên LCD như sau:
TON DUC THANG UNIVERSITY
HAVE A GOOD DAY!...
;**************************************************************************
;
; This module is presented here only to serve as a sample for
; 8051 program development on the MINI-MAX/51 or PRO-MAX/51 system.
; BiPOM Electronics does not guarantee its functionality
; with other micro-controller systems.
; Please e-mail any questions and suggestions to info@bipom.com.
; Visit BiPOM Electronics webpage at www.bipom.com for 8051 code examples.
;
; Module: LCDASM.ASM
;
; Revision: 1.01
;
; Description: Subroutines to access an alphanumeric LCD
;
; InitLCD : Initializes the LCD
; WriteData : Writes the value to the data register
;WriteCtrl : Writes the value to the control register
;_MM51C_PWM : Sets a new level of Vee (LCD contrast)
;
;
; NOTE: The LCD is accessed in 4-bit mode to save port pins.
;
;*************************************************************************
CTRL EQU P0.0 ;CONTROL BIT (CONTROL=RESET & DATA=SET)
READ EQU P0.1 ;READ=SET & WRITE=RESET
STROBE EQU P0.2 ;DATA STROBE (ENABLE)
DATAPORT EQU P0 ;LCD DATA ( ONLY LOWER 4 BITS ARE USED )
;*************** INTERRUPT HANDLERS ***************************************
ORG 0H ;Reset vector
SJMP main
;**************************************************************************
; Function: Main
;
; Description: Main program.
; Serves as an example of how to access peripherals
; on MINI-MAX/51.
; Never returns.
;**************************************************************************
main:
MOV R7,#40
ACALL InitLCD ;Initialize LCD
MOV DPTR,#LCD_MESSAGE0 ;Assign pointer to LCD message
PRINT:
CLR A ;Clear offset
MOVC A,@A+DPTR ;Read next char from string
JZ EXIT ;If == 0 then exit
ACALL WriteData ;Write next char to LCD
INC DPTR ;Increase pointer
;SJMP PRINT ;Go to next char
DJNZ R7,PRINT
MOV DPTR,#LCD_MESSAGE0 ;Assign pointer to LCD message
PRINT1:
CLR A ;Clear offset
MOVC A,@A+DPTR ;Read next char from string
JZ EXIT ;If == 0 then exit
ACALL WriteData ;Write next char to LCD
INC DPTR ;Increase pointer
SJMP PRINT1 ;Go to next char
EXIT:
SJMP $ ;Loop forever
LCD_MESSAGE0:
STRZ 'TON DUC THANG UNIVERSITY (16 cái tab) HAVE A GOOD DAY!... “
;**************************************************************************
; Function: InitLCD
;
; Description: Initializes the LCD
;
; Inputs: None
;
; Returns: None
;
;**************************************************************************
InitLCD:
;CTRL = READ = STROBE = 1
MOV P0,#7
;Initialize the LCD to 4-bit mode
MOV A,#3
ACALL WriteCtrl ;WriteCtrl(3)
MOV R3,#50
MOV R4,#0
ACALL Delay ;delay(50);
;
MOV A,#3
ACALL WriteCtrl ;WriteCtrl(3);
ACALL Delay10ms ;delay(10);
;
MOV A,#3
ACALL WriteCtrl ;WriteCtrl(3);
ACALL Delay10ms ;delay(10);
;
MOV A,#2
ACALL WriteCtrl ;WriteCtrl(2);
ACALL Delay10ms ;delay(10);
; Function Set
MOV A,#2
ACALL WriteCtrl ;WriteCtrl(2);
ACALL Delay10ms ;delay(10);
;
MOV A,#8
ACALL WriteCtrl ;WriteCtrl(8);
ACALL Delay10ms ;delay(10);
; Display OFF
CLR A
ACALL WriteCtrl ;WriteCtrl(0);
ACALL Delay10ms ;delay(10);
;
MOV A,#8
ACALL WriteCtrl ;WriteCtrl(8);
ACALL Delay10ms ;delay(10);
; Display ON
CLR A
ACALL WriteCtrl ;WriteCtrl(0);
ACALL Delay10ms ;delay(10);
;
MOV A,#0FH
ACALL WriteCtrl ;WriteCtrl(0x0F);
ACALL Delay10ms ;delay(10);
;
; Entry mode
CLR A
ACALL WriteCtrl ;WriteCtrl(0);
ACALL Delay10ms ;delay(10);
;
MOV A,#6
ACALL WriteCtrl ;WriteCtrl(6);
ACALL Delay10ms ;delay(10);
; Clear Screen
CLR A
ACALL WriteCtrl ;WriteCtrl(0);
ACALL Delay10ms ;delay(10);
;
MOV A,#1
ACALL WriteCtrl ;WriteCtrl(1);
MOV R3,#100
MOV R4,#0
ACALL Delay ;delay(100);
; Cursor home
CLR A
ACALL WriteCtrl ;WriteCtrl(0);
ACALL Delay10ms ;delay(10);
;
MOV A,#2
ACALL WriteCtrl ;WriteCtrl(2);
MOV R3,#100
MOV R4,#0
ACALL Delay ;delay(100);
;
RET
;***************************************************************************
; Function: WriteCtrl
;
; Description: Writes the value to the control register
;
; Inputs: ACC = value
;
; Returns: None
;
;***************************************************************************
WriteCtrl:
CLR CTRL ;select control register
ACALL WriteCommon ;write value to control register
RET
;***************************************************************************
; Function: WriteData
;
; Description: Writes the value to the data register
;
; Inputs: ACC = value
;
; Returns: None
;
;***************************************************************************
WriteData:
SETB CTRL ;select data register
PUSH ACC ;store 4 low bits
SWAP A ;ACC = value >> 4
ACALL WriteCommon ;write data to LCD
POP ACC ;ACC = value
ACALL WriteCommon ;write data to LCD
RET
;***************************************************************************
; Function: WriteCommon
;
; Description: Writes the value to LCD
;
; Inputs: ACC = value
;
; Returns: None
;
;**************************************************************************
WriteCommon:
CLR READ ;clrbit (READ);
SWAP A
ANL A,#0F0H ;value=value<<4;
ANL P0,#7 ;P0&=0x07;
ORL P0,A ;P0|=value;
ACALL Delay1ms ;delay(1);
SETB STROBE ;setbit(STROBE);
ACALL Delay1ms ;delay(1);
CLR STROBE ;clrbit(STROBE);
ACALL Delay1ms ;delay(1);
SETB READ ;setbit(READ);
ACALL Delay1ms ;delay(1);
RET
;*********************************************************************
;
; Routine: _MM51C_WDT
;
; Description: Sets a new WDT period
;
; Inputs: Accumulator contains new WDT period
; 0 - disables WDT
; 1..127 - specifies WDT period (in seconds)
;
; Returns: None
;
;*********************************************************************
;*********************************************************************
;
; Routine: _MM51C_PWM
;
; Description: Sets a new level of Vee (LCD contrast)
;
; Inputs: Accumulator contains new setting
; 0..15 - specifies Vee level
;
; Returns: None
;
;*********************************************************************
;*********************************************************************
;
; Routine: _MM51C
;
; Description: Services I2C communication to on-board PIC
;
; Inputs: Accumulator contains a value to be sent to PIC
;
; Returns: None
;
;*********************************************************************
;***************************************************************
; Function: _MM51C_TRANSMIT
;
; Description: Transmits a byte to I2C device with
; most significant bit first.
;
; Inputs: A - Contains the byte to be transmitted.
; SCL and SDA should be low on entry.
;
; Returns: - Carry is set if I2C device can not acknowledge.
; - A is modified.
;
;****************************************************************
;*****************************************************************************
; Function: _MM51C_START
;
; Description: Signals a Start which is defined as negative going
; transition of SDA while SCL is high.
;
; Inputs: None
;
; Returns: - Carry is set if bus is not available.
; - Carry is reset if success.
; - SCL and SDA are reset upon return.
;
;******************************************************************************
;****************************************************************************
; Function: _MM51C_STOP
;
; Description: Signals a Stop which is defined as positive going
; transition of SDA while SCL is high.
;
; Inputs: SCL should be reset on entry
;
; Returns: SCL and SDA are set upon return.
;
;****************************************************************************
;***************************************************************************
;
; Function: _MM51C_DELAY
;
; Description: Produces very small delay
:
; Inputs: None
;
; Returns: None
;
;***************************************************************************
;***************************************************************************
;
; Function: Delay1ms
;
; Description: Produces 1ms delay
;
; Inputs: None
;
; Returns: None
;
;***************************************************************************
Delay1ms:
MOV R3,#2
SJMP DelayEntry
;***************************************************************************
;
; Function: Delay10ms
;
; Description: Produces 10ms delay
;
; Inputs: None
;
; Returns: None
;***************************************************************************
Delay10ms:
MOV R3,#20
DelayEntry:
MOV R4,#0
SJMP Delay
;***************************************************************************
;
; Function: Delay
;
; Desription: Produces a delay via software timing loop
; R2 count is calculated as: (crystal-72000)/48000
;
; Inputs: R3 - Low Counter
; R4 - High Counter
;
; Returns: None
;
;***************************************************************************
Delay CJNE R3,#0,Delay_0 ; Not zero
CJNE R4,#0,Delay_0 ; Not zero
RET
Delay_0
MOV R2,#229 ; 1ms at 11059200Hz
Delay_1ms
NOP
NOP ; Waste 2 cycles
DJNZ R2,Delay_1ms ; Loop for 1-ms
DEC R3 ; Reduce count
CJNE R3,#-1,Delay ; No carry
DEC R4 ; Reduce high
SJMP Delay_0 ; And proceed
;***************************************************************************
END
BÀI 8: GIAO TIẾP VỚI MẠCH CÒI (Buzzer)
Bài tập : Lập trình chân P1.2 trên vi điều khiển như là một chân ra.
Chọn tần số của sóng vuông trong khoảng từ 1KHz đến 15Khz.
Tạo ra một tín hiệu với thời gian tín hiệu ở mức cao bằng thời gian tín hiệu ở mức thấp.
Kích hoạt còi và chú ý đến những âm thanh khác nhau được phát ra.
Thay đổi duty cycle và chú ý các cường độ âm khác nhau.
Chương trình mẫu:
ORG 00H
LJMP MAIN
ORG 03H
RETI
ORG 0BH
RETI
ORG 13H
RETI
ORG 1BH
RETI
ORG 23H
JNB SCON.0,SeriallntExit
SeriallntExit:
RETI
***************************************************
ORG 60H
MAIN:
MOV R0,#50FH
N1: LCALL DO
DJNZ R0.N1
MOV R0,#05FH
N2: LCALL RE
DJNZ R0,N2
MOV R0,#05FH
N3: LCALL MI
DJNZ R0,N3
MOV R0,#05FH
N4: LCALL FA
DJNZ R0,N4
MOV R0,#05FH
N5: LCALL SO
DJNZ R0,N5
MOV R0,#05FH
N6: LCALL LA
DJNZ R0,N6
MOV R0,#05FH
N7: LCALL SI
DJNZ R0,N7
MOV R0,#05FH
N8: LCALL D00
DJNZ R0,N8
SJMP MAIN
;***************************************************
DO:
CPL P1.2
MOV R1,#8
LCALL DELAY
RET
RE:
CPL P1.2
MOV R1,#7
LCALL DELAY
RET
MI:
CPL P1.2
MOV R1,#6
LCALL DELAY
RET
FA:
CPL P1.2
MOV R1,#5
LCALL DELAY
RET
SO:
CPL P1.2
MOV R1,#4
LCALL DELAY
RET
LA:
CPL P1.2
MOV R1,#3
LCALL DELAY
RET
SI:
CPL P1.2
MOV R1,#2
LCALL DELAY
RET
DOO:
CPL P1.2
MOV R1,#1
LCALL DELAY
RET
DELAY:
LOOP1:
MOV R2,#100
LOOP2:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R2,LOOP2
DJNZ R1,LOOP1
RET
END
Tạo các vòng lặp N3….N7 tương tự như trên cho các hàm MI, FA, SO,LA,SI
Đ
Tạo vòng N8
Đ
SĐ
Tạo vòng N2
Đ
Tạo vòng N1
Khởi động chương trình
Ghi giá trị thời gian
giữa các âm vào RO
Giảm R0
nếu R0=1?
Kết thúc
Gọi hàm con DO
SĐ
Ghi giá trị thời gian
giữa các âm vào RO
Gọi hàm con RE
Giảm R0
nếu R0=1?
Ghi giá trị thời gian
giữa các âm vào RO
Gọi hàm con DOO
Giảm R0
nếu R0=1?
SĐ
Câu hỏi 2: Giá trị nạp cho R0 có ý nghĩa gì?
Trả lời: biểu thị cho giá trị thời gian phát 1 nốt nhạc ( 0FFH : âm chậm, thời gian phát giữa các âm dài, làm cho thời gian phát 7 nốt dài ra. 001H: âm ngắn, thời gian phát nhanh, làm ta không phân biệt được các âm cao hay thấp)
Câu hỏi 3: Tại sao đối với cùng một giá trị nạp cho R0. khi phát các nốt nhạc càng cao ( tần số càng cao) thì thời gian phát ngắn?
Trả lời: dựa trên quan hệ giữa T và f , ta có:
T=1 / f
Tần số f càng cao thì T càng thấp, nghĩa là chu kỳ phát càng ngắn
Câu hỏi 4: Duty cycle của tín hiệu ra là bao nhiêu? Có thay đổi được không? Tại sao?
Trả lời: D= 50%, và ta không thể thay đổi được. Vì đây là code mặc định của chương trình, ta chưa can thiệp sửa chữa vào , thì nó đã có D=50%
Câu hỏi 5: Viết lại chương trình với Duty cycle có thể thay đổi được? ( từ 25% tới 75%)
Trả lời:
Ban đầu
T
75%
25%
75%
25%
50%
50%
TH1
TH2
TH1:
GIATRI EQU 019H
ORG 00H
LJMP MAIN
ORG 03H
RETI
ORG 0BH
RETI
ORG 13H
RETI
ORG 1BH
RETI
ORG 23H
JNB SCON.0,SeriallntExit
SeriallntExit:
RETI
***************************************************
ORG 60H
MAIN:
MOV R0,#GIATRI
N1: LCALL DO
DJNZ R0,N1
MOV R0,#GIATRI
N2: LCALL RE
DJNZ R0,N2
MOV R0,#GIATRI
N3: LCALL MI
DJNZ R0,N3
MOV R0,#GIATRI
N4: LCALL FA
DJNZ R0,N4
MOV R0,#GIATRI
N5: LCALL SO
DJNZ R0,N5
MOV R0,#GIATRI
N6: LCALL LA
DJNZ R0,N6
MOV R0,#GIATRI
N7: LCALL SI
DJNZ R0,N7
MOV R0,#GIATRI
N8: LCALL DOO
DJNZ R0,N8
SJMP MAIN
***************************************************
DO:
CPL P1.2
MOV R1,#8
SETB P1.2
LCALL DELAY
CLR P1.2
LCALL DELAY
LCALL DELAY
LCALL DELAY
RET
RE:
CPL P1.2
MOV R1,#7
SETB P1.2
LCALL DELAY
CLR P1.2
LCALL DELAY
LCALL DELAY
LCALL DELAY
RET
MI:
CPL P1.2
MOV R1,#6
SETB P1.2
LCALL DELAY
CLR P1.2
LCALL DELAY
LCALL DELAY
LCALL DELAY
RET
FA:
CPL P1.2
MOV R1,#5
SETB P1.2
LCALL DELAY
CLR P1.2
LCALL DELAY
LCALL DELAY
LCALL DELAY
RET
SO:
CPL P1.2
MOV R1,#4
SETB P1.2
LCALL DELAY
CLR P1.2
LCALL DELAY
LCALL DELAY
LCALL DELAY
RET
LA:
CPL P1.2
MOV R1,#3
SETB P1.2
LCALL DELAY
CLR P1.2
LCALL DELAY
LCALL DELAY
LCALL DELAY
RET
SI:
CPL P1.2
MOV R1,#2
SETB P1.2
LCALL DELAY
CLR P1.2
LCALL DELAY
LCALL DELAY
LCALL DELAY
RET
DOO:
CPL P1.2
MOV R1,#1
SETB P1.2
LCALL DELAY
CLR P1.2
LCALL DELAY
LCALL DELAY
LCALL DELAY
RET
DELAY:
LOOP1:
MOV R2,#2
LOOP2:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R2,LOOP2
DJNZ R1,LOOP1
RET
END
TH2:
GIATRI EQU 019H
ORG 00H
LJMP MAIN
ORG 03H
RETI
ORG 0BH
RETI
ORG 13H
RETI
ORG 1BH
RETI
ORG 23H
JNB SCON.0,SeriallntExit
SeriallntExit:
RETI
***************************************************
ORG 60H
MAIN:
MOV R0,#GIATRI
N1: LCALL DO
DJNZ R0,N1
MOV R0,#GIATRI
N2: LCALL RE
DJNZ R0,N2
MOV R0,#GIATRI
N3: LCALL MI
DJNZ R0,N3
MOV R0,#GIATRI
N4: LCALL FA
DJNZ R0,N4
MOV R0,#GIATRI
N5: LCALL SO
DJNZ R0,N5
MOV R0,#GIATRI
N6: LCALL LA
DJNZ R0,N6
MOV R0,#GIATRI
N7: LCALL SI
DJNZ R0,N7
MOV R0,#GIATRI
N8: LCALL DOO
DJNZ R0,N8
SJMP MAIN
***************************************************
DO:
CPL P1.2
MOV R1,#8
SETB P1.2
LCALL DELAY
LCALL DELAY
LCALL DELAY
CLR P1.2
LCALL DELAY
RET
RE:
CPL P1.2
MOV R1,#7
SETB P1.2
LCALL DELAY
LCALL DELAY
LCALL DELAY
CLR P1.2
LCALL DELAY
RET
MI:
CPL P1.2
MOV R1,#6
SETB P1.2
LCALL DELAY
LCALL DELAY
LCALL DELAY
CLR P1.2
LCALL DELAY
RET
FA:
CPL P1.2
MOV R1,#5
SETB P1.2
LCALL DELAY
LCALL DELAY
LCALL DELAY
CLR P1.2
LCALL DELAY
RET
SO:
CPL P1.2
MOV R1,#4
SETB P1.2
LCALL DELAY
LCALL DELAY
LCALL DELAY
CLR P1.2
LCALL DELAY
RET
LA:
CPL P1.2
MOV R1,#3
SETB P1.2
LCALL DELAY
LCALL DELAY
LCALL DELAY
CLR P1.2
LCALL DELAY
RET
SI:
CPL P1.2
MOV R1,#2
SETB P1.2
LCALL DELAY
LCALL DELAY
LCALL DELAY
CLR P1.2
LCALL DELAY
RET
DOO:
CPL P1.2
MOV R1,#1
SETB P1.2
LCALL DELAY
LCALL DELAY
LCALL DELAY
CLR P1.2
LCALL DELAY
RET
DELAY:
LOOP1:
MOV R2,#2
LOOP2:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R2,LOOP2
DJNZ R1,LOOP1
RET
END
Câu hỏi 6: Với cùng một giá trị tần số, khi thay đổi duty cycle thì giá trị nào của âm thanh phát ra được thay đổi ( cường độ, cao độ, âm sắc)?
Trả lời:
T
Ton
Toff
D= Ton / T off
Giá trị thay đổi là cường độ (f ), cao độ giữa các âm khác nhau khi ta thay đổi D
BÀI 9: TỔNG HỢP
;******************** DEFINITION **************
ADCCS BIT P3.7
ADCCLK BIT P1.6
ADCDIN BIT P1.4
ADCDOUT EQU P1
;*********************** LCD ******************
CTRL EQU P0.0 ;CONTROL BIT (CONTROL=RESET & DATA=SET)
READ EQU P0.1 ;READ=SET & WRITE=RESET
STROBE EQU P0.2 ;DATA STROBE (ENABLE)
DATAPORT EQU P0 ;LCD DATA ( ONLY LOWER 4 BITS ARE USED )
;*************** INTERRUPT HANDLERS ***********
ORG 00H ; Reset
LJMP MAIN
ORG 03H ; INT0
RETI ; do nothing
ORG 0BH ; Timer 0
RETI ; do nothing
ORG 13H ; INT1
RETI ; do nothing
ORG 1BH ; Timer 1
RETI ; do nothing
ORG 23H ; Serial port
RETI ; do nothing
;==============================================================================
ORG 40H ; Data & Subroutines
;==============================================================================
KeyTBL: DB '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
MESSAGE1 STR "Ch0:"
LCD_MESSAGE0:
STRZ " Ch0:"
LCD_MESSAGE1:
STRZ "h Ch1:"
LCD_MESSAGE2:
STRZ "h Ch2:"
LCD_MESSAGE3:
STRZ "h Ch3:"
LCD_MESSAGE:
STRZ "ADC results :"
LCD_END:
STRZ "h"
;******************************************************************************
MAIN:
;******************************************************************************
ACALL InitLCD
BEGIN:
;******/CURSOR HOME/******
CLR A
ACALL WriteCtrl
;
MOV A,#2
ACALL WriteCtrl
MOV DPTR,#LCD_MESSAGE
;*************************
LOOP:
CLR A
MOVC A,@A+DPTR
JZ NEXT
ACALL WriteData
INC DPTR
SJMP LOOP
;*********************
NEXT: MOV B,#0
MOV DPTR,#LCD_MESSAGE0
ACALL CONVERT
MOV P2,A
ACALL DISP
;*********************
MOV B,#1
MOV DPTR,#LCD_MESSAGE1
ACALL CONVERT
ACALL DISP
;*********************
MOV B,#2
MOV DPTR,#LCD_MESSAGE2
ACALL CONVERT
ACALL DISP
;*********************
MOV B,#3
MOV DPTR,#LCD_MESSAGE3
ACALL CONVERT
ACALL DISP
;*********************
CLR A
MOV DPTR,#LCD_END
MOVC A,@A+DPTR
ACALL WriteData
SJMP BEGIN
CONVERT:
;********RESET ADC************
SETB ADCCS
CLR ADCCLK
SETB ADCDIN
;******/START CONVRSION/******
CLR ADCCS
ACALL DELAY
;**********/START BIT/********
SETB ADCDIN
ACALL CLOCK
;**********/SGL/DIF/**********
SETB ADCDIN
ACALL CLOCK
ACALL ODD_SIGH
ACALL SELECT
ACALL READ_ADC
RET
;**********/ODD_SIGH/*********
ODD_SIGH:
JNB B.0,ELSE
SETB ADCDIN
AJMP QUIT
ELSE:
CLR ADCDIN
QUIT: ACALL CLOCK
RET
;**********/SELECT/***********
SELECT:
JNB B.1,ELSE1
SETB ADCDIN
AJMP QUIT1
ELSE1:
CLR ADCDIN
QUIT1: ACALL CLOCK
ACALL DELAY
RET
;***********/READ_ADC/********
READ_ADC
SETB ADCDIN
MOV R0,#8
MOV A,#0
ACALL CLOCK
LOOP3:
MOV R7,ADCDOUT
CJNE R7,#0AFH,ELSE2
CLR C
RLC A
ACALL CLOCK
DJNZ R0,LOOP3
AJMP EXIT1
ELSE2:
SETB C
RLC A
ACALL CLOCK
DJNZ R0,LOOP3
EXIT1:
RET
;**********************************
CLOCK:
SETB ADCCLK
CLR ADCCLK
RET
;***************************************
DELAY
MOV R0,#1
LOOP0:
MOV R1,#100
LOOP1:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R1,LOOP1
DJNZ R0,LOOP0
RET
DISP: MOV R4,#2
MOV R5,A
SCAN:
CLR A
MOVC A,@A+DPTR
JZ PRINT
ACALL WriteData
INC DPTR
SJMP SCAN
PRINT:
MOV DPTR,#KeyTBL
MOV A,R5
ANL A,#0F0H
SWAP A
MOVC A,@A+DPTR
ACALL WriteData
MOV A,R5
ANL A,#0FH
MOVC A,@A+DPTR
ACALL WriteData
RET
InitLCD:
;CTRL = READ = STROBE = 1
MOV P0,#7
;Initialize the LCD to 4-bit mode
MOV A,#3
ACALL WriteCtrl ;WriteCtrl(3)
;
MOV A,#3
ACALL WriteCtrl ;WriteCtrl(3);
;
MOV A,#3
ACALL WriteCtrl ;WriteCtrl(3);
;
MOV A,#2
ACALL WriteCtrl ;WriteCtrl(2);
; Function Set
MOV A,#2
ACALL WriteCtrl ;WriteCtrl(2);
;
MOV A,#8
ACALL WriteCtrl ;WriteCtrl(8);
; Display OFF
CLR A
ACALL WriteCtrl ;WriteCtrl(0);
;
MOV A,#8
ACALL WriteCtrl ;WriteCtrl(8);
; Display ON
CLR A
ACALL WriteCtrl ;WriteCtrl(0);
;
MOV A,#0FH
ACALL WriteCtrl ;WriteCtrl(0x0F);
; Entry mode
CLR A
ACALL WriteCtrl ;WriteCtrl(0);
;
MOV A,#6
ACALL WriteCtrl ;WriteCtrl(6);
; Clear Screen
CLR A
ACALL WriteCtrl ;WriteCtrl(0);
;
MOV A,#1
ACALL WriteCtrl ;WriteCtrl(1);
; Cursor home
CLR A
ACALL WriteCtrl ;WriteCtrl(0);
;
MOV A,#2
ACALL WriteCtrl ;WriteCtrl(2);
;
RET
WriteCtrl:
CLR CTRL ;select control register
ACALL WriteCommon ;write value to control register
RET
WriteData:
SETB CTRL ;select data register
PUSH ACC ;store 4 low bits
SWAP A ;ACC = value >> 4
ACALL WriteCommon ;write data to LCD
POP ACC ;ACC = value
ACALL WriteCommon ;write data to LCD
RET
WriteCommon:
CLR READ ;clrbit (READ);
SWAP A
ANL A,#0F0H ;value=value<<4;
ANL P0,#7 ;P0&=0x07;
ORL P0,A ;P0|=value;
ACALL DELAY ;delay(1);
SETB STROBE ;setbit(STROBE);
ACALL DELAY ;delay(1);
CLR STROBE ;clrbit(STROBE);
ACALL DELAY ;delay(1);
SETB READ ;setbit(READ);
ACALL DELAY ;delay(1);
RET
END
Các file đính kèm theo tài liệu này:
- ALL BAO CAO VI XU LI.doc