Giáo trình Vi điều khiển (Phần 2) - Cao đẳng nghề Yên Bái

pdf 81 trang ngocly 3130
Bạn đang xem 20 trang mẫu của tài liệu "Giáo trình Vi điều khiển (Phần 2) - Cao đẳng nghề Yên Bái", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên

Tài liệu đính kèm:

  • pdfgiao_trinh_vi_dieu_khien_phan_2_cao_dang_nghe_yen_bai.pdf

Nội dung text: Giáo trình Vi điều khiển (Phần 2) - Cao đẳng nghề Yên Bái

  1. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Bài 4: BỘ ĐỊNH THỜI 1. Mở đầu Định thời là sự hoạt động để kiểm soát thời gian thực thi các câu lệnh trong quá trình xử lý của vi điều khiển. 8051 có hai bộ định thời/ bộ đếm. Chúng có thể được dùng như các bộ định thời để tạo một bộ trễ thời gian hoặc như các bộ đếm để đếm các sự kiện xảy ra bên ngoài bộ VĐK. Các timer này đều là timer 16bit, giá trị đếm được tính từ 0 đến 0xFFFF(đếm từ 0 đến 65535). Mỗi bộ Timer có 4 chế độ hoạt động khác nhau và được dùng để: - Đếm sự kiện tại các chân T0 (chân 14) hay T1 (chân 15). - Chờ một khoảng thời gian. - Tạo tốc độ cho port nối tiếp. Quá trình điều khiển hoạt động của Timer / Counter được thực hiện thông qua các thanh ghi sau: Bảng 4.1 : Các thanh ghi điều khiển hoạt động timer Thanh ghi Địa chỉ byte Địa chỉ bit TCON 88H 88H – 8FH TMOD 89H Không TL0 90H Không TL1 91H Không TH0 92H Không TH1 93H Không Hoạt động cơ bản của Timer / Counter gồm có các thanh ghi timer THx và TLx (x = 0, 1) mắc liên tầng tạo thành dạng thanh ghi 16 bit. Khi set bit TRx trong thanh ghi TCON, timer tương ứng sẽ hoạt động và giá trị trong thanh ghi TLx tăng lên 1 sau mỗi xung đếm. Khi TLx tràn (thay đổi từ 255 đến 0), giá trị của THx tăng lên 1. Khi THx tràn, cờ tràn tương ứng TFx (trong thanh ghi TCON) sẽ được đưa lên mức 1. Tuỳ theo nội dung của bit C/T xung đếm có thể lấy từ dao động nội (C/T = 0) hay từ các chân Tx bên ngoài (C/T = 1). Lưu ý rằng phải xoá bit TRx khi thay đổi chế độ hoạt động của Timer. Khi xung đếm lấy từ dao động nội, tốc độ đếm = fOSC/12 hay fOSC/2 trong chế độ X2(nghĩa là nếu fOSC = 12 MHz thì tốc độ xung đếm là 1 MHz hay cứ 1 90
  2. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái µs thì có 1 xung đếm trong chế dộ chuẩn) hay tốc độ đếm = fPER/6 (fPER: tần số xung ngoại vi – peripheral clock). Khi lấy xung đếm từ bên ngoài (các chân Tx), bộ đếm sẽ tăng lên 1 khi ngõ vào Tx ở mức 1 trong 1 chu kỳ và xuống mức 0 trong chu kỳ kế tiếp. Do đó, tần số xung tối đa tại các chân Tx là fOSC/24 trong chế độ thường hay fOSC/12 trong chế độ X2 (=fPER/12). 2. Thanh ghi SFR của timer 2.1. Thanh ghi chế độ TMOD Cả hai bộ định thời Timer 0 và Timer 1 đều dùng chung một thanh ghi được gọi là TMOD để thiết lập các chế độ làm việc khác nhau của bộ định thời. Thanh ghi TMOD là thanh ghi 8 bít gồm có 4 bít thấp được thiết lập dành cho bộ Timer 0 và 4 bít cao dành cho Timer 1. Trong đó hai bít thấp của chúng dùng để thiết lập chế độ của bộ định thời, còn 2 bít cao dùng để xác định phép toán. TMOD Register MSB LSB GATE C/T M1 M0 GATE C/T M1 M0 Timer1 Timer0 Chức năng các bit của thanh ghi TMOD: - Các bit M1, M0 : Là các bít chế độ của các bộ Timer 0 và Timer 1. Chúng chọn chế độ của các bộ định thời: 0, 1, 2 và 3. Chế độ 0 là một bộ định thời 13 bit, chế độ 1 là một bộ định thời 16 bít và chế độ 2 là bộ định thời 8 bít. Chúng ta chỉ tập chung vào các chế độ thường được sử dụng rộng rãi nhất là chế độ 1 và 2. Các chế độ được thiết lập theo trạng thái của M1 và M0 như sau : M1 M0 Mode Chế độ hoạt động 0 0 0 Chế độ định thời 13 bit. 0 1 1 Chế độ định thời 16 bit, không định tỉ lệ trước 1 0 2 Chế độ 8 bit tự nạp lại 1 1 3 Chế độ bộ định thời chia tách Ví dụ: Xác định chế độ và bộ định thời của các trường hợp sau: 91
  3. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái a) MOV TMOD, #20H b) MOV TMOD, #12H Giải: Trường hợp a: TMOD = 20H = 00100000B . Đối chiếu với thanh ghi TMOD ta thấy đây là chế độ 2 bộ định thời Timer 1 được chọn. Trường hợp b: TMOD = 12H = 00010010. Đối chiếu với thanh ghi TMOD ta thấy đây là chế độ 1 bộ định thời Timer 1 và chế độ 2 bộ định thời Timer 0 được chọn. Bit C/T ( Counter / Timer): Bít này trong thanh ghi TMOD được dùng để quyết định xem bộ định thời được dùng như một máy tạo độ trễ hay bộ đếm sự kiện. + C/T = 1: Đếm xung từ bên ngoài. + C/T = 0 : Đếm xung nội bên trong. Nguồn đồng hồ cho chế độ trễ thời gian là tần số thạch anh của 8051. Bit cổng GATE : Một bít khác của thanh ghi TMOD là bít cổng GATE. Để ý trên thanh ghi TMOD ta thấy cả hai bộ định thời Timer 0 và Timer 1 đều có bít GATE. Mỗi bộ định thời thực hiện điểm khởi động và dừng. Một số bộ định thời hực hiện điều này bằng phần mềm, một số khác bằng phần cứng và một số khác vừa bằng phần cứng vừa bằng phần mềm. Các bộ định thời trên 8051 có cả hai. Việc khởi động và dừng bộ định thời được khởi động bằng phần mềm bởi các bít khởi động bộ định thời TR là TR0 và TR1. 2.2. Thanh ghi điều khiển TCON MSB LSB TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 Bảng 4.2 :Hoạt động từng bit của thanh ghi TCON. Bit Ký hiệu Địa chỉ Chức năng 7 TF1 8FH Cờ tràn Time 1: TF1=1 khi timer 1 bị tràn và có thể xóa bằng phần mềm hoặc khi vi điều khiển thực hiện chương trình con phục vụ ngắt timer 1 thì tự động xóa luôn cờ tràn TF1 92
  4. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái 6 TR1 8EH Bit điều khiển timer 1 đếm/ ngừng đếm: TR1=1 thì timer 1 được phép đếm xung. TR1=0 thì timer 1 ngừng đếm xung. 5 TF0 8DH Cờ tràn timer 0( hoạt động tương tự TF1) 4 TR0 8CH Bit điều khiển timer 0 3 IE1 8BH Cờ báo ngắt của ngắt INT1. Khi có ngắt xảy ra ở ngõ vào INT1 ( cạnh xuống) thì cờ IE1 tác động lên mức 1. Khi vi điều khiển thực hiện chương trình con phục vụ ngắt INT1 thì tự động xóa luôn cờ báo ngắt IE1. 2 IT1 8AH Bit điều khiển cho phép ngắt INT1 tác động bằng mức hay bằng cạnh: IT1=0 thì ngắt INT1 tác động bằng mức. IT1=1 thì ngắt INT1 tác động bằng cạnh xuống. 1 IE0 89H Giống như IE1 nhưng phục vụ cho ngắt INT0. 0 IT0 88H Giống như IT1 nhưng phục vụ cho ngắt INT0. Ví dụ: Tìm giá trị của TMOD nếu muốn lập trình bộ Timer 1 ở chế độ 1 và sử dụng thạch anh XTLA 8051 làm nguồn đồng hồ và sử dụng lệnh để khởi động và dừng bộ định thời. TMOD = 00010000 Chế độ 1 và chế độ 2 là hai chế độ được sử dụng khá phổ biến, vì vậy chúng ta sẽ nghiên cứu kỹ hơn. 3. Các chế độ làm việc 8051 có 2 timer là timer 0 và timer 1. Ta dùng ký hiệu TLx và THx để chỉ 2 thanh ghi byte cao va byte thấp của timer 0 hoặc timer 1. Như đã trình bày ở trên các timer có 4 chế độ hoạt động, sau đây là chi tiết các kiểu hoạt động của timer : 93
  5. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái 3.1. Chế độ time 13 bit (Mode 0) Chế độ 0 là chế độ 13 bit bao gồm 8 bit của thanh ghi THx và 5 bit của thanh ghi TLx còn 3 bit cao của thanh ghi TLx không sử dụng. Mỗi lần có xung đếm, giá trị trong thanh ghi 13 bit tăng lên 1. Khi giá trị này thay đổi từ 1 1111 1111 1111b đến 0 thì bộ đếm tràn làm cho TFx được đặt lên mức 1. Do chế độ 0 sử dụng 13 bit nên giá trị đếm tối đa là 213 = 8192. Chế độ này được cung cấp nhằm mục đích tạo khả năng tương thích với 8048 và thường không được sử dụng hiện nay. Hình 4.1: Timer chế độ 13 bit 3.2. Chế độ time 16 bit (Mode 1) Dưới đây là những đặc trưng và những phép toán của Model 1. - Đó là bộ định thời 16 bit, do vậy các giá trị từ 0000 – FFFFH được nạp vào thanh ghi TL và TH của bộ định thời. - Sau đó bộ định thời được khởi động nhờ lệnh “SETB TR0” cho Timer 0 và “SETB TR1” cho Timer 1. - Sau khi được khởi động thì bộ định thời bắt đầu đếm tăng. Bộ định thời đếm lên cho đến khi đạt giới hạn FFFFH. Khi đó nó sẽ quay vòng từ FFFFH về 0 và bật cờ định thời TF (Timer Flag) lên mức cao. - Bộ định thời sau khi đạt giá trị giới hạn thì thực hiện quay vòng về 0. Để lặp lại quá trình đếm thì các thanh ghi TH và TL phải được nạp lại giá trị ban đầu và cờ TF cần được xoá về 0. 94
  6. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Hình 4.2: Chế độ timer 16 bit Các bước lập trình chế độ 1: Để tạo ra bộ trễ thời gian khi dùng chế độ 1 của bộ định thời thì cần phải thực hiện các bước dưới đây: - Bước 1: Nạp giá trị cho thanh ghi TMOD xác định bộ định thời nào (Timer O hay Timer 1) và chế độ nào được chọn. - Bước 2: Nạp giá trị đếm ban đầu cho các thanh ghi TL và TH. - Bước 3: Khởi động bộ định thời. - Bước 4: Kiểm tra trạng thái bật của cờ bộ định thời. Thoát khỏi vòng lặp khi TF được bật lên. - Bước 5: Dừng bộ định thời. - Bước 6: Xoá cờ TF cho vòng kế tiếp. - Bước 7: Quay trở lại bước 2 để nạp lại giá trị cho TL và TH.Để tính toán thời gian trễ chính xác (với XTAL cụ thể) ta có thể sử dụng một trong hai cách tính. Tính theo số hexa Tính theo số thập phân (FFFFH – YYXXH +1)xT Đổi YYXXH ra số thập phân Trong đó:YYXXH: Giá trị khởi tạo của NNNNN. Sau đó tính (65536 – TH, TL tương ứng NNNNN)xT T: Chu kỳ bộ định thời Ví dụ 1: Viết chương trình tạo ra xung vuông độ dày 50% trên chân P0.1 sử dụng bộ định thời Timer 0 để tạo trễ. CLR TF0 ;xoa co Timer 0 MOV TMOD,#01H ;su dung Timer 0 che do 1 95
  7. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái HERE: MOV TL0,#0F2H ;TL0 = F2H, byte thap MOV TH0,#0FFH ;TH0 = FFH, byte cao CPL P0.1 ;su dung chan P0.1 ACALL DELAY ;tao tre SJMP HERE ;nap lai TH, TL ; Tao tre dung Timer 0. DELAY: SETB TR0 ;khoi dong bo dinh thoi Timer 0 AGAIN: JNB TF0,AGAIN ;kiem tra cờ bộ định thời CLR TR0 ; Xóa cờ bộ định thời CLR TF0 ;xoa co Timer 0 RET Với giả thiết tần số XTAL = 11,0592MHz ta sẽ tính được thời gian tạo trễ như sau. Bộ định thời làm việc ở tần số đồng hồ bằng 1/12 tần số XTAL do vậy ta có: f = 11, 0592/12 = 0, 9216MHz và T = 1/f = 1/0, 9216 = 1, 085s. Thời gian trong chương trình con DELAY là (FFFFH – FFF2H +1) x1, 085 = 14x1, 085 = 15, 19s. Ví dụ 2: Giả sử tần số XTAL = 11, O592 MHz. Hãy viết chương trình tạo xung có tần số 2KHz trên chân P1.5. Giải: - Chu kỳ sóng vuông là: T = 1/f = 1/2KHz = O, 5ms = 5OOs. - Khoảng thời gian cao (hoặc thấp) là: O, 5T = O, 5.5OO = 25Os. - Số nhịp đếm cần trong khoảng thời gian đó là: 25O/1, O85 = 23O nhịp - Giá trị cần nạp vào thanh ghi TH và TL là: 65536 – 23O = 653O6 = FF1AH. Chương trình được viết như sau: 96
  8. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái CLR TF0 ;xoa co Timer 0 MOV TMOD,#01H ;su dung Timer 0 che do 1 AGAIN: MOV TL0,#1AH ;TL0 = 1AH, byte thap MOV TH0,#0FFH ;TH0 = FFH, byte cao SETB TR0 ;khoi dong bo dinh ;thoi Timer 0 BACK: JNB TF0,BACK 3.3. Chế độ tự nạp lại 8 bit ( Mode 2) Chế độ 2 là chế độ 8 bit trong đó sử dụng thanh ghi TLx đế chứa giá trị đếm còn thanh ghi THx chứa giá trị nạp lại (do đó chế độ này được gọi là chế độ tự động nạp lại – autoreload). Trong chế độ 2, mỗi khi giá trị trong thanh ghi TLx thay đổi từ 1111 1111b đến 0 thì cờ TFx được set lên mức 1 đồng thời giá trị trong thanh ghi THx được chuyển vào thanh ghi TLx. Như vậy, giá trị đếm trong TLx và THx chỉ được nạp một lần khi khởi động timer (có thể không cần nạp cho TLx nhưng khi đó chu kỳ hoạt động đầu tiên của timer sẽ sai). Chế độ 2 sử dụng 8 bit đếm trong thanh ghi TLx nên giá trị đếm tối đa là 28 = 256. Hình 4.3: Chế độ tự nạp lại 8 bit 3.4. Chế độ tách biệt time ( Mode 3) Ở chế độ này chức năng Timer 0 và chức năng Timer 1 khác nhau. Bộ Timer 1 ở chế độ 3 chỉ chứa chức năng đếm của nó, kết quả giống khi đặt TR1 = 0. Bộ Timer 0 ở chế độ 3 thiết lập TH0, TL0 như là 2 bộ đếm riêng biệt. Mạch 97
  9. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái logic đối với chế độ 3 của Timer 0 thể hiện ở hình 2.7. Bộ đếm TL0 được điều khiển bởi các bit: C/(/T), GATE, TR0, /INTO và khi đếm tràn nó thiết lập cờ ngắt TF0. Bộ đếm TH0 chỉ được điều khiển bởi bit TR1 và khi đếm tràn nó thiết lập cờ ngắt TF1. Vậy TH0 điều khiển ngắt Timer/Counter 1. Chế độ 3 thường được dùng khi yêu cầu cần có bộ thời gian hoặc bộ đếm ngoài 8 bit. Đối với Timer 0 ở chế độ 3, AT89C51 có thể có 3 bộ Timer/Counter còn 8052 có thể có 4 bộ. Khi Timer 0 hoạt động ở chế độ 3 thì Timer 1 có thể được bật hoặc tắt bằng chuyển mạch ngoài. Ở chế độ này Timer1 có thể được sử dụng bởi cổng nối tiếp như một bộ tạo tốc độ Baud hoặc trong bất kỳ ứng dụng nào mà không yêu cầu một ngắt. Hình 4.4: Chế độ tách biệt timer 4. Nguồn cung cấp xung cho time Có thể sử dụng hai nguồn tạo xung nhịp cung cấp cho các timer. Chúng được chọn bằng cách ghi vào bit C/T ( count/timer) trong TMOD. Một nguồn tạo xung nhịp dùng cho định khoảng thời gian, cái khác cho đếm sự kiện. 4.1. Chức năng định thời Nếu C/T = 0 hoạt động timer liên tục được chọn và timer được dùng cho việc định khoảng thời gian. Lúc đó timer lấy xung nhịp từ bộ dao động trong chip. Xung nhịp ngõ ra bộ tạo dao động được giảm tần số bằng bộ chia 12 trước khi cấp vào timer để thích hợp cho phần lớn các ứng dụng. Như vậy với thạch anh 12 MHz, thì tốc độ xung nhịp cung cấp cho timer sẽ là 1 MHz. Báo tràn timer xảy ra một số ( cố định) xung nhịp, tùy thuộc vào giá trị ban đầu được nạp vào các thanh ghi timer TLx / THx. 4.2. Chức năng đếm sự kiện Nếu C/T = 1 timer lấy xung nhịp từ nguồn bên ngoài. Trong hầu hết các ứng dụng, nguồn bên ngoài này cung cấp cho timer một xung khi xảy ra một “ sự kiện” timer dùng đếm sự kiện. Số sự kiện được xác định bằng phần mềm bằng cách đọc các thanh ghi TLx/THx, vì giá trị 16 bit trong các thanh ghi này tăng thêm 1 cho mỗi sự kiện. 98
  10. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Nguồn xung nhịp ngoài được cung cấp bằng các chân cổng 3. Bit 4 của cổng 3 (P3.4) dùng là ngõ vào tạo xung nhịp bên ngoài cho timer 0 và được gọi là “T0”, còn P3.5 hay “T1” là ngõ vào tạo xung nhịp cho timer 1. Trong các ứng dụng đếm, các thanh ghi timer được tăng thêm 1 tương ứng với sự chuyển trạng thái logic từ 1 xuống 0 ở ngõ vào bên ngoài (Tx). Ngõ vào bên ngoài được lấy mẫu trong S5P2 của mọi chu kỳ máy. Như vậy, khi ngõ vào cao trong một chu kỳ và thấp trong một chu kỳ kế thì số đếm được tăng thêm 1. Giá trị mới xuất hiện trong các thanh ghi trong S3P1 của chu kỳ theo sau chu kỳ phát hiện sự chuyển trạng thái. Do đó cần 2 chu kỳ máy ( 2µs) để ghi nhận một sự chuyển trạng thái 1 sang 0, tần số ngoài tối đa là 500 KHz ( giả sử hệ thống hoạt động ở 12 MHz). Hinh 4.5: Sơ đồ cung cấp xung nhịp cho timer 5. Khởi động, dừng, điều khiển timer Phương pháp đơn giản nhất để bắt đầu ( cho chạy) và dừng các timer là dùng các bit điều khiển chạy ( TRx) trong TCON. TRx bị xóa sau khi reset hệ thống, như vậy các timer theo mặc định là bị cấm ( bị dừng) sau khi reset. TRx được đặt lên 1 bằng phần mềm để cho các timer chạy. Vì TRx ở trong thanh ghi TCON có địa chỉ theo bit, nên việc cho chạy và dừng timer có thể thực hiện dễ dàng trong chương trình. Ví dụ : Cho time 0 chạy bằng lệnh : SETB TR0. Dừng bằng lệnh : CLR TR0 Trình hợp dịch sẽ thực hiện việc chuyển đổi ký hiệu cần thiết từ “ TR0” sang địa chỉ bit tương ứng của nó. Lệnh SETB TR0 sẽ giống như SETB 8CH. Một cách khác để điều khiển các timer là dùng bit GATE trong TMOD và ngõ vào bên ngoài INTx. Đặt GATE = 1 cho phép timer sẽ được điều khiển bằng INTx, cách này hữu dụng cho việc đo độ rộng xung. Ví dụ để đo độ rộng xung ngõ vào INT0 có thể thực hiện như sau : 99
  11. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Khởi động time 0 ở chế độ 2 ( chế độ timer 16 bit), với TL0/TH0 = 0000H, GATE = 1 và TR0 = 1. Khi INT0 xuống thấp, timer bị “ đóng cổng” và khoảng thời gian của xung tính bằng µs là số đếm được trong TL0/TH0 ( có thể lập trình INT0 để tạo ra một ngắt khi nó xuống thấp). Hình dưới minh họa timer 1 hoạt động chế độ 1 như một timer 16 bit. Sơ đồ chỉ khả năng điều khiển việc cấp nguồn tạo xung nhịp cho timer. Hình 4.6: Sơ đồ điều khiển hoạt động của Timer 0 chế độ 1 6. Khởi tạo truy xuất thanh ghi timer Các timer thường được khởi tạo một lần ở đầu chương trình để thiết lập chế độ hoạt động phục vụ cho các ứng dụng điều khiển liên quan đến định thời hay đếm xung ngoại. Tùy thuộc vào yêu cầu cụ thể mà ta điều khiển các timer bắt đầu đếm , ngừng hay khởi động đếm lại từ đầu Thanh ghi TMOD là thanh ghi đầu tiên cần phải khởi tạo để thiết lập chế độ hoạt động cho các timer. Ví dụ khởi động cho timer 0 hoạt động ở chế độ 1 ( chế độ 16 bit) và hoạt động định thời đếm xung nội bên trong thì ta khởi tạo bằng lệnh : MOV TMOD, # 000000001B Trong lệnh này M1 = 0, M0 = 1 để vào chế độ 1 và C/T = 0, GATE = 0 để cho phép đếm xung nội bên trong đồng thời xóa các bit chế độ timer 1. Sau lệnh trên timer 0 chỉ đếm khi thiết lập bit điều khiển TR0. Nếu ta không thiết lập các giá trị bắt đầu đếm cho các thanh ghi TLx/ THx thì timer sẽ bắt đầu đếm từ 0000H lên và khi chuyển trạng thái từ FFFFH sang 0000H sẽ sinh ra tràn làm cho bit TFx = 1 rồi tiếp tục đếm từ 0000H lên tiếp 100
  12. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Nếu ta thiết lập giá trị bắt đầu đếm cho TLx/THx khác 0000H thì timer sẽ bắt đầu từ giá trị thiết lập đó lên nhưng khi chuyển trạng thái từ FFFFH sang 0000H thì timer lại đếm từ 0000H lên. Để timer luôn bắt đầu đếm từ giá trị ta gán thì ta có thể lập trình chờ sau mỗi lần tràn ta sẽ xóa cờ TFx và gán lại giá trị cho TLx/ THx để timer luôn luôn bắt đầu đếm từ giá trị cho TLx/ THx để timer luôn luôn bắt đầu đếm từ giá trị khởi gán lên. Đặc biệt nếu bộ định thời hoạt động trong phạm vi nhỏ hơn 256 µs thì ta nên dùng timer ở chế độ tự động nạp 8 bit. Sau khi khởi tạo giá trị đầu cho thanh ghi THx và TLx khi set bit TRx thì timer sẽ bắt đầu đếm từ giá trị đã gán trong TLx và khi tràn từ FFH sang 00H trong TLx thì cờ tràn TFx tự động được thiết lập, đồng thời giá trị trong THx tự động nạp sang cho TLx và timer bắt đầu đếm từ giá trị khởi gán này lên. Nói cách khác sau mỗi lần tràn ta không cần gán lại cho các thanh ghi timer mà chúng vẫn đếm được lại từ giá trị đã gán. 6.1. Đọc thời gian đang hoạt động Trong một số ứng dụng cần đọc giá trị trong các thanh ghi timer khi nó đang chạy. Vì phải đọc hai thanh ghi timer thì “sai pha” có thể xảy ra nếu byte thấp tràn vào byte cao giữa hai lần đọc. Giá trị đọc được có thể không đúng. Giải pháp là đọc byte cao trước kế đó đọc byte thấp rồi đọc byte cao lại một lần nữa. Nếu byte cao đã thay đổi thì lặp lại các hoạt động đọc. Các lệnh dưới đây đọc nội dung của các thanh ghi timer TL1/ TH1 vào các thanh ghi R6/ R7: AGAIN : MOV A, TH1 MOV R6, TL1 CJNZ A, TH1, AGAIN MOV R7, A 6.2. Thời gian ngắn và thời gian dài Như ta đã biết từ các ví dụ trên là lượng thời gian trễ cần tạo ra phụ thuộc vào hai yếu tố: - Tần số thạch anh XTAL. - Thanh ghi 16 bít của bộ định thời ở chế độ 1. Cả hai yếu tố này nằm ngoài khả năng điều chỉnh của lập trình viên 8051. Ví như ta đã biết giá trị lớn nhất của độ trễ thời gian có thể đạt được bằng cách đặt cả TH và TL bằng 0. Thời gian ngắn: Là khoảng thời gian mà bộ định thời có thể tạo ra nhỏ hơn giá trị tối đa của bộ định thời ở chế độ 16 bit. Thời gian dài: Là khoảng thời gian mà bộ định thời có thể tạo ra lớn hơn giá trị tối đa của bộ định thời ở chế độ 16 bit. Giả sử tần số thạch anh là 12 MHz do đó xung kích cho bộ định thời là 101
  13. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái 1 MHz.Khoảng thời gian định thời ngắn nhất không phụ thuộc tần số xung kích timer mà phụ thuộc vào phần mềm, có nghĩa là do thời gian thực hiện các lệnh, lệnh có thời gian thực hiện nhanh nhất của 8051 là một chu kỳ máy hoặc 1 μS. Ví dụ: Viết chương trình tạo xung tuần hoàn tạI chân P1.0 với tần số cao nhất có thể được. Cho biết tần số và tỉ số giữa độ rộng xung với chu kỳ. Bài làm: Tần số cao nhất có nghĩa là chu kỳ ngắn nhất. Do đó không thể dùng bộ định thời mà chỉ dùng phần mềm. Chương trình như sau: LOOP : SETB P1.0 : 1 chu kỳ CLR P1.0 : 1 chu kỳ SJMP LOOP : 2 chu kỳ Chu kỳ của xung là 4µs trong đó mức cao la 1 µs và mức thấp 3 µs suy ra tần số 250 KHz và tỉ số độ rộng / chu kỳ là 25%. Chu kỳ tín hiệu ra có thể được kéo dài bằng cách thêm vào lệnh NOP ( No operation) vào trong vòng lặp mỗi lệnh NOP sẽ tăng lên 1 µS thêm 2 lệnh NOP sau lệnh SETB P1.0 sẽ làm xung ra có dạng hình vuông với chu kỳ là 6 µS tương đương tần số 166,7 KHz. Tuy nhiên cách làm trên không hay lắm và cách tốt nhất để tạo thời gian trì hoãn là dùng bộ định thời. 7. Time 2 của 8052 Timer 2 là bộ định thời 16 bit (chỉ có trong họ 8x52). Giá trị đếm của timer 2 chứa trong các thanh ghi TH2 và TL2. Giống như timer 0 và timer1, timer 2 cũng hoạt động như bộ định thời (timer) hay đếm sự kiện (counter). Chế độ định thời đếm bằng dao động nội, chế độ đếm sự kiện đếm bằng xung ngoài tại chân T2 (P1.0) và chọn chế độ bằng bit C/ 2 của thanh ghi T2CON. Họ vi điều khiển 8052 có 3 timer T0,T1,T2. Các timer T0 và T1 có các thanh ghi và hoạt động giống như họ 8051. Ở đây chỉ trình bày thêm phần hoạt động của timer T2. Các thanh ghi điều khiển timer 2 bao gồm: T2CON, T2MOD, RCAP2H, RCAP2L, TH2 và TL2. Timer T2 của 8052 có 2 chế độ hoạt động: Chế độ tự động nạp lại, chế độ thu nhận. Các bit chọn chế độ được mô tả như bảng sau : Bảng 4.3 : Chức năng các bít chọn chế độ 102
  14. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái RCLK TCLK CP/RL2 TR2 Chế độ 0 0 0 1 Tự động nạp lại 16 bit 0 0 1 1 Giữ 16 bit x 1 x 1 Tạo tốc độ baud 1 x x 1 x x x 0 Ngưng Các thanh ghi điều khiển Timer T2 - Thanh ghi điều khiển T2CON TF2 EXF2 RCLK TCLK EXEN2 TR2 C/T2 CP/RL2 Bảng 4.4 : Chức năng các bit thanh ghi T2CON được mô tả trong bảng sau : Bit Ký hiệu Địa chỉ Chức năng 7 TF2 CFH Cờ tràn timer 2 : Hoạt động giống như các timer trên ( TF2 sẽ không được thiết lập lên mức 1 nếu bit TCLK hoặc RCLK ở mức 1). 6 EXF2 CEH Cờ ngoài của timer T2 : Chỉ được thiết lập khi xảy ra sự thu nhận hoặc nạp dữ liệu bởi sự chuyển trạng thái từ 1 sang 0 ở ngõ vào T2EX và EXEN = 1 ; khi cho phép timer T2 ngắt, EXF2 = 1 thì CPU sẽ thực hiện chương trình con phục vũ ngắt timer T2, bit EXF2 có thể bằng phần mềm. 5 RCLK CDH Xung clock thu của timer 2. Khi RCLK = 1 thì timer T2 cung cấp tốc độ baud cho port nối tiếp để nhận dữ liệu về và timer T1 sẽ cung cấp tốc độ baud cho port nối tiếp để phát dữ liệu đi. 4 TCLK CCH Xung clock phát của timer 2. Khi TCLK = 1 thì timer T2 cung cấp tốc độ baud cho port nối tiếp để phát dữ liệu đi và timer T1 sẽ cung cấp tốc độ baud cho port nối tiếp để nhận dữ liệu về. 103
  15. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái 3 EXEN2 CBH Bit điều khiển cho phép tác động từ bên ngoài. Khi EXEN2 = 1 thì hoạt động thu nhận và nạp lại của timer T2 chỉ xảy ra khi ngõ vào T2EX có sự chuyển trạng thái từ 1 sang 0. 2 TR2 CAH Bit điều khiển timer 1 đếm/ ngừng đếm: TR2 = 1 thì timer 1 được phép đếm xung. TR2 = 0 thì timer 1 không được phép đếm xung. Dùng lệnh điều khiển bit TR2 để cho phép timer 1 đếm hay ngừng đếm. 1 C/T2 C9H Bit lựa chọn counter hay timer: C/T2 = 1: Đếm xung từ bên ngoài đưa đến ngõ vào T2. C/T2 = 0 :Định thời đếm xung nội bên trong. 0 CP/RL2 C8H Cờ thu nhận / nạp lại dữ liệu của timer T2. Khi bit này bằng 1 thì thu nhận chỉ xảy ra khi có sự chuyển trạng thái từ 1 sang 0 ở ngõ vào T2EX và EXEN2 = 1. Khi bit này bằng 0 thì quá trình nạp lại khi timer T2 tràn hoặc khi có sự chuyển trạng thái ở ngõ vào T2EX và bit EXEN = 1; nếu bit RCLK hoặc TCLK = 1 thì bit này xem như bỏ. Thanh ghi TMOD - - - - - T2OE DCEN - Bảng 4.5: Chức năng các bit thanh ghi TMOD được mô tả trong bảng sau : Bit Tên Mô tả 7 - 104
  16. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái 6 - 5 - 4 - 3 - 2 - 1 T2OE Timer 2 Output Enable Bit = 0 : T2 ( P1.0) là ngõ vào clock hay I/O port = 1 : T2 là ngõ ra Clock 0 DCEN Down Counter Enable Bit = 0 : Cấm timer 2 là bộ đếm lên / xuống. = 1 : Cho phép timer 2 là bộ đếm lên / xuống. Giá trị khi reset : T2MOD = xxxx xx00b, MOD không cho phép định vị bit. Các thanh ghi TH2, TL2, RCAP2H và RCAP2L không cho phép định vị bit và giá trị khi reset là 00h. Các chế độ hoạt động của timer 2 mô tả trong phần tiếp theo. 7.1. Chế độ tự động nạp lại Chế độ tự động nạp lại cũng có 2 trường hợp giống như chế độ giữ: - Nếu EXEN2 = 0: khi Timer tràn, cờ tràn TF2 được đặt lên 1 và nạp lại giá trị cho TH2, TL2 (từ cặp thanh ghi RCAP2H, RCAP2L) đồng thời tạo ngắt. - Nếu EXEN2 = 1: hoạt động giống như trên nhưng khi có xung âm tại chân T2EX thì cũng nạp lại giá trị cho TH2, TL2 và đặt cờ EXF2 lên 1. Chế độ tự động nạp lại cũng cho phép thực hiện đếm lên hay xuống (điều khiển bằng bit DCEN trong thanh ghi T2MOD). Khi DCEN được đặt lên 1 và chân T2EX ở mức cao thì timer 2 sẽ đếm lên; còn nếu T2EX ở mức thấp thì timer 2 đếm xuống. Khi đếm lên, timer tràn tại giá trị đếm 0FFFFh. Khi tràn, cờ TF2 được đặt lên mức 1 và giá trị trong cặp thanh ghi RCAP2H, RCAP2L chuyển vào căp thanh ghi TH2, TL2. Khi đếm xuống, timer tràn khi giá trị trong cặp thanh ghi TH2, TL2 bằng giá trị trong cặp thanh ghi RCAP2H, RCAP2L. Khi tràn, cờ TF2 được đặt lên 1 và giá trị 0FFFFh được nạp vào cặp thanh ghi TH2, TL2. Trong chế độ này, khi timer tràn, giá trị trong cờ EXF2 sẽ chuyển mức và không tạo ngắt (có thể dùng thêm EXF2 để tạo giá trị đếm 17 bit). 105
  17. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Hình 4.7: Chế độ tự nạp lại 16 bit 7.2. Chế độ thu nhận Chế độ thu nhận của Timer 2 có 2 trường hợp xảy ra: - Nếu EXEN2 = 0: Timer 2 hoạt động giống như Timer 0 và 1, nghĩa là khi giá trị đếm tràn (TH2_TL2 thay đổi từ FFFFh đến 0) thì cờ tràn TF2 được đặt lên mức 1 và tạo ngắt tại Timer 2 (nếu cho phép ngắt). - Nếu EXEN2 = 1: vẫn hoạt động như trên nhưng thêm một tính chất nữa là: khi xuất hiện cạnh âm tại chân T2EX (P1.1), giá trị hiện tại của TH2 và TL2 được chuyển vào cặp thanh ghi RCAP2H, RCAP2L (quá trình thu xảy ra); đồng thời, bit EXF2 = 1 (sẽ tạo ngắt nếu cho phép ngắt tại Timer 2). 106
  18. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Hình 4.8: Hoạt động của timer T2 ở chế độ thu nhận dữ liệu Để cho phép chế độ thu nhận hoạt động thì làm cho bit EXEN2 = 1. Nếu bit EXEN2 = 1 và khi có sự chuyển trạng thái từ 1 sang 0 ở ngõ vào T2EX thì chế độ thu nhận sẽ xảy ra : Giá trị đếm được trong thanh ghi TL2, TH2 sẽ được chuyển sang 2 thanh ghi RCAP2L và RCAP2H. Cờ EXF2 cũng được chuyển lên mức 1 để báo hiệu quá trình thu nhận đã xảy ra , cờ EXF2 có thể kiểm tra bằng phần mềm hoặc tạo ngắt. 8. Luyện tập 8.1. Phương pháp Để điều khiển hoạt động của timer, cần thực hiện: - Nạp giá trị cho thanh ghi TMOD để xác định chế độ hoạt động (thông thường chỉ dùng chế độ 1 – 16 bit và chế độ 2 – 8 bit tự động nạp lại). - Nạp giá trị đếm trong các thanh ghi THx, TLx (thông thường sử dụng timer 0 và timer 1 nên quá trình đếm là đếm lên). - Đặt các bit TR0, TR1 = 1 (cho phép timer hoạt động) hay xoá các bit này về 0 (cấm timer). - Trong quá trình timer chạy, thực hiện kiểm tra các bit TF0, TF1 để xác định timer đã tràn hay chưa. - Sau khi timer tràn, nếu thực hiện kiểm tra tràn bằng phần mềm (không dùng ngắt) thì phải thực hiện xoá TF0 hay TF1 để có thể tiếp tục hoạt động. 8.2. Bài tập Bài tập 1: Viết chương trình tạo sóng vuông tần số 10 KHz tại chân P1.0 dùng timer 0 (tần số thạch anh là fOSC = 12MHz). Bài làm : Do fOSC = 12MHz nên chu kỳ máy = 1 µs. 107
  19. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái f = 10 KHz → T = 1/f = 0.1 ms = 100 µs →một chu kỳ sóng vuông chiếm khoảng thời gian 100 chu kỳ máy →thời gian trì hoãn cần thiết là 50 chu kỳ máy. \ Do giá trị đếm là 50 (ứng với 50 chu kỳ máy) nên chỉ cần dùng chế độ 8 bit (có thể đếm từ 1 đến 256) cho timer 0 (chế độ 2). Nội dung thanh ghi TMOD: GATE C/T1 M11 M10 GATE0 C/T0 M01 M00 1 0 0 0 0 0 0 1 0 Timer 1 không dùng Không dùng Đếm bằng dao Chế độ 8 bit INT0 động nội TMOD = 0000 0010b (02h) Giá trị đếm là 50 và do timer 0 đếm lên nên giá trị cần nạp cho TH0 là -50 (có thể không cần nạp cho TL0 nhưng lúc đó chu kỳ đầu tiên của xung sẽ sai). Chương trình thực hiện như sau: MOV TMOD, # 02h MOV TH0, # (-50) MOV TL0, # (-50) SETB TR0 ; Cho phép timer 0 chạy Lặp: JNB TF0, Lặp ; Nếu timer chưa tràn thì chờ CLR TF0 CPL P1.0 ; Đảo bit P1.0 để tạo xung vuông SJMP Lặp END Bài tập 2: Viết chương trình tạo xung vuông tần số f = 1 Hz tại P1.2 dùng timer 1. 108
  20. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Bài làm : f = 1 Hz → T = 1/f = 1 s = 1 000 000 µs → một chu kỳ sóng vuông chiếm khoảng thời gian 500 000 chu kỳ máy → thời gian trì hoãn cần thiết là 500 000 chu kỳ máy. Giá trị đếm là 500 000, vượt quá khả năng của timer (tối đa chỉ đếm được 65536 chu kỳ) nên phải thực hiện tạo vòng lặp đếm nhiều lần cho đến khi đạt đến giá trị 500 000 (có thể đếm mỗi lần 50 000 và thực hiện vòng lặp 10 lần). Chương trình thực hiện như sau: MOV TMOD,#10h Batdau: MOV R7,#10 ; Lặp 10 lần Lap: MOV TH1,#HIGH(-50000) MOV TL1,#LOW(-50000) SETB TR1 KtrT1: JNB TF1,KtrT1 CLR TF1 CLR TR0 DJNZ R7,Lap ; Nếu R7 ≠ 0 thì lặp lại CPL P1.2 ; Đảo bit để tạo xung SJMP Batdau END Bài tập 3: Viết chương trình con tạo thời gian trì hoãn 1s dùng timer 0. Bài làm : Chương trình như sau: MOV TMOD,#01h ; Chương trình chính Delay1s: MOV R7,#20 ; Lặp 20 lần Lap: MOV TH0,#HIGH(-50000) ; Mỗi lần trì hoãn 50 000 µs 109
  21. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái MOV TL0,#LOW(-50000) SETB TR0 Lap1: JNB TF0,Lap1 CLR TF0 CLR TR0 DJNZ R7,Lap ; Lặp đủ 20 lần thì thoát RET Bài 5: CỔNG NỐI TIẾP 1. Mở đầu Máy tính thường truyền dữ liệu theo 2 phương pháp : song song và nối tiếp. Truyền dữ liệu song song thường dùng 8 hoặc nhiều đường dây dẫn ở cách xa một vài mét. Phương pháp này cho phép truyền dữ liệu với tốc độ cao nhờ dùng nhiều dây dẫn. Để truyền dữ liệu đi xa thường dùng phương pháp truyền nối tiếp phương pháp này truyền dữ liệu theo từng bit một. Hình 5.1: Phương thức truyên thông song song va nối tiếp Để truyền tin nối tiếp người ta sử dụng một đường dữ liệu thay thế bus dữ liệu 8 bit của truyền tin song song. Nhờ vậy không chỉ làm giá thành hạ hơn nhiều mà còn mở ra một khả năng để 2 máy tính ở cách xa nhau vẫn có thể truyền thông với nhau. Để tổ chức truyền tin nối tiếp trước hết byte dữ liệu được chuyển thành các bit nối tiếp nhờ thanh ghi dịch vào song song ra nối tiếp. Tiếp theo dữ liệu được truyền qua một đường truyền dữ liệu đơn. Ở đầu thu cũng phải có một thanh ghi dịch vào nối tiếp ra song song để nhận dữ liệu nối tiếp và sau đó gói chúng lại thành từng byte một. 110
  22. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Truyền tin có 2 phương pháp: Đồng bộ và dị bộ. Phương pháp đồng bộ chuyển một lần một khối dữ liệu, còn phương pháp dị bộ chỉ truyền từng byte một. Bộ vi điều khiển 8051 được xây dựng sẵn một bộ thu phát dị bộ tổng hợp UART ( Universal Asynchronous Receiver Transmitter). 1.1. Khái niệm truyền dữ liệu đơn công và song công - Truyền đơn công: Máy phát chỉ có phát dữ liệu bên máy thu chỉ có thu dữ liệu. - Truyền song công: Mỗi bên đều vừa có thể phát vừa có thể thu dữ liệu. Truyền song công có 2 loại + Bán song công : Tại một thời điểm dữ liệu chỉ có thể truyền một chiều. + Song công hoàn toàn : Dữ liệu có thể truyền cả hai chiều đồng thời. Hình 5.2: Các kiểu truyền dữ liệu 1.2. Truyền thông nối tiếp dị bộ và đóng khung dữ liệu. Dữ liệu đi vào ở đầu thu của đường dữ liệu trong truyền dữ liệu nói tiếp toàn là các số 0 và 1, nó thật là khó làm cho dữ liệu ấy có nghĩa là nếu bên phát và bên thu không cùng thống nhất về một tệp các luật, một thủ tục, về cách dữ liệu được đóng gói, bao nhiêu bít tạo nên một ký tự và khi nào dữ liệu bắt đầu và kết thúc. 1.3. Các bít bắt đầu và dừng. Truyền thông dữ liệu nối tiếp dị bộ được sử dụng rộng rãi cho các phép truyền hướng kỹ tự, còn các bộ truyền dữ liệu theo khối thì sử dụng phương phát đồng bộ. Trong phương pháp dị bộ, mỗi ký tự được bố trí giữa các bít bắt đầu (start) và bít dừng (stop). Công việc này gọi là đóng gói dữ liệu. Trong đóng gói dữ liệu đối với truyền thông dị bộ thì dữ liệu chẳng hạn là các ký tự mã ASCII được đóng gói giữa một bít bắt đầu và một bít dừng. Bít bắt đầu luôn luôn chỉ là một bít, còn bít dừng có thể là một hoặc hai bít. Bít bắt đầu luôn là bít thấp (0) và các bít dừng luôn là các bít cao (bít 1). Ví dụ, hãy xét ví dụ trên hình 10.3 trong đó ký tự “A” của mã ASCII (8 bít nhị phân là 0100 0001) đóng gói khung 111
  23. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái giữa một bít bắt đầu và một bít dừng. Lưu ý rằng bít thấp nhất LSB được gửi ra đầu tiên. Hình 5.3: Khung truyền dữ liệu 1.4. Tốc độ truyền dữ liệu Tốc độ truyền tin nối tiếp được tính bằng bit/giây bps ( Bit per sencond). Một thuật ngữ khác cũng được sử dụng là baud. Tuy nhiên khái niệm bps và baud không hoàn toàn giống nhau. Baud là đơn vị dùng cho modem và được định nghĩa là số lần thay đổi tín hiệu trong một giây. Còn đối với modem mỗi lần thay đổi tín hiệu có thể truyền được nhiều bit dữ liệu. Còn đối đường truyền thì tốc độ baud và bps là một. 1.5. Chuẩn RS232 Để đảm bảo sự tương thích giữa các thiết bị truyền dữ liệu nối tiếp do các hãng khác nhau sản xuất năm 1960 Hiệp hội công nghiệp điện tử EIA đã xây dựng một chuẩn giao diện được gọi RS232. Ngày nay RS232 là chuẩn giao diện I/O được sử dụng rộng rãi nhất. Tuy nhiên do chuẩn ra đời khá lâu trước khi có họ vi mạch điện tử TTL vì vậy các mức điện áp vào/ra của nó không tương thích với TTL. Ở RS232 mức logic 1 tương ứng -3V đến -25V, còn mức 0 tương ứng từ +3V đến +25V, khoảng -3V đến +3V không xác định. Do đó để kết nối RS232 với máy tính đều phải qua bộ biến đổi điện áp như MAX232 để chuyển mức TTL sang mức điện áp của RS232 và ngược lại. 112
  24. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Hình 5.4: Sơ đồ chân của cáp RS232 Bảng 5.1 : Mô tả chức năng các chân : Chân Mô tả Ý nghĩa 1 Data carrier detect (DCD) Tách tín hiệu dữ liệu 2 Received data (RxD) Dữ liệu được nhận 3 Transmitted data (TxD) Dữ liệu được gửi 4 Data terminal ready (DTR Đầu cuối dữ liệu sẵn sàng 5 Signal ground (GND) Đất của tín hiệu 6 Data set ready (DSR) Dữ liệu sẵn sàng 7 Request to send (RTS) Yêu cầu gửi 8 Clear to send (CTS) Xóa để gửi 9 Ring indicator (RL) Báo chuông 8051 có một cổng nối tiếp trong chip có thể hoạt động ở nhiều chế độ, trên một dải tần số rộng. Chức năng chủ yếu của cổng nối tiếp là thực hiện chuyển đổi song song sang nối tiếp đối với dữ liệu xuất và chuyển đổi nối tiếp sang song song với dữ liệu nhập. Việc truy xuất phần cứng qua cổng nối tiếp được thực hiện bằng các chân TXD và RXD. Các chân này là hai bit của cổng 3 là P3.1 ( TXD) và P3.0 ( RXD). 2. Thanh ghi điều khiển Hai thanh ghi chức năng đặc biệt cho phép phần mềm truy xuất đến cổng nối tiếp là SCON và SBUF. Bộ đệm cổng nối tiếp SBUF có địa chỉ 99H thực chất bao gồm hai bộ đệm. Dữ liệu ghi vào SBUF sẽ được truyền ra thiết bị bên ngoài và đọc SBUF để truy xuất dữ liệu thu được. Đây là hai thanh ghi riêng biệt một thanh ghi chỉ ghi để phát và một thanh ghi chỉ đọc để thu. 2.1. Thanh ghi SCON Thanh ghi điều khiển cổng nối tiếp SCON có địa chỉ 98H là thanh ghi địa chỉ hóa theo bit nó chứa các bit trạng thái và các bit điều khiển. Các bit điều khiển cho phép thiết lập các chế độ hoạt động cho cổng nối tiếp và các bit trạng thái chỉ thị việc kết thúc phát hoặc thu ký tự. Các bit trạng thái có thể được kiểm tra bằng phần mềm hoặc có thể được lập trình để tạo ngắt. Chế độ hoạt động của cổng nối tiếp được thiết lập bằng cách ghi dữ liệu vào thanh ghi điều khiển cổng nối tiếp SCON. Cấu trúc thanh ghi SCON như sau : MSB LSB SM0 SM1 SM2 REN TB8 RB8 T1 R1 113
  25. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Hình 5.3: Thanh ghi điều khiển SCON. Chức năng các bit điều khiển thanh ghi SCON như sau: Các bit SM0, SM1 : Đây là các bit D7, D6 của thanh ghi SCON. Chúng được dùng để xác định chế độ đóng khung dữ liệu, trạng thái của 2 bit SM0 và SM1 trong thanh ghi này thiết lập nên 4 chế độ hoạt động giao tiếp nối tiếp chuẩn như sau: SM0 SM1 Chế độ Chức năng Tốc độ baud 0 0 0 Thanh ghi dịch Cố định( tần số dao động chia cho12). 0 1 1 8 bit UART Thay đổi ( theo giá trị timer) 1 0 2 9 bit UART Cố định ( tần số dao động chia cho 12 hoặc 64). 1 1 3 9 bit UART Thay đổi ( theo giá trị timer). - Chế độ 0 Dữ liệu nối tiếp vào và ra sẽ thông qua chân RxD. Chân TxD đưa ra xung nhịp đồng hồ. 8 bit dữ liệu được truyền/nhận nối tiếp, với bit LSB được thực hiện đầu tiên. Tốc độ Baud được cố định bằng 1/12 tần số của bộ dao động. - Chế độ 1: 10 bit được truyền (thông qua TxD) hoặc nhận (thông qua RxD), trong đó gồm có: 1 bit khởi động (có giá trị 0), 8 bit dữ liệu (đầu tiên là LSB), và 1 bit dừng (có giá trị là 1). Khi nhận, bit dừng được chuyển vào RB8 của thanh ghi SCON. Tốc độ Baud có thể thay đổi được. - Chế độ 2: 11 bit được truyền (thông qua TxD) hoặc nhận (thông qua RxD) bao gồm: bit khởi động (có giá trị 0), 8 bit dữ liệu (đầu tiên là LSB), một bit dữ liệu thứ 9 có thể lập trình được, và một bit dừng (có giá trị 1). Khi truyền, bit dữ liệu thứ 9 (TB8 ở trong SCON) có thể được gán giá trị 0 hoặc 1. Chẳng hạn như bit chẵn lẻ (P ở trong PSW) có thể được chuyển vào TB8. Khi nhận, bit dữ liệu thứ 9 được chuyển vào RB8 ở thanh ghi SCON, trong khi bit dừng được lọc bỏ. Tốc độ Baud có thể lập trình được bằng 1/32 hoặc 1/64 tần số bộ dao động. - Chế độ 3: 11 bit được truyền (thông qua TxD) hoặc được nhận (thông qua RxD) bao gồm: 1 bit khởi động (có giá trị 0), 8 bit dữ liệu (đầu tiên là LSB), 1 bit dữ liệu thứ 9 có thể lập trình được, và 1 bit dừng (có giá trị 1). Trên thực tế, chế độ 3 giống chế độ 2 ở mọi góc độ trừ tốc độ Baud. Tốc độ Baud ở chế độ 3 là khả biến và được xác định theo bộ Timer 1. 114
  26. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Trong cả 4 chế độ trên, việc truyền được bắt đầu bởi bất kỳ một lệnh nào mà sử dụng thanh ghi SBUF như là một thanh ghi đích. Việc nhận được bắt đầu ở chế độ 0 khi RI=0 và REN=1. Đối với các chế độ khác, việc nhận được bắt đầu khi bit REN=1. Bit SM2: bit D5 của thanh ghi SCON, bit này cho phộp khả năng đa xử lý của 8051. Đối với cỏc ứng dụng của chương trỡnh học ta đặt SM2 = 0 vỡ ta khụng sử dụng 8051 trong mụi trường đa xử lý. Bit REN Đây là bit cho phộp thu, nằm vị trớ D4 của thanh ghi SCON. Bit REN cũng được tham chiếu như là SCON.4 vỡ SCON là thanh ghi cú thể đánh địa chỉ theo bit. Khi bit REN cao thỡ nú cho phộp 8051 thu dữ liệu trờn chõn RxD của nú và kết quả là nếu ta muốn 8051 vừa truyền và nhận dữ liệu thỡ bit REN phải được đặt lờn 1. Khi đặt REN bộ thu bị cấm, việc đặt REN = 1 hay REN = 0 cú thể đạt được bằng lệnh: SETB SCON.4 và CLR SCON.4 tương ứng. Bit này cú thể dựng khống chế mọi việc nhận dữ liệu nối tiếp và nố là bit cực kỳ quan trọng trong thanh ghi SCON. Bit TB8 và RB8 Bit TB8 là bit SCON.3 của thanh ghi SCON. Nó được dựng để cho chế độ nối tiếp 2 và 3. Ta đặt TB8 vỡ nỳ khụng được sử dụng trong cỏc ứng dụng của mỡnh. Bit RB8 ( bit thu 8) là bit SCON.2 của thanh ghi SCON. Trong chế độ nối tiếp 1 thỡ bit này nhận một bản sao của bit stop khi một dữ liệu 8 bit được nhận. Bit này cũng như bit TB8 rất hiếm được sử dụng. Trong cỏc ứng dụng của mỡnh ta đặt RB8 = 0 vỡ nú được sử dụng cho chế độ nối tiếp 2 và 3. Các bít TI và RI Các bit ngắt truyền TI và ngắt thu RI là các bit D1 và D0 của thanh ghi SCON, các bit này là cực kỳ quan trọng của thanh ghi SCON. Khi 8051 kết thúc truyền một ký tự 8 bit thì nó bật TI để báo rằng nó sẵn sàng truyền một byte khác, bit TI được bật lên trước bit stop. 2.2. Thanh ghi SBUF 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 được 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 lưu mọi thanh ghi của 8051 truy cập. MOV SBUF, # ”A” MOV A, SBUF MOV SBUF, A 115
  27. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Khi byte dữ liệu được ghi vào thanh ghi SBUF thỡ byte sẽ được định khung dữ liệu với bit start và stop và được truyền nối tiếp qua chân RxD. Tương tự như vậy khi các bit được nhận nối tiếp qua từ RxD thỡ 8051 mở khung loại trừ các bit start và stop để lấy ra một byte dữ liệu nhận được và đặt vào thanh ghi SBUF. Còn khi 8051 nhận được dữ liệu nối tiếp qua chân RxD và nó tách các bit start và stop để lấy ra 8 bit dữ liệu để đặt vào SBUF, sau khi hoàn tất nó bật cờ RI để báo rằng nó đó nhận xong một byte và cần phải lấy đi kẻo nó bị mất cờ RI được bật khi đang tách bit stop. 3. Chế độ làm việc Cổng nối tiếp có 4 chế độ hoạt động, có thể chọn được bằng cách lập trình cho các bit SM0 và SM1 trong SCON. Có 3 chế độ cho phép truyền cận đồng bộ ( UART) trong chế độ này mỗi ký tự được thu nhận hoặc phát đều nằm trong khung có 1 bit start và 1 bit stop. Ở chế độ 0 cổng nối tiếp hoạt động như một thanh ghi dịch thông thường. 3.1. Thanh ghi dịch 8 bit Để định cấu hình cho truyền dữ liệu ở chế độ thanh ghi dịch 8 bit ( chế độ 0) thì các bit SM0 và SM1 trong SCON được chọn bằng 0. Dữ liệu nối tiếp nhận vào và dữ liệu truyền đi đều thông qua chân RxD còn chân TxD thì dùng để dịch chuyển xung clock. 8 bit dữ liệu để truyền đi hay nhận về thì luôn bắt đầu với bit có trọng số nhỏ nhất LSB. Tốc độ baud được thiết lập cố định ở tần số bằng 1/12 tần số dao động của thạch anh trên chip. Khi thực hiện lệnh ghi dữ liệu lên thanh ghi SBUF thì quá trình truyền dữ liệu bắt đầu. Dữ liệu được dịch ra ngoài thông qua chân RxD cùng các xung nhịp cũng được gởi ra ngoài thông qua chân TxD. Mỗi bit truyền đi chỉ có xuất hiện trên chân RxD trong khoảng thời gian một chu kỳ máy. Trong khoảng thời gian của mỗi chu kỳ máy tín hiệu xung clock xuống mức thấp tại thời điểm S3P1 và lên mức cao tại thời điểm S6P1 trong giản đồ thời gian: Một ứng dụng cụ thể sử dụng chế độ 0 để mở rộng thêm số lượng ngõ ra cho 8051 với cách thực hiện như sau: Một thanh ghi dịch từ nối tiếp thành song song được nối đến các đường TxD và RxD của 8051 để mở rộng thêm 8 đường. Nếu dùng thêm nhiều thanh ghi dịch mắc nối tiếp vào thanh ghi dịch đầu tiên sẽ mở rộng được nhiều ngõ ra. 116
  28. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Hình 5.5 : Tăng thêm cổng vào ra song song sử dụng cổng nối tiếp ở chế độ 0 3.2. Chế độ UART 8 bit có tốc độ baud thay đổi Trong chế độ này truyền dữ liệu nối tiếp hoạt động bất đồng bộ UART 8 bit có tốc độ baud thay đổi được, UART là bộ thu và phát dữ liệu nối tiếp với mỗi ký tự dữ liệu luôn bắt đầu bằng 1 bit start ( ở mức 0) và kết thúc bằng 1 bit stop ( ở mức 1), bit parity đôi khi được ghép vào giữa bit dữ liệu sau cùng và bit stop. Trong kiểu này 10 bit dữ liệu sẽ phát đi ở chân TxD và nếu nhận thì sẽ nhận ở chân RxD . 10 bit đó bao gồm: + 1 bit start. + 8 bit data (LSB là bit đầu tiên). + 1 bit stop. Đối với hoạt động nhận dữ liệu thì bit stop được đưa vào bit RB8 trong thanh ghi SCON. Trong 8051 tốc độ baud được thiết lập bởi tốc độ tràn của timer T1. Đối 8052 có 3 timer thì tốc độ baud có thể thiết lập bởi tốc độ tràn của timer T1 hoặc timer T2 hoặc cả 2 timer T1 và T2 một timer cho máy phát và một timer cho máy thu. Nguồn cung cấp xung clock để đồng bộ các thanh ghi truyền dữ liệu nối tiếp hoạt động ở kiểu 1,2,3 được thiết lập bởi bộ đếm 16, ngõ ra của bộ đếm là xung clock tạo tốc độ baud, xung ngõ vào của bộ đếm có thể lập trình bằng phần mềm. Khi có một lệnh ghi dữ liệu lên thanh ghi SBUF thì quá trình truyền dữ liệu bắt đầu nhưng nó chưa truyền mà chờ cho đến khi bộ chia 16 ( cung cấp tốc độ baud cho truyền dữ liệu nối tiếp) bị tràn. Dữ liệu được xuất ra trên chân TxD bắt đầu với bit start theo sau là 8 bit data và sau cùng là bit stop. Các cờ TI được nâng lên mức 1 cùng lúc với thời điểm xuất hiện bit stop trên chân TxD. Quá trình nhận dữ liệu được khởi động khi có sự chuyển đổi từ mức 1 sang mức 0 ở ngõ vào RxD. Bộ đếm 4 bit được reset ngay lập tức để sắp xếp bit 117
  29. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái dữ liệu đang đến từ ngõ vào RxD. Mỗi bit dữ liệu đến được lấy mẫu ở trạng thái đếm thứ 8 trong một chu kỳ 16 trạng thái của bộ đếm 4 bit. Khi có sự chuyển trạng thái từ 1 xuống 0 ở ngõ vào RxD của bộ thu thì trạng thái 0 này phải tồn tại trong 8 trạng thái liên tục của bộ đếm 4 bit. Nếu trường hợp này không đúng thì bộ thu xem như bị tác động bởi tín hiệu nhiễu. Bộ thu sẽ reset và trở về trạng thái nghỉ và chờ sự chuyển trạng thái tiếp theo. Giả sử việc kiểm tra bit start là hợp lệ thì bit start sẽ được bỏ qua và 8 bit data được nhận vào thanh ghi dịch nối tiếp. Khi tất cả 8 bit được ghi vào thanh ghi dịch thì 3 công việc sau sẽ được thực hiện tiếp theo: - Bit thứ 9 được dịch vào bit RB8 trong SCON. - 8 bit data được nạp vào thanh ghi SBUF. - Cờ ngắt nhận RI = 1. - Tuy nhiên 3 công việc trên chỉ xảy ra nếu hai điều kiện sau tồn tại: - RI = 0 - SM2 = 1 3.3. UART 9 bit với tốc độ baud cố định Khi SM1 = 1 và SM0 = 0 thì truyền dữ liệu hoạt động kiểu 2 có tốc độ baud cố định. Có 11 bit được phát hoặc thu: - 1 bit start. - 8 bit data. - 1 bit data thứ 9 được lập trình. - 1 bit stop. Khi phát thì bit thứ 9 được đặt vào TB8 của SCON. Khi thu thì bit thứ 9 được đặt vào bit RB8 của thanh ghi SCON, tốc độ baud trong chế độ 2 bằng 1/12 hoặc 1/64 tần số dao động trên chip. 3.4. Chế độ UART với tốc độ baud cố định Khi SM1 = 1 và SM0 = 1 thì truyền dữ liệu hoạt động ở kiểu 3 là kiểu UART 9 bit có tốc độ baud thay đổi. Kiểu 3 tương ứng kiểu 2 ngoại trừ tốc độ baud được lập trình và được cung cấp bởi timer. Các kiểu 1, kiểu 2, kiểu 3 rất giống nhau, nhưng điểm khác nhau là ở tốc độ baud ( kiểu 2 cố định, kiểu 1 và kiểu 3 thay đổi) và số bit dữ liệu ( kiểu 1 có 8 bit, kiểu 2 và kiểu 3 có 9 bit data). 4. Khởi tạo và truy xuất thanh ghi PORT nối tiếp 4.1. Cho phép nhận Để cho phép thu dữ liệu thì chương trình phải làm cho bit REN = 1 và điều này được thực hiện ở đầu chương trình. Ta có thể khởi tạo cho phép truyền dữ liệu bằng lệnh : SETB REN 118
  30. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Hoặc : MOV SCON, #xxx1xxxB Sẽ lập REN lên 1 và lập hoặc xóa các bit khac trong SCON tùy theo yêu cầu khác nhau ( Các x phải là 0 hoặc 1 để khởi động các chế độ hoạt động). 4.2. Bit dữ liệu thứ 9 Bit dữ liệu thứ 9 được phát trong kiểu 2 và kiểu 3 phải được nạp vào bit TB8 bằng phần mềm có nghĩa là người lập trình phải thực hiện công việc này trước khi dữ liệu truyền đi, còn bit dữ liệu thứ 9 của dữ liệu thu được thì tự động đặt vào trong bit RB8. Phần mềm có thể hoặc không đòi hỏi bit dữ liệu thứ 9 tham gia vào quá trình truyền dữ liệu tùy thuộc vào đặc tính của các thiết bị nối tiếp kết nối với nhau thiết lập ra quy định. Bit dữ liệu thứ 9 đóng vai trò quan trọng truyền thông nhiều vi xử lý. 4.3. Thêm vào bit chẵn – lẻ Bit thứ 9 thường được dùng là bit kiểm tra chẵn – lẻ. Ở mỗi chu kỳ máy bit P trong thanh ghi trạng thái PSW bằng 1 hay bằng 0 tùy thuộc vào quá trình kiểm tra chẵn 8 bit dữ liệu chứa trong thanh ghi A. Nếu hệ thống truyền dữ liệu yêu cầu 8 bit data cộng thêm 1 bit kiểm tra chẵn thì các lệnh sau đây sẽ phát 8 bit trong thanh ghi A cộng với bit kiểm tra chẵn được cộng vào bit thứ 9: MOV C, P : Chuyển cờ chẵn lẻ P sang cờ C. MOV TB8, C : Chuyển cờ C sang bit TB8 để chuẩn bị truyền đi. MOV Sbuf, A : Truyền dữ liệu 8 bit trong A và bit thứ 9 trong TB8 đi. Nếu kiểm tra lẻ được yêu cầu thì các lệnh trên được sửa lại là : MOV C, P : Chuyển cờ chẵn lẻ P sang cờ C CPL C : Ngịch đảo chẵn thành lẻ MOV TB8, C : Chuyển cờ C sang bit TB8 để chuẩn bị truyền đi. MOV Sbuf, A : Truyền dữ liệu 8 bit trong A và bit thứ 9 trong TB8 đi. Trong kiểu 1 ta vẫn có thể sử dụng bit kiểm tra chẵn lẻ như sau: 8 bit data được phát trong kiểu 1 có thể bao gồm 7 bit dữ liệu và 1 bit kiểm tra chẵn lẻ. Để phát một mã ASCII 7 bit với 1 bit kiểm tra chẵn vào 8 bit các lệnh sau đây được dùng: MOV C, P : Đưa cờ chẵn vào C 119
  31. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái MOV ACC.7, C : Đưa cờ chẵn vào bit MSB của A. MOV SBUF, A : Gửi bit data cùng bit cờ chẵn. 4.4. Các cờ ngắt Cờ ngắt nhận RI và phát TI trong thanh ghi SCON đóng vai trò quan trong truyền dữ liệu của 8051. Cả hai bit đều được thiết lập bởi phần cứng nhưng phải được xóa bằng phần mềm. Điển hình là cờ RI được thiết lập ở mức 1 khi kết thúc quá trình nhận đầy đủ 1 kí tự và cho biết thanh ghi đệm thu đã đầy. Trạng thái của cờ RI có thể kiểm tra bằng phần mềm hoặc có thể lập trình để sinh ra ngắt. Nếu muốn nhận một ký tự từ một thiết bị đã được kết nối đến Port nối tiếp thì chương trình phải chờ đến khi cờ RI = 1, sau đó xóa cờ RI và đọc ký tự từ thanh ghi SBUF. Quá trình này được lập trình như sau: WAIT : JNB RI, WAIT : Kiểm tra RI xem có bằng 1 hay không. CLR RI : Khi cờ RI = 1 thì đã nhận xong dữ liệu và xóa cờ RI. MOV A, SBUF : Đọc ký tự nhận được thanh ghi SBUF. Cờ TI lên mức 1 cho biết đã phát xong ký tự và cho biết thanh ghi đệm SBUF đã rỗng. Nếu muốn gởi 1 ký tự đến một thiết bị đã được đã kết nối đến Port nối tiếp thì trước tiên phải kiểm tra xem Port nối tiếp đã sẵn sàng chưa. Nếu ký tự trước đang được gửi đi thì phải chờ cho đến khi kết thúc quá trình gửi. Các lệnh sau đây dùng để phát một ký tự trong thanh ghi A : WAIT : JNB TI, WAIT : Kiểm tra TI có bằng 1 hay không và chờ nếu bằng 0 CLR TI : Xóa cờ ngắt thu TI MOV SBUF, A : Gửi nội dung trong thanh ghi A. Các đoạn chương trình trên là một phần của các hàm nhập và xuất ký tự chuẩn. 5. Truyền thông đa xử lý Chế độ 2 và 3 có một chức năng đặc biệt cho việc truyền thông đa xử lý. Ở các chế độ 2 và chế độ 3 thì 9 bit dữ liệu thu và bit thứ 9 được lưu vào bit RB8. Truyền dữ liệu có thể lập trình sao cho khi thu được bit stop thì ngắt của truyền dữ liệu nối tiếp tác động chỉ khi bit RB8 = 1. Cấu trúc này được phép bởi cách thiết lập bit SM2 = 1trong thanh ghi SCON. Kiểu này được ứng dụng trong mạng sử dụng 8051 được tổ chức theo cấu hình máy chủ và máy tớ như hình sau: 120
  32. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Hình 5.6: Truyền thông tin nối tiếp trong hệ thống đa xử lý. Quá trình truyền dữ liệu mô tả như sau: - Khi khởi động, các vi điều khiển slave có bit SM2 = 1 (trong thanh ghi SCON) và hoạt động ở chế độ UART 9 bit. Như vậy, slave chỉ nhận được dữ liệu khi bit truyền thứ 9 (TB8 của master) là 1. - Mỗi slave được gán trước một địa chỉ. Khi cần trao đổi thông tin với slave nào, master sẽ gởi dữ liệu 9 bit gồm 8 bit địa chỉ của slave và bit 9 = 1. Dữ liệu này sẽ được tất cả các slave nhận về (do bit 9 = 1). Chương trình trong slave sẽ kiểm tra giá trị địa chỉ tương ứng, nếu trùng với địa chỉ đã cài đặt sẵn thì đảo bit SM2 (= 0), nếu khác thì bỏ qua. - Tiếp tục, master sẽ gởi dữ liệu đến slave nhưng lúc này bit 9 = 0. Khi đó, chỉ có slave nào có bit SM2 = 0 mới nhận được dữ liệu. - Sau khi truyền xong dữ liệu, master gởi lại 8 bit địa chỉ và bit 9 = 1. Slave nhận được sẽ đảo bit SM2 lần nữa để khôi phục trạng thái ban đầu. Như vậy, trong quá trình truyền thông đa xử lý, có 2 loại thông tin gởi: byte địa chỉ nếu bit 9 = 1 và byte dữ liệu nếu bit 9 = 0. Nhận dạng địa chỉ động: Trong các phiên bản mới của 8051, địa chỉ của các slave có thể nhận dạng bằng các thanh ghi SADDR và thanh ghi mặt nạ SADEN (các bit không quan tâm trong thanh ghi địa chỉ SADDR sẽ tương ứng với các bit 0 trong thanh ghi SADEN). Xét hệ thống có 1 master và 3 slave: Slave 1: SADDR = 1111 0001b, SADEN = 1111 1010b Slave 2: SADDR = 1111 0011b, SADEN = 1111 1001b. 121
  33. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Slave 3: SADDR = 1111 0001b, SADEN = 1111 1010b. Nếu chỉ cần gởi dữ liệu cho slave 1, địa chỉ cần sử dụng có bit 0 = 0 (do địa chỉ của slave 2 và slave 3 có bit 0 = 1 còn địa chỉ của slave 1 có bit 0 tuỳ ý), giả sử là 1111 0000b. Nếu cần gởi cho slave 2 và slave 3 mà không gởi cho slave 1 thì địa chỉ cần dùng có bit 1 = 1 (do địa chỉ của slave 1 có bit 1 = 0 còn slave 2 và 3 thì tuỳ ý), giả sử như 1111 0011b. Nhận dạng địa chỉ Broadcast Địa chỉ broadcast tạo thành từ phép toán OR giữa các thanh ghi SADDR và SADEN trong đó các bit 0 xác định đó là các bit không quan tâm. Giả sử SADDR = 0101 0000b và SADEN = 1111 1101b thì: Địa chỉ broadcast là 1111 11x1 6. Tốc độ Baud Tốc độ truyền dữ liệu của một hệ máy tính đã cho phụ thuộc vào các cổng truyền thông kết nối vào trong hệ thống đo. Ví dụ, các máy tính PC/XT trước đây của IBM có thể truyền dữ liệu với tốc độ 100 đến 9600 bps. Tuy nhiên, trong những năm gần đây thì các máy tính PC dựa trên Pentium truyền dữ liệu với tốc độ lên tới 56kbps. Cần phải nói thêm rằng trong truyền thông dữ liệu nối tiếp dị bộ thì tốc độ baud nhìn chung là bị giới hạn ở 100.000 bps. Tốc độ baud mỗi chế độ cụ thể như sau: - Chế độ 0: Tốc độ baud cố định = 1/12 tần số thạch anh. - Chế độ 2: 122
  34. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Tốc độ baud = 1/32 tần số thạch anh khi SMOD = 1. Tốc độ baud = 1/64 khi SMOD = 0. (SMOD: nằm trong thanh ghi PCON). - Chế độ 1 và 3: tốc độ baud xác định bằng tốc độ tràn của timer 1. Trong họ 8052 có thể dùng timer 2 để tạo tốc độ baud còn trong các phiên bản mới, có thể dùng bộ tạo tốc độ nội (INT_BRG – Internal Baud Rate Generator). Việc xác định nguồn tạo tốc độ baud mô tả như hình: Hình 5.7: Lựa chọn tốc độ baud Vì thanh ghi PCON không được định địa chỉ bit nên để set bit SMOD mà không làm thay đổi các bit khác cần một thao tác đọc- sửa- ghi như sau: MOV A, PCON ; Đọc giá trị hiện hành của PCON SETB ACC.7 ; set bit 7 ( SMOD) MOV PCON, A ; Ghi giá trị mới vào PCON 6.1. Tạo tốc độ baud bằng Timer 1 Khi bộ Timer 1 được dùng để tạo tốc độ Baud, thì các tốc độ Baud ở các chế độ 1 và 3 do tốc độ tràn của timer 1 và giá trị của SMOD quyết định: Tốc độ Baud ở chế độ 1 và 3 = (2SMOD*(Tốc độ tràn của timer 1))/32 Ngắt của Timer 1 sẽ mất tác dụng trong ứng dụng này. Bản thân bộ Timer có thể được thiết lập để thực hiện chức năng thời gian hay bộ đếm ở bất kỳ một trong 3 chế độ hoạt động. Trong hầu hết các kiểu ứng dụng, nó thường được thiết lập để thực hiện chức năng thời gian, hoạt động ở chế độ Auto-reload (nửa byte cao của TMOD = 0010b). Trong trường hợp này, tốc độ baud được tính bằng công thức: 123
  35. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Tốc độ Baud chế độ 1 và 3 = (2SMOD*Tần số bộ dao động)/(32*(12*[256- (TH1)]) Ta có thể nhận được các tốc độ Baud rất thấp với bộ Timer 1 bằng cách làm cho ngắt của timer 1 có tác dụng, và thiết lập Timer 1 để hoạt động như một bộ đếm thời gian 16 bit (Nửa byte cao của TMOD=0001b). Bảng 2.8 liệt kê các tốc độ Baud khác nhau thường được sử dụng và cách chúng có thể nhận được từ Timer 1. Tốc độ Baud Tần số Timer 1 d.động SMODE (Hz) (MHz) C/(/T) Mode Giá trị nạp lại Mode 0 Max: 1M 12 x X X X Mode 2 Max: 375K 12 1 X X X Mode 1,3 12 1 0 2 FFh Max:62,5K 19,2K 11,059 1 0 2 FDh 9,6K 11,059 0 0 2 FDh 4,8K 11,059 0 0 2 FAh 2,4K 11,059 0 0 2 F4h 1,2K 11,059 0 0 2 E8h 137,5 11,966 0 0 2 1Dh 110 6 0 0 2 72h 110 12 0 0 1 FEEBh Bảng 5.2: Các tốc độ Baud được tạo ra khi sử dụng Timer 1 Ví dụ: Viết đoạn mã lệnh khởi tạo cổng nối tiếp hoạt động như một UART với tốc độ 2400 baud dùng timer 1 để cung cấp xung baud. Trong ví dụ này phải khởi tạo 4 thanh ghi SMOD, TMOD, TCON và TH1 các giá trị cần thiết được tóm tắt như sau: SMO SM1 SM2 REN TB8 RB8 Ti Ri SCON: 0 1 0 1 0 0 1 0 124
  36. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái GTE C/T M1 M0 GTE C/T M1 M0 TMOD: 0 0 1 0 0 0 0 0 TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 TCON: 0 1 0 0 0 0 0 0 TH1: 1 1 1 1 0 0 1 1 Thiết lập SM0/ SM1 = 0/1 để đặt cổng nối tiếp vào chế độ UART 8 bit, REN = 1 cho phép cổng nối tiếp nhận các kí tự đặt Ti=1 cho phép phát kí tự đầu tiên bằng cách báo rằng bộ đệm trống. Đối với TMOD việc thiết lập M1/ M0 = 1/0 sẽ đặt timer1 ở chế độ tự nạp lại 8 bit, đặt TR1 = 1 để khởi động timer 1, các bit khác bằng 0 vì chúng điều khiển các đặc tính khác và các chế độ không cần dùng trong ví dụ này. Tốc độ tràn của Timer 1 là 2400 baud x 32 = 76,8 Khz. Giả sử tần số thạch anh của 8051 là 12 MHz nên xung kích timer 1 là 1 MHz = 1.000KHz do đó xung cho mỗi lần tràn là 1.000KHz ÷ 76,8 KHz = 13,02 ( làm tròn 13) vậy giá trị nạp lại là -13 hoặc 0F3H đoạn lệnh khởi tạo như sau : INIT : MOV SCON,#52H ; cổng nối tiếp ở mode 1 MOV TMOD,# 20H ; timer 1,mode 2 MOV TH1,# -13 ; trị nạp lại tương ứng 2.400 baud SET TR1 ; khởi động timer 1 6.2. Tạo tốc độ baud bằng Timer 2 Timer 2 được dùng để tạo tốc độ baud khi đặt các bit TCLK, RCLK lên 1 (trong thanh ghi T2CON). Công thức liên quan giữa tốc độ baud và giá trị nạp như sau (lưu ý rằng giá trị nạp chứa trong cặp thanh ghi RCAP2H_RCAP2L): Khi dùng Timer 2 để tạo tốc độ baud, xung clock thu và phát có thể tách riêng bằng cách chỉ dùng TCLK hay RCLK. Lúc đó, xung clock còn lại được xác định theo Timer 1. Ngoài ra, cũng có thể tạo ngắt cho Timer 2 bằng cách đặt bit EXEN2 = 1 và ngắt tạo ra khi xuất hiện cạnh âm tại chân T2EX. 7. Luyện tập Những bài tập sau đây là các chương trình điển hình trong yêu cầu giao tiếp giữa các thiết bị đầu cuối (hoặc các thiết bị nối tiếp khác) với máy tính. Giả sử cổng nối tiếp của 8051 được khởi tạo ở chế độ UART 8 bít và tốc độ buade được cung cấp bởi timer 1. 1. Viết chương trình con có tên là OUTSTR để gởi một chuỗi mã ASCII kết thúc bằng ký tự null đến thiết bị kết nối với cổng nối tiếp 125
  37. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái của 8051. Giả sử chuỗi mã ASCII được chứa ở bộ nhớ chương trình ngoài và chương trình gọi đặt địa chỉ của chuỗi vào con trỏ dử liệu trước khi gọi OUTSTR. Chuuỗi này là các byte ASCII nối tiếp và kết thúc bằng byte 00H. 2. Viết chương trình con có tên INLINE để nhập một dòng mã ASCII từ một thiết bị nối với cổng nối tiếp của 8051 và lưu vào RAM nội tại địa chỉ 50H. Giả sử dòng dử liệu được kết thúc bằng ký tự xuống dòng. Đặt mã của ký tự xuống dòng trong bộ đệm dòng theo sau các mã khác và sau đó kết thúc bộ đệm dòng bằng byte 00H. 3. Viết chương trình gởi liên tục các chử cái (chử nhỏ) đến thiết bị kết nối với port nối tiếp 8051. Dùng chương trình con OUTCHAR ở phần trên. 4. Dựa trên chương trình con OUTCHAR viết chương trình gởi liên tục các mã ASCII hiển thị được (20H – 7EH) đến thiết bị kết nối với ccổng nối tiếp của 8051. 5. Sửa lại lời giải của bài tập trên để đưa ngỏ ra đến màn hình bằng cách dùng mã XOFF và XON nhập vào từ bàn phím. Bỏ qua các mã nhập vào khác (lưu ý: XOFF = CONTROL-S; XON = CONTROL-Q) 6. Dựa trên các chương trình con INCHAR và OUTCHR, viết chương trình nhập các ký tự từ bàn phím và hiển thị chúng trên màn hình. Biến đổi chử nhỏ thành chử in. 7. Dựa trên các chương trình con INCHAR và OUTCHR, viết chương trình nhập các ký tự từ một thiết bị kết nối với port nối tiếp của 8051 và hiển thị trên màn hình bằng cách thay thế bằng dấu chấm (.) đối với các ký tự điều khiển (có mã ASCII 00H đến 1FH và 7FH). 8. Dùng chương trình con OUTCHR viết chương trình xóa màn hình kết nối với port nối tiếp 8051 sau đó gởi tên của bạn ra màn hình 10 lần trên 10 dòng khác nhau. Chức năng xóa màn hình được thực hiện bằng cách gởi mã CONTROL-Z đối với đa số thiết bị hoặc đối với các thiết bị hổ trợ chuẩn ANSI (american national standarts institute). 9. Trong hình 5.1 cho thấy một kỹ thuật mở rộng ngỏ ra của 8051. Giả sử với cấu hình như thê viết một chương trình khởi tạo port nối tiếp 8051 ở chế độ thanh ghi dịch và sau đó ánh xạ nội dung của RAM nội tại địa chỉ 20H đến 8 ngỏ ra mở rộng, mỗi giây 10 lần 126
  38. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Bài 6: Ngắt (Interrupt) 1. Mở dầu Ngắt là sự xuất hiện của một điều kiện, một sự kiện làm tạm dừng chương trình trong khi điều kiện này được phục vụ bởI một chương trình khác. Ngắt có một vai trò quan trọng trong thiết kế và thực hiện các ứng dụng của vi điều khiển. Chúng cho phép hệ thống đáp ứng không đồng bộ vớI một sự kiện và xử lý sự kiện trong khi một chương trình khác đang hoạt động. Một hệ thống được điều khiển bằng ngắt tạo một ảo giác thực hiện đồng thờI nhiều công việc cùng một lúc Dỉ nhiên, tạI một thờI điễm CPU không thể thực hiện nhiều hơn một lệnh nhưng nó có thể tạm dừng chương trình để thực hiện một chương trình khác và sau đó trở lạI chương trình đầu tiên. Điễm khác là trong một hệ thống điều khiển bằng ngắt, các ngắt không xảy ra như là kết quả của một lệnh (như lệnh gọI chương trình con) mà là đáp ứng vớI một sự kiện xảy ra một cách không đồng bộ vớI chương trình chính có nghĩa là không biết trước chương trình chính sẻ bị ngắt lúc nào. Chương trình xử lý ngắt được gọI là chương trình phục vụ ngắt (Interrupt service routine) viết tắt là ISR hay quản lý ngắt. ISR hoạt động để đáp ứng một ngắt và thường thực hiện một thao tác vào hoặc ra đến một thiết bị. Khi xảy ra một ngắt thì chương trình chính tạm thờI dừng lạI và rẻ nhánh đến ISR. ISR thực hiện các thao tác cần thiết và kết thúc vớI lệnh trở về từ ngắt và chương trình chính lạI tiếp tục từ nơi tạm dừng. Như vậy có thể nói chương trình chính hoạt động ở mức cơ sở và các ISR hoạt động ở mức ngắt cũng có dùng các thuật ngữ: “phía trước” (foreground) để chỉ mức cơ sở và “phía sau” (backgrround) để chỉ mức ngắt, trong hình 6.1a trình bày hoạt động của một chương trình không có ngắt và 6.1b là hoạt động của chương trình chính ở mức cơ sở có ngắt và các ngắt hoạt động ở mức ngắt. Một ví dụ điển hình về ngắt là việc nhập dử liệu bằng tay dùng bàn phím. Hãy khảo sát một ứng dụng về lò vi sóng: Chương trình chính điều khiển phần tử tạo năng lượng vi sóng để nấu ăn, nhưng trong khi đang nấu hệ thống cần phảI đáp ứng việc nhập bằng tay trên cửa lò ví dụ tăng hoặc giãm thờI gian nấu. Khi ngườI xử dụng thả nút nhấn, một ngắt được tạo ra (có thể là một tín hiệu chuyển từ mức cao xuống mức thấp) và chương trình chính bị dừng lạI, chương trình ISR hoạt động đọc các mả của bàn phím và thay đổI quá trình nấu tương ứng sau đó chấm dứt bằng cách chuyển điều khiển về cho chương trình chính, chương trình chính lạI tiếp tục từ nơi bị ngắt. Một điểm quan trọng trong ví dụ này là việc nhập bằng tay xảy ra một cách không đồng bộ có nghĩa là không biết trước hoặc không được điều khiển bằng phần mềm đang chạy trong hệ thống. Đó chính là đặc điễm của ngắt 127
  39. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Thời gian Chương trình chính a) Thực hiện không có chương trình ngắt ỈSR ỈSR ỈSR main main main main a) Thực hiện có chương trình ngắt Hình 6.1 Thực hiện chương trình 2. Tổ chức ngắt của 8051 8051 có năm nguồn tín hiệu ngắt: 2 ngắt ngoài, 2 ngắt định thời và 1 ngắt cổng nối tiếp. 8052 có thêm ngắt thứ sáu của timer thứ ba. Trạng thái mặc định của các ngắt là không hoạt động sau khi reset hệ thống và chuyển sang hoạt động từng ngắt riêng rẻ bằng phần mềm. Trong trường hợp có hai hoặc nhiều ngắt xuất hiện đồng thời hoặc một ngắt xảy ra trong khi một ngắt khác đang được phục vụ. Có hai sơ đồ sắp xếp ưu tiên các ngắt đó là: Chuỗi pooling và ưu tiên hai cấp, thứ tự theo chuỗi pooling thì cố định nhưng sơ đồ ưu tiên hai cấp thì lập trình được. Sau đây là phương pháp cho phép và không cho phép sự hoạt động của các ngắt. 2.1. Cho phép và không cho phép các ngắt Mỗi một tín hiệu ngắt được cho phép hoặc không cho phép bởi địa chỉ bít trong thanh ghi chức năng đặc biệt IE (Interrupt enable) tại địa chỉ 0A8H, có một bít cho phép toàn cục, bít này khi bị xóa sẻ ngăn tất cả các ngắt. (bảng 6.1). Để cho phép một ngắt cần phải set hai bít: Một bít cho phép riêng và bít cho phép toàn cục. VD Ngắt timer 1 được cho phép như sau: SETB ET1 SETB EA Hoặc MOV IE,#10001000B Mặc dù hai cách trên có cùng kết quả sau khi reset hệ thống nhưng kết quả sẻ khác nhau nếu IE được ghi ở giữa chương trình trong khi đang chạy. Cách thứ nhất không ảnh hưỡng đến 5 bít còn lại trong thanh ghi IE còn cách thứ hai sẻ xóa các bít còn lại khác. Tốt nhất nên dùng cách thứ hai tại vị trí bắt đầu chương trình (nghĩa là khi bắt đầu mở máy hoặc reset hệ thống) nên dùng 128
  40. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái lệnh SETB và CLR trong khi chương trình đang chạy để tránh ảnh hưỡng các bít khác trong thanh ghi IE. 2.2. Mức ưu tiên Mỗi ngắt được lập trình ở một trong hai mức ưu tiên bằng thanh ghi IP (Interrupt priority) tại địa chỉ oB8H (bảng 6.2) Thanh ghi IP tự động xóa sau khi reset hệ thống để đặt các ngắt ở mức ưu tiên thấp Bảng 6.1 Thanh ghi IE Mô tả BÍT Ký hiệu Địa chỉ bít (1=cho phép, 0=không cho phép) IE.7 EA AFH Cho phép toàn cục IE.6 - AEH Không dùng IE.5 ET2 ADH Cho phép ngắt timer 2 (8052) IE.4 ES ACH Cho phép ngắt cổng nối tiếp IE.3 ET1 ABH Cho phép ngắt timer 1 IE.2 EX1 AAH Cho phép ngắt 1 ngoài IE.1 ET0 A9H Cho phép ngắt timer 0 IE.0 EX0 A8H Cho phép ngắt 0 ngoài Bảng 6.1 Thanh ghi IP Mô tả BÍT Ký hiệu Địa chỉ bít (1=cho phép, 0=mức thấp) IP.7 - - Không dùng IP.6 - - Không dùng IP.5 PT2 0BDH Ưu tiên ngắt timer 2 (8052) IP.4 PS 0BCH Ưu tiên ngắt cổng nối tiếp IP.3 PT1 0BBH Ưu tiên ngắt timer 1 IP.2 PX1 0BAH Ưu tiên ngắt 1 ngoài IP.1 PT0 0B9H Ưu tiên ngắt timer 0 IP.0 PX0 0B8H Ưu tiên ngắt 0 ngoài Khái niệm “ưu tiên” cho phép một ISR bị dừng bởi một ngắt khác nếu ngắt mới xuất hiện này có mức ưu tiên cao hơn ngắt đang được phục vụ, điều này phù hợp với 8051 vì chỉ có hai mức ưu tiên, nếu một ISR ưu tiên thấp đang chạy nhưng lại xảy ra một ngắt ưu tiên cao thì ISR sẻ bị dừng. Một ISR ưu tiên 129
  41. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái không thể bị dừng. Chương trình chính hoạt động ở mức ưu tiên cơ sở và không liên hệ với một ngắt bất kỳ nào nên luôn bị dừng khi xảy ra ngắt. Nếu hai ngắt có mức ưu tiên khác nhau cùng xảy ra thì ngắt có mức ưu tiên cao sẻ được phục vụ trước. 2.3. Chuỗi pooling Nếu đồng thời xuất hiện hai ngắt có cùng mức ưu tiên thì ngắt được phục vụ trước được xác định theo thứ tự chuỗi pooling: Ngắt 0 ngoài, ngắt timer 0, ngắt 1 ngoài, ngắt timer 1, ngắt cổng nối tiếp, ngắt timer 2. Hình 6.2 trình bày năm nguồn tín hiệu ngắt cùng cơ chế cho phép toàn cục và riêng rẻ, chuỗi pooling và các mức ưu tiên, trạng thái của tất cả các nguồn tín hiệu ngắt có thể thông qua các bít cờ trong thanh ghi chức năng đặc biệt. Dỉ nhiên, nếu một ngắt nào đó không được cho phép thì ngắt tương ứng không được tạo ra nhưng phần mềm vẩn có thể kiểm tra cờ ngắt. Các ví dụ về timer và cổng nối tiếp trong hai bài trước đã sử dụng các cờ ngắt mà thực tế không dùng các ngắt. Một ngắt cổng nối tiếp là kết quả từ phép OR của ngắt thu (RI) với ngắt phát (TI).Tương tự, ngắt timer 2 được tạo ra bởi cờ tràn TF2 hoặc với cờ nhập bên ngoài EXF2. Khả năng tạo ngắt của các bít cờ được tóm tắt trong bảng 6.3 3. Xử lý ngắt Khi một ngắt xuất hiện được CPU nhận ra, chương trình chính sẻ dừng lại và kế tiếp là các thao tác như sau: - Thực hiện hoàn tất lệnh hiện hành - Lưu nội dung thanh ghi PC vào ngăn xếp - Lưu trạng thái ngắt hiện hành - Các ngắt được chặn lại tại mức ngắt - Nạp địa chỉ vectơ của ISR vào PC - Thực hiện ISR Chương trình ISR hoạt động và thực hiện các thao tác tương ứng với ngắt. Sau đó, kết thúc khi gặp lệnh RETI (return from interrupt), lệnh này lấy lại giá trị của PC từ ngăn xếp và phục hồi trạng thái ngắt cũ, chương trình tiếp tục chạy từ nơi tạm dừng. Ngắt Cờ Thanh ghi SFR và vị trí bit 0 ngoài IE0 TCON.1 1 ngoài IE1 TCON.3 timer 1 TF1 TCON.7 timer 0 TF0 TCON.5 130
  42. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái cổng nối tiếp TI SCON.1 cổng nối tiếp RI SCON.0 timer 2 TF2 T2CON.7 (8052) timer 2 EXF2 T2CON.6 (8052) Ưu tiên cao IE0 TF0 Ưu tiên IE1 TF1 Chuỗi Ri poolin Ti TF2 EXF2 Cho phép riêng phép Cho toàn Hình 6.2 Cấu trúc ngắt 8051 Các vec tơ ngắt Khi một ngắt được chấp nhận, giá trị nạp vào bộ đếm chương trình PC được gọi là véc tơ ngắt. Đây là địa chỉ bắt đầu của ISR đối với ngắt tương ứng. Các véc tơ ngắt được cho trong bẳng 6.4. Véc tơ reset hệ thống (RST tại địa chỉ 0000H) cũng được cho trong bảng nên nó cũng giống như một ngắt, nó dừng chương trình chính và nạp vào PC một giá trị mới. Khi trỏ đến một ngắt, cờ gây ra ngắt sẻ bị xóa tự động bị xóa bởi phần cứng ngoại trừ Ri và Ti đối với ngắt cổng nối tiếp và TF2, EXF2 đối với ngắt timer 2. Do có hai nguyên nhân tạo ngắt cho các ngắt này nên thật là không thực tế nếu CPU xóa cờ ngắt. Các bít này phải được kiểm tra trong ISR để xác định nguyên nhân tạo ngắt và sau đó cờ ngắt được xóa bằng phần mềm, thường có một sự rẻ nhánh đến các thao tác tương ứng phụ thuộc vào nguồn tạo ra ngắt. Vì các véc tơ ngắt được đặt phía dưới đáy của bộ nhớ chương trình nên lệnh đầu tiên của chương trình chính thường là lệnh nhảy qua vùng này VD lệnh LJMP 0030H. 131
  43. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái 4. Thiết kế chương trình dùng ngắt Trong các bài trước đây đã không dùng đến ngắt mà dùng nhiều các vòng lặp để kiểm tra cờ tràn của timer TF0, TF1 hoặc TF2 hoặc các cờ thu phát của cổng nối tiếp Ti hoặc Ri, vấn đề của phương pháp này là thời gian hoạt động của CPU hoàn toàn được dùng vào việc chờ các cờ này được set, điều này hoàn toàn không thích hợp với các ứng dụng hướng điều khiển mà trong đó yêu cầu vi điều khiển phải đồng thời tương tác với nhiều thiết bị vào ra. Một ví dụ trong phần này sẻ minh họa các phương pháp thực tế viết phần mềm cho các ứng dụng hướng điều khiển, thành phần chính là các ngắt. Mặc dù các ví dụ này không cần thiết lớn hơn nhưng chúng sẻ phức tạp hơn, điều này được nhận ra bằng cách tiến hành từng bước. Một số rắc rối xảy ra trong khi thiết kế hệ thống là do các ngắt. Các chương trình ví dụ sau đây được bắt đầu tại địa chỉ 0000H và chương trình sẻ bắt đầu thực hiện khi reset hệ thống, các chương trình này phát triển cho các ứng dụng thực tế và được lưu vào ROM hoặc EPROM. Khuôn mẫu đề nghị cho một chương trình có xử dụng ngắt như sau: ORG 0000H ; reset điễm nhập LJMP MAIN . . ; các điễm nhập ISR . ORG 0030H ; điễm nhập chương trình chính MAIN: ; bắt đầu chương trình chính Lệnh đầu tiên nhảy đến địa chỉ 0030H ngay phía trên các vị trí của véc tơ ngắt và cũng là nơi bắt đầu các ISR như ở hình 6.3, chương trình chính bắt đầu tại địa chỉ 0030H Bảng 6.4 Các véc tơ ngắt Ngắt Cờ Địa chỉ véc tơ Reset hệ thống RST 0000H 0 bên ngoài IE0 0003H Timer 0 TF0 000BH 1 bên ngoài IE1 0013H Timer 1 TF1 001BH Cổng nối tiếp Ri hoặc Ti TF2 0023H Timer 2 hoặc EXF2 002BH 132
  44. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái RAM ngoài FFFF Chương trình chính 0030 002F Điểm nhập reset và ngắt 0000 Hình 6.3 Tổ chức ngắt trong bộ nhớ 4.1. Chương trình phục vụ ngắt kích thước nhỏ Các chương trình phục vụ ngắt phải bắt đầu gần phía dưới đáy của bộ nhớ chương trình tại các địa chỉ cho trong bảng 6.4. Mặc dù giữa các điễm nhập chỉ có 8 byte nhưng thường cũng đủ để thực hiện các thao tác cần thiết và trở lại chương trình chính từ ISR Nếu chỉ dùng một tín hiệu ngắt ví dụ timer 0 thì có thể áp dụng chương trình sau đây ORG 0000H ; reset LJMP MAIN ORG 000BH ; điễm nhập timer 0 T0ISR: ; bắt đầu ISR của timer 0 RETI ; trở về chương trình chính MAIN: ; chương trình chính Nếu dùng nhiều ngắt thì phải cẩn thận để bảo đãm rằng chúng bắt đầu tại các vị trí đúng (bảng 6.4) và không đè lên các ISR kế tiếp vì trong ví dụ trên chỉ dùng có một ngắt nên chương trình chính có thể bắt đầu ngay phía dưới lệnh 133
  45. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái RETI 4.2. Chương trình phục vụ ngắt kích thước lớn Nếu một ISR có kích thước nhiều hơn 8 byte thì có thể chuyển nó đến vị trí khác trong bộ nhớ chương trình hoặc cho lấn sang điễm nhập của ngắt kế tiếp. Điển hình là ISR bắt đầu bằng một lệnh nhảy đến nơi khác trong bộ nhớ chương trình và tại đó ISR có thể trải rộng ra. Hãy xem ví dụ sau chỉ dùng ngắt timer 0 ORG 0000H ; reset LJMP MAIN ORG 000BH ; điễm nhập timer 0 LJMP T0ISR ORG 0030H;; trên vùng véc tơ ngắt MAIN: T0ISR: ; ISR của timer 0 RETI ; trở về chương trình chính Để cho đơn giản các chương trình chỉ làm một việc tại thời điễm bắt đầu, chương trình chính sẻ khởi tạo timer, cổng nối tiếp và các thanh ghi ngắt tương ứng và sau đó không làm gì hết. Toàn bộ công việc được thực hiện trong ISR, sau các dòng lệnh khởi tạo chương trình chính chỉ còn dòng lệnh sau đây HERE: SJMP HERE Khi một ngắt xảy ra, chương trình chính tạm thời dừng lại trong khi ISR đang hoạt động, lệnh RETI ở cuối ISR trả quyền điều khiển về cho chương trình chính và chương trình lại tiếp tục không làm gì cả. Điều này cũng không có gì lạ, trong nhiều ứng dụng hướng điều khiển phần lớn công việc thường được thực hiện trong chương trình phục vụ ngắt Ví dụ 6-1: Tạo xung vuông bằng ngắt timer Viết chương trình dùng timer 0 và các ngắt để tạo xung vuông 1 KHz tại chân P1.0 Các ngắt timer xảy ra khi các thanh ghi THx/TLx tràn và cờ TFx được set, chương trình như sau ORG 0 ; reset LJMP MAIN ; nhảy qua vùng véc tơ ngắt ORG 000BH ; véc tơ ngắt timer 0 134
  46. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái T0ISR: CPL P1.0 ; đảo port bít RETI ORG 0030H MAIN: MOV TMOD,#02H ; timer 0 mode 2 MOV TH0,#-50 ; delay 50μS SETB TR0 ; khởi động timer MOV IE,#82H ; cho phép ngắt timer 0 SJMP $ ; không làm gì cả Đây là một chương trình đầy đủ có thể nạp vào EPROM và cài đặt vào UNIKIT để chạy thử. Ngay sau khi reset bộ đếm chương trình sẻ được nạp giá trị 0000H, lệnh đầu tiên được thực hiện là LJMP MAIN và chương trình nhảy qua ISR của timer đến địa chỉ 0030H trong bộ nhớ chương trình, ba lệnh tiếp theo khởi tạo timer 0 ở chế độ tự động nạp lại 8 bít và tràn sau mỗi 50 μS. Lệnh MOV IE,#82H cho phép ngắt timer 0 có nghĩa lấy mỗi lần tràn của timer sẻ tạo ra một ngắt. Dĩ nhiên lần tràn đầu tiên sẻ không xảy ra sau 50 μS do chương trình chính rơi vàovòng lặp “không làm gì cả”. Cứ sau mỗi 50 μS một ngắt sẻ xuất hiện, chương trình chính bị dừng và chương trình T0ISR hoạt động đảo trạng thái của port bít và sau đó trở về chương trình chính thực hiện tiếp vòng lặp “không làm gì cả” và chờ một ngắt khác sau 50 μS tiếp theo. Lưu ý là cờ timer TF0 không bị xóa bằng phần mềm, khi các ngắt được cho phép TF0 sẻ bị xóa tự động bởi phần cứng ngay khi CPU trỏ đến ngắt. Địa chỉ trở về trong chương trình chính là vị trí của lệnh SJMP, địa chỉ này được CPU cất vào trong ngăn xếp trước khi trỏ đến véc tơ ngắt và được lấy lại từ ngăn xếp khi thực hiện lệnh RETI ở cuối chương trình ngắt. Do thanh ghi SP đã không được khởi tạo nên địa chỉ mặc định sau khi reset của ngăn xếp là 07H, lệnh PUSH sẻ cất địa chỉ trở về trong RAM nội tại 08H (PCL) và 09H (PCH) Ví dụ 6-2: Tạo hai xung bằng ngắt Viết chương trình xử dụng ngắt tạo đồng thời hai xung vuông 7 KHz và 500 Hz tại port P1.7 và P1.6 Cấu hình phần cứng và dạng sóng ra được trình bày ở hình 6.4 135
  47. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái 143S 8051 P1.7 7KHZ 2mS P1.6 500HZ Hình 6.4 Dạng sóng Việc kết hợp các ngỏ ra là cực kỳ khó khăn đối với các hệ thống không được điều khiển bằng ngắt. Timer 0 hoạt động ở mode 2 cung cấp xung 7 KHz và timer 1 hoạt động ở mode 1 cung cấp xung 500 Hz. Vì xung 500 Hz có thời gian mức cao là 1 mS và mức thấp cũng là 1 mS nên không thể dùng mode 2, chương trình như sau ORG 0 LJMP MAIN ORG JMP 0BH ORG T0ISR LJMP 1BH ; địa chỉ véc tơ timer 0 ORG T1ISR 30H MOV TMOD,#12H ; địa chỉ véc tơ timer 1 MAIN: ; timer 1=mode ;timer 0=mode 2 MAIN: ; timer 1=mode 1; timer 0=mode 2 136
  48. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái MOV TH0,#-71 ; tạo xung 7 KHz SETB TR0 SETB TF1 ; tạo ngắt timer 1 MOV IE,#8AH ; cho phép cả hai ngắt timer SJMP $ T0ISR: CPL P1.7 RETI T1ISR: CLR TR1 MOV TH1,#HIGH (-; 1 mS mức cao 1000) MOV TL1,#LOW (-; và 1 mS mức thấp 1000) SETB TR1 CPL P1.6 RETI Chương trình chính và các ISR được đặt phía trên vùng dành cho các véc tơ ngắt và reset hệ thống, cả hai dạng sóng được tạo ra bởi lệnh CPL. Tuy nhiên, cách tạo thời gian trì hoản thì có khác nhau. Vì cặp thanh ghi TL1/TH1 phải được nạp lại sau mỗi lần tràn ( có nghĩa là sau mỗi ngắt ) nên ISR của timer 1 hoạt động như sau: (a) dừng timer, (b) nạp lại TL1/TH1, (c) khởi động timer và sau đó (d) đảo port bít. Một điễm lưu ý là TL1/TH1 không được khởi tạo tại vị trí bắt đầu của chương trình chính giống như TH0 vì TL1/TH1 phải được khởi tạo lại sau mỗi lần tràn. TF1 được set trong chương trình chính bằng phần mềm để tạo ra ngắt ban đầu ngay khi các ngắt được cho phép để bắt đầu dạng sóng 500 Hz. ISR của timer 0 chỉ có nhiệm vụ đơn giản là đảo port bít và sau đó trở về chương trình chính, SJMP $ là dạng viết tắt của HERE: SJMP HERE 5. Ngắt cổng nối tiếp Các ngắt của cổng nối tiếp xảy ra khi một trong hai cờ ngắt phát Ti hoặc cờ ngắt thu Ri được set. Ngắt phát xuất hiện khi quá trình phát của ký tự trước đó được viết vào SBUF hoàn tất, một ngắt thu xuất hiện khi một ký tự đã được nhận đầy đủ và đang chờ đọc trong SBUF 137
  49. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Các ngắt cổng nối tiếp khác với các ngắt của timer, cờ tạo ra ngắt cổng nối tiếp không được xóa bằng phần cứng khi CPU trỏ đến véc tơ ngắt lý do là có hai nguồn tạo ra một ngắt cổng nối tiếp đó là Ti hoặc Ri. Nguồn tạo ra ngắt phải được xác định trong ISR và cờ ngắt được xóa bằng phần mềm. Trở lại với các ngắt timer, cờ ngắt được xóa bằng phần cứng khi CPU trỏ đến ISR Ví dụ 6-3: Xuất ký tự bằng ngắt Viết chương trình dùng ngắt xuất liên tục bảng mã ASCII (bao gồm cả ký tự điều khiển) đến một thiết bị cuối nối với cổng nối tiếp của 8051có 128 mã 7 bít trong bảng mã ASCII bao gồm 95 mã đồ họa (20H đến 7EH) và 33 mã điều khiển (00H đến 1FH và 7FH) chương trình sau đây được thực hiện ngay sau khi reset hệ thống ORG 0 LJMP MAIN ORG 0023H ; điễm nhập ngắt cổng nối tiếp LJMP SPISR ORG 0030H MAIN: MOV TMOD,#20H ; timer 1 mode 2 MOV TH1,#-26 ; nạp giá trị 1200 baud SETB TR1 ; khởi động timer MOV SCON,#42H;mode1, set Ti để tạo ngắt đầu tiên ; gởi ký tự thứ nhất MOV A,#20H ; gởi ký tự trắng đầu tiên MOV IE,#90H ; cho phép ngắt cổng nối tiếp SJMP $ ; không làm gì cả SPISR: CJNE A,#7FH,SKIP MOV A,#20H SKIP: MOV SBUF, A INC A CLR Ti ; xóa cờ ngắt RETI Sau khi nhảy đến MAIN tại địa chỉ 003H, ba lệnh đầu tiên khởi tạo timer 1 để cung cấp xung đồng hồ 1200 baud cho cổng nối tiếp. MOV SCON,#42H khởi tạo cổng nối tiếp hoạt động ở mode 1 (8 bít UART) và set Ti để gây ra một ngắt ngay khi các ngắt được cho phép. Sau đó mã ASCII đầu tiên (20H) được nạp vào A và cho phép các ngắt, cuối cùng phần thân của chương trình chính là vòng lặp “không làm gì cả” (SJMP $) 138
  50. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Chương trình phục vụ ngắt cổng nối tiếp làm tất cả công việc mỗi khi chương trình chính thiết lập các điều kiện ban đầu. Hai lệnh đầu tiên kiểm tra bộ tích lủy và nếu mã ASCII có giá trị là 7FH (mã cuối cùng được gởi đi là 7EH) thì bộ tích lủy được reset về 20H, sau đó mã ASCII được gởi đến bộ đệm cổng nối tiếp (MOV SBUF, A) mã được tăng lên (INC A), cờ ngắt phát bị xóa (CLR Ti) và kết thúc ISR (RETI), điều khiển được trả về chương trình chính và thực hiện tiếp lệnh SJMP $ cho đến khi Ti được set khi kết thúc quá trình xuất ký tự tiếp theo. Nếu so sánh tốc độ của CPU với tốc độ truyền ký tự sẻ thấy rằng SJMP $ được thực hiện với phần trăm rất lớn về thời gian trong chương trình, tỉ lệ phần trăm này là bao nhiêu ? Với tốc độ 1200 baud thì mỗi bít truyền đi cần 1/1200 = 0,833 mS, 8 bít dử liệu cộng với 1 bít start và 1 bít stop cần 8,33 mS hoặc 8330 μS, thời gian thực hiện dài nhất của SPISR là tổng các chu kỳ của từng lệnh nhân với 1 μS (giả sử tần số thạch anh là 12MHz), trong trường hợp này là 8 μS. Như vậy, với mỗi 8333 μS cần thiết để truyền một ký tự thì chỉ cần 8 μS cho SPISR, lệnh SJMP thực hiện với tỉ lệ (8325/8333) x 100 = 99,90 % thời gian. Do dùng ngắt nên lệnh SJMP có thể được thay thế bằng các lệnh khác để thực hiện các công việc cần thiết khác của ứng dụng. Các ngắt vẩn xảy ra sau mỗi 8333 μS và ký tự vẩn được xuất ra cổng nối tiếp như nêu trên. 6. Các ngắt ngoài Các ngắt ngoài xảy ra tại mức thấp hoặc cạnh âm ở chân INT0 hoặc INT1 của 8051, đây là các chân đa năng của port 3: Bít P3.2 (chân 12) và bít P3.3 (chân 13). Các cờ tạo ra các ngắt này là bít IE.0 và IE.1 trong thanh ghi TCON, cờ tạo ra ngắt bị xóa bởi phần cứng khi CPU trỏ đến ISR nếu ngắt là loại tác động cạnh, còn đối với ngắt tác động bằng mức thì nguồn tạo ngắt bên ngoài sẻ điều khiển mức của cờ ngắt. Việc chọn lựa ngắt tác động mức thấp hoặc tác động cạnh âm được được lập trình thông qua bít IT0 và IT1 trong thanh ghi TCON. VD: Nếu IT1 = 0 thì ngắt 1 ngoài đượckích bởi mức thấp tại chân INT1 và nếu IT1 = 1 thì ngắt này được kích bằng cậnh âm. Trong chế độ này nếu các mẫu tại chân INT1 ở mức cao trong một chu kỳ và ở mức thấp trong các chu kỳ kế tiếp thì cờ IE1 trong TCON được set và sau đó cờ này sẻ yêu cầu một ngắt. Vì các chân ngắt ngoài được lấy mẫu mỗi chu kỳ máy một lần nên ngỏ vào này phải được duy trì ít nhất trong 12 chu kỳ dao động để bảo đãm việc lấy mẫu là thích hợp. Nếu là loại tác động cạnh thì nguồn ngoài phải giữ ở mức cao ít nhất một chu kỳ và ở mức thấp ít nhất một chu kỳ hoặc hơn để bảo đãm nhận ra được sự chuyển mức. IE0 và IE1 được xóa tự động khi CPU trỏ đến ngắt. Nếu ngắt ngoài là loại tác động mức thì nguồn ngoài phải duy trì mức tác động cho đến khi ngắt yêu cầu thực sự được tạo ra. Sau đó phải trở về mức 139
  51. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái không tác động trước khi ISR hoàn tất hoặc trước khi một ngắt khác được tạo ra. Thông thường một thao tác trong ISR làm cho nguồn tạo ngắt trả tín hiệu ngắt trở về trạng thái không tác động. Ví dụ 6-4: Điều khiển lò sưởi Xử dụng ngắt thiết kế chương trình điều khiển lò sưởi ổn định tại nhiệt độ 200C ± 10C Giả sử rờ le tắt/mở lò sưởi được đặt P1.7 P1.7 = 1 (lò sưởi mở) P1.7 = 0 (lò sưởi tắt) Các cảm biến nhiệt độ được nối đến INT0 và INT1. Tạo ra các tín hiệu HOT và COLD HOT = 0 nếu T> 210C COLD = 0 nếu T 210C, cấu trúc phần cứng và đồ thị thời gian được trình bày ở hình 6.5 8051 P1.7 Lò sưởi 140
  52. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái 210 200 190 P1.7 Hình 6,5 Sơ đồ lò sưởi và đồ thị thời gian ORG 0 LJMP MAIN EX0ISR: CLR P1.7 ; véc tơ ngắt 0 ngoài tại 0003H ; lò sưởi tắt RETI ORG 13H ; địa chỉ véctơ 1 ngoài, lò sưởi mở EX1ISR: SETB P1.7 RETI ORG 30H MAIN: MOV IE,#85H ; cho phép các ngắt ngoài SETB IT0 ; tác động cạnh âm SETB IT1 SETB P1.7 ; mở lò sưởi JB P3.2,SKIP ; nếu T> 21 CLR P1.7 ; thì tắt lò sưởi SKIP: SJMP $ ; không làm gì cả Ba dòng lệnh đầu tiên trong chương trình chính cho phép các ngắt ngoài và làm cho cả hai INT0 và COLD trở thành loại tác động cạnh âm. Vì trạng thái hiện tại của các ngỏ vào HOT (P3.2) và COLD(P3.1) không biết trước nên cần 141
  53. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái ba dòng lệnh tiếp theo để tắt hoặc mở lò sưởi tùy theo nhiệt độ. Trước tiên, lò được mở (SETB P1.7) và ngỏ vào HOT được lấy mẫu (JB P3.2,SKIP) nếu ngỏ vào này ở mức cao, nhiệt độ chưa cao hơn 210C nên lệnh kế tiếp bị bỏ qua và lò vẩn tiếp tục được mở. Ngược lai, nếu ngỏ vào HOT ở mức thấp (T> 210C) thì lệnh kế tiếp CLR P1.7 được thực hiện để tắt lò trước khi đi vào vòng lặp “không làm gì cả”. Lưu ý là chỉ dẩn ORG 0003H không cần thiết phải hiện diện ngay trên nhản EX0ISR do lệnh LJMP MAIN dài 3 byte nên EX0ISR chắc chắn được bắt đầu tại địa chỉ 0003H, điễm nhập của ngắt 0 ngoài. Ví dụ 6-5: Hệ thống báo động Dùng ngắt để thiết kế một hệ thống báo động tạo ra âm thanh 400 Hz trong 1 giây (nhờ 1 loa nối vào chân P1.7) mỗi khi cãm biến đặt ở cửa (nỗi đến chân INT0 ) tạo ra một sườn xuống. 8051 P1.7 7404 Xung cửa mở 1 giây 400 Hz 2,5s Hình 6.6 Điều khiển loa bằng ngắt Hướng giải quyết là dùng 3 ngắt: Ngắt 0 ngoài (cãm biến cửa), ngắt timer 0 (âm thanh 400 Hz) và ngắt timer 1 (định thời 1 giây). Sơ đồ mạch và đồ thị thời gian trình bày ở hình 6.6 ORG 0 LJMP MAIN LJMP EX0ISR ORG 000BH ; véc tơ timer 0 142
  54. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái LJMP T0ISR ORG 001BH ; véc tơ timer 1 LJMP T1ISR ORG 0030H MAIN:SETB IT0 ; tác động cạnh âm MOV TMOD,#11H ; chế độ định thời 16 bít MOV IE,#81H ; cho phép EX0 SJMP $ EX0ISR: MOV R7,#20 ; 20x5000 μS = 1 S SETB TF0 ; tạo ngắt timer 0 SETB TF1 ; tạo ngắt timer 1 SETB ET0 ; tạo âm thanh trong 1 S SETB ET1 RETI T0ISR: CLR TR0 DJNZ R7,SKIP ; nếu chưa đủ 20 lần, thoát CLR ET0 ; nếu đủ, kết thúc âm thanh CLR ET1 LJMP EXIT SKIP: MOV TH0,#HIGH(-50000) ; trì hoản 0,05 S MOV TL0,#LOW(-50000) SETB TR0 EXIT: RETI T1ISR: CLR TR1 MOV TH1,#HIGH(1250) MOV Tl1,#LOW(-1250) CPL P1.7 143
  55. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái SETB TR1 RETI END Chương trình trên gồm 5 phần phân biệt: Vị trí các véc tơ ngắt, chương trình chính và 3 chương trình phục vụ ngắt. Các vị trí véc tơ ngắt chứa các lệnh LJMP để chuyển điều khiển đến các ISR tương ứng. Chương trình chính bắt đầu tại địa chi3 0030H chỉ gồm 4 lệnh. Lệnh SETB IT0 cho phép ngỏ vào ngắt nối với cảm biến cửa được kích bởi cạnh âm. Lệnh MOV TMOD,#11H xác định chế độ hoạt động của cả hai timer là chế độ định thời 16 bít, chỉ có ngắt 0 ngoài được bắt đầu (MOV IE,#81H) khi cửa mở là điều kiện cần phải có trước khi một ngắt nào đó được chấp nhận. Lệnh cuối cùng SJMP $ đưa chương trình chính vào vòng lặp “không làm gì cả” khi trạng thái mở cửa được phát hiện (cạnh âm tại INT0 thì ngắt 0 ngoài sẻ được tạo ra. Chương trình phục vụ ngắt EX0ISR bắt đầu bằng việc nạp hằng số 20 cho R7 rồi set cờ tràn của cả hai timer để buộc các ngắt định thời xuất hiện. Tuy nhiên, các ngắt timer chỉ xuất hiện khi các bít tương ứng trong thanh ghi IE cho phép. Hai lệnh kế tiếp SETB ET0 và SETB ET1 cho phép các ngắt bộ định thời, cuối cung EX0ISR trở về chương trình chính bằng lệnh RETI. Timer tạo ra khoảng thời gian trì hoãn 1 S và timer 1 tạo ra âm thanh 400 Hz. Sau khi chương trình EX0ISR kết thúc, các ngắt timer được lập tức tạo ra và được thực hiện sau khi thực hiện 1 lệnh SJMP $. Do tác dụng của chuỗi pooling nên ngắt của timer 0 được phục vụ trước tiên. Khoảng thời gian 1 S được tạo ra bằng cách lập trình để lặp lại 20 lần khoảng thời gian định thời 50000 μS, thanh ghi R7 hoạt động như một bộ đếm. Chương trình phục vụ ngắt T0ISR hoạt động như sau: Trước tiên, timer 0 được điều khiển dừng và thanh ghi R7 bị giãm 1, tiếp theo TH0/TL0 được nạp lại giá trị -50000, timer 0 chạy trở lại và ngắt được kết thúc. Ở lần ngắt thứ 20, R7 được giãm xuống 0 (đã trôi qua 1 S), các ngắt của cả hai timer bị ngăn (CLR ET0, CLR ET1) và ngắt kết thúc. Không còn ngắt do bộ định thời tạo ra nữa cho đến khi phát hiện cửa mở một lần nữa. Âm thanh 400 Hz được lập trình bằng cách xử dụng ngắt timer 1, tần số 400 Hz tương đương chu kỳ là 2500 μS với 1250 μS mức cao và 1250 μS mức thấp. Chương trình T1ISR chỉ đơn giản nạp -1250 cho TH1/TL1, đảo port bít để điều khiển loa và kết thúc. 7. Đồ thị thời gian của ngắt Các ngắt được lấy mẫu và được chốt ở S5P2 của mỗi chu kỳ máy (hình 6.7), chúng được xoay vòng đến chu kỳ máy kế tiếp và nếu có một điều kiện ngắt tồn tại, ngắt được chấp nhận nếu: a. Không có ngắt nào khác có ưu tiên bằng hay cao hơn đsng xảy ra. b. Chu kỳ xoay vòng là chu kỳ cuối của một lệnh. 144
  56. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái c. Lệnh hiện hành không phải là lệnh RETI hoặc lệnh truy xuất đến thanh ghi IE hoặc IP. Trong suốt hai chu kỳ kế tiếp, CPU cất nội dung của PC vào ngăn xếp và nạp cho PC địa chỉ véc tơ ngắt, chương trình phục vụ ngắt được bắt đầu Điều kiện lệnh hiện hành không phải là lệnh RETI nhằm bảo đãm rằng có ít nhất một lệnh được thực hiện sau mỗi một ISR Một chu kỳ máy (1s) S1 S2 S3 S4 S5 S6 S5P1 S5P2 S5P1 S5P2 0,25s Ngắt được lấy mẫu Hình 6.7 Lấy mẫu các ngắt tại S5P2 Chu kỳ 1 Chu kỳ 2 Chu kỳ 3 Chu kỳ 4 Chu kỳ 5 Lấy mẫu ngắt Xoay vòng Chấp nhận ngắt Bắt đầu ISR ngắt ( Cất PC vào * Phải là chu kỳ cuối cùng của lệnh hiện hành Hình 6.8 Quá trình thực hiện ngắt Thời gian từ lúc có một điều kiện ngắt xuất hiện đến khi ISR bắt đầu được gọi là interrupt latency và rất quan trọng trong một số các ứng dụng điều khiển. Với thạch anh 12 MHz, interrupt latency có thể ngắn khoảng 3,25 μS đối với 8051. Một hệ thống dùng 8051 với ngắt ưu tiên cao sẻ có interrupt latency xấu nhất là 9,25 μS (giả sử ngắt ưu tiên cao luôn luôn được phép). Điều này xảy ra nếu điều kiện ngắt xuất hiện ngay trước khi có lệnh RETI của ISR mưc 0 được theo sau bởi một lệnh nhân (hình 6.9) 145
  57. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Mức ngắt 0 Mức ngắt chính Mức ngắt 1 RETI MUL AB Cất PC 9 s Ngắt mức 1 xuất hiện ở đây ( cơ hội cuối cùng bị bỏ qua trước khi xuất hiện lệnh RETI ) Hình 6.9 Interrupt latency 8. Bài tập 1. Viết lại chương trình ở ví dụ 1 để ngăn các ngắt và kết thúc khi có một phím bất kỳ được ấn. 2. Viết chương trình dùng ngắt tạo xung vuông 1 KHz tại chân P1.7 3. Dùng ngắt viết chương trình tạo xung vuông 7 KHz với chu kỳ làm việc là 30% tại chân P1.6 4. Kết hợp ví dụ 6.1 và 6.3 thành một chương trình duy nhất Viết lại ví dụ 6.3 để gởi 1 ký tự trong 1 S 146
  58. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Bài 7: Phần mềm hợp ngữ 1. Mở đầu Theo phân cấp ngôn ngữ lập trình hợp ngữ nằm giữa ngoonn ngữ máy và ngôn ngữ cấp cao. Các ngôn ngữ cấp cao điển hình như ngôn ngữ Pascal, C sử dụng các từ hoặc các khai báo dễ hiểu với người sử dụng, mặc dù nó vẫn còn khoảng cách rất xa so ngôn ngữ tự nhiên. Còn ngôn ngữ máy là ngôn ngữ nhị phân của máy tính. Một chương trình ngôn ngữ máy là một chuỗi các byte nhị phân biểu diễn cho các lệnh mà máy tính có thể thực hiện được. Hợp ngữ thay thế các mã nhị phân của ngôn ngữ máy thành các mã gợi nhớ để thuận lợi hơn khi lập trình. Ví dụ 7.1: Lệnh cộng trong ngôn ngữ máy được biểu diễn bằng mã nhị phân “ 10110011” còn trong hợp ngữ là “ADD”. Việc lập trình được thực hiện bằng hợp ngữ thay vì ngôn ngữ máy. Các toán hạng của lệnh được biểu diễn bằng các cách định vị địa chỉ khác nhau, trong mã nhị phân của các lệnh ngôn ngữ máy cũng được thay thế bằng các ký hiệu trong lệnh hợp ngữ. Một chương trình hợp ngữ ( assembly) không thể thực hiện trên máy tính mà nó phảo được dịch sang mã nhị phân ngôn ngữ máy. Tùy thuộc vào mức độ phức tạp của mỗi chương trình mà quá trình dịch sang chương trình ngôn ngữ máy có thể bao gồm một hoặc nhiều bước. Chương trình dịch tối thiểu được gọi là chương trình hợp dịch nó dịch các lệnh gợi nhớ thành các lệnh mã máy. Bước đòi hỏi tiếp theo thường là liên kết (linker). Một chương liên kết thực hiện việc kết hợp các phần khác nhau của chương trình trên các tập tin khác nhau và thiết lập địa chỉ trong bộ nhớ nơi chương trình sẽ thực hiện. Một số khái niệm cần nhớ: - Chương trình hợp ngữ ( Assembly Language Program) Là chương trình được viết bằng các cách dùng các nhãn, các từ gợi nhớ trong đó mỗi phát biểu tương ứng với một lệnh của ngôn ngữ máy. Chương trình viết bằng hợp ngữ gọi là mã nguồn và chương trình này không thể thực thi mà nhằm giúp người lập trình đọc hiểu những gì vi xử lý thực hiện và gỡ rối một cách dễ dàng. - Chương trình ngôn ngữ máy ( Machine Language Program) Là chương trình gồm các mã nhị phân tương ứng với một lệnh của vi xử lý. Các chương trình viết bằng ngôn ngữ máy thường được gọi là mã đối tượng ( object code) và thực thi được. - Chương trình Assembler: 147
  59. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Là chương trình dịch một chương trình viết bằng hợp ngữ sang chương trình ngôn ngữ máy. Chương trình ngôn ngữ máy có thể ở dạng tuyệt đối hoặc dạng tái định vị. - Chương trình Linker: Là chương trình kết hợp các chương trình đối tượng tái định vị được tạo ra chương trình đối tượng tuyệt đối để thực thi được. - Segment Là một đơn vị bộ nhớ chứa mã lệnh hoặc chứa dữ liệu. Một segment có thể tuyệt đối hoặc tái định vị được. Segment tái định vị được sẽ có tên, kiểu và các thuộc tính cho phép chương trình linker kết hợp nó với các phần của các đoạn khác nếu cần để định vị đúng đoạn. Segment ở dạng tuyệt đối không có tên và không thể kết hợp được với các đoạn khác. - Module Chứa một hoặc nhiều segment hoặc một phần segment. Một module có tên do người sử dụng đặt. Những định nghĩa module định tầm của các ký hiệu cục bộ. Một tập tin đối tượng chứa một hay nhiều module. Một module được xem như là một tập tin trong nhiều tình huống. - Chương trình Gồm nhiều module tuyệt đối trộn tất cả các đoạn tuyệt đối và tái định vị được tất cả các module nhập. Một chương trình chỉ chứa các mã nhị phân cho các chỉ thị mà máy tính hiểu. 2. Hoạt động của ASSEMBLER Có nhiều trình hợp dịch và các chương trình hỗ trợ khác hiện có để phát triển các ứng dụng vi điều khiển. ASM 51 là hợp dịch chuẩn nhất so các chương trình khác. Trong phần này sẽ giới thiệu về cấu trúc lập trình với ASM51. Mặc dù được tiêu chuẩn hóa nhưng một số khai báo trong phần này cũng có thể không sử dụng được với các trình hợp dịch khác. ASM51 là trình hợp dịch mạnh nó sử dụng cho việc phát triển hệ thống vi điều khiển trên hệ thống Intel và các máy tính họ IBM PC. Vì các máy tính sử dụng để chạy phần mềm này có CPU khác 8051 nên ASM51 được gọi là trình hợp dịch chéo( cross assembeler). Chương trình nguồn 8051 có thể viết trên máy tính bằng cách soạn thảo văn bản sau đó có thể hợp dịch thành file đối tượng ( object) và file liệt kê ( listing) bằng ASM51. Chú ý rằng máy tính với một CPU khác nên nó sẽ không hiểu được các lệnh nhị phân của file đối tượng. Vì thế cần một chương trình có khả năng nạp chương trình đối tượng vào hệ thống 8051 để thực hiện. Để thực hiện hợp dịch bằng ASM51 có thể đánh lệnh sau từ dấu nhắc hệ thống : ASM51 source file { assembly controls} 148
  60. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Source file là tên của file nguồn cần hợp dịch còn assembler controls là các khóa điều khiển tạo ra các tác động khác nhau khi hợp dịch. ASM51 sẽ nhận một file nguồn làm ngõ vào và tạo ra một file đối tượng ( PROGRAM.OBJ) và file listing ( PROGRAM.LST). Hình 7.1 : Biên dịch một chương trình nguồn Tất cả các chương trình biên dịch đều quét chương trình nguồn 2 lần để thực hiện dịch ra ngôn ngữ máy nên được gọi là assembler hai bước. Assembler sử dụng bộ đếm vị trí làm địa chỉ của các lệnh và các giá trị cho các nhãn. Hoạt động của từng bước được mô tả như sau : Bước 1 : File nguồn được xem xét từng đường và bảng ký hiệu được xây dựng. Vị trí bộ đếm chương trình được mặc định là 0 hoặc được thiết lập bằng chỉ thị ORG ( origin). Khi file được xem xét bộ đếm được tăng lên tùy theo độ dài mỗi lệnh. Các chỉ thị định nghĩa dữ liệu ( DB hoặc DW) tăng bộ đếm bằng số byte được định nghĩa. Các chỉ thị nhớ lưu trữ ( DS) tăng bộ đếm bằng số byte được dự trữ. Khi tìm thấy một nhãn ( bắt đầu một hướng rẽ nhánh) thì nó sẽ được đặt trong bảng ký hiệu theo giá trị hiện hành của bộ đếm. Các kí hiệu bằng chỉ thị EQU ( equal) được đặt trong bảng kí hiệu. Bảng kí hiệu được cất giữ và sau đó dùng trong bước 2. Bước 2 : Tạo ra các file đối tượng và liệt kê. Các lệnh gợi nhớ được dịch thành các opcode và đặt trong file ra. Các toán hạng được định giá trị và đặt phía sau opcode. Khi các toán hạng là ký hiệu giá trị của chúng sẽ được lấy lại từ bảng ký hiệu được tạo ra trong giai đoạn 1và dùng để tạo thành dữ liệu hoặc địa chỉ đúng cho lệnh. Với 2 giai đoạn được thực hiện như trên nên chương trình nguồn có thể sử dụng các kí hiệu trước khi nó được định nghĩa. File đối tượng khi hợp dịch thành công sẽ chỉ chứa các byte nhị phân ( 00H đến FFH) cảu chương trình ngôn ngữ máy. File đối tượng định vị (object relocatable) sẽ chứa một bảng ký hiệu và thông tin khác cần thiết cho sự liên kết và định vị chương trình. File liệt kê và định chương trình, file liệt kê là một file văn bản bao gồm cả các lệnh gợi nhớ nhớ và mã máy tương ứng của nó. Khi có lệnh lỗi file liệt kê cũng chứa cả các thông báo lỗi. 149
  61. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái 3. Cấu trúc chương trình dữ liệu Các lệnh trong chương trình hợp ngữ bao gồm : + Các lệnh máy ( Machine instructions) + Chỉ thị hợp dịch ( Assembler directives) + Lệnh điều khiển trình hợp dịch (Assembler controls) + Chú thích ( Comments) Các lệnh máy tương đương với các lệnh gợi nhớ chúng được đổi thành các lệnh mã máy khi hợp dịch. Các chỉ thị hợp dịch được sử dụng để trình hợp dịch định nghĩa cấu trúc chương trình, các kí hiệu, các dữ liệu, các hằng Các lệnh điều khiển sẽ thiết lập các chế độ hợp dịch và chỉ thị thực hiện của chương trình hợp ngữ. Các chú thích sử dụng giải thích về hoạt động và mục đích của mỗi chuỗi lệnh giúp người đọc dễ hiểu hơn. Các dòng lệnh phải được tuân theo một quy tắc nhất định bởi trình hợp dịch. Khuôn dạng mỗi hàng lệnh như sau : [ label :] mnemonic [ operand] [,operand] [ ] [ ;comment] Trong đó: Label : Nhãn theo sau bởi dấu “ ; ”. Menemonic : Là từ gợi nhớ của lệnh. Operand : Là toán hạng tùy thuộc vào lệnh có một hoặc nhiều toán hạng hoặc không có toán hạng ,cuối cùng là chú thích cho lệnh đó đi sau là dấu chấm phẩy “ ; “. Chỉ có phần mã gợi nhớ ( mnemonic) là bắt buộc phải có trong hàng lệnh trong tất cả các trình hợp dịch. Một số trình biên dịch yêu cầu phải có nhãn ở cột thứ nhất trong tất cả các dòng lệnh và các phần sau nó phải được ngăn cách với nhau bằng khoảng trắng ( space) hoặc khoảng cách quãng ( tab). Với ASM51 nhãn không nhất thiết phải có trên mỗi hàng lệnh và nhãn cũng không cần phải nằm trong cùng hàng với lệnh gợi nhớ. - Nhãn ( label fiel) : Một nhãn tượng trưng cho địa chỉ của lệnh hoặc dữ liệu nằm sau nó. Khi rẽ nhánh đến lệnh này nhãn này được dùng trong toán hạng của lệnh rẽ nhánh hoặc lệnh nhảy. Khác với “ nhãn” luôn chỉ thị một địa chỉ, kí hiệu ( symbol) có ứng dụng tổng quát hơn. Nhãn chỉ là một trong các loại ký hiệu và nó được phân biệt bằng dấu ( ; ) phía sau. Ký hiệu để gán các giá trị hoặc thuộc tính sử dụng trong các chỉ thị hợp dịch của hợp ngữ nhứ: EQU, SEGMENT, bit, DATA Các ký hiệu 150
  62. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái có thể là địa chỉ, hằng số, tên các đoạn hoặc các cấu trúc khác được hiểu bởi người lập trình. Ví dụ 7.1: PAR EQU 500 ; PAR là kí hiệu biểu diễn thay cho giá trị 500. START: MOV A, #0FFH ; start là nhãn tượng trưng địa chỉ lệnh MOV. Một ký hiệu hoặc nhãn phải bắt đầu bằng một chữ cái, dấu “ ? “ hoặc dấu “ – “ và có thể chứa tới 31 kí tự. Các kí hiệu có thể là chữ hoa hoặc chữ thường đều được hiểu giống nhau nhưng chúng không được trùng với các lệnh gợi nhớ, các ký hiệu được định nghĩa trước và các chỉ thị hợp dịch. - Lệnh gợi nhớ ( mnemonic) Các lệnh gợi nhớ hoặc các chỉ thị hợp dịch được viết tại phần mnemonic của dòng lệnh sau nhãn hoặc kí hiệu. Ví dụ 7.2: Các lệnh gợi nhớ như : ADD, MOV, DIV, INC Các chỉ thị hợp dịch : ORG, EQU, DB. - Toán hạng ( operand): Phần toán hạng được viết sau phần mã gợi nhớ trong hàng lệnh. Vùng này chứa địa chỉ hoặc dữ liệu sử dụng trong lệnh. Một nhãn có thể được dùng để biểu diễn cho địa chỉ của dữ liệu hoặc một ký hiệu có thể được dùng để biểu diễn cho hằng dữ liệu. Có nhiều cách biểu diễn toán hạng tùy thuộc vào lệnh cụ thể. Một số lệnh không có toán hạng: RET, NOP còn một số lệnh lại có nhiều toán hạng được phân ra bằng các dấu phẩy. - Chú thích ( comment) Các chú thích làm dễ hiểu chương trình chúng được đặt ở cuối mỗi dòng lệnh và trước nó phải có dấu chấm phấy ( ; ). Cũng có thể thực hiện cả một dòng chú thích bằng cách bắt đầu bằng dấu “ ; “. Một chương trình con hoặc một đoạn lệnh dài có thể bắt đầu bằng một khối chú thích gồm nhiều dòng liên tiếp để giải thích tính chất chung của phần chương trình bên dưới. - Các kí hiệu hợp dịch đặc biệt ( special assembler symbol) Các kí hiệu hợp dịch đặc biệt được dùng trong các chế độ định vị thanh ghi cụ thể. Chúng bao gồm thanh ghi A, R0 – R7, DPTR, PC, C, AB. Cũng như kí hiệu $ được dùng để biểu diễn giá trị hiện hành của bộ đếm chương trình. Ví dụ 7.3: Lệnh JNB TI, $ tương đương với dòng lệnh sau: HERE : JNB TI, HERE Trong hợp ngữ ASM51 có các kiểu toán hạng sau: - Dữ liệu tức thời ( Immediate data) 151
  63. GT: Vi điều khiển Trường Cao đẳng nghề Yên Bái Các lệnh sử dụng định vị tức thời cung cấp dữ liệu toán hạng trong một phần của lệnh. Các dữ liệu tức thời phải bắt đầu bằng dấu “ # “. Ví dụ 7.4: CONSTAN EQU 100 MOV A, #0FFH ORL 40, # CONSTANT Tất cả các toán hạng tức thời trừ trong lệnh MOV DPTR, #DATA đều là 8 bit. Nếu dữ liệu được viết thành 16 bit thì byte thấp sẽ được sử dụng. Tất cả các bit trong byte cao phải giống nhau 00H hoặc FFH nếu không sẽ có thông báo lỗi “ value not fit in a byte” ( giá trị không nằm trong một byte). Ví dụ 7.5: Lệnh sau đúng cú pháp MOV A, #0FF00H MOV A, #00FFH Hai lệnh sau đây sinh ra thông báo lỗi MOV A, #0FE00H MOV A, #01FFH Các hằng số thập phân từ - 256 đến + 256 cũng có thể sử dụng cho toán hạng tức thời. Ví dụ 7.6: 2 lệnh sau đúng cú pháp MOV A, # -256 MOV A, #0FF01H - Địa chỉ trực tiếp ( DATA address) Nhiều lệnh truy xuất các vùng nhớ sử dụng định vị trực tiếp và cần một toán hạng địa chỉ RAM nội từ 00H đến FFH. Các kí hiệu được định nghĩa có thể được dùng cho các địa chỉ SFR. Ví dụ 7.7: MOV A, 45H Hoặc MOV A, SBUF tương đương với lệnh MOV A, 99 - Địa chỉ bit ( bit address) Một trong các điểm mạnh của bộ vi điều khiển là khả năng truy xuất các bit riêng lẻ. Các lệnh truy xuất các bit phải cung cấp một địa chỉ trong RAM nội vùng 00H đến 7FH hoặc địa chỉ trong các SFR vùng 80H đến FFH. Có 3 cách để chỉ thị địa chỉ bit trong một lệnh: + Dùng địa chỉ trực tiếp + Dùng chỉ thị vị trí của bit trong một byte dữ liệu. + Dùng kí hiệu hợp dịch đã được định nghĩa trước. 152