khi vi điều khiển nhận hoặc truyền xong một byte bằng cổng
TI,RI RI
Để cho phép một ngắt, bit tơng ứng với ngắt đó và bit EA phải đợc đặt bằng 1. Thanh ghi IE là thanh ghi đánh địa chỉ bit, do đó có thể dùng các lệnh tác động bit để tác động riêng rẽ lên từng bit mà không làm ảnh hởng đến giá trị các bit khác. Cờ ngắt hoạt động độc lập với việc cho phép ngắt, điều đó có nghĩa
là cờ ngắt sẽ tự động đặt lên bằng 1 khi có sự kiện gây ngắt xảy ra, bất kể sự
kiện đó có đợc cho phép ngắt hay không. Do vậy, trớc khi cho phép một ngắt,
ta nên xóa cờ của ngắt đó để đảm bảo sau khi cho phép, các sự kiện gây ngắt trong quá khứ không thể gây ngắt nữạ Ví dụ trớc khi cho phép ngắt timer0 mà timer 0 đã chạy và tràn (dù là tràn một hay nhiều lần) thì cờ TF0 sẽ bằng 1, nếu sau đó ta cho phép ngắt timer0 thì sẽ gây ra ngắt ngay do cờ tràn đang bằng 1
(sự kiện tràn gây ngắt trong trờng hợp này là tràn trong quá khứ, không phải sự kiện ta quan tâm đến). Vì vậy hãy xóa cờ TF0 trớc khi cho phép ngắt tràn timer0.
Ngoại trừ cờ của của ngắt nối tiếp (và cờ của ngắt timer2 trong 8052), các
phục vụ ngắt. Lý do là ngắt cổng nối tiếp (và ngắt timer2 trong 8052) đợc gây ra bởi 2 nguyên nhân (có 2 cờ cho mỗi ngắt), khi xảy ra ngắt, ngời lập trình cần phải kiểm tra xem cờ nào đợc đặt bằng 1 để phân biệt nguyên nhân gây ra ngắt đó là nguyên nhân nào để xử lý thích hợp. Ví dụ ngắt cổng nối tiếp là ngắt đợc gây ra bởi 1 trong 2 nguyên nhân: vi điều khiển nhận xong hoặc truyền xong một byte dữ liệu qua cổng nối tiếp. Xảy ra sự kiện nào thì cờ ngắt tơng ứng sẽ tự động đợc đặt lên bằng 1, nếu nhận xong thì cờ RI bằng 1, nếu truyền xong thì cờ TI bằng 1. Trong chơng trình xử lý ngắt, ngời lập trình phải kiểm tra cờ TI hay cờ
RI bằng 1 để quyết định xử lý ngắt truyền hay xử lý ngắt nhận. Sau khi kiểm tra, ngời lập trình phải viết lệnh xóa cờ đó vì việc này không đợc CPU thực hiện
tự động nh các cờ ngắt khác.
Nói đến ngắt không thể không nói đến mức u tiên của ngắt. Mức u tiên của ngắt ở đây có thể đợc hiểu là sự phân bậc, quyết định xử lý ngắt nào khi hai hay nhiều ngắt xảy rạ Có 2 cơ chế phân bậc u tiên. Thứ nhất là cơ chế phân bậc dành cho các ngắt xảy ra đồng thời, hai ngắt A và B xảy ra cùng một thời điểm nhìn từ phía vi điều khiển. Thứ hai là cơ chế phân bậc dành cho các ngắt xảy ra xen kẽ nhau, trong khi đang xử lý ngắt A thì ngắt B xảy ra, vậy thì trong từng trờng hợp, CPU sẽ xử lý ra saỏ Hãy xem dới đâỵ
Với trờng hợp các ngắt xảy ra đồng thời, CPU sẽ xem xét mức u tiên của các ngắt đó, từ đó quyết định xử lý ngắt có mức u tiên cao hơn tr- ớc. Mức u tiên trong trờng hợp này là mức u tiên cứng (đợc quy định bởi nhà sản xuất, bởi cấu trúc sẵn có của 8051 và ngời lập trình không thể thay đổi đợc).
Nhìn vào bảng trên ta thấy ngắt INT0 là ngắt có mức u tiên cao nhất và ngắt timer2 là ngắt có mức u tiên thấp nhất trong số các ngắt. Nh vậy nếu ngắt ngoài 1 và ngắt timer0 cùng xảy ra một lúc, ngắt ngoài 1 sẽ đ- ợc CPU xử lý trớc, sau đó mới xử lý ngắt timer0.
Với trờng hợp xảy ra ngắt xen kẽ, khi CPU đang xử lý ngắt A mà ngắt B xảy ra, CPU sẽ giải quyết theo 2 hớng: tiếp tục xử lý ngắt A nếu mức u tiên của ngắt B không cao hơn mức u tiên của ngắt A, hoặc sẽ dừng việc xử lý ngắt A lại, chuyển sang xử lý ngắt B nếu mức u tiên của ngắt B
cao hơn mức u tiên của ngắt Ạ Mức u tiên cho các ngắt trong trờng hợp này không phải
là mức u tiên cứng do nhà sản xuất quy định (tức là không căn cứ vào bảng trên) mà là do ngời lập trình đặt. Ngời lập trình có thể dùng thanh ghi IP để quy định mức u tiên cho các ngắt ở một trong hai mức: mức cao và mức thấp. Để đặt mức u tiên của một ngắt (trong trờng hợp xảy ra xen kẽ) ở mức cao, ta đặt bit tơng ứng với ngắt đó trong thanh ghi IP bằng 1, mức thấp ứng với giá trị bit = 0.
Thanh ghi IP (Interrupt Priority)
Các bit trong thanh ghi IP tơng ứng với các ngắt đúng nh trong thanh ghi
IE (bit PX0 dành cho ngắt ngoài 0, bit PT0 dành cho ngắt timer 0…) Một điều dễ nhận ra là nếu một ngắt đợc đặt mức u tiên cao (bit t-
ơng
ứng trong thanh ghi IP bằng 1) thì sẽ chẳng có ngắt nào có thể xen vào quá trình xử lý nó đợc nữạ
Nói về mức u tiên ngắt, có thể dùng một ví dụ tổng quát sau, giả sử hai ngắt timer0 và ngắt cổng nối tiếp cùng đợc cho phép (các bit tơng ứng và bit EA trong thanh ghi IE đợc đặt bằng 1), bit PT0 = 0, bit PS = 1 thì:
- Nếu hai ngắt cùng xảy ra, ngắt timer0 sẽ thắng thế và đợc phục vụ
trớc.
- Nếu ngắt cổng nối tiếp xảy ra trớc và đang đợc xử lý thì ngắt timer0 nếu có xảy ra cũng không thể chen vào, làm dừng quá trình xử lý ngắt cổng nối tiếp đợc.
- Nếu ngắt timer0 xảy ra trớc và đang đợc xử lý mà ngắt cổng nối tiếp xảy ra thì CPU sẽ phải dừng việc xử lý ngắt timer0 lại, chuyển sang xử lý ngắt cổng nối tiếp, xử lý xong mới quay lại xử lý tiếp ngắt timer0.
Ngắt ngoài (external interrupt )
Nh đã nói ở trên, 8051 có 2 ngắt ngoài là INT0 và INT1. Ngắt ngoài đợc hiểu là ngắt đợc gây ra bởi sự kiện mức lôgic 0 (mức điện áp thấp, gần 0V) hoặc sờn xuống (sự chuyển mức điện áp từ mức cao về mức thấp) xảy ra ở chân ngắt tơng ứng (P3.2 với ngắt ngoài 0 và P3.3 với ngắt ngoài 1). Việc lựa chọn kiểu ngắt đợc thực hiện bằng các bit IT (Interrupt Type) nằm trong thanh ghi TCON. Đây là thanh ghi điều khiển timer nhng 4 bit LSB (bit0..3) đợc dùng cho các ngắt ngoàị
Khi bit ITx = 1 thì ngắt ngoài tơng ứng đợc chọn kiểu là ngắt theo sờn xuống, ngợc lại nếu bit ITx = 0 thì ngắt ngoài tơng ứng đợc sẽ có kiểu ngắt
là ngắt theo mức thấp. Các bit IE là các bit cờ ngắt ngoài, chỉ có tác dụng trong trờng hợp kiểu ngắt đợc chọn là ngắt theo sờn xuống.
Khi kiểu ngắt theo sờn xuống đợc chọn thì ngắt sẽ xảy ra duy nhất một lần khi có sờn xuống của tín hiệu, sau đó khi tín hiệu ở mức thấp, hoặc có sờn lên, hoặc ở mức cao thì cũng không có ngắt xảy ra nữa cho đến khi có sờn xuống tiếp theọ Cờ ngắt IE sẽ dựng lên khi có sờn xuống và tự động bị xóa khi CPU bắt đầu xử lý ngắt.
Khi kiểu ngắt theo mức thấp đợc chọn thì ngắt sẽ xảy ra bất cứ khi nào tín hiệu tại chân ngắt ở mức thấp. Nếu sau khi xử lý xong ngắt mà tín hiệu vẫn ở mức thấp thì lại ngắt tiếp, cứ nh vậy cho đến khi xử lý xong ngắt lần thứ n , tín hiệu đã lên mức cao rồi thì thôi không ngắt nữạ Cờ ngắt IE trong trờng hợp này không có ý nghĩa gì cả.
Thông thờng kiểu ngắt hay đợc chọn là ngắt theo sờn xuống. Các timer/counter trong 8051
8051 có 2 timer tên là timer0 và timer1. Các timer này đều là timer 16bit, giá trị đếm max do đó bằng 216 = 65536 (đếm từ 0 đến 65535).
Hai timer có nguyên lý hoạt động hoàn toàn giống nhau và độc lập. Sau
khi cho phép chạy, mỗi khi có thêm một xung tại đầu vào đếm, giá trị của timer sẽ tự động đợc tăng lên 1 đơn vị, cứ nh vậy cho đến khi giá trị tăng lên vợt quá giá trị max mà thanh ghi đếm có thể biểu diễn thì giá trị đếm lại đợc đa trở về giá trị min (thông thờng min = 0). Sự kiện này đợc hiểu là sự kiện tràn timer (overflow) và có thể gây ra ngắt nếu ngắt tràn timer đợc cho phép (bit ETx trong thanh ghi IE = 1).
Việc cho timer chạy/dừng đợc thực hiện bởi các bit TR trong thanh ghi
Khi bit TRx = 1, timerx sẽ đếm, ngợc lại khi TRx = 0, timerx sẽ không đếm mặc dù vẫn có xung đa vàọ Khi dừng không đếm, giá trị của timer đợc giữ nguyên.
Các bit TFx là các cờ báo tràn timer, khi sự kiện tràn timer xảy ra, cờ sẽ đợc tự động đặt lên bằng 1 và nếu ngắt tràn timer đợc cho phép, ngắt sẽ xảy rạ Khi CPU xử lý ngắt tràn timerx, cờ ngắt TFx tơng ứng sẽ tự động đợc xóa
về 0.
Giá trị đếm 16bit của timerx đợc lu trong hai thanh ghi THx (byte cao) và TLx (byte thấp). Hai thanh ghi này có thể ghi/đọc đợc bất kỳ lúc nàọ Tuy nhiên nhà sản xuất khuyến cáo rằng nên dừng timer (cho bit TRx = 0) trớc khi ghi/đọc các thanh ghi chứa giá trị đếm.
Các timer có thể hoạt động theo nhiều chế độ, đợc quy định bởi các bit trong thanh ghi TMOD (không đánh địa chỉ đến từng bit).
Để xác định thời gian, ngời ta chọn nguồn xung nhịp (clock) đa vào
đếm trong timer là xung nhịp bên trong (dành cho CPU). Nguồn xung nhịp này
thờng rất đều đặn (có tần số ổn định), do đó từ số đếm của timer ngời ta có
thể nhân với chu kỳ xung nhịp để tính ra thời gian trôi quạ Timer lúc này đợc gọi chính xác với cái tên “timer”, tức bộ định thờị
Để đếm các sự kiện bên ngoài, ngời ta chọn nguồn xung nhịp đa vào đếm trong timer là tín hiệu từ bên ngoài (đã đợc chuẩn hóa về dạng xung vuông 0V/5V). Các tín hiệu này sẽ đợc nối với các bit cổng có dồn kênh thêm các tính năng T0/T1/T2. Khi có sự kiện bên ngoài gây ra thay đổi mức xung ở đầu vào đếm, timer sẽ tự động tăng lên 1 đơn vị giống nh trờng hợp đếm xung nhịp bên trong. Lúc này, timer đợc gọi chính xác với cái tên khác:
“counter”, tức bộ đếm (sự kiện).
có 2 bộ 4 bit giống nhau (gồm GATEx, C/Tx, Mx0 và Mx1) dành cho 2 timer0 và 1. ý nghĩa các bit là nh nhau đối với mỗi timer.
Bit GATEx quy định việc cho phép timer đếm (run timer). Nếu GATEx = 0,
timerx sẽ đếm khi bit TRx bằng 1, dừng khi bit TRx bằng 0. Nếu GATEx = 1, timerx sẽ chỉ đếm khi bit TRx = 1 và tín hiệu tại chân INTx = 1, dừng khi một trong hai điều kiện trên không còn thỏa mãn. Thông thờng ngời ta dùng timer với GATE = 0, chỉ dùng timer với GATE = 1 trong trờng hợp muốn đo độ rộng xung vì lúc đó timer sẽ chỉ đếm thời gian khi xung đa vào chân INTx ở mức caọ Bit C/Tx quy định nguồn clock đa vào đếm trong timer. Nếu C/Tx = 0,
timer sẽ đợc cấu hình là bộ định thời, nếu C/Tx = 1, timer sẽ đợc cấu hình là bộ đếm sự kiện.
Hai bit còn lại (Mx0 và Mx1) tạo ra 4 tổ hợp các giá trị (00,01,10 và 11) ứng với 4 chế độ hoạt động khác nhau của timerx. Trong 4 chế độ đó thờng chỉ dùng chế độ timer/counter 16bit (Mx1 = 0, Mx0 = 1) và chế độ Auto Reload 8bit timer/counter (Mx1 = 1, Mx0 = 0).
Trong chế độ timer/counter 16bit, giá trị đếm (chứa trong hai thanh ghi THx và TLx) tự động đợc tăng lên 1 đơn vị mỗi lần nhận đợc thêm một xung nhịp. Khi giá trị đếm tăng vợt quá giá trị max = 65535 thì sẽ tràn về 0, cờ ngắt TFx đợc tự động đặt = 1. Chế độ này đợc dùng trong các ứng dụng đếm thời gian và đếm sự kiện.
Trong chế độ Auto Reload 8bit, giá trị đếm sẽ chỉ đợc chứa trong thanh ghi TLx, còn giá trị của thanh ghi THx bằng một số n (từ 0 đến 255) do ngời lập trình đa vàọ Khi có thêm 1 xung nhịp, giá trị đếm trong TLx đ- ơng nhiên cũng tăng lên 1 đơn vị nh bình thờng. Tuy nhiên trong trờng hợp này, giá trị đếm lớn nhất là 255 chứ không phải 65535 nh trờng hợp trên vì
timer/counter chỉ còn 8bit. Do vậy sự kiện tràn lúc này xảy ra nhanh hơn, chỉ cần vợt quá 255 là giá trị đếm sẽ tràn. Cờ ngắt TFx vẫn đợc tự động đặt = 1 nh trong trờng hợp tràn 16bit. Điểm khác biệt là thay vì tràn về 0, giá trị THx sẽ đợc tự động nạp lại
(Auto Reload) vào thanh ghi TLx, do đó timer/counter sau khi tràn sẽ có giá trị bằng n (giá trị chứa trong THx) và sẽ đếm từ giá trị n trở đị Chế độ này đợc dùng trong việc tạo Baud rate cho truyền thông qua cổng nối tiếp.
Để sử dụng timer của 8051, hãy thực hiện các bớc sau:
- Quy định chế độ hoạt động cho timer bằng cách tính toán và ghi giá trị cho các bit trong thanh ghi TMOD.
- Ghi giá trị đếm khởi đầu mong muốn vào 2 thanh ghi đếm THx và TLx. Đôi khi ta không muốn timer/counter bắt đầu đếm từ 0 mà từ một giá trị nào đó để thời điểm tràn gần hơn, hoặc chẵn hơn trong tính toán sau nàỵ Ví dụ nếu cho timer đếm từ 15535 thì sau 50000 xung nhịp (tức 50000 micro giây với thạch anh 12MHz) timer sẽ tràn, và thời gian một giây có thể dễ dàng tính ra khá chính xác = 20 lần tràn của timer (đơng nhiên mỗi lần tràn lại phải nạp lại giá trị 15535).
- Đặt mức u tiên ngắt và cho phép ngắt tràn timer (nếu muốn).
- Dùng bit TRx trong thanh ghi TCON để cho timer chạy hay dừng theo ý muốn.
Cổng nối tiếp (serial Port) của 8051
Cổng nối tiếp trong 8051 chủ yếu đợc dùng trong các ứng dụng có yêu cầu truyền thông với máy tính, hoặc với một vi điều khiển khác. Liên quan đến cổng nối tiếp chủ yếu có 2 thanh ghi: SCON và SBUF. Ngoài ra, một thanh ghi khác là thanh ghi PCON (không đánh địa chỉ bit) có bit 7
tên là SMOD quy định tốc độ truyền của cổng nối tiếp có gấp đôi lên (SMOD = 1) hay không (SMOD =
0).
Dữ liệu đợc truyền nhận nối tiếp thông qua hai chân cổng P3.0(RxD) và P3.1(TxD).
Thanh ghi SBUF là thanh ghi 8bit chứa dữ liệu truyền hoặc nhận. Về thực chất có hai thanh ghi dữ liệu khác nhau, một dành để chứa dữ liệu truyền đi, một để chứa dữ liệ nhận đợc. Cả hai thanh ghi này đều có chung một tên là SBUF, tuy nhiên CPU hoàn toàn phân biệt đợc một cách dễ dàng. Khi ta muốn truyền dữ liệu đi, ta phải ghi vào thanh ghi SBUF (ví dụ viết lệnh mov SBUF,a), còn khi muốn đọc kiểm tra dữ liệu nhận về ta phải đọc thanh ghi SBUF (ví dụ viết lệnh mov a,SBUF). CPU sẽ căn cứ vào việc thanh ghi SBUF nằm ở vị trí toán hạng đích (toán hạng bên trái) hay toán hạng nguồn (toán hạng bên phải) để quyết định sẽ truy nhập (đọc/ghi) thanh ghi SBUF nàọ Ngời lập trình không cần phải quan tâm xử lý vấn đề nàỵ
Thanh ghi quy định chế độ hoạt động và điều khiển cổng nối tiếp là thanh ghi
SCON (đánh địa chỉ bit).
Bit SM0, SM1, SM2 quy định chế độ hoạt động của cổng nối tiếp. Thông thờng để truyền thông giữa 2 vi điều khiển hoặc giữa 1 vi điều khiển và 1 máy tính, giá trị của bit SM2 đợc đặt bằng 0. Khi truyền thông theo kiểu mạng đa vi xử lý (multiprocessor communication), SM2 đợc đặt bằng
1. Hai bit SM0 và SM1 thực sự là các bit quy định chế độ hoạt động của cổng nối tiếp, chúng tạo ra 4 tổ hợp (00,01,10 và 11) ứng với 4 chế độ hoạt động mô tả trong bảng saụ
Chế độ 0: là chế độ truyền đồng bộ duy nhất. Chân RxD sẽ là tín hiệu truyền/nhận dữ liệu, chân TxD là tín hiệu xung nhịp. Bit LSB (bit 0) của dữ liệu đợc truyền đi trớc tiên. Tốc độ truyền cố định và bằng 1/12 giá