Giải toàn bộ đề thi vi xử lý vấn đáp Đại học Bách khoa Hà Nội 8051 vi xử lý đại học bách khoa viện Điện Điều khiển và Tự động hoá vi điều khiển 8051 Giải bài tập vấn đáp cuối kì Vi Xử Lý ĐHBK Hà Nội
Trang 1Bài tập vi xử lý ôn thi cuối kì Điều khiển và tự động hoá
Nguyễn Tiến Hoàng- DK-TDH -5 K62
;Bài 1: cong 2 so n byte luu ket qua vao
push 00H; cat giu r0
push 01H; cat giu r1
push 02H; cat giu r2
mov r0,#DC_so1; con tro r0 tro toi byte cua So I
mov r1,#DC_so2; con trỏ r1 trỏ tới byte của Số II
mov r2,#sobyte ; so lan lap
clr c; xoa co nho c
Chuong_trinh_cong:
mov a,@r0; nạp byte số hạng thứ nhất mà r0 trỏ tới vào A đển thực hiện cộng A=R0
addc a,@r1; cộng có nhỏ A=A+r1+C=r0+r1+c
mov @r0,a; cập nhật lại kết quả vào byte của số hạng thứ nhất
dec r0; giảm nhớ trỏ xuống ô nhớ thấp hơn để thực hiện vòng tiếp
dec r1; giảm ô nhớ trỏ xuống ô nhớ thấp hơn để thực hiện vòng tiếp
djnz r2,Chuong_trinh_cong; giảm r2 rồi nhảy về chương trình cộng
Trang 2Pop 00H; lay lai du lieu tu ngan xep
; Input R1=dia chi dau;
; r2 dia chi cuoi
ORG 00H; reset
LJMP Main
ORG 30H; tranh phan ngat
Main:
; SBR: dao dau n byte
; Input : R1 = dia chi dau, R2 = dia chi cuoi
; thay doi : none
;r1 la dia chi dau
; r2 la dia chi cuoi
tinhdodai:
mov a,r2 ; nap dia chi cuoi vao a
subb a,r1 ; tru dia chi cuoi cho dia chi dau R2-R1
add a, 1 ; cong theo 1 ra do dai cua so
mov r3,a ; nap vao r3
doi_sang_ma_bu_2:
mov a,@r1 ; nap gia tri dau vao a
cpl a ; dao dau a(ma bu 1)
add a, 01h ; cong them 1 ra ma bu 2
mov @r1,a ; nap vao r1
inc r1 ; tang den gia tri tiep theo
djnz r3,tran ;lap cho den khi het do dai cua so
Trang 3ORG 30H; tranh khoi chuong trinh
mov a,@r1; A= byte ma A tro den
mul ab; nhan A voi B byte cao luu vao B byte thap luu vao A
mov 52H,a; cat byte thap vao 50H
mov 51H,b; cat byte cao cao 51H
dec r1; giam R1 để r1 tro vao byte MSB cua so 2byte
; nhan R0 voi byte MSB
mov b,r0; thiet lap lai B=R0
mov a,@r1; thiet lap A=MSB 2
mul ab; nhan lain nhu truoc
ADDC a,51H; A=LSB byte2*r0+C+nd 51H
MOV 51H,a; cat bye LSB cua ket byte 2*R0 vao 51H
MOv A,B; A=MSB r0*byte
ADDC a,#0; cong co nho A= MSB r0*byte2+C( neu tran)
MOV 50H,a; cat byte msb r0*byte2 MSB vao 50H
END
; neu thay r0 bang dptr
; thi bai toan tro thanh nhan 2 so
; 2 byte
; cach giai quyet
; tach ra thanh 2 so 1 byte nhan
; voi so 2 byte
; roi nhan ra tuong tu nhu tren
Trang 4Bài 4 Dịch một số m byte của bộ nhớ trong, n vị trí theo cách của lệnh RL
; so m byte vd m=3:msb 8 bit 8 bit 8bit msb
; n vi tri vd n=3 ➔ dich 2 bit
mov r0,#32H; khởi tạo giá trị dịch msb 32H
mov r7,#3; số byte cần dịch ở đây là 3 byte do 20H 21H 22H
mov r6,#2; nap bo dem so bit can dich vi du o day la 2
chuong_trinh_dich 1 bit 1:
mov a,@r0; nap gia tri R0 chua byte tut hap den cao cua so can dich
rlc a; dich phai 1 byte co co nho
mov 40H,A; 40H la la o nho trung gian
mov @r0,40H ;; @r0=A= gia tri sau khi dich 1 byte
Trang 5dec r0; giam con tro r0 de tro den byte cao hon
djnz r7,chuong_trinh_dich_1_bit r7 la do dai cua so can dich theo byte: sau 1 lần dịch xong ; 1 byte thì phải giảm r7
; sau khi xong thực hiện xong chương trình dịch 1 bit tất cả các byte thì ta phải khởi tạo lại các
; giá trị khởi đầu lưu để dịch tiếp bit tiếp theo lưu ý là r7 số byte là giữ nguyên và r6 thì số bit ;
; phải giảm đi 1 vì đã dịch 1 bit
MOV R0,#32H; cho R0 tro la LSB 32H
mov R7,#3; thiet lap lai do dai la 3 byte 30H 31H 32H
Djnz R6,chuong_trinh_dich_1_bit; giam bit di
Mov r0,#30H; nạp con tro 10 so 1 byte 30H 31H…………39H
Mov r7,#10; nap bo dem có 10 số 1 byte
Mov r2,#0; o luu gia tri trung binh (x1+x2+ x10)/10
Trang 6Mov r3,#0; luu gia tri du
Lap: ;;; muc tieu chia tung so x/10 lay thuong va du sau lai cộng tất cả dư vào rồi lại chia cho 10
;;; lấy thương tìm được cộng với thương kia ra kết quả
Mov a,@r0; gan gia tri ma r0 tro den vao a
Mov b,#10; co 10 so nen gan b bang 10
Div ab; chia a cho b thuong luu vao a, dua luu vao b
Add a,r2; AA+R2 lương thương vào r2 nhưng để thực hiện phép cộng thì lại phải dùng A Mov r2,A; r2=A cap nhat lai r2
Mov a,b; lay so du luu vao a lấy số dư lưu vào A
Add A,r3; R3+A cong cac phan so du lai
Mov r3,A; luu lai so du cap nhat vao a
Inc r0; tang con tro tro den so tiếp theo
Djnz r7,lap; giam van hay cho den khi bang khong thi khong nhay nua tức là đủ 10 lần
Mov B,#10; luu lai b =10 de chia
Div ab; luc nay a dang la tong cac phan du
Add a,R2; cộng thương ban đầu+ với thương của tổng các số dư cho 10
Mov r2,a; cap nhat lai gia tri chia vao r2
Mov a,@r1; nap con tro dem tu r1 la o chua dia chi dau
Xlr a,B; phep toan xor : giong nhau thi a=0 con khac nhau thi a=1
Trang 7Inc r1; tang bien con tro de tro toi o tiep theo
Cjne a,#0, khong_tim_duoc; neu khong bang 0=1 thi nhay =0 thi khong nhay
Inc r7; =0 thi tang bien dem len tim duoc
MOV R0,#10; biến đếm vi can phat 10 xung
SETB P1.1;;;;;; dau tien cho P1.1 bang khong de xung chua phat voi
Trang 8n equ 20; khai bao hang ở giả sử có 20 byte
mov dptr,#8000H; nạp giá trị con trỏ dptr tại ô dầu tiên
mov r7,#n; n vào r7 tức r7 chứa số byte cần phải xoá
mov A,#0; clear A
truòng hợp n>65536 thì ta có thể phối hợp nhiều thanh ghi 8 bit
ví dụng cần xoá n=510 byte ta có thể làm như sau
Trang 9mov r3,#0; luu 4 byte địa chỉ thấp dptr bcd
mov r4,#0; luu 4 byte địa chỉ thấp dptr đại chỉ sau khi đổi sang ascii
mov r0,#n; luu gia tri bien dem n
swap a; lenh dao 4 bit thap va 4 bit cao trong a
mov r2,a; lay 4 bit dau trong a vao r2
Trang 10BÀI 10: Đọc 16 byte từ ADC, cất vào bộ nhớ bởi R0
;Doc 16 byte ADC cat vao bo nho co dia chi bat dau bang R0
;P0: Du lieu doc tu ADC
;P2.2: CS - chan chon chip Tich cuc muc thap Báo hoạt động chip
;P2.1: RD - Tao xung tu 1->0 cho phep xuat du lieu ra từ ADC
;P2.0: WR - Tao xung 1->0 cho phep bat dau chuyen doi Tích cu
;P2.3:INTR – tích cực thấp là ngắt sau khi bộ chuyển đổi ADC đã chuyển đooi xong thì INTR lên 1
Trang 12mov P0,#0ffh; dat p2 làm cổng vào
clr P2.2; P2.2=CS là chân tích cực thấp chân chọn chip
; xoá đưa về mức thấp để ADC hoạt động
Loop:
setb P2.0;;;; đưa P2.0=WR
clr P2.0; đưa WR từ cao xuông thấp để bắt đầu chuyển đổi
Here: jb P2.3,here;;;;; chờ P2.3=INTR mức tích cực thấp chờ chân P2.3 lên 0
;; để báo rằng ADC đã chuyển đổi xong cần phải ngắt để đưa dữ liệu vào vi xử lý clr P2.1; P2.1=RD tích cực mức thấp cho phép xuất dữ liệu ra từ ADC
mov @R0,P0
inc R0;;;; tăng cpm trỏ R0 lên 1
setb P2.1;;;;; ngừng đưa dữ liệu vào vi xử lý RD=1
djnz R1,Loop
ABCD: jmp ABCD; nhảy tại chỗ để quan sát kết quả
end
Bài 11: Viết chương trình con cộng 10 số BCD, Kết quả ở dạng ascii
Input: r1 địa chỉ đầu, r3 độ dài
Output: r0 kết quả địa chỉ kết quả
Giải
Org 0000h
Ljmp main;; tranh khoi phan ngat
Trang 13Org 0030h
Main:
Sumhi equ 30h;;; luu byte cao cua ket qua
Sumlo equ 31h;;; luu byte thap cua ket qua
;;;;; 30H (x tram) 31H(chục đơn vị)
Clr A
Lap:
AddC a,@r1; cong A voi dia tri ma r1 tro den
Da A; luu y o day ta chi can dung da cho 31h ma khong can cho 30h
Jnc khongnho;;; neu khong nho thi nhay
Inc sumhi;; neu co nho thi tang byte cao len 1
Khongnho:
Inc r1
Djnz r3; giam do dai;;;; r3 là độ dài nên đã lưu sẵn là 10
Mov sumlo,A;;; luu byte thap vao A
Mov A, @r1; lay địa chỉ con trỏ R1 trỏ tới vào A
Swap A; dao byte cao nhat vao so dau
ANL A,#0Fh; xoa bo 4 bit dau
ADD A,#30H; tạo thành số BCD
Mov @r0,A;;; cap nhat A dia chi ma con tro R0 tro toi
Inc r0; tang con tro len 1
Mov A,@r1; gan lại nội dung r1 trỏ tới vào A
Trang 14Anl A,#0fh; lấy 4 bit thấp
ADD A,#30H;;; cộng vào để tạo số ASCII
MOV @r0,A;;; cập nhật A vào nd con trỏ r0 trỏ đến lúc trc r0 đã tăng lên 1 rồi nên nó đã trỏ
; tới ô tiếp theo
Inc R1; tăng r1 là chuỗi kết quả bcd để tiếp tục chu trình
Djnz R7,lap; chờ khi nào hết 2 lần là kết thúc do có 30H 31H
Movx @dptr,A; cap nhat lai thanh ghi dptr tro den sau khi dao
Inc dptr; tang con tro dptr len 1
Djnz r3,loop; choc hay het r3 roi ket thuc
Pop r3;
Pop dpl;
Pop dph;
Trang 15Pop A
End
BÀI 13: Chương trinh con tạo byte checksum của n byte trong bộ nhớ
;tao byte checksum cua n byte trong bo nho (n<65536)
;;; do dptr input vào các ô nhớ nên ta cần phải sử dụng dph và pdl
main: ;;; duoi day la phan khoi tao
push 02h;;; luu R2 vào ngăn xếp
push 03h; lưu r3 vào ngăn xếp
clr c;; xoá cờ nhớ
mov a,dpl; dpl đang ở giá trị thấp nhất
;tinh dia chi byte thu n(max) = dptr( thấp nhất) +do dai-1
add a,r2;;;
SUBB A,#1;;; cong them 1 de tim ra dia chi thu n
mov 31h,a ;luu byte thap dia chi cua byte thu n
mov a,dph; lưu vào A dịa chỉ byte cao
addc a,r3;;; cộng thêm r3 ra đại chỉ nếu byte thấp tràn nên phải có cờ nhớ
Trang 16add a,r0;;; r0 là nơi lưu tổng sum=r0 khong can nho
mov r0,a;;; cập nhật lại r0
inc dptr;;; tăng dptr lên
;kiem tra xem da den byte cuoi cung chua
mov a,dph;;;lưu byte cao vào A để thực hiện lệnh so sánh
cjne a,31h,checksum ;;; kiểm tra dph và dph max trong ô 31 xem nếu không
; bằng nhau thì nhảy về thực hiện tiếp
mov a,dpl;;; lưu dpl của dptr đang trỏ đến hiện thời vào A
cjne a,30h,checksum;;;; kiểm tra dpl với dpl lax xem có trung nhau không
; nếu không trùng nhau nhảy lại về checksum thực hiện tiếp
mov a,r0;;; nếu đã đạt đến giá trị giới hạn thì lưu tổng r0 vào A
;;;; lưu ý sum r0 ở đây là cộng không có nhớ
pop 03h;;; lấy dữ liệu ban đầu lưu trữ ở ngăn xếp ra
pop 02h
here: jmp here; nhảy tại chỗ để quan sát kết quả
end
BÀI 14: Đọc 10 byte từ cổng P1 theo chế độ có đối thoại
;;; câu này xem lại lý thuyết về cổng vào ra có đối thoại
;nhan 10 byte tu cong p1 theo che do co doi thoai;;;
;;; kết quả lưu vào bộ nhớ được trỏ bởi con trở dptr;;;;;;;;;;;
;P0.1 = IBF : Input Buffer Full: dau ra Q cua D-FF thong qua bo dem den Data bus
;P0.2 = STB : Strobe: Lam xung clock cua D-ff Tu 1-0 báo dữ liệu đã truyền đủ org 0000h
ljmp main;;; tránh chương trình ngắt
org 030h
main:
mov dptr,#1000h;;; nạp địa chỉ dptr
Trang 17wait: jb p0.2,wait;;;;; P0.2=STB tích cực mức thấp thì bắt đầu thực hiện tiếp ; còn nếu STB=1 thì cứ nhảy qua lại STB đóng vai trò là xung clock
setb p0.1;;;; P0.1=IBF=Q đầu ra của D flop flip khi IBF báo sáng thì
; tức là báo dữ liệu đã truyền qua latch
mov a,p1;;; đọc 1 byte từ cổng P1 vào A
movx @dptr,a ;;;; lấy dữ liệu A đọc được vào dptr
inc dptr;;; tăng con trỏ dptr lên để sau đọc byte tiếp theo
mov a,dpl;;;; lưu dữ liệu dpl thấp vào A
;;;;; do chỉ cần đọc 10 byte lên dptr 16 bit thì chỉ dùng đến 1 byte
;;;; để lưu 10
cjne a,#10,wait; nếu không bằng 10 thì quay lại thực hiện tiếp cho đủ
;;;; nếu đủ 10 byte thì tức là ta đã truyền xong
loop: jmp loop;;;; nhảy tại vị trí để quan sát
end
BÀI 15: Nhận một chuỗi ký tự từ cổng nối tiếp bắt đầu bởi ký tự #STX
;chuong trinh nhan chuoi ki tu tu cong noi tiep bat dau boi #STX, ket thuc boi
mov dptr,#1000H; nap con tro dptr
mov tmod,#20h ;Timer1 che do 2 đếm 16 bit
mov th1,#-3 ;Bauurate=9600 tạo tốc đọ band
Trang 18mov scon,#0101 0010b ;UART 8 bit che do 1 Scon SM0 SM1 SM2 REN TB8
;RB8 TI RI đóng khung chế độ 1 bit start data 1 bit stop;;;; va bat cờ ngắt truyền ;;
;; vì dang nhận nên không kích hoạt RI
Setb tr1; khởi động timer bắt đầu truyền dữ liệu
Kiemtradauvao:
jnb RI,$;;;; nhay tai cho den khi cờ ngắt nhận lên 1
mov a,sbuf;;; cat ky tu sbuf vao thanh ghi A
clr ri;;;; xoá cờ ngắt để nhận dữ liệu tiếp theo
cjne a,#STXh,Kiemtra ; neu không bằng STX thì nhảy về kiểm tra
;;; chờ đến khi nào nhận đúng kí tự STX mới qua
MOV @dptr,A;;; luu dư liệu từ A gửi ra bộ nhớ ngoài bằng dptr
INC DPTR; tăng con trỏ thêm 1
Nhan:;;;; neu nhan ky tu dau la STX thi tiep tuc kiem tra ki tu cuoi
jnb RI,$; nhay tai cho neu
Trang 19Phân tích bài toán sơ đầu f thạch anh-→ qua bộ chia 12
f/12=1MHZ→T=1/f=1us
f=50hz-→ cần 0.02s nên ck là 20000us
cần 20000 xung nhị đếm nhưng phải chia đôi vì chỉ cần nửa thôi:
20000/2=10000 xung nhịp đếm cho đến khi ngắt
10000 nhịp p1.5 bằng 1
10000 nhị p1.5 bằng 0
10000<65535 nên ta dùng timer 0 mode 1
Tính toán giá trị cần nạp 65535-10000+1=D8F0=10000Hex-10000dec=D8F0hex
Phân tích bài toán: Thạch anh tần số 12mhz ➔ tần số của timer: 1mhz ➔ thời gian để timer tang ORG 00H
LJMP ctrinh;
ORG 0BH;;;; chuong trinh ngat
Ljmp TM0_ISR; nhảy đến chương trình phục vụ ngắt của timer 0
0rg 0100H
Setb P1.5;
Mov TMOD,#01H chọn timer 0 chế độ 1 đếm 16 bit
MOV IE,#1000 0010b; EA – ET2 ES ET1 EX1 ET0 EX0;
Mov TH0,#0D8H:
MOV TL0,#0F0H
SETb TR0; cho timer0 bắt đầu chạy
Loop: sjmp loop; nhảy tại chỗ chờ chương trình ngắt
TM0_ISR:
Mov TH0,#0D8H
Mov TL0,#0f0H
Setb Tr0 khởi động timer 0
Cpl P1.5; sau mỗi lần ngắt thì đảo bit cpl p1.5
Reti
Trang 20end
Bài 17: tìm địa chỉ offset của 1 số 1 byte cho trước trong miền nhớ địa chỉ 1000H đến 2000H; giải quyết trường hợp không tìm thấy tìm thấy được nhiều số
Ví dụ byte trong B có giá trị là #54H
Cần tìm trong miền nhớ địa chỉ từ 1000H đến 1200H các ô nhớ có giá trị 54H
Sau đó lấy nội dung ô nhớ trừ đi 1000H ra địa chỉ offset
JNZ NEXT; A khác 0 thì nhảy tới Next
;;; còn A=0 tức là tìm được offset
INC R3 ; tăng số offset tìm được
MOV A,dph
Clr c
Subb A,#10H
Mov @r0,A; lưu địa chỉ offset tìm được
INC R0; tăng con trỏ r0 lên
MOV A,DPL; lay byte thấp dptr vào A để thực hiện lệnh tính toán
Clr c;;; clr vì lệnh subb có cờ nhớ
Subb A,#00H
Trang 21MOV @r0,A; lựu địa chỉ byte thấp vào ô tiếp theo lúc này r0 đã tăng lên 1
INC R0; tăng con trỏ lên tiếp ô tiếp theo
BÀI 18: Điều khiển cổng P2 thành cổng ra chế độ đối thoại
;Chuong trinh dieu khien cong ra P2 cua mcs-51 thanh cong ra co doi thoai
;P1.0 OBF: tich cuc muc cao:Output Buffer Full: duoc setb khi du lieu da san sang
Trang 22clr P1.0; xoa OBF ve vi tri ban dau vi OBF là cổng vào I/O cho biết
;;;; khi OBF lên 1 thì cho biết dữ liệu đã sẵn sàng
movx a,@dptr;;; A làm trung gian
mov p2,a;;;; @dptr -A—P2
setb P1.0; bật OBF lên cho biết dữ liệu đã sẵn sàng
Wait: jb P1.1,Wait; chờ cho đến khi ACK từ 1 xuống 0 thì báo đã chốt dữ liệu qua
;; latch và nhận dữ liệu vào I/O lúc
inc dptr; tăng con trỏ lên để trỏ vào byte dữ liệu tiếp theo
mov a,dpl;;;
cjne a,#10,start; cho đến khi chưa bằng 10 thì tiếp tục quay về thực hiện tiếp
Trang 23loop: jmp loop; nhảy tại chỗ xem kết quả
Phân tích bài toán
SBUF là thanh ghi 8 bit được dùng cho truyền thông nối tiếp của 8051 Để byte dữ liệu đường truyền qua đường TxD thì cần đặt dữ liệu trong thanh ghi SBUF Tương tự, SBUF lưu một byte
dữ liệu khi nó được nhận qua đường RxD của 8051 SBUF có thể được mọi thanh ghi của 8051 truy cập xem ví dụ sau:
MOV SBUF,#”D”; Nạp 44H ( mã aSCII của “D” vào thanh ghi SBUFF
MOV SBUF,A; sao thanh ghi A vào SBUF
MOV A,SBUF; sao SBUF vao fthanh ghi A
Mov r2,#100; phai nhận 100 100 xung
Mov TMOD,#0010 0000b; chon timer 1 che do 2 dem 8 bit tu nap lại dùng trong truyền thông ;
;; nối tiếp
Mov th1,#-3; tao toc do baud =9600
MOV SCON,#0101 0010b; chon mode 1 ren=1,t1=1 ngat truyen co duoc bat de vi xu
ly ;;biet ;;;rang san sang de nhan bit tie che do mode 1 co 8 bit du lieu 1 start 1 stop
Setb tr1; cho timer1 chay để khởi động truyền