Tóm tắt: 1. Khai báo các nguồn ngắt - Mức ưu tiên ngắt 2. Vector ngắt - Trình phục vụ ngắt(ISR) 3. Hoạt động ngắt 4. Ngắt Timer 5. Ngắt cổng nối tiếp(SPI) 6. Ngắt ngoài 7. Tổng hợp Ø Sinh viên phải tham khảo trước các slide bài giảng chương 7
Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 2
BT7.1: Khai báo cho phép các nguồn ngắt sau: (a) Ngắt Timer0,ngắt /INT0 (b) Ngắt Timer1,ngắt SPI,ngắt /INT1 Giải: EA - ET2 ES ET1 EX1 ET0 EX0 (a) Ngắt Timer0,ngắt /INT0 MOV IE,#10000011B SFR IE Hay MOV IE,#83H (b) Ngắt Timer1,ngắt SPI,ngắt /INT1 MOV IE,#10011100B Hay MOV IE,#9CH
Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 3
BT7.2: Khai báo cho phép các nguồn ngắt sau: (a) Ngắt Timer1,ngắt /INT0.ưu tiên ngắt Timer0 (b) Ngắt Timer0,ngắt SPI,ngắt /INT1,ưu tiên ngắt SPI,ngắt /INT1 tác động cạnh xuống Giải: EA - ET2 ES ET1 EX1 ET0 EX0 (a) Ngắt Timer1,ngắt /INT0, ưu tiên ngắt Timer0 SFR IE MOV IE,#89H - - PT2 PS PT1 PX1 PT0 PX0 SETB PT0 SFR IP (b) Ngắt Timer0,ngắt SPI,ngắt /INT1,ưu tiên ngắt SPI,ngắt /INT1 tác động cạnh xuống MOV IE,#96H SETB PS SETB IT1
Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 4
BT7.3: Giả sử ở đầu chương trình chính có khai báo các dòng lệnh như sau: .... MOV IE,#99H SETB PT1 SETB IT0 .... (a) Cho biết nguồn ngắt nào được phép hoạt động và mức ưu tiên? (b) MCU đang chạy chương trình chính thì có 2 tín hiệu yêu cầu ngắt SPI và /INT0 đồng thời xảy ra.Mô tả trình tự thực hiện chương trình của MCU? (c) MCU đang chạy ISR SPI thì có tín hiệu yêu cầu ngắt /INT0,sau đó là tín hiệu yêu cầu ngắt Timer1.Mô tả trình tự thực hiện chương trình của MCU? Giải: (a) Cho biết nguồn ngắt nào được phép hoạt động và mức ưu tiên? - Ngắt SPI,Timer1,ngắt /INT0.Ngắt Timer1 ưu tiên cao nhất,ngắt SPI,ngắt /INT0 cùng mức ưu tiên thấp.Ngắt /INT0 tác động cạnh xuống. Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 5 (b) MCU đang chạy chương trình chính thì có 2 tín hiệu yêu cầu ngắt SPI và /INT0 đồng thời xảy ra.Mô tả trình tự thực hiện chương trình của MCU? Ngắt SPI và ngắt /INT0 cùng mức ưu tiên nên ngắt /INT0 thực hiện trước: - MCU dừng chương trình chính,lưu trạng thái báo ngắt SPI,chuyển sang thực hiện ISR của ngắt /INT0 - Sau khi thực hiện xong ISR /INT0(lệnh RETI),MCU chuyển sang thực hiện ISR SPI - Sau khi thực hiện xong ISR SPI(RETI),MCU quay về thực hiện tiếp chương trình chính (c) MCU đang chạy ISR SPI thì có tín hiệu yêu cầu ngắt /INT0,sau đó là tín hiệu yêu cầu ngắt Timer1.Mô tả trình tự thực hiện chương trình của MCU? - MCU đang thực hiện ISR SPI,khi có tín hiệu yêu cầu ngắt /INT0 đồng mức ưu tiên nên MCU chỉ lưu trạng thái báo ngắt /INT0 và tiếp tục thực hiện ISR SPI - Khi có tín hiệu yêu cầu ngắt Timer1 mức ưu tiên cao hơn,MCU tạm dừng thực hiện ISR SPI chuyển sang thực hiện ISR Timer1. - Sau khi thực hiện xong ISR Timer1(RETI),MCU quay về thực hiện tiếp ISR SPI - Sau khi thực hiện xong ISR SPI(RETI),MCU chuyển sang thực hiện ISR /INT0 đã lưu trạng thái trước đó - Sau khi thực hiện xong ISR /INT0(RETI),MCU quay về thực hiện tiếp chương trình chính
Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 6
BT7.4: Giải thích từng dòng lệnh đoạn chương trình sau: ORG 0 Giải: LJMP MAIN ORG 0 ;điểm vào reset bắt đầu CT LJMP EX0_ISR LJMP MAIN ;nhảy đến điểm vào CT chính ORG 0023H LJMP EX0_ISR ;điểm vào ISR /INT0 nhảy đến LJMP SPI_ISR ;nhãn EX0_ISR ORG 0023H ;điểm vào ISR SPI ORG 0030H LJMP SPI_ISR ;nhãy đến nhãn SPI_ISR MAIN: MOV IE,#91H ORG 0030H ;điểm vào CT chính SETB IT0 MAIN: MOV IE,#91H ;cho phép ngắt SPI,ngắt /INT0 ... SETB IT0 ;ngắt /INT0 tác động cạnh xuống ....
Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 7
BT7.5: Giải thích hoạt động các cờ báo ngắt của nguồn ngắt sau(đã khai báo cho phép ngắt): (a) Ngắt Timer0 (b) Ngắt SPI (c) Ngắt /INT0 tác động cạnh,tác động mức Giải: (a) Ngắt Timer0: cờ báo ngắt TF0 - Khi Timer0 tràn phần cứng đặt TF0=1 báo ngắt - Ngay khi MCU chuyển đến thực thi ISR Timer0,phần cứng xóa TF0=0 (b) Ngắt SPI: cờ báo ngắt RI(ngắt thu)hay TI(ngắt phát) - Khi SBUF thu đủ ký tự RI=1,hoặc khi SBUF phát xong ký tự TI=1 báo ngắt SPI (phần cứng đặt RI hoặc TI) - Khi MCU chuyển đến thực thi ISR SPI phần cứng không xóa các cờ RI/TI,phải xóa bằng mềm (c) Ngắt /INT0 tác động cạnh/mức:cờ báo ngắt IE0,tín hiệu báo ngắt đưa vào ngõ /INT0 - Tác động cạnh IT0=1.Khi xuất hiện cạnh xuống trên ngõ /INT0 báo ngắt,phần cứng đặt IE0=1.Ngay khi MCU chuyến đến thực thi ISR /INT0,phần cứng xóa IE0=0 - Tác động mức IT0=0.Khi xuất hiện mức thấp trên ngõ /INT0 báo ngắt,phần cứng đặt IE0=1 - Phần cứng chỉ xóa IE0=0 khi ngõ /INT0=1 Ø Lưu ý: Nếu /INT0=0 khi thực thi lệnh RETI→IE0=0 tiếp tục báo ngắt /INT0 lại Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 8 BT7.6: Giả sử MCU đang thực thi lệnh ở dòng 13,giải thích hoạt động của chương trình và nội dung PC,SP tương ứng khi Timer0 tràn? LOC OBJ LINE SOURCE 0000 1 ORG 0 0000 020030 2 LJMP MAIN 000B 3 ORG 000BH 000B B290 4 CPL P1.0 000D 32 5 RETI 0030 6 ORG 0030H 0030 75815F 7 MAIN: MOV SP,#5FH 0033 75A882 8 MOV IE,#82H 0036 758902 9 MOV TMOD,#02H 0039 758CCE 10 MOV TH0,#-50 003C 858C8A 11 MOV TL0,TH0 003F D28C 12 SETB TR0 0041 80FE 13 SJMP $ 14 END
Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 9
Giải: - Timer0 tràn,TF0=1 báo ngắt Timer0,MCU đang thực thi lệnh ở dòng 13→(PCHH)=0041H - MCU thực thi xong lệnh ở dòng 13 SJMP $ - Cất (PCHH) vào stack: (SP)+1=60H,(60H)=(PCL)=41H,(SP)+1=61H,(61H)=(PCH)=00H - PC nạp giá trị vector ngắt Timer0: (PC)=000BH - MCU thực thi lệnh ở dòng 4 CPL P1.0 - MCU thực thi tiếp lệnh ở dòng 5 RETI: kết thúc ngắt Timer0 trở về điểm dừng chương trình chính: (SP)=61H→(PCH)=(61H)=00H,(SP)-1=60H→(PCL)=(60H)=41H,(SP)-1=5FH - (PC)=0041H chương trình thực thi tiếp dòng lệnh 13 SJMP $
Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 10
BT7.7: Thiết kế mạch tạo chuỗi xung vuông đối xứng f=10Khz trên P1.0,cho Fck=12Mhz. Giải: • Trong chương 5 đã có ví dụ sử dụng Timer tạo xung. • Sử dụng ngắt Timer0 tạo xung: sau mỗi 50μs Timer0 tràn,TF0=1 tạo ngắt Timer0 • Trong ISR Timer0 chỉ cần bù bit P1.0 ORG 0 ;điểm vào reset • Sử dụng ISR ngắn do chỉ có 2 lệnh 4 byte LJMP MAIN ;nhảy đến ct chính • Khi MCU chuyển đến thực thi ISR phần ORG 000BH ;điểm vào ISR Timer0 cứng tự động xóa cờ TF0=0 CPL P1.0 ;bù bit P1.0 • Lệnh SJMP $ thay cho MCU thực thi RETI ;kết thúc ISR Timer0 công việc khác trong chương trình chính ORG 0030H ;điểm vào CT chính MAIN: MOV SP,#5FH ;đưa stack lên vùng RAM cao MOV IE,#82H ;cho phép ngắt Timer0 MOV TMOD,#02H ;Timer0 mode 2 định thì MOV TH0,#-50 ;gíá trị reload MOV TL0,TH0 ;nạp giá trị reload từ đầu SETB TR0 ;chạy Timer0 SJMP $ ;Lập vòng tại chỗ END Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 11 BT7.8: Thiết kế mạch tạo 2 chuỗi xung hoạt động như sau,Fck=12Mhz: • Chuỗi xung 1 : xung vuông đối xứng chu kỳ T1=200μs trên P1.0 • Chuỗi xung 2 : xung vuông đối xứng chu kỳ T2=T1xN trên P1.1,với N=data nhập từ P2 Giải: • Sử dụng ngắt Timer0 tạo xung T1 trên P1.0,giá trị reload=-100→mode 2 định thì • Sử dụng ngắt Timer1 tạo xung T2=T1xN,Nmax=FFH=255→T2=200x255=51000μs →giá trị reload=-25500→mode 1 định thì • Chương trình chính tính giá trị reload cho Timer1=bù 2(T1/2xN) v Chương trình TF EQU 100 ORG 0 ;diểm vào reset LJMP MAIN ;nhảy đến CT chính ORG 000BH ;diểm vào ISR Timer0 CPL P1.0 ;bù bit P1.0 RETI ;kết thúc ISR Timer0 ORG 001BH ;điểm vào ISR Timer1 LJMP T1_ISR ;nhảy đến T1_ISR ORG 0030H ;diểm vào CT chính Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 12 MAIN: MOV SP,#5FH ;dưa stack lên vùng RAM cao MOV IE,#8AH ;cho phép ngắt Timer0,Timer1 MOV TMOD,#12H ;Timer0 mode 2,Timer1 mode 1 định thì MOV TH0,#(-TF) ;giá trị reload Timer0 MOV TL0,TH0 CALL T2_PULSE ;tính giá trị reload Timer1 SETB TR0 ;chạy Timer0 SETB TF1 ;ép ngắt Timer1 để reload AGAIN: CALL T2_PULSE ;tính giá trị reload Timer1 SJMP AGAIN ;lập vòng lại ;======================================== ;======================================= ;T2_PULSE tính giá trị reload Timer1,output (R7)(R6) T1_ISR: CLR TR1 ;dừng Timer1 ;======================================== CPL P1.1 ;bù bit P1.1 T2_PULSE: MOV A,P2 ;đọc hệ số nhân N MOV TH1,R7 ;reload byte cao MOV B,#TF ;nạp độ rông xung Timer0 MOV TL1,R6 ;reload byte thấp MUL AB ;nhân cho N SETB TR1 ;chạy Timer1 CPL A ;bù 1 byte thấp kq RETI ADD A,#1 ;bù 2 byte thấp kq ;======================================== MOV R6,A ;cất byte thấp reload END MOV A,B ;lấy byte cao kq CPL A ;bù 1 byte cao kq ADDC A,#0 ;bù 2 byte cao kq MOV R7,A ;cất byte cao reload RET Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 13 • Hình trên là kết quả chạy mô phỏng với N=4,với F1=5Khz theo tính toán F2=1250Hz • Thực tế đo được F2=1214Hz,do Timer1 chạy mode 1 phải dừng và nạp lại giá trị đếm khi Timer1 tràn trong T1_ISR,nên bị trễ trong khoảng thời gian này Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 14 BT7.9: Thiết kế MCU 8051 làm việc với cổng nối tiếp như sau: • Sử dụng ngắt SPI thu ký tự từ cổng nối tiếp: - Nếu ký tự là phím CR=0DH cho phép phát chuỗi ký tự từ bộ nhớ chương trình ra SPI - Nếu ký tự là phím 0=30H dừng phát chuỗi ký tự ra SPI • Chương trình chính phát chuỗi ký tự kết thúc bằng mã NULL=00H từ bộ nhớ chương trình ra SPI • Cho SPI làm việc như UART 8 bit BR=9600,Fosc=11.059Mhz Giải: • Chỉ cho phép ngắt thu SPI qua nhận dạng RI=1,nếu TI=1 thoát khỏi ISR SPI • Trong ISR SPI đặt cờ F0=1 nếu thu ký tự “CR” và xóa F0=0 nếu thu ký tự “0” • Đầu ISR SPI phải cất (A) và trước khi thoát ISR SPI phục hồi lại (A),do trong chương trình chính có sử dụng A • Chương trình chính là chương trình con PHAT kiểm tra nếu cờ F0=0 sẽ thoát,nếu F0=1 sẽ phát chuỗi ký tự đã khai báo trong bộ nhớ chương trình địa chỉ đầu TAB_CHR,kết thúc phát khi gặp ký tự NULL=00H Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 15 CR EQU 0DH ;mã ASCII phím enter PAUSE EQU "0" ;mã ASCII phím 0 ORG 0 LJMP MAIN ORG 0023H ;điểm vào ISR SPI LJMP SPI_ISR ;nhảy đến SPI_ISR ORG 0030H MAIN: MOV SP,#5FH MOV IE,#90H ;cho phép ngắt SPI MOV SCON,#50H ;UART 8 bit,cho phép thu MOV TMOD,#20H ;Timer1 mode 2 tạo BR MOV TH1,#(-3) ;BR=9600 Fosc=11.059Mhz MOV TL1,TH1 ;nạp giá trị reload SETB TR1 ;chạy Timer1 CLR F0 ;xóa cờ cho phép phát AGAIN: CALL PHAT ;phát chuỗi ký tự SJMP AGAIN ;lập vòng lại ;======================================== PHAT: JNB F0,EXIT ;F0=0 thoát MOV DPTR,#TAB_CHR ;lấy đ/c đầu chuỗi ký tự TIEP: CLR A ;offset=0 trỏ ký tự đầu chuỗi MOVC A,@A+DPTR ;lấy ký tự từ bộ nhớ CT JZ EXIT ;ký tự NULL thoát Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 16 MOV SBUF,A ;phát ký tự ra SPI JNB TI,$ ;chờ TI=1 CLR TI ;xóa TI để phát tiếp INC DPTR ;tăng con trỏ đ/c SJMP TIEP ;lập vòng phát tiếp EXIT: RET ;======================================== SPI_ISR: PUSH ACC ;cất (A) JB TI,QUIT ;TI=1 thoát CLR RI ;ngắt thu xóa RI MOV A,SBUF ;thu ký tự từ SPI CJNE A,#CR,P_CHK ;ký tự=”CR” SETB F0 ;đặt F0=1 cho phép phát SJMP QUIT ;thoát P_CHK: CJNE A,#PAUSE,QUIT ;ký tự=”0” CLR F0 ;xóa F0=0 cấm phát QUIT: POP ACC ;phục hồi (A) RETI ;======================================== TAB_CHR: DB "DAI HOC BACH KHOA ",0DH,"TP. HO CHI MINH",0DH,00H ;chuỗi ký tự lưu trong bộ nhớ CT END
Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 17
Ø Sử dụng VIRTUAL TERMINAL mô phỏng thu ký tự từ bàn phím và phát ký tự ra SPI Khai báo BR=9600,UART 8bit không bit parity,1 stop bit
Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 18
BT7.10: Thiết kế MCU8051 giao tiếp SPI làm việc như sau: • Sử dụng ngắt thu SPI thu chuỗi ký tự mã ASCII,dài tối đa 60 ký tự hoặc ký tự kết thúc “%” , cất vào RAM nội • Sử dụng ngắt phát SPI phát chuỗi ký tự vừa thu được.Trong quá trình phát MCU vẫn có thể thu chuỗi ký tự mới • Cho SPI làm việc như UART 8 bit,BR=9600,Fosc=11.059Mhz Giải: • Đặt vùng stack từ 60H-7FH,chọn địa chỉ đầu RAM nội 21H→Vùng RAM nội chứa data =60H-21H=3FH=63 byte đạt yêu cầu không phủ lên vùng stack! • Để đơn giản khi thu đủ 60 ký tự,cẩn thêm ký tự kết thúc ”%”,để khi phát chỉ cần kiểm tra ký tự kết thúc “%” • Trong ISR thu : đặt cờ F0=1 khi thu đủ 60 ký tự hoặc ký tự kết thúc “%” và đặt TI=1 để tạo ngắt phát SPI • Trong ISR phát : thoát khi cờ F0=0,xóa cờ F0=0 khi phát ký tự kết thúc “%”
Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 19
ST_BUF EQU 21H ;đ/c đầu vùng RAM nội chứa ký tự LENGTH EQU 60 ;chiều dài max chuỗi ký tự ORG 0 LJMP MAIN ORG 0023H ;điểm vào ISR SPI LJMP SPI_ISR ORG 0030H MAIN: MOV SP,#5FH ;đưa stack lên vùng RAM đ/c cao MOV IE,#90H ;cho phép ngắt SPI MOV SCON,#50H ;UART 8 bit cho phép thu MOV TMOD,#20H ;Timer1 mode 2 định thì tạo BR MOV TH1,#(-3) ;BR=9600 MOV TL1,TH1 SETB TR1 MOV R0,#ST_BUF ;con trỏ thu trỏ đ/c đầu vùng nhớ MOV R1,#ST_BUF ;con trỏ phát trỏ đ/c đầu vùng nhớ CLR F0 ;xóa cờ báo kết thúc thu,cấm phát SJMP $ ;lập vòng tại chỗ ;======================================== SPI_ISR: JBC TI,PHAT ;TI=1 ngắt phát,xóa TI CLR RI ;ngắt thu xóa RI MOV A,SBUF ;thu ký tự MOV @R0,A ;cất vào bộ nhớ Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 20 INC R0 ;tăng đ/c vùng nhớ CJNE R0,#ST_BUF+LENGTH+1,ST_CHK;kiểm tra chiều dài chuỗi ký tự MOV @R0,#"%" ;đủ chiều dài cẩn thêm ký tự kết thúc SJMP SET_FLG ;kết thúc thu ST_CHK: CJNE A,#"%",EXIT ;kiểm tra ký tự kết thúc SET_FLG: SETB F0 ;đúng ký tự kết thúc, đặt F0=1 cho phép phát MOV R0,#ST_BUF ;đặt con trỏ thu về đ/c đầu vùng nhớ SETB TI ;cho phép ngắt phát SJMP EXIT ;thoát PHAT: JNB F0,EXIT ;F0=0 cấm phát ,thoát MOV A,@R1 ;lấy ký tự từ vùng nhớ MOV SBUF,A ;phát ký tự INC R1 ;tăng đ/c vùng nhớ CJNE A,#"%",EXIT ;kiểm tra ký tự kết thúc CL_FLG: CLR F0 ;đúng ký tự kết thúc F0=0 cấm phát MOV R1,#ST_BUF ;đặt con trỏ phát về đ/c đầu vùng nhớ EXIT: RETI ;======================================== END
Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 21
Ø Sử dụng VIRTUAL TERMINAL mô phỏng thu ký tự từ bàn phím và phát ký tự ra SPI Khai báo BR=9600,UART 8bit không bit parity,1 stop bit Để hiển thị chuỗi ký tự nhập từ bàn phím khi chạy mô phỏng,nhấp chuột phải vào màn hình VIRTUAL TERMINAL chọn Echo Typed Characters Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 22 BT7.11: Thiết kế mạch đếm sản phẩm trên băng chuyền như hình,hoạt động như sau: CB ra OUT
• Ngõ CONT=1/0 điều khiển đóng/mở cửa
vào băng chuyền MCU8051
• Khi 1 sản phẩm vào băng chuyền,cảm biến
CB vào DRIVER LED 7 ĐOẠN CA ngõ vào phát 1 xung tích cực mức 0 đưa vào IN
ngõ IN Cửa vào
băng • Khi 1 sản phẩm ra băng chuyền,cảm biến chuyền CONT
ngõ ra phát 1 xung tích cực mức 0 đưa vào
ngõ OUT • Khi số sản phẩm vào băng chuyền đạt tới 95,điều khiển đóng cửa vào băng chuyền cho đến khi số sản phẩm trên băng chuyển giảm xuống còn 85 mới mở cửa vào băng chuyền lại • Hiển thị cập nhật số sản phẩm trên băng chuyền
Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 23
Giải: • Ngõ CONT=P2.2 • Ngõ IN=/INT0=P3.2 • Ngõ OUT=/INT1=P3.3 • U3=74HC573 lái LED A chung digit đơn vị LE=LE0=P2.0 đk mở chốt • U2=74HC573 lái LED A chung digit chục LE=LE1=P2.1 đk mở chốt • R2 là bộ đếm sản phẩm • Khi có xung IN tạo ngắt /INT0 tăng (R2) cho đến khi (R2)=95 đóng cửa CONT=1 • Khi có xung OUT tạo ngắt /INT1 giảm (R2) cho đến khi (R2)=85 mở cửa CONT=0 • Trong chương trình chính,gọi CTC HEX_BCD chuyển số nhị phân sang BCD và CTC DISPLAY hiển thị cập nhật số sản phẩm trên băng chuyền Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 24 OUTPORT EQU P1 LE0 BIT P2.0 LE1 BIT P2.1 CONT BIT P2.2 ORG 0 JMP MAIN JMP EX0_ISR ;điểm vào ISR /INT0 ORG 0013H ;điểm vào ISR /INT1 JMP EX1_ISR ORG 0030H MAIN: MOV SP,#5FH CLR CONT ;mở cửa băng chuyền CLR LE0 ;khóa chốt hiển thị CLR LE1 MOV R2,#0 ;khởi động bộ đếm MOV IE,#85H ;cho phép ngắt /INT0 và /INT1 SETB IT0 ;ngắt /INT0 tác động cạnh SETB IT1 ;ngắt /INT1 tác động cạnh START: MOV A,R2 ;nạp giá trị đếm CALL HEX_BCD ;chuyển sang số BCD CALL DISPLAY ;hiển thị số đếm JMP START ;lập vòng lại
Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 25
;============================================== HEX_BCD: MOV 30H,#0 MOV 31H,#0 MOV 32H,#0 MOV R0,#30H LOOP: MOV B,#10 JZ SKIP DIV AB MOV @R0,B INC R0 JMP LOOP SKIP: MOV B,32H MOV A,31H SWAP A ORL A,30H RET ;=============================================== DISPLAY: MOV DPTR,#TAB PUSH ACC ANL A,#0FH MOVC A,@A+DPTR MOV OUTPORT,A SETB LE0 CLR LE0 Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 26 POP ACC SWAP A ANL A,#0FH MOVC A,@A+DPTR MOV OUTPORT,A SETB LE1 CLR LE1 RET ;======================================================= EX0_ISR: JB CONT,EXIT0 ;CONT=0 cửa đóng,thoát INC R2 ;tăng bộ đếm CJNE R2,#95,$+3 ;đếm tới 95? JC EXIT0 ;<95 thoát SETB CONT ;>=95 đóng cửa CONT=1 EXIT0: RETI ;======================================================= EX1_ISR: CJNE R2,#0,GIAM ;bộ đếm khác 0 giảm SJMP EXIT1 ;bộ đếm=0 thoát GIAM: DEC R2 ;giảm bộ đếm CJNE R2,#86,$+3 ;giảm còn 85 JNC EXIT1 ;>85 thoát CLR CONT ;<=85 mở cửa CONT=0 EXIT1: RETI ;======================================================= TAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H END Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 27 BT7.12: Xem lại bài tập 4.5(HDGBTC4),sơ đồ hoạt động như sau: • Khi nhấn/nhả SW1 BarLED sáng dịch 1 đèn từ trên xuống và quay vòng lại với thời gian dịch đèn khoảng 0.5s • Khi nhấn/nhả SW2 BarLed sáng/tối với thời gian chuyển trạng thái khoảng 0.5s • Chống rung SW khi nhấn/nhả v Thiết kế lại BT4.5,khi nhấn SW tạo tín hiệu ngắt để MCU thực hiện các việc như trên
Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 28
Giải:
v Thiết kế phần cứng
• Thêm cổng AND2 kết nối 2 ngõ vào SW1,SW2,ngõ ra nối chân /INT1=P3.3 • Khi có SW nhấn tạo mức 0 ngõ ra cổng AND báo ngắt /INT1 tác động mức 0 Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 29 v Thiết kế phần chương trình: • Dựa trên chương trình BT4.5,có điều chỉnh lại việc nhấn SW sẽ tạo ngắt ngoài /INT1,không cần kiểm tra SW có nhấn hay không • Khi có SW nhấn,MCU sẽ chuyển đến thực thi ISR /INT1: - Gọi CTC SW_CHK kiểm tra 50 lần chờ SW nhả và đặt (C)=1 trước khi thoát để báo có SW nhấn - CTC SW_CHK nhận dạng SW nhấn tương tự như BT4.5,chỉ sửa lại trả về (R5)=mã SW - MCU chỉ thoát khỏi ISR /INT1 khi SW nhả,ngõ /INT1=1 và CTC SW_CHK trả về (C)=0, do đó khai báo /INT1 tác động mức thấp sẽ thích hợp và đặt (C)=1 trước khi thoát để báo CT chính có nhấn SW - Do CTC SW_CHK có sử dụng thanh ghi A nên phải push/pop thanh ghi A ở đầu/cuối ISR để bảo toàn (A) khi quay về CT chính • CTC DELAY_500MS chỉ cần kiểm tra (C)=1 sẽ thoát,điều chỉnh (R4)=125 với vòng lặp 2 lệnh 4MC→thời gian vòng lặp cho R4=125x4=500μs • CT chính so sánh (R5) với mã phím để chạy CT con thích hợp tương ứng Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 30 vChương trình SW1 BIT P1.0 SW2 BIT P1.1 BAR_LED EQU P2 ;================================================= ORG 0 LJMP MAIN ORG 0013H ;điểm vào ISR /INT1 LJMP EX1_ISR ORG 0030H MAIN: MOV BAR_LED,#0 ;xóa các LED tối MOV IE,#84H ;cho phép ngắt/INT1 START: CJNE R5,#01H,SW2_PR ;mã phím=01H? CALL SW1_DISP ;hiển thị mode SW1 SW2_PR: CJNE R5,#02H,SKIP ;mã phím =02H CALL SW2_DISP ;hiển thị mode SW2 SKIP: JMP START ;lập vòng lại ;================================================== ;SW_CHK kiểm tra nếu có SW nhấn trả về (C)=1 và (R5)=mã SW ;nếu không có SW nhấn trả về (C)=0 ;================================================== Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 31 SW_CHK: SETB SW1 ;đặt chốt port=1 trước khi đọc SETB SW2 MOV A,P1 ;đọc trạng thái các SW ANL A,#03H ;che các bit SW CJNE A,#03H,SW_PRESS ;có SW nhấn? JMP EXIT ;không có SW nhấn,(C)=0,thoát SW_PRESS: MOV R6,#2 ;R6 đếm số SW kết nối MOV R5,#01H ;R5 chứa mã SW CONT: RRC A ;quay phải A qua C JNC DONE ;(C)=0,SW tương ứng nhấn,thoát INC R5 ;tăng mã SW DJNZ R6,CONT ;đếm số lần quay kiểm tra SW CLR C ;không có SW nhấn,(C)=0 JMP EXIT ;thoát DONE: SETB C ;(C)=1 xác nhận có SW nhấn EXIT: RET ;thoát chương trình con ;========================================================== SW1_DISP: MOV R1,#01H ;R1 chứa bit lái LED đầu tiên SHIFT_LED: MOV A,R1 ;chuyển mã lái đèn vào A MOV BAR_LED,A ;xuất mã lái đèn RL A ;quay trái tạo dịch mã lái đèn MOV R1,A ;cất mã lái đèn vào R1 CALL DELAY_500M ;delay 0.5s JNC SHIFT_LED ;(C)=0 tiếp tục hiển thị RET Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 32 ;======================================================== SW2_DISP: MOV BAR_LED,#0 ;mã tối đèn CALL DELAY_500M ;delay 0.5s JC QUIT ;(C)=1 có SW nhấn,thoát MOV BAR_LED,#0FFH ;mã sáng đèn CALL DELAY_500M ;delay 0.5s JNC SW2_DISP ;(C)=0 không có SW nhấn,tiếp tục hiển thị QUIT: RET ;========================================================== DELAY_500M: MOV R2,#10 LOOP1: MOV R3,#100 LOOP2: MOV R4,#125 ;500us=125x4MC CHK_C: JC EXIT_DL ;2MC DJNZ R4,CHK_C ;2MC DJNZ R3,LOOP2 DJNZ R2,LOOP1 EXIT_DL: RET ;==================================================================== EX1_ISR: PUSH ACC ;cất (A) WAIT: MOV R7,#50 ;đếm 50 lần chống rung SW AGAIN: CALL SW_CHK ;đọc trạng thái SW JC WAIT ;(C)=1 SW chưa nhả, đọc lại từ đầu DJNZ R7,AGAIN ;đọc lại 50 lần chống rung khi nhả SETB C ;báo có SW nhấn trước khi thoát POP ACC ;lấy lại (A) RETI END Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 33 BT7.13: Thiết kế mạch đo độ rộng xung vuông từ 10-255μs,hiển thị giá trị HEX độ rộng xung ra LED 7 đoạn.Khi SPI thu được ký tự CR=0DH,sẽ phát ra SPI mã ASCII giá trị HEX đo được. Trường hợp độ rộng xung >255μs,sẽ hiển thị ký hiệu -- báo tràn và SPI sẽ phát ra ký tự báo tràn OV khi thu được ký tự CR.Các hoạt động trên xảy ra tức thời và liên tục. Cho SPI làm việc mode UART 8 bit,BR=1200,Fosc=12Mhz. Giải: • Timer1 tạo baudrate→Timer0 đo độ rộng xung điều khiển ngoài GATE=1,mode 2,định thì • Xung đo độ rộng đưa vào chân /INT0=P3.2: cạnh lên/xuống chạy/dừng Timer0 • Ngắt /INT0 tác động cạnh xuống để đọc giá trị đo và reset Timer0,xóa cờ báo tràn OV_FLG=0,nếu bộ đếm Timer0 chưa tràn(nhận dạng bằng ngắt Timer0 dừng đếm TR0=0) • Ngắt Timer0 ưu tiên cao: khi Timer0 đếm tràn xảy ra trước khi xuất hiện cạnh xuống,thực hiện dừng Timer0,xóa bộ đếm và đặt cờ báo tràn OV_FLG=1.Đặt ngắt Timer0 ưu tiên cao để xử lý báo tràn khi độ rộng xung =256μs,Timer0 tràn đồng thời điểm cạnh xuống xung,2 ngắt Timer0 và /INT0 xảy ra cùng thời điểm • Ngắt SPI thu ký tự và kiểm tra nếu đúng mã CR=0DH sẽ phát mã ASCII giá trị đo.Nếu cờ báo tràn OV_FLG=1 sẽ phát ký tự báo tràn OV • Chương trình chính liên tục hiển thị giá trị HEX độ rộng xung/hoặc ký tự báo tràn -- nếu cờ báo tràn OV_FLG=0/hoặc 1(xem lại CTC DISPLAY ở chương 4) Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 34 v Thiết kế phần cứng • Khối hiển thị sử dụng 2 mạch chốt U2,U3=74HC573 và LED AC • Tín hiệu mở chốt LE0=P2.0 LE1=P2.1(xem lại chương 4) • Sử dụng Virtual Terminal(UART 8 bit,BR=1200)mô phỏng thu ký tự từ bàn phím và phát ký tự ra SPI.
Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 35
vChương trình OUTPORT EQU P1 CR EQU 0DH OVF EQU 0BFH LE0 BIT P2.0 LE1 BIT P2.1 OV_FLG BIT 00H ORG 0 JMP MAIN JMP EX0_ISR ;điểm vào ISR ?INT0 ORG 000BH ;điểm vào ISR Timer0 ;======================================== T0_ISR: CLR TR0 ;Timer0 tràn,dừng Timer0 SETB OV_FLG ;set cờ báo tràn MOV TL0,#0 ;xóa bộ đếm Timer0 RETI ;======================================== ORG 0023H ;điểm vào ISR SPI JMP SPI_ISR ORG 0030H MAIN: MOV SP,#5FH MOV SCON,#50H ;SPI UART 8bit cho phép thu MOV TMOD,#2AH ;Timer1 mode 2 tạo BR,Timer0 mode 2 định thì đk ngoài MOV TH1,#-26 ;BR=1200 MOV TL1,TH1 Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 36 SETB TR1 CLR LE0 ;khóa chốt hiển thị CLR LE1 MOV IE,#93H ;cho phép ngắt /INT0,Timer0,SPI SETB IT0 ;ngắt /INT0 tác động cạnh xuống SETB PT0 ;ngắt Timer0 ưu tiên cao SETB TR0 ;Timer0 sẳn sàng chạy CLR OV_FLG ;xóa cờ báo tràn START: JNB OV_FLG,DISP ;chưa tràn hiển thị giá trị đo MOV OUTPORT,#OVF ;tràn hiển thị ký tự -- SETB LE0 SETB LE1 CLR LE0 CLR LE1 JMP START DISP: MOV A,R2 ;lấy giá trị đo CALL DISPLAY ;hiển thị JMP START ;=================================================== DISPLAY: MOV DPTR,#TAB ;DPTR trỏ đầu bảng tra PUSH ACC ;cất data ANL A,#0FH ;lấy nibble thấp MOVC A,@A+DPTR ;lấy mã 7 đoạn tương ứng MOV OUTPORT,A ;xuất mã 7 đoạn
Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 37
SETB LE0 ;hiển thị số HEX thấp CLR LE0 POP ACC ;lấy lại data SWAP A ;hoán vị ANL A,#0FH ;lấy nibble cao MOVC A,@A+DPTR ;lấy mã 7 đoạn tương ứng MOV OUTPORT,A ;xuất mã 7 đoạn SETB LE1 ;hiển thị số HEX cao CLR LE1 RET ;===================================================== OUT_CHR: PUSH ACC ;cất data SWAP A ;hoán vị ANL A,#0FH ;lấy nibble cao CJNE A,#0AH,$+3 ;so sánh với 0AH JNC GT0 ;>=0AH ký tự chữ ADD A,#30H ;<0AH ký tự số,chuyển sang mã ASCII JMP PHAT0 GT0: ADD A,#37H ;chuyển sang mã ASCII ký tự chữ PHAT0: JNB TI,$ ;chờ phát xong CLR TI ;xóa TI MOV SBUF,A ;phát ký tự POP ACC ;lấy lại data ANL A,#0FH ;lấy nibble thấp CJNE A,#0AH,$+3 ;so sánh với 0AH Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 38 JNC GT1 ;>=0AH ký tự chữ ADD A,#30H ;<0AH ký tự số,chuyển sang mã ASCII JMP PHAT1 GT1: ADD A,#37H ;chuyển sang mã ASCII ký tự chữ PHAT1: JNB TI,$ CLR TI MOV SBUF,A RET ;======================================================= EX0_ISR: JNB TR0,EXIT_EX0 ;TR0=0 Timer0 tràn,thoát MOV R2,TL0 ;lấy giá trị đếm MOV TL0,#0 ;xóa bộ đếm CLR OV_FLG ;xóa cờ báo tràn EXIT_EX0: SETB TR0 ;cho Timer0 sẵn sàng chạy RETI ;======================================================= SPI_ISR: PUSH ACC ;cất data JBC TI,EXIT_SPI ;TI=1 ngắt phát xóa TI,thoát CLR RI ;ngắt thu,xóa RI MOV A,SBUF ;thu ký tự CJNE A,#CR,EXIT_SPI ;ký tự khác CR thoát SETB TI ;cho phép phát JNB OV_FLG,T_PULSE ;cờ báo tràn=0 phát giá trị đo JNB TI,$ ;cờ báo tràn=1 phát ký tự OV CLR TI Hướbg Dẫn Giải Bài Tập Chương 7 VXL - Lưu Phú 39 MOV SBUF,#"O" JNB TI,$ CLR TI MOV SBUF,#"V" JMP EXIT_SPI T_PULSE: MOV A,R2 ;lấy giá trị đo CALL OUT_CHR ;phát giá trị đo EXIT_SPI: POP ACC ;lấy lại data RETI ;======================================================= TAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,88H,83H,0C6H,0A1H,86H,8EH END