Khi gặp lệnh RET CPU sẽ thực hiện công việc gì
Full PDF PackageDownload Full PDF Package This Paper A short summary of this paper 37 Full PDFs related to this paper Download PDF Pack
Trong chương trình học ngành Công nghệ Kỹ thuật Điện, Điện tử, sinh viên sẽ được học 6 tín chỉ về Vi xử lý, bao gồm: 1. Vi xử lý 1 2. Vi xử lý 2 3. Thực hành Vi xử lý & Vi điều khiển Các học phần này được học sau học phần Kỹ thuật số. Không chỉ là học phần cơ sở ngành, Vi xử lý & Vi điều khiển còn có nhiều ứng dụng thực tế. Đồ án môn học 2, các cuộc thi sáng tạo kỹ thuật và Robocon do khoa tổ chức cũng gắn liền với môn học này. Có thể nói, đây là các học phần rất thú vị nhưng sinh viên cũng gặp nhiều khó khăn với nhiều khái niệm mới. Vi xử lý 1: Nội dung học phần Vi xử lý 1 bao gồm 2 phần chính: - vi xử lý 80x86 - vi điều khiển 8051 Phần đầu cung cấp cho các em các kiến thức cơ bản về kiến trúc hệ vi xử lý, cấu trúc và nguyên tắc hoạt động của CPU, tổ chức bộ nhớ và các thiết bị ngoại vi, cách mã hóa lệnh, các chế độ định địa chỉ, tập lệnh và cách viết chương trình cho 80x86, ngắt và truy nhập trực tiếp bộ nhớ DMA. Tiếp theo các em sẽ học về Vi điều khiển họ 8051. Đây là một họ vi điều khiển khá phổ biến và sinh viên dễ tiếp cận. Khi có kiến thức về họ vi điều khiển này, các em sẽ dễ dàng học về các họ vi điều khiển khác như PIC, AVR, v.v. Các em sẽ được học về cấu trúc, các chế độ định địa chỉ, tập lệnh, viết chương trình hợp ngữ cho vi điều khiển 8051. Ngắt và timer/counter cũng được giới thiệu cùng với một số bài tập ứng dụng. Để học tốt học phần này ngoài tài liệu, các em cần một số phần mềm hỗ trợ lập trình, mô phỏng như EMU8086, Pinnacle 52 (nên thay thế bằng Keil C để chạy tốt trên các bản Windows mới và được sử dụng nhiều trong thực tế) và Proteus.Download EMU8086: download Download Pinnacle 52: download Phần mềm Proteus (để mô phỏng): trang chủ Các em cần cài đặt các phần mềm đã giới thiệu, học cách sử dụng chúng. Tài liệu hướng dẫn sử dụng phần mềm thầy đã gửi link ở phần dưới. Các em nên làm một số ví dụ mẫu để biết quy trình sử dụng, sau đó làm các bài tập, học cách mô phỏng từng bước chương trình để kiểm tra so sánh giữa ý hiểu và kết quả thực tế. Một số vấn đề khi học phần vi xử lý 80x86 1. Cách mã hóa lệnh Qua cách mã hóa lệnh các em sẽ hiểu được cách thức một lệnh được viết dưới dạng mã nhị phân mà vi xử lý có thể hiểu được. Từ đó giúp các em hiểu rằng tất cả lệnh và dữ liệu trong hệ vi xử lý đều tồn tại dưới dạng nhị phân và tại sao khi đọc một chuỗi số nhị phân vi xử lý biết được phải làm gì. Các em không phải nhớ một lệnh, ví dụ MUL, có mã nhị phân là bao nhiêu mà cần hiểu một lệnh được xây dựng từ các trường nào? ý nghĩa của mỗi trường ra sao? Từ đó em biết cách mã hóa một lệnh gợi nhớ bất kỳ. Ví dụ, lệnh MOV AL, BL được mã hóa dưới dạng nhị phân thế nào? Tra trong tài liệu ta sẽ thấy lệnh MOV được mã hóa bởi một trường gồm 6 bit. Tiếp theo để chuyển dữ liệu vào thanh ghi AL, vậy AL được xác định bằng các trường nào? Chúng ta thấy có các trường hướng D (D=1 dữ liệu đi tới thanh ghi, D=0 dữ liệu đi từ thanh ghi), trường W (W=0: toán hạng byte, W=1 toán hạng word), trường REG gồm 3 bit dùng để xác định thanh ghi. Để xác định thanh ghi BL sẽ cần các trường MOD và R/M. Tra bảng ta sẽ thấy hai trường này kết hợp với nhau để tạo ra chế độ định địa chỉ thanh ghi để truy nhập đến BL. Với việc xác định như vậy, các em sẽ lần lượt xác định được giá trị của các trường và bit tương ứng từ đó biết được mã lệnh của cả lệnh. Sau khi mã hóa, cần gõ lệnh vào phần mềm, hợp dịch để kiểm tra mã nhị phân tương ứng của lệnh có đúng với cách tính toán không.
Vi xử lý 80x86 có tập lệnh rất lớn và các em không cần thiết phải học tất cả các lệnh. Điều các em cần học là học cách tra cứu và sử dụng một lệnh bất kỳ. Sau một quá trình làm các bài tập và ví dụ, các em sẽ tự nhớ một số lệnh hay được sử dụng. Trước tiên các em cần tổ chức các lệnh thành các nhóm lệnh cho dễ học, ví dụ nhóm lệnh di chuyển dữ liệu, nhóm lệnh số học, nhóm lệnh logic, nhóm lệnh rẽ nhánh chương trình, v.v. Với mỗi nhóm lệnh này cần liệt kê một vài lệnh. Với mỗi lệnh cần tìm hiểu cú pháp của lệnh bao gồm: mã lệnh, toán hạng (có bao nhiêu toán hạng, có thể sử dụng chế độ định địa chỉ nào), tác dụng của lệnh và ảnh hưởng lên các cờ thế nào. Với mỗi lệnh tài liệu đã giải thích rõ. Tuy nhiên, để thực sự hiểu và vận dụng được lệnh các em cần sử dụng phần mềm để kiểm chứng ý hiểu của mình. Lấy ví dụ muốn biết lệnh DIV có ý nghĩa gì và cách sử dụng như thế nào? Các em tra trong tài liệu sẽ thấy cú pháp của lệnh có dạng: DIV Toánhạng Lệnh này thực hiện chia 2 toán hạng. - Trường hợp Toánhạng kiểu byte, lấy nội dung thanh ghi AX chia cho toán hạng. Kết quả phần dư lưu trên AH, phần nguyên lưu trên AL - Trường hợp Toánhạng kiểu word, lấy nội dung thanh ghi DX AX chia cho toán hạng. Kết quả phần nguyên lưu trên thanh ghi AX, phần dư lưu trên DX. Để kiểm tra ý hiểu của mình có đúng không, các em cần làm một vài ví dụ nhỏ để kiểm tra kết quả trên phần mềm. Nếu kết quả trùng với suy đoán thì em đã hiểu hoạt động của lệnh. Ví dụ, trong trường hợp này, nếu ta nạp giá trị 102 vào thanh ghi AX và giá trị 100 vào thanh ghi BL thì kết quả phép chia DIV BL sẽ phải cho thanh ghi AH giá trị 2 và AL giá trị 1. Viết đoạn lệnh sau: org 100h mov ax,102 mov bl,100 div bl Dịch và thực hiện lệnh từng bước. Sau khi thực hiện xong lệnh DIV, nếu thanh ghi AH và AL cho cùng giá trị như suy đoán thì ta đã hiểu đúng sự thực hiện của lệnh. Một số vấn đề khi học vi điều khiển 8051 1. Sự khác biệt giữa Vi xử lý và Vi điều khiển? Vi xử lý (microprocessor) là một chip chứa thành phần trung tâm của một hệ vi xử lý: CPU. Để hệ vi xử lý có thể hoạt động được thì một mình chip vi xử lý là chưa đủ. Hệ thống cần bổ xung các thành phần khác như bộ nhớ, các thiết bị vào ra và mạch phụ trợ. Chính vì vậy mà việc thiết kế hệ thống rất linh hoạt, đáp ứng cho các hệ thống từ đơn giản đến phức tạp với dung lượng bộ nhớ thay đổi, số lượng thiết bị ngoại vi thay đổi. Các chương trình thường được lưu trữ trong bộ nhớ ngoài và được tải vào RAM để hoạt động. Các chương trình điều khiển các thành phần trong hệ thống có dung lượng nhỏ và thường ít thay đổi mới được lưu trong bộ nhớ ROM. Các hệ thống xây dựng dựa trên chip vi xử lý cũng thường có khả năng mở rộng để thêm các tính năng mới phù hợp với người sử dụng. Việc xây dựng các hệ thống dựa trên chip vi xử lý thường khá phức tạp và thường là các hệ đa mục đích với khả năng tính toán, xử lý dữ liệu nhanh. Khác với vi xử lý, vi điều khiển (microcontroller) là một hệ thống trên chip (system on chip), nghĩa là bên trong một chip đã tổ hợp sẵn không chỉ bộ vi xử lý mà còn tích hợp cả bộ nhớ, mạch ngoại vi phụ trợ. Hệ thống xây dựng dựa trên chip vi điều khiển thường đơn giản hơn rất nhiều so với hệ thống xây dựng dựa trên vi xử lý. Hệ thống dựa trên vi điều khiển thường đáp ứng cho một nhiệm vụ cụ thể khi được xây dựng. Chúng thường là các hệ thống điều khiển có yêu cầu tính toán xử lý dữ liệu không đòi hỏi tốc độ và khối lượng lớn ví dụ như máy giặt, lò vi sóng, VCR, v.v. Hệ thống dựa trên vi điều khiển thường có kích thước nhỏ, tiêu tốn ít năng lượng và giá thành thấp hơn so với hệ thống dựa trên vi xử lý. Chương trình được lưu trữ trong bộ nhớ chương trình ROM. Đối với sinh viên ngành điện tử, việc tiếp cận với vi xử lý thông qua chip vi điều khiển thường dễ dàng hơn trong việc tự xây dựng một ứng dụng thực tế hoàn chỉnh, giá thành thấp.
Để mạch này có thể hoạt động được thì vi điều khiển cần được nạp một chương trình. Sau đây là một chương trình ví dụ để điều khiển led đơn nối với chân P1.0 nhấp nháy: org 0 loop: cpl P1.0 call delay jmp loop delay: mov r6,#250 dl1: mov r7,#250 djnz r7,$ djnz r6,dl1 ret end Soạn thảo chương trình này trên Pinnacle 52, lưu vào ổ cứng với tên ví dụ là "nhapnhay.asm". Dịch và mô phỏng để kiểm tra hoạt động (xem tài liệu hướng dẫn sử dụng phần mềm Pinnacle 52 trong link bên dưới). Sau khi dịch chương trình, phần mềm sẽ tạo ra một file cùng tên có đuôi .hex, ví dụ "nhapnhay.hex". File này có thể sử dụng để nạp vào vi điều khiển. Trước tiên các em nên vẽ mạch trên phần mềm Proteus để mô phỏng hoạt động, sau đó lắp ráp mạch trên board cắm. Sử dụng bộ nạp (nếu chưa có bộ nạp thì nhờ thầy hoặc các bạn) nạp file "nhapnhay.hex" đã tạo ra ở bước trên vào vi điều khiển. Lắp ráp mạch, cấp nguồn và kiểm tra hoạt động của mạch thực tế. Như vậy các em đã hoàn thành một mạch đơn giản ứng dụng vi điều khiển. Qua công việc này, các em sẽ hiểu được quy trình làm việc với vi điều khiển và quan trọng hơn là thấy được sự thú vị của vi điều khiển. Để có hứng thú và trực quan hơn các em nên sử dụng thêm phần mềm Protues, đây là phần mềm cho phép mô phỏng các vi điều khiển khá trực quan.
Như vậy, trong chế độ định địa chỉ tức thời thì giá trị của toán hạng được chỉ ra và nằm sau mã lệnh. - Chế độ định địa chỉ trực tiếp. Ví dụ: MOV A, 10 ;di chuyển nội dung ô nhớ có địa chỉ bằng 10 trong RAM trong vào thanh ghi A. Sau lệnh này thanh ghi A có giá trị bằng nội dung ô nhớ trong RAM trong có địa chỉ bằng 10.Trong chế độ định địa chỉ trực tiếp, địa chỉ của toán hạng được chỉ ra sau mã lệnh. - Chế độ định địa chỉ thanh ghi Ví dụ: MOV A, R0 ; di chuyển nội dung thanh ghi R0 vào thanh ghi A. Sau lệnh này, thanh ghi A có giá trị bằng nội dung thanh ghi R0.Trong chế độ định địa chỉ thanh ghi, toán hạng là một thanh ghi từ R0-R7. - Chế độ định địa chỉ gián tiếp Ví dụ: MOV A, @R0 ; di chuyển nội dung ô nhớ trong RAM trong có địa chỉ là nội dung của thanh ghi R0 vào thanh ghi A.Trong chế độ định địa chỉ gián tiếp, địa chỉ của toán hạng được xác định gián tiếp thông qua một thanh ghi.Các thanh ghi được sử dụng để định địa chỉ gián tiếp bao gồm: R0, R1 và DPTR - Chế độ định địa chỉ chỉ số thanh ghi: Ví dụ: MOVC A, @A+DPTR ;di chuyển nội dung ô nhớ trong ROM có địa chỉ xác định bởi tổng 2 thanh ghi A và DPTR vào thanh ghi A.Trong chế độ định địa chỉ chỉ số thanh ghi, địa chỉ của ô nhớ trong ROM được xác định thông qua nội dung hai thanh ghi A và DPTR (hoặc PC). Ngoài ra, có một chế độ định địa chỉ đặc biệt thanh ghi. Ví dụ hai lệnh MOV A, #10 và MOV Acc, #10 cho cùng kết quả là thanh ghi Acc có giá trị bằng 10 nhưng khi dịch ra mã máy thì khác nhau về dung lượng. Lệnh thứ nhất có dung lượng 2 byte trong khi lệnh thứ hai có dung lượng 3 byte. Trong ví dụ trên toán hạng A được gọi là định địa chỉ đặc biệt thanh ghi trong khi toán hạng Acc được định địa chỉ trực tiếp. Các chế độ định địa chỉ được sử dụng để truy nhập đến các vùng nhớ khác nhau. Có thể tổng kết như sau: - RAM trong có 3 chế độ định địa chỉ có thể truy nhập tới là: trực tiếp, thanh ghi và gián tiếp - RAM ngoài có duy nhất chế độ định địa chỉ gián tiếp sử dụng lệnh MOVX - ROM có chế độ định địa chỉ duy nhất là chỉ số thanh ghi, sử dụng lệnh MOVC A, @A+DPTR hoặc MOVC A, @A+PC - SFRs có chế độ định địa chỉ trực tiếp Phân biệt giữa truy nhập giữa RAM trong và SFRs ở chế độ định địa chỉ trực tiếp là RAM trong có địa chỉ từ 0-7FH trong khi SFRs có địa chỉ từ 80H-0FFH
Timer/counter hoạt động với chức năng timer khi nguồn xung là dao động bên trong. Số đếm của timer tăng 1 đơn vị tương ứng với 1 chu kỳ máy của vi điều khiển (12 chu kỳ xung nhịp). Như vậy số đếm của timer tăng liên tục, thời gian giữa các số đếm là bằng nhau. Timer/counter hoạt động với chức năng counter khi nguồn xung đưa tới bộ đếm từ bên ngoài (đưa tới chân P3.4 đối với timer/counter0 và P3.5 đối với timer/counter1). Số đếm của counter tăng 1 đơn vị khi có xung đưa tới đầu vào counter. Như vậy số đếm của counter chỉ tăng lên khi có xung tác động tới các chân đầu vào. Để điều khiển hoạt động của timer/counter cần tác động lên các thanh ghi TMOD, TCON, TLx và THx (x=0, 1 tương ứng với timer/counter 0 và timer/counter 1). TMOD là thanh ghi 8 bit, cho phép truy nhập ở mức byte, trong đó 4 bit cao (từ bit 3 đến bit 7) là các bit điều khiển timer/counter1 và 4 bit thấp (từ bit 0 đến bit 3) là các bit điều khiển timer/counter0. Do hai bộ timer/counter counter hoạt động giống nhau nên các bit điều khiển có chức năng giống nhau. Timer/counter có 4 mode hoạt động tương ứng với trạng thái của hai bit M1 và M0 trong thanh ghi TMOD. 4 mode này xác lập số đếm lớn nhất mà bộ đếm có thể đếm được. Để lựa chọn chức năng timer hay counter cần tác động lên bit C/T. Nếu C/T=0, timer/counter làm chức năng timer. Nếu C/T=1, timer/counter làm chức năng counter. GATE là bit lựa chọn điều khiển hoạt động của timer/counter bằng phần cứng hay phần mềm. Nếu GATE=0, điều khiển hoạt động của timer/counter bằng phần mềm, nghĩa là chỉ cần TRx=1 là timer/counter hoạt động. Nếu GATE=1, để timer/counter hoạt động (đếm) cần thêm điều kiện có chân P3.2 ( đối với timer/counter0) hoặc P3.3 (đối với timer/counter1) phải ở mức cao.TCON là thanh ghi 8 bit cho phép truy nhập ở mức bit. Bit TRx là bit cho phép timer/counter hoạt động hay dừng. Nếu TRx=0, timer/counter dừng hoạt động. Nếu TRx=1, timer/counter hoạt động hay dừng còn phụ thuộc vào trạng thái của bit GATE như trình bày ở phía trên. Bit TFx trong thanh ghi TCON là cờ tràn. TFx được tự động đặt lên 1 khi timer/counterx đếm tràn. Cờ TFx được xóa về 0 bằng phần mềm hoặc gặp lệnh RETI khi trở về từ chương trình phục vụ ngắt tương ứng. Nghĩa là TF0 được tự động xóa về 0 khi gặp lệnh RETI của chương trình phục vụ ngắt timer/counter0 và TF1 được tự động xóa về 0 khi gặp lệnh RETI của chương trình phục vụ ngắt timer/counter1.Các thanh ghi THx và TLx kết hợp thành các bộ đếm 16 bit, 13 bit hay 8 bit auto-reload phụ thuộc vào mode hoạt động được xác lập bởi các bit M1 và M0. Trong đó THx chứa các bit cao, TLx chứa các bit thấp. Hoạt động ở mode 0 (13 bit) và mode 1 (16 bit), khi timer/counter đếm tràn sẽ trở về đếm từ 0. Mode 2 (8 bit) có chức năng auto-reload, nghĩa là khi timer/counter đếm đến giá trị lớn nhất (255), khi đếm thêm một số đếm nữa thì timer/counter đếm tràn và trở về giá trị được đặt trước trong thanh ghi THx. Khi lập trình sử dụng timer/counter cần biết phải sử dụng bộ timer/counter nào. Khi sử dụng với chức năng timer thì thông thường có thể tùy chọn 1 trong 2 bộ timer. Tuy nhiên, khi sử dụng timer/counter với chức năng counter thì việc lựa chọn bộ counter0 hay counter1 là do tín hiệu đưa tới chân nào. Nếu tín hiệu đưa tới chân P3.4(T0) thì phải sử dụng bộ counter0, nếu tín hiệu đưa tới chân P3.5(T1) thì phải sử dụng bộ counter1. Khi sử dụng trong truyền thông nối tiếp để tạo tốc độ baud, timer0 được sử dụng. Ví dụ: chương trình tạo xung vuông có chu kỳ T=0.1 giây, độ rỗng 50% tại chân P1.0. Biết thạch anh sử dụng có tần số 12Mhz. Với yêu cầu này ta có thể sử dụng timer/counter0 hay timer/counter1 đều được với chức năng timer. Tần số thạch anh 12Mhz, như vậy trong 1 giây sẽ có 12.10^6/12 =10^6 chu kỳ máy. Vậy để đếm được 1 giây timer cần đếm được 10^6 số đếm (vì số đếm của timer tăng 1 đơn vị tương ứng với 1 chu kỳ máy). Xung vuông có chu kỳ T=0.1 giây, độ rỗng 50% vậy xung sẽ có 0.05 giây ở mức cao và 0.05 giây ở mức thấp. Để tạo được thời gian 0.05 giây, timer cần đếm được 0.05*(10^6)=50.000 số đếm. Ta có thể lựa chọn timer hoạt động ở mode 1 (số đếm lớn nhất là 2^16-1=65.535). Số đếm ban đầu của timer sẽ là: 65.536-50.000=15.536. Vậy khi timer đếm bắt đầu từ 15.536 trở lên đến khi đếm tràn sẽ đếm được 50.000 số đếm tương ứng với 0.05 giây. Với các phân tích ở trên ta có thể thiết lập timer như sau: - Sử dụng timer0 (có thể sử dụng timer1) - Mode hoạt động 1: M1=0, M0=0 - Chức năng timer: C/T=0 - Điều khiển bằng phần mềm: Gate=0 - Số đếm ban đầu của timer: 15.536=3CB0H, như vậy TH0=3CH, TL0 = B0H - Cờ tràn TF0 được xóa Chương trình có thể viết như sau:org 0 loop: cpl P1.0 call delay_0_05s jmp loop delay_0_05s: mov TMOD,#00000001B;timer0, mode 1, timer, gate=0 mov TH0,#high(15536) ;phần mềm sẽ tự động lấy byte cao của số 15.536 đưa vào thanh ghi TH0 mov TL0,#low(15536) ;phần mềm lấy byte thấp của 15.536 đưa vào thanh ghi TL0 clr TF0 ; xóa cờ tràn TF0 setb TR0 ; cho phép timer bắt đầu hoạt động jnb TF0,$ ;khi TF0 bằng 1 nghĩa là timer0 đếm đủ 50000 số đếm ret end Tất nhiên chương trình này chưa hoàn toàn chính xác do còn một số lệnh tiêu tốn thời gian nhưng không được tính, ta hoàn toàn có thể chỉnh sửa bằng cách thay đổi lại giá trị ban đầu nạp vào TH0 và TL0. 12. Ngắt Ngắt là cơ chế đặc biệt trong các hệ vi xử lý. Khi có một sự kiện xảy ra tại thiết bị ngoại vi (ví dụ như timer/counter đếm tràn hay truyền/nhận xong một ký tự) sẽ yêu cầu CPU tạm dừng công việc hiện tại để đáp ứng sự kiện này. Sự kiện ngắt thường không biết trước thời gian xảy ra, nhưng khi sự kiện xảy ra lại yêu cầu CPU phải đáp ứng nhanh nhất có thể. 8051 có 6 nguồn ngắt tương ứng với 5 vector ngắt. 6 nguồn ngắt bao gồm 2 ngắt ngoài INT0 (P3.2) và INT1 (P3.3), 2 ngắt timer/counter đếm tràn và 2 ngắt của cổng nối tiếp (ngắt truyền và ngắt nhận). Vector ngắt là địa chỉ bắt đầu của chương trình phục vụ ngắt trong bộ nhớ chương trình. Ứng với mỗi một sự kiện ngắt, CPU tạm thời dừng công việc hiện tại để thực hiện chương trình phục vụ ngắt tương ứng nằm tại các vị trí xác định trong bộ nhớ. Cụ thể: Ngắt Vector ngắt INT0 03H T0 0BH INT1 13H T1 1BH Serial 23H Nghĩa là nếu có xung đưa tới chân P3.2(INT0) và sự kiện này được xác lập là một sự kiện ngắt, CPU sẽ tạm dừng công việc hiện tại để thực hiện lệnh bắt đầu tại địa chỉ 03H. Mặc định CPU cấm tất cả các ngắt. Để xác lập một sự kiện là ngắt, thiết lập mức ưu tiên ngắt chúng ta phải tác động lên các bit trong các thanh ghi cho phép ngắt IE (Interrupts Enable), thanh ghi ưu tiên ngắt IP (Interrupts Priority). Khi lập trình bằng assembly, chúng ta phải nhớ tên và chức năng của từng bit trong các thanh ghi này. Thanh ghi IE là thanh ghi 8 bit, cho phép truy nhập ở mức bit. Trong thanh ghi này chứa các bit cho phép ngắt chung EA, các bit cho phép ngắt tương ứng với các nguồn ngắt cụ thể: EX0, ET0, EX1, ET1, ES. Để cho phép một ngắt ta phải cho EA=1 và bit cho phép ngắt tương ứng bằng 1. Ví dụ, để cho phép sự kiện timer/counter0 đếm tràn là một ngắt ta phải cho EA=1 và ET0=1. Khi 2 hoặc nhiều ngắt xảy ra sẽ nảy sinh vấn đề ngắt nào được CPU ưu tiên thực hiện trước. Về nguyên tắc, CPU chỉ thực hiện được 1 lệnh tại một thời điểm. 8051 có thanh ghi IP xác lập chế độ ưu tiên ngắt. Trong IP có các bit tương ứng với các ngắt là PX0, PT0, PX1, PT1 và PS. Khi các bit này ở mức cao thì ngắt tương ứng sẽ có mức ưu tiên cao và ngược lại. Ví dụ, đoạn chương trình sau sẽ xác lập cho phép 2 sự kiện được coi là ngắt là xung ngoài đưa tới chân P3.2 (INT0) và timer/counter1 đếm tràn. Trong đó ngắt timer/counter1 có mức ưu tiên cao (tức là được ưu tiên phục vụ trước).SETB P3.2 ; xác lập P3.2 là chân đầu vào SETB EA ;cho phép ngắt chung SETB EX0; cho phép ngắt ngoài INT0 SETB PT1 ;ưu tiên timer/counter1 ở mức cao CLR PX0 ;ưu tiên ngắt ngoài INT0 ở mức thấp Với việc xác lập như trên, khi chương trình phục vụ ngắt INT0 đang được phục vụ mà timer/counter1 đếm tràn thì ngắt INT0 tạm thời bị dừng lại để phục vụ ngắt timer/counter1. Sau khi chương trình phục vụ ngắt timer/counter thực hiện xong mới quay trở lại thực hiện tiếp chương trình phục vụ ngắt ngoài INT0. Trong trường hợp bit PX0 trong ví dụ trên cũng được đặt bằng 1 (nghĩa là ngắt ngoài INT0 cũng có mức ưu tiên cao) thì khi 2 ngắt xảy ra đồng thời thì CPU sẽ phục vụ ngắt nào? Việc căn cứ vào thanh ghi IP là không thể xác định được ngắt nào sẽ được phục vụ trước. Trong trường hợp này, CPU sẽ căn cứ vào thứ tự ưu tiên ngắt mặc định. 8051 quy định mức ưu tiên mặc định từ cao xuống thấp như sau: INT0->T0->INT1->T1->Serial. Mặc định, ngắt INT0 sẽ có mức ưu tiên cao hơn ngắt timer/counter1. Như vậy, ngắt INT0 trong trường hợp này sẽ được ưu tiên phục vụ trước. Cấu trúc chương trình phục vụ ngắt: khác với chương trình con có thể nằm tại vị trí bất kỳ trong bộ nhớ chương trình, chương trình phục vụ ngắt ứng với mỗi sự kiện ngắt nằm tại một vị trí xác định trong bộ nhớ. Do đó, cấu trúc chương trình phục vụ ngắt có sự khác biệt với chương trình con. Cụ thể, cấu trúc chung của chương trình phục vụ ngắt là: ORG Vector_ngắt Thân chương trình RETI Ví dụ, với chương trình phục vụ ngắt ngoài INT0 thì vector_ngắt sẽ được thay bằng địa chỉ 03H. Thân chương trình là tập hợp các lệnh của 8051 nhằm thực hiện công việc tương ứng với sự kiện ngắt. Ví dụ: chương trình đếm xung ngoài đưa tới chân P3.2(INT0), hiển thị số đếm từ 0-200 trên các led đơn nối với cổng P1. biendem equ 70h org 0 jmp start org 03h ;địa chỉ của chương trình phục vụ ngắt ngoài INT0 inc biendem ;tăng biến đếm 1 đơn vị mỗi khi có một ngắt (xung tác động tại sườn xuống) reti start: setb P3.2 ;xác lập cho chân P3.2 là đầu vào mov biendem,#0 mov IE,#10000001B; cho phép ngắt ngoài INT0 setb IT0 ;ngắt tích cực ở sườn xuống loop: mov a,biendem mov P1,a cjne a,#201,loop mov biendem,#0 ;xóa biến đếm khi số đếm bằng 201 jmp loop end Thông thường, các thanh ghi quan trọng được sử dụng nhiều như PSW, Acc được cất giữ để trạng thái của chúng không bị thay đổi khi thực hiện xong chương trình phục vụ ngắt so với trước khi thực hiện chương trình phục vụ ngắt. Để cất giữ các thanh ghi này ta sử dụng lệnh PUSH, để lấy lại nội dung của thanh ghi ta sử dụng lệnh POP. Một số lỗi rất khó phát hiện do nguyên nhân không cất giữ các thanh ghi này trong chương trình phục vụ ngắt.
MOV SCON,#01010000B Thanh ghi SBUF là thanh ghi đệm truyền và đệm nhận. Mặc dù chỉ có một tên nhưng thực chất đây là 2 thanh ghi, một thanh ghi đệm truyền và một thanh ghi đệm nhận. Khi ghi đến SBUF là truy nhập đến thanh ghi đệm truyền. Khi đọc từ thanh ghi SBUF là đọc từ thanh ghi đệm nhận. Dữ liệu truyền các bit có trọng số thấp trước, bit trọng số cao sau.Xác lập tốc độ baud: - Khi hoạt động ở mode 0 và mode 2, tốc độ baud được xác định dựa trên tần số thạch anh sử dụng. Trong mode 0, tốc độ baud luôn luôn bằng tần số dao động thạch anh chia 12. Điều này có nghĩa là nếu tần số thạch anh là 11,0592Mhz, khi hoạt động ở mode 0 tốc độ baud sẽ là 921.600 baud. Khi hoạt động ở mode 2, tốc độ baud luôn bằng tần số thạch anh chia 64. Ví dụ nếu sử dụng thạch anh tần số 11.0592Mhz, tốc độ baud sẽ là 11,0592*10^6/64=172.800. - Khi hoạt động ở mode 1 và mode 3, tốc độ baud được xác lập dựa trên tốc độ tràn của timer1. Tốc độ tràn của timer1 càng lớn thì tốc độ baud càng lớn. Thông thường timer1 được hoạt động ở chế độ auto-reload để tạo tốc độ baud trong đó thanh ghi TH1 sẽ chứa giá trị tái nạp cho TL1. Cũng cần lưu ý rằng khi sử dụng cổng nối tiếp thạch anh thường được sử dụng có tần số là 11,0592Mhz. Tần số này tạo ra các tốc độ truyền với sai số nhỏ. Ví dụ đoạn chương trình sau xác lập timer1 tạo tốc độ baud 9600 cho cổng nối tiếp UART, tần số thạch anh sử dụng là 11,0592Mhz.MOV TMOD,#20h ;Timer 1 hoạt động trong chế độ auto-reload MOV TH1,#0FDh ;Giá trị tái nạp cho timer1 khi đếm tràn MOV TL1,#0FDh ;giá trị đếm ban đầu của timer1 SETB TR1 ; Cho phép timer1 hoạt động Lưu ý, bit SMOD trong thanh ghi PCON nếu được đặt bằng 1 sẽ nhân đôi tốc độ baud của UART nếu timer1 được sử dụng để tạo tốc độ baud. Mặc định SMOD bị xóa về 0. 14. Điều chế độ rộng xung PWM Một số vi điều khiển 8051 như AT89C51RD2 hỗ trợ khối PCA hoạt động ở chế độ điều chế độ rộng xung. Điều chế độ rộng xung có thể được sử dụng trong điều khiển tốc độ động cơ một chiều. Sơ đồ khối của bộ PCA hoạt động ở chế độ PWM như sau:
Quan sát sơ đồ khối ta thấy rằng CCAPnH là thanh ghi đệm chứa giá trị độ rỗng của xung. CL là thanh ghi chứa số đếm của bộ PCA Counter/Timer. CCAPnL là thanh ghi chứa giá trị độ rỗng được lấy từ CCAPnH. Giá trị của CL và CCAPnL luôn được kiểm tra bởi bộ so sánh 8 bit. Khi CL
Để bộ so sánh hoạt động các bit ECOMn và PWMn phải đặt bằng 1.
Có thể viết lệnh như sau (ví dụ viết với bộ CCP0):
MOV A, CCAPM0
ORL A,#01000010B
MOV CCAPM0,A
MOV A, CMOD CLR ACC.1 CLR ACC.2 ;cho nguon xung Fclk/6 (CPS1=0,CPS1=0) MOV CMOD,A CLR CCON.7 ; cho phep timer hoat dong (CIDL=0) SETB CCON.6 ; CR=1 Mô phỏng tương tác kết hợp Keil C và Proteus Keil C là phần mềm phục vụ soạn thảo, dịch và mô phỏng cho các vi điều khiển 8051 và ARM. Phần mềm hỗ trợ viết chương trình bằng ngôn ngữ Assembly và C. Keil C được sử dụng phổ biến với số lượng IC hỗ trợ lớn. Proteus là phần mềm thiết kế mạch nguyên lý và mạch in. Một điểm mạnh của Proteus làm cho phần mềm này được sử dụng rộng rãi trong những năm gần đây là khả năng mô phỏng các họ vi điều khiển như 8051, PIC, AVR v.v. Không chỉ mô phỏng trực quan, Proteus còn có khả năng kết hợp với các phần mềm để mô phỏng ở mức lệnh. Để mô phỏng ở mức lệnh kết hợp giữa Keil C và Proteus làm theo các bước sau:- Bước 1: Cài đặt Proteus VSM Keil Driver (đường link download tại: http://www.labcenter.com/support/vdmkeil.cfm) - Bước 2: Thiết lập mô phỏng trong Keil C. Trong menu Project, chọn Options for target 'target1'.... Một cửa sổ hiện ra, chọn tab Debug, lựa chọn "Use: Proteus VSM Simulator".- Bước 3: Khởi động Proteus, mở file nguyên lý. Nháy chuột phải vào IC vi điều khiển, chọn file .hex Keil C đã tạo ra. - Bước 4: Trong menu Debug của Proteus, chọn Use Remote Debug Monitor - Bước 5: Mô phỏng từng bước trong Keil C, các lệnh sẽ chạy tương ứng trong Protues Video tạo một dự án mới cho vi điều khiển 8051 trong Keil C (viết bằng ngôn ngữ C): xem Một số trang web gợi ý một số dự án và hướng dẫn: http://www.8051projects.info/projects.asp http://8052.com/ http://www.mikroe.com/eng/products/view/267/architecture-and-programming-of-8051-mcu-s/ http://www.kmitl.ac.th/~kswichit/ Diễn đàn điện tử để trao đổi, tham khảo: http://www.dientuvietnam.net/forums/ Tài liệu tham khảo chính của môn học: [1]. Văn Thế Minh. Kỹ thuật Vi xử lý. NXB Giáo Dục. 1997 [2]. Nguyễn Tăng Cường, Phan Quốc Thắng. Cấu trúc và lập trình họ vi điều khiển 8051. NXB KHKT. 2003 Ngân hàng câu hỏi (download): Ngân hàng câu hỏi tham khảo Hướng dẫn sử dụng phần mềm EMU8086 (download): Hướng dẫn sử dụng phần mềm EMU8086 Hướng dẫn sử dụng phần mềm Pinnacle 52 (download): Hướng dẫn sử dụng Pinnacle 52 Hướng dẫn tạo một dự án với Keil uVision(download): Su_dung_keil_C.pdf Tài liệu tiếng Anh tham khảo thêm: [1]. B.Brey, B. The Intel Microprocessors, 8086/8088, 80186/80188, 80286, 80386, 80486, Pentium and Pentium Pro Processor Architecture, Programming, and Interfacing. Prentice-Hall, Inc, 1997
[2]. Ayala, K. J. The 8051 Microcontroller: Architecture, Programming, and Applications. West Publishing Company, 1991 Ví dụ bài tập cho 8086: 1. Viết chương trình tính tổng 2 số từ 0-9 nhập vào từ bàn phím. Hiển thị kết quả (download): Congso0_9 2. Viết chương trình tính tổng 2 số từ 0-99 nhập vào từ bàn phím. Hiển thị kết quả (download) Congso0_99 Ví dụ bài tập cho 8051:(Các bài tập viết và dịch bằng phần mềm Pinnacle 52) 1. Viết chương trình điều khiển các led đơn nối với cổng P1 và P2 sáng dần từ giữa ra 5 lần sau đó tắt dần 10 lần: sangdan_tatdan 2. Chương trình điều khiển led 7 nối với cổng P0 hiển thị số từ 0-9 (led 7 anode chung): hienthiso0_9 3. Chương trình đếm xung ngoài đưa tới chân P3.2(INT0) sử dụng ngắt ngoài: dem_xung_P3_2 4. Chương trình đếm xung ngoài đưa tới chân P3.4 (T0) sử dụng timer/counter với chức năng counter: counter0 5. Chương trình đếm xung ngoài đưa tới chân P3.4(T0) sử dụng timer/counter0 với chức năng counter. Hiển thị số đếm từ 0-45 trên 2 led 7 đoạn nối song song với cổng P0. Các led 7 đoạn loại anode chung. Hai chân P2.0 và P2.1 lần lượt điều khiển đóng ngắt hai transistor nối với chân anode của led hàng đơn vị và hàng chục:download 6. Chương trình tạo xung vuông có chu kỳ 0,1 giây. Thạch anh tần số 12Mhz. Sử dụng timer/counter0 với chức năng timer: xung vuong 7. Chương trình đếm giây từ 0-59, hiển thị giây trên 2 led 7 đoạn nối song song với cổng P0. Các led 7 đoạn loại anode chung. Hai chân P2.0 và P2.1 lần lượt điều khiển đóng ngắt hai transistor nối với chân anode của led hàng đơn vị và led hàng chục. Thạch anh tần số 12Mhz: demgiay 8. Chương trình truyền nhận dữ liệu nối tiếp: Truyen_nhan_noi_tiep Video hướng dẫn sử dụng phần mềm Proteus:
Video hướng dẫn tạo dự án trên Keil C viết bằng C (viết bằng ngôn ngữ Assembly thao tác tương tự):
Page 2
Trang chủ Vi xử lý 1 Vi xử lý 2 Chuyên đề công nghệ mới Về tôi ▼
|