You are on page 1of 117

GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

MỤC LỤC
MỤC LỤC..............................................................................................................................1
DANH MỤC HÌNH ẢNH .....................................................................................................3
LỜI NÓI ĐẦU .......................................................................................................................5
Chƣơng 1: TỔNG QUAN VỀ VI ĐIỀU KHIỂN .................................................................6
1.1. Khái quát về vi điều khiển .........................................................................................6
1.2. Phân loại vi điều khiển và ứng dụng ..........................................................................8
1.2.1. Phân loại ..............................................................................................................8
1.2.2.Ứng dụng........................................................................................................... 10
1.3. Sơ đồ khối của một vi điều khiển ........................................................................... 11
Chƣơng 2: KIẾN TRÚC VI ĐIỀU KHIỂN ....................................................................... 14
2.1. Khái quát chung....................................................................................................... 14
2.2. Giới thiệu vi điều khiển PIC 16F877A ................................................................... 14
2.3. Tổ chức bộ nhớ ........................................................................................................ 20
2.3.1. Bộ nhớ chƣơng trình ........................................................................................ 20
2.3.2. Bộ nhớ dữ liệu .................................................................................................. 21
2.3.2.1. Thanh ghi chức năng đặc biệt SFR .............................................................. 22
2.3.2.2. Thanh ghi mục đích chung GPR .................................................................. 24
2.3.3. Stack ................................................................................................................. 24
2.4. Các cổng xuất nhập của PIC 16F877A ................................................................... 24
2.4.1. PORT A ................................................................................................................ 25
2.4.2. PORT B ................................................................................................................ 26
2.4.3. PORT C ................................................................................................................ 26
2.4.4. PORT D ................................................................................................................ 26
2.4.5. PORT E................................................................................................................. 26
2.5. Hoạt động Reset ...................................................................................................... 27
2.6. Chế độ tiết kiệm năng lƣợng ................................................................................... 29
Chương 3: LẬP TRÌNH CHO VI ĐIỀU KHIỂN .............................................................. 33
3.1.Giới thiệu các phần mềm lập trình và mô phỏng .................................................... 33
3.2.Trình biên dịch, ngôn ngữ lập trình cho vi điều khiển ............................................ 34
3.3.Cấu trúc một chƣơng trình vi điều khiển và các bƣớc lập trình .............................. 36
3.3.1.Khai báo tiền xử lý............................................................................................ 36
3.3.2.Phần khai báo biến toàn cục ............................................................................. 37
3.3.3.Phần khai báo, định nghĩa các chƣơng trình con ............................................. 38
3.3.4.Phần chƣơng trình chính: .................................................................................. 38
3.3.5.Các cấu trúc thuật toán của ngôn ngữ CCS...................................................... 38
3.3.6.Các toán tử cơ bản trong CCS .......................................................................... 40
3.3.7.Các hàm số học cơ bản trong CCS ................................................................... 40
3.3.8.Các hàm vào ra cơ bản trong CCS ................................................................... 41
3.3.9.Các hàm tạo trễ ................................................................................................. 41
3.4.Điều khiển xuất nhập dữ liệu (input, output, GPIO) ............................................... 42
3.5.Các bộ chuyển đổi tín hiệu ADC, COMPARATOR, CCP ..................................... 46
Chƣơng 4: HOẠT ĐỘNG ĐỊNH THỜI (TIMER/COUNTER) ........................................ 58
4.1. Mở đầu ..................................................................................................................... 58
4.2. Nguyên lý hoạt động cơ bản của một bộ định thời................................................. 58
4.2.1.Chế độ định thời:............................................................................................... 58

ĐƢỜNG KHÁNH SƠN Trang 1


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

4.2.2.Chế độ bộ đếm .................................................................................................. 59


4.3. TIMER 0 .................................................................................................................. 60
4.4. TIMER 1 .................................................................................................................. 63
4.5. TIMER 2 .................................................................................................................. 64
4.6 Một số ứng dụng định thời ....................................................................................... 66
Chƣơng 5: GIAO TIẾP VÀ TRUYỀN DỮ LIỆU VỚI VI ĐIỀU KHIỂN ....................... 71
5.1.GIAO TIẾP NỐI TIẾP ............................................................................................. 71
5.1.1. USART ............................................................................................................. 71
5.1.1.1 USART BẤT ĐỒNG BỘ .............................................................................. 72
5.1.1.2 USART ĐỒNG BỘ ....................................................................................... 76
5.2 MSSP ....................................................................................................................... 81
5.2.1. SPI .................................................................................................................... 82
5.2.2.I2C ..................................................................................................................... 87
Chƣơng 6: HOẠT ĐỘNG NGẮT .................................................................................... 105
6.1 Mở đầu .................................................................................................................... 105
6.2 Tổ chức và xử lý ngắt ............................................................................................. 105
6.3 Thiết kế chƣơng trình xử lý ngắt............................................................................ 106
6.5 Các ngắt bộ định thời ............................................................................................. 108
6.6 Các ngắt port nối tiếp ............................................................................................. 109
6.7 Các ngắt ngoài ........................................................................................................ 111
TÀI LIỆU THAM KHẢO ................................................................................................ 117

ĐƢỜNG KHÁNH SƠN Trang 2


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

DANH MỤC HÌNH ẢNH

Hình 1.1: Cấu trúc chung họ vi điều khiển ........................................................................ 11


Hình 2.1: Các dạng sơ đồ chân của vi điều khiển PIC16F877A/ PIC16F874A ............... 16
Hình 2.2: Sơ đồ khối của vi điều khiển PIC16F877A ....................................................... 17
Hình 2.3: Chức năng các chân của vi điều khiển PIC16F877A ........................................ 18
Hình 2.4: Bộ nhớ chƣơng trình PIC16F877A .................................................................... 21
Hình 2.5: Bộ nhớ dữ liệu PIC16F877A ............................................................................. 22
Hình 2.6: Mạch reset qua pin MCLR .................................................................................. 27
Hình 2.7: Sơ đồ các chế độ reset của PIC 16F877A .......................................................... 29
Hình 2.8: RC oscillator ....................................................................................................... 32
Hình 3.1: Mô phỏng chƣơng trình bật tắt 8 đèn led ở port bằng proteus .......................... 46
Hình 3.2: Sơ đồ khối bộ chuyển đổi ADC ......................................................................... 48
Hình 3.3: Các cách lƣu kết quả chuyển đổi AD................................................................. 48
Hình 3.4: Nguyên lý hoạt động của một bộ so sánh đơn giản ........................................... 49
Hình 3.5: Các chế độ hoạt động của bộ comparator .......................................................... 50
Hình 3.6: Sơ đồ khối bộ tạo điện áp so sánh ...................................................................... 51
Hình 3.7: Sơ đồ khối bộ CCP ............................................................................................. 53
Hình 3.8: Sơ đồ khối bộ CCP (Compare mode) ................................................................ 54
Hình 3.9: Sơ đồ khối bộ CCP (PWM mode) ..................................................................... 55
Hình 3.10: Các tham số của PWM ..................................................................................... 56
Hình 4.1: Sơ đồ khối của timer 0 ....................................................................................... 61
Hình 4.2: Sơ đồ khối của timer 2 ....................................................................................... 65
Hình 4.3: Mô phỏng dùng ngắt timer 0 định thì 1s............................................................ 67
Hình 4.4: Mô phỏng đo tốc độ động cơ sử dụng timer 1 ................................................... 70
Hình 5.1: Sơ đồ khối của khối truyền dữ liệu USART ...................................................... 72
Hình 5.2: Sơ đồ khối của khối nhận dữ liệu USART ........................................................ 74
Hình 5.3: Sơ đồ khối MSSP (giao diện SPI) ...................................................................... 82
Hình 5.4: Sơ đồ khối của chuẩn giao tiếp SPI ................................................................... 85
Hình 5.5: Giản đồ xung SPI ở chế độ Master mode ......................................................... 86
Hình 5.6: Giản đồ xung SPI ở chế độ Slave mode ........................................................... 87
Hình 5.7: Sơ đồ khối MSSP (I2C Slave mode) ................................................................ 89
Hình 5.8: Giản đồ xung của I2C Slave mode 7 bit địa chỉ trong quá trình nhận dữ liệu
(bit SEN=0) ......................................................................................................................... 92
Hình 5.9: Giản đồ xung của I2C Slave mode 10 bit địa chỉ trong quá trình nhận dữ liệu
(bit SEN=0) ......................................................................................................................... 92
Hình 5.10: Giản đồ xung của I2C Slave mode 7 bit địa chỉ trong quá trình nhận dữ liệu
(bit SEN=1) ......................................................................................................................... 93
Hình 5.11: Giản đồ xung của I2C Slave mode 10 bit địa chỉ trong quá trình nhận dữ liệu
(bit SEN=1) ......................................................................................................................... 93
Hình 5.12: Giản đồ xung của I2C Slave mode 7 bit địa chỉ trong quá trình truyền dữ liệu
............................................................................................................................................. 95
Hình 5.13: Giản đồ xung của I2C Slave mode 10 bit địa chỉ trong quá trình truyền dữ
liệu ....................................................................................................................................... 95
Hình 5.14: Giản đồ xung của I2C Slave khi nhận địa chỉ GCA ....................................... 96
Hình 5.15: Sơ đồ khối MSSP ( I2C Master mode) ............................................................ 96

ĐƢỜNG KHÁNH SƠN Trang 3


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Hình 5.16: Sơ đồ khối BRG (Baud Rate Benerator) của I2C Master mode .................... 97
Hình 5.17: Giản đồ xung I2C Master mode trong quá trình tạo điều kiện Start ............... 98
Hình 5.18: Giản đồ xung I2C Master mode trong quá trình tạo điều kiện Stop .............. 99
Hình 5.19: Giản đồ I2C Master mode trong quá trình tạo điều kiện Start liên tục ........ 100
Hình 5.20: Giản đồ xung I2C Master mode trong quá trình truyền dữ liệu ................... 101
Hình 5.21: Giản đồ xung I2C Master mode trong quá trình nhận dữ liệu ...................... 102
Hình 5.22: Sơ đồ của PortD và PortE khi hoạt động ở chế độ PSP Slave mode ........... 104
Hình 6.1: Sơ đồ logic của tất cả các ngắt trong vi điều khiển PIC 16F877A ................ 106
Hình 6.2: Mô phỏng ngắt ngoài với PIC 16F877A.......................................................... 116

ĐƢỜNG KHÁNH SƠN Trang 4


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

LỜI NÓI ĐẦU

Giáo trình này đƣợc biên soạn để phục vụ cho việc giảng dạy môn Vi điều khiển
của các ngành điện tử, điện công nghiệp, cơ điện tử, tự động hóa...
Nội dung giáo trình gồm 6 chƣơng trình bày các vấn đề chính sau :
- Tổng quan về vi điều khiển.
- Kiến trúc vi điều khiển.
- Lập trình cho vi điều khiển.
- Hoạt động định thời (Timer/Counter).
- Giao tiếp và truyền dữ liệu với vi điều khiển.
- Hoạt động ngắt.
Thông qua giáo trình này sinh viên có thể nắm đƣợc các kiến thức cơ bản về vi
điều khiển và ứng dụng trong thực tế. Hiểu đƣợc nguyên lý hoạt động, cấu trúc của một
hệ vi xử lý và vi điều khiển. Nắm đƣợc ngôn ngữ lập trình để lập trình ứng dụng với vi
điều khiển. Nhận biết đƣợc xu hƣớng phát triển liên quan đến vi điều khiển...
Để sử dụng giáo trình có hiệu quả cao sinh viên cần xem kỹ phần lý thuyết để nắm
đƣợc các khái niệm cơ bản . Sau đó áp dụng vào giải các bài tập cuối mỗi chƣơng . Bên
cạnh đó sinh viên cần tham gia đầy đủ các buổi thực hành ở phòng thí nghiệm.
Do đây là lần đầu biên soạn nên khó tránh khỏi sai sót, tác giả rất mong nhận đƣợc
ý kiến đóng góp quý báu từ quý thầy cô, các bạn sinh viên để có điều kiện sửa chữa bổ
sung giáo trình hoàn thiện hơn.

Tác giả

Đường Khánh Sơn


.

ĐƢỜNG KHÁNH SƠN Trang 5


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Chương 1: TỔNG QUAN VỀ VI ĐIỀU KHIỂN

1.1. Khái quát về vi điều khiển


 Khái niệm vi xử lý và vi điều khiển
Về cơ bản hai khái niệm này không khác nhau nhiều, “vi xử lý” là thuật ngữ chung
dùng đề cập đến kỹ thuật ứng dụng các công nghệ vi điện tử, công nghệ tích hợp và khả
năng xử lý theo chƣơng trình vào các lĩnh vực khác nhau. Vào giai đoạn đầu trong quá
trình phát triển của công nghệ vi xử lý, các chip (hay các vi xử lý) đƣợc chế tạo chỉ tích
hợp những phần cứng thiết yếu nhƣ CPU cùng các mạch giao tiếp giữa CPU và các phần
cứng khác. Trong giai đoạn này, các phần cứng khác (kể cả bộ nhớ) thƣờng không đƣợc
tích hợp trên chip mà phải ghép nối thêm bên ngoài. Các phần cứng này đƣợc gọi là các
ngoại vi (Peripherals). Về sau, nhờ sự phát triển vƣợt bậc của công nghệ tích hợp, các
ngoại vi cũng đƣợc tích hợp vào bên trong IC và ngƣời ta gọi các vi xử lý đã đƣợc tích
hợp thêm các ngoại vi là các “vi điều khiển”.
Vi xử lý có các khối chức năng cần thiết để lấy dữ liệu, xử lý dữ liệu và xuất dữ
liệu ra ngoài sau khi đã xử lý. Và chức năng chính của vi xử lý chính là xử lý dữ liệu,
chẳng hạn nhƣ cộng, trừ, nhân, chia, so sánh.v.v... Vi xử lý không có khả năng giao tiếp
trực tiếp với các thiết bị ngoại vi, nó chỉ có khả năng nhận và xử lý dữ liệu.
Để vi xử lý hoạt động cần có chƣơng trình kèm theo, các chƣơng trình này điều
khiển các mạch logic và từ đó vi xử lý xử lý các dữ liệu cần thiết theo yêu cầu.
Chƣơng trình là tập hợp các lệnh để xử lý dữ liệu thực hiện từng lệnh đƣợc lƣu trữ
trong bộ nhớ, công việc thực hành lệnh bao gồm: nhận lệnh từ bộ nhớ, giải mã lệnh và
thực hiện lệnh sau khi đã giải mã.
Để thực hiện các công việc với các thiết bị cuối cùng, chẳng hạn điều khiển động
cơ, hiển thị kí tự trên màn hình .... đòi hỏi phải kết hợp vi xử lý với các mạch điện giao
tiếp với bên ngoài đƣợc gọi là các thiết bị I/O (nhập/xuất) hay còn gọi là các thiết bị
ngoại vi. Bản thân các vi xử lý khi đứng một mình không có nhiều hiệu quả sử dụng,
nhƣng khi là một phần của một máy tính, thì hiệu quả ứng dụng của vi xử lý là rất lớn. Vi
xử lý kết hợp với các thiết bị khác đƣợc sử trong các hệ thống lớn, phức tạp đòi hỏi phải
xử lý một lƣợng lớn các phép tính phức tạp, có tốc độ nhanh. Chẳng hạn nhƣ các hệ
thống sản xuất tự động trong công nghiệp, các tổng đài điện thoại, hoặc ở các robot có
khả năng hoạt động phức tạp v.v...
ĐƢỜNG KHÁNH SƠN Trang 6
GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Bộ vi xử lý có khả năng vƣợt bậc so với các hệ thống khác về khả năng tính toán,
xử lý, và thay đổi chƣơng trình linh hoạt theo mục đích ngƣời dùng, đặc biệt hiệu quả đối
với các bài toán và hệ thống lớn. Tuy nhiên đối với các ứng dụng nhỏ, tầm tính toán
không đòi hỏi khả năng tính toán lớn thì việc ứng dụng vi xử lý cũng đòi hỏi các khối
mạch điện giao tiếp phức tạp. Các khối này bao gồm bộ nhớ để chứa dữ liệu và chƣơng
trình thực hiện, các mạch điện giao tiếp ngoại vi để xuất nhập và điều khiển trở lại, các
khối này cùng liên kết với vi xử lý thì mới thực hiện đƣợc công việc. Để kết nối các khối
này đòi hỏi ngƣời thiết kế phải hiểu biết rõ về các thành phần vi xử lý, bộ nhớ, các thiết
bị ngoại vi. Hệ thống đƣợc tạo ra khá phức tạp, chiếm nhiều không gian, mạch in phức
tạp và vấn đề chính là trình độ ngƣời thiết kế. Kết quả là giá thành sản phẩm cuối cùng
rất cao, không phù hợp để áp dụng cho các hệ thống nhỏ.
Vì vậy nên các nhà chế tạo tích hợp một ít bộ nhớ và một số mạch giao tiếp ngoại
vi cùng với vi xử lý vào một IC duy nhất đƣợc gọi là Microcontroller (Vi điều khiển). Vi
điều khiển có khả năng tƣơng tự nhƣ khả năng của vi xử lý, nhƣng cấu trúc phần cứng
dành cho ngƣời dùng đơn giản hơn nhiều.
Vi điều khiển ra đời mang lại sự tiện lợi đối với ngƣời dùng, họ không cần nắm
vững một khối lƣợng kiến thức quá lớn nhƣ ngƣời dùng vi xử lý, kết cấu mạch điện dành
cho ngƣời dùng cũng trở nên đơn giản hơn nhiều và có khả năng giao tiếp trực tiếp với
các thiết bị bên ngoài. Vi điều khiển tuy đƣợc xây dựng với phần cứng dành cho ngƣời sử
dụng đơn giản hơn, nhƣng thay vào lợi điểm này là khả năng xử lý bị giới hạn (tốc độ xử
lý chậm hơn và khả năng tính toán ít hơn, dung lƣợng chƣơng trình bị giới hạn). Tuy
nhiên vi điều khiển có giá thành rẻ hơn nhiều so với vi xử lý, việc sử dụng đơn giản, do
đó nó đƣợc ứng dụng rộng rãi vào nhiều ứng dụng có chức năng đơn giản, không đòi hỏi
tính toán phức tạp.
Năm 1976 Intel giới thiệu bộ vi điều khiển 8748, một chip tƣơng tự nhƣ các bộ vi
xử lý và là chip đầu tiên trong họ MCS-48. Độ phức tạp, kích thƣớc và khả năng của vi
điều khiển tăng thêm một bậc quan trọng vào năm 1980 khi intel tung ra chip 8051, bộ vi
điều khiển đầu tiên của họ MCS-51 và là chuẩn công nghệ cho nhiều họ vi điều khiển
đƣợc sản xuất sau này. Sau đó rất nhiều họ vi điều khiển của nhiều nhà chế tạo khác nhau
lần lƣợt đƣợc đƣa ra thị trƣờng với tính năng đƣợc cải tiến ngày càng mạnh.

ĐƢỜNG KHÁNH SƠN Trang 7


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

1.2. Phân loại vi điều khiển và ứng dụng


1.2.1. Phân loại
 Độ dài thanh ghi
Dựa vào độ dài của các thanh ghi và các lệnh của vi điều khiển mà ngƣời ta chia ra
các loại vi điều khiển 8 bit, 16 bit, hay 32 bit....
Các loại vi điều khiển 16 bit do có độ dài lệnh lớn hơn nên các tập lệnh cũng nhiều
hơn, phong phú hơn. Tuy nhiên bất cứ chƣơng trình nào viết bằng vi điều khiển 16 bit
chúng ta đều có thể viết trên vi điều khiển 8 bit với chƣơng trình thích hợp.
 Kiến trúc CISC (Complex Instruction Set Computer) và RISC (Reduced
Instruction Set Computer)
Vi điều khiển CISC là vi điều khiển có tập lệnh phức tạp. Các vi điều khiển này có
một số lƣợng lớn các lệnh nên giúp cho ngƣời lập trình có thể linh hoạt và dễ dàng hơn
khi viết chƣơng trình. Vi điều khiển RISC là vi điều khiển có tập lệnh đơn giản. Chúng
có một số lƣợng nhỏ các lệnh đơn giản. Do đó, chúng đòi hỏi phần cứng ít hơn, giá thành
thấp hơn, và nhanh hơn so với CISC. Tuy nhiên nó đòi hỏi ngƣời lập trình phải viết các
chƣơng trình phức tạp hơn, nhiều lệnh hơn.
 Kiến trúc Harvard và kiến trúc Vonneumann
Kiến trúc Harvard sử dụng bộ nhớ riêng biệt cho chƣơng trình và dữ liệu. Bus địa
chỉ và bus dữ liệu độc lập với nhau nên quá trình truyền nhận dữ liệu đơn giản hơn. Kiến
trúc Vonneumann sử dụng chung bộ nhớ cho chƣơng trình và dữ liệu. Điều này làm cho
vi điều khiển gọn nhẹ hơn, giá thành rẻ hơn.
 Một số loại vi điều khiển có trên thị trường:
- Vi điều khiển MCS-51
Họ vi điều khiển MCS-51 do Intel sản xuất đầu tiên vào năm 1980 là các IC thiết
kế cho các ứng dụng hƣớng điều khiển. Các IC này chính là một hệ thống vi xử lý hoàn
chỉnh bao gồm các các thành phần của hệ vi xử lý: CPU, bộ nhớ, các mạch giao tiếp, điều
khiển ngắt. MCS-51 là họ vi điều khiển sử dụng cơ chế CISC, có độ dài và thời gian thực
thi của các lệnh khác nhau. Tập lệnh cung cấp cho MCS-51 có các lệnh dùng cho điều
khiển xuất/nhập tác động đến từng bit. MCS-51 bao gồm nhiều vi điều khiển khác nhau,
bộ vi điều khiển đầu tiên là 8051 có 4KB ROM, 128 byte RAM và 8031, không có ROM
nội, phải sử dụng bộ nhớ ngoài. Sau này, các nhà sản xuất khác nhƣ Siemens, Fujitsu,

ĐƢỜNG KHÁNH SƠN Trang 8


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

…cũng đƣợc cấp phép làm nhà cung cấp thứ hai. MCS-51 bao gồm nhiều phiên bản khác
nhau, mỗi phiên bản sau tăng thêm một số thanh ghi điều khiển hoạt động của MCS-51.
AT89C51 là vi điều khiển do Atmel sản xuất, chế tạo theo công nghệ CMOS.
- Vi điều khiển AVR
AVR là một kiến trúc Harvard sửa đổi 8-bit RISC đơn chip vi điều khiển đã đƣợc
phát triển bởi Atmel vào năm 1996. Các AVR là một trong những họ vi điều khiển đầu
tiên sử dụng on-chip bộ nhớ flash để lƣu trữ chƣơng trình, trái với One-Time
Programmable ROM, EPROM hoặc EEPROM đƣợc sử dụng bởi vi điều khiển khác vào
lúc đó. AVR là một kiến trúc máy Modified Harvard với chƣơng trình và dữ liệu đƣợc
lƣu trữ trong các hệ thống bộ nhớ vật lý riêng biệt xuất hiện trong không gian địa chỉ
khác nhau, nhƣng có khả năng đọc ghi dữ liệu từ bộ nhớ bằng cách sử dụng lệnh đặc biệt.
- Vi điều khiển PIC
PIC là một họ vi điều khiển RISC đƣợc sản xuất bởi công ty Microchip
Technology. Dòng PIC đầu tiên là PIC1650 đƣợc phát triển bởi Microelectronics
Division thuộc General Instrument .
PIC bắt nguồn là chữ viết tắt của "Programmable Intelligent Computer" (Máy tính
khả trình thông minh) là một sản phẩm của hãng General Instruments đặt cho dòng sản
phẩm đầu tiên của họ là PIC1650. Lúc này, PIC1650 đƣợc dùng để giao tiếp với các thiết
bị ngoại vi cho máy chủ 16 bit CP1600, vì vậy, ngƣời ta cũng gọi PIC với cái tên
"Peripheral Interface Controller" (Bộ điều khiển giao tiếp ngoại vi). CP1600 là một CPU
tốt, nhƣng lại kém về các hoạt động xuất nhập, và vì vậy PIC 8-bit đƣợc phát triển vào
khoảng năm 1975 để hỗ trợ hoạt động xuất nhập cho CP1600. PIC sử dụng microcode
đơn giản đặt trong ROM, và mặc dù, cụm từ RISC chƣa đƣợc sử dụng thời bây giờ,
nhƣng PIC thực sự là một vi điều khiển với kiến trúc RISC, chạy một lệnh một chu kỳ
máy (4 chu kỳ của bộ dao động). Năm 1985 General Instruments bán bộ phận vi điện tử
của họ, và chủ sở hữu mới hủy bỏ hầu hết các dự án - lúc đó đã quá lỗi thời. Tuy nhiên
PIC đƣợc bổ sung EEPROM để tạo thành 1 bộ điều khiển vào ra khả trình. Ngày nay rất
nhiều dòng PIC đƣợc xuất xƣởng với hàng loạt các module ngoại vi tích hợp sẵn (nhƣ
USART, PWM, ADC...), với bộ nhớ chƣơng trình từ 512 Word đến 32K Word.

ĐƢỜNG KHÁNH SƠN Trang 9


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

1.2.2.Ứng dụng
Vi điều khiển có thể dùng trong thiết kế các loại máy tính nhúng. Máy tính nhúng
có trong hầu hết các thiết bị tự động thông minh ngày nay. Chúng ta có thể dùng vi điều
khiển để thiết kế bộ điều khiển cho các sản phẩm nhƣ:
 Trong các sản phẩm dân dụng:
- Nhà thông minh: Cửa tự động, khóa số, tự động điều tiết ánh sáng thông minh
(bật/tắt đèn theo thời gian, theo cƣờng độ ánh sáng,...).
- Điều khiển các thiết bịt từ xa (qua điều khiển, qua tiếng vỗ tay,...).
- Điều tiết hơi ẩm, điều tiết nhiệt độ, điều tiết không khí, gió.
- Hệ thống vệ sinh thông minh,...
 Trong quảng cáo:
- Các loại biển quảng cáo nháy chữ.
- Quảng cáo ma trận LED (một màu, 3 màu, đa màu).
- Điều khiển máy cuốn bạt quảng cáo,...
 Các máy móc dân dụng
- Máy điều tiết độ ẩm cho vƣờn cây.
- Buồng ấp trứng gà/vịt.
- Đồng hồ số, đồng hồ số có điều khiển theo thời gian.
 Các sản phẩm giải trí
- Máy nghe nhạc.
- Máy chơi game.
- Đầu thu kỹ thuật số, đầu thu set-top-box,...
 Trong các thiết bị y tế:
- Máy móc thiết bị hỗ trợ: máy đo nhịp tim, máy đo đƣờng huyết, máy huyết áp,
điện tim đồ, điện não đồ,…
- Máy cắt/mài kính.
- Máy chụp chiếu (city, X-quang,...)
 Các sản phẩm công nghiệp:
- Điều khiển động cơ.
- Điều khiển số (PID, mờ,...).

ĐƢỜNG KHÁNH SƠN Trang 10


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

- Đo lƣờng (đo điện áp, đo dòng điện, áp suất, nhiệt độ,...).


- Cân băng tải, cân toa xe, cân ô tô,...
- Máy cán thép: điều khiển động cơ máy cán, điều khiển máy quấn thép,..
- Làm bộ điều khiển trung tâm cho Robot.
- Ổn định tốc độ động cơ.
- Đếm sản phẩm của 1 nhà máy, xí nghiệp,…
- Máy vận hành tự động (dạng CNC).
1.3. Sơ đồ khối của một vi điều khiển
Nhƣ ta thấy, tất cả các hoạt động trong các vi điều khiển đƣợc thực hiện ở tốc độ
cao và khá đơn giản và vi điều khiển bao gồm các bộ phận sau đây:

Hình 1.1: Cấu trúc chung họ vi điều khiển

 Read Only Memory (ROM)


ROM là bộ nhớ dùng để lƣu giữ chƣơng trình. ROM còn dùng để chứa số liệu các
bảng, các tham số hệ thống, các số liệu cố định của hệ thống. Trong quá trình hoạt động
nội dung ROM là cố định, không thể thay đổi, nội dung ROM chỉ thay đổi khi ROM ở
chế độ xóa hoặc nạp chƣơng trình. đích khác.
 Random Access Memory (RAM)
Random Access Memory (RAM) là một loại bộ nhớ sử dụng cho các dữ liệu lƣu trữ
tạm thời và kết quả trung gian đƣợc tạo ra và đƣợc sử dụng trong quá trình hoạt động của
bộ vi điều khiển. Nội dung của bộ nhớ này bị xóa khi nguồn cung cấp bị tắt.

ĐƢỜNG KHÁNH SƠN Trang 11


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

 Các thanh ghi chức năng đặc biệt (SFR)


Thanh ghi chức năng đặc biệt (Special Function Registers) là một phần của bộ nhớ
RAM. Mục đích của chúng đƣợc định trƣớc bởi nhà sản xuất và không thể thay đổi đƣợc.
Các bit của chúng đƣợc liên kết vật lý tới các mạch trong vi điều khiển nhƣ bộ chuyển
đổi A/D, modul truyền thông nối tiếp,… Mỗi sự thay đổi trạng thái của các bit sẽ tác
động tới hoạt động của vi điều khiển hoặc các vi mạch.
 Bộ đếm chƣơng trình (PC: Program Counter)
Bộ đếm chƣơng trình chứa địa chỉ chỉ đến ô nhớ chứa câu lệnh tiếp theo sẽ đƣợc kích
hoạt. Sau mỗi khi thực hiện lệnh, giá trị của bộ đếm đƣợc tăng lên 1. Vì lý do đó nên
chƣơng trình chỉ thực hiện đƣợc từng lệnh trong một thời điểm.
 Central Processor Unit (CPU)
Đây là một đơn vị có nhiệm vụ điều khiển và giám sát tất cả các hoạt động bên trong
vi điều khiển và ngƣời sử dụng không thể tác động vào hoạt động của nó.
 Các cổng vào/ra (I/O Ports)
Để vi điều khiển có thể hoạt động hữu ích, nó cần có sự kết nối với các thiết bị ngoại
vi. Mỗi vi điều khiển sẽ có một hoặc một số thanh ghi (đƣợc gọi là cổng) đƣợc kết nối
với các chân của vi điều khiển. Chúng đƣợc gọi là cổng vào/ra (I/O port) bởi vì chúng có
thể thay đổi chức năng, chiều vào/ra theo yêu cầu của ngƣời dùng.
 Bộ dao động (Oscillator)
Bộ dao động đóng vai trò nhạc trƣởng làm nhiệm vụ đồng bộ hóa hoạt động của tất cả
các mạch bên trong vi điều khiển. Nó thƣờng đƣợc tạo bởi thạch anh hoặc gốm để ổn
định tần số. Các lệnh không đƣợc thực thi theo tốc độ của bộ dao động mà thƣờng chậm
hơn, bởi vì mỗi câu lệnh đƣợc thực hiện qua nhiều bƣớc. Mỗi loại vi điều khiển cần số
chu kỳ khác nhau để thực hiện lệnh.
 Bộ định thời/đếm (Timers/Counters)
Hầu hết các chƣơng trình sử dụng các bộ định thời trong hoạt động của mình. Chúng
thƣờng là các thanh ghi SFR 8 hoặc 16 bit, sau mỗi xung dao động clock, giá trị của
chúng đƣợc tăng lên. Ngay khi thanh ghi tràn, một ngắt sẽ đƣợc phát sinh.
 ADC (Analog-to-digital converter)

ĐƢỜNG KHÁNH SƠN Trang 12


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Bộ phận chuyển tín hiệu analog sang tín hiệu digital. Các tín hiệu bên ngoài đi vào vi
điều khiển thƣờng ở dạng analog. ADC sẽ chuyển tín hiệu này về dạng tín hiệu digital mà
vi điều khiển có thể hiểu đƣợc.

ĐƢỜNG KHÁNH SƠN Trang 13


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Chương 2: KIẾN TRÚC VI ĐIỀU KHIỂN

2.1. Khái quát chung


Hiện nay trên thị trƣờng có rất nhiều họ vi điều khiển nhƣ 8051, Motorola 68HC,
AVR, ARM,... tuy nhiên trong giáo trình này sẽ tập trung trình bày về vi điều khiển PIC
vì các nguyên nhân sau:
 Họ vi điều khiển này có thể tìm mua dễ dàng tại thị trƣờng Việt Nam. Giá
thành không quá đắt. Có đầy đủ các tính năng của một vi điều khiển khi hoạt
động độc lập.
 Số lƣợng ngƣời sử dụng họ vi điều khiển PIC. Hiện nay tại Việt Nam cũng nhƣ
trên thế giới, họ vi điều khiển này đƣợc sử dụng khá rộng rãi. Điều này tạo
nhiều thuận lợi trong quá trình tìm hiểu và phát triển các ứng dụng nhƣ: số
lƣợng tài liệu, số lƣợng các ứng dụng mở đã đƣợc phát triển thành công, dễ
dàng trao đổi, học tập, dễ dàng tìm đƣợc sự chỉ dẫn khi gặp khó khăn,…
 Sự hỗ trợ của nhà sản xuất về trình biên dịch, các công cụ lập trình, nạp
chƣơng trình từ đơn giản đến phức tạp,…
 Các tính năng đa dạng của vi điều khiển PIC, và các tính năng này không
ngừng đƣợc phát triển.
2.2. Giới thiệu vi điều khiển PIC 16F877A
Đây là vi điều khiển thuộc họ PIC16Fxxx với tập lệnh gồm 35 lệnh có độ dài
14bit. Mỗi lệnh đều đƣợc thực thi trong một chu kì xung clock. Tốc độ hoạt động tối đa
cho phép là 20 MHz với một chu kì lệnh là 200ns. Bộ nhớ chƣơng trình 8Kx14 bit, bộ
nhớ dữ liệu 368x8 byte RAM và bộ nhớ dữ liệu EEPROM với dung lƣợng 256x8 byte.
Số PORT I/O là 5 với 33 pin I/O. Có 8 kênh chuyển đổi A/D.
 Các đặc tính ngoại vi bao gồm các khối chức năng sau:
- Timer 0: bộ đếm 8 bit với bộ chia tần số 8 bit.
- Timer 1: bộ đếm 16 bit với bộ chia tần số, có thể thực hiện chức năng đếm
dựa vào xung clock ngoại vi ngay khi vi điều khiển hoạt động ở chế độ sleep.
- Timer 2: bộ đếm 8 bit với bộ chia tần số, bộ postcaler.
- Hai bộ Capture/so sánh/điều chế độ rộng xung.
- Các chuẩn giao tiếp nối tiếp SSP (Synchronous Serial Port), SPI và I2C.
- Chuẩn giao tiếp nối tiếp USART với 9 bit địa chỉ.
ĐƢỜNG KHÁNH SƠN Trang 14
GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

- Cổng giao tiếp song song PSP (Parallel Slave Port) với các chân điều khiển
RD, WR.
 Bên cạnh đó là một vài đặc tính khác của vi điều khiển nhƣ:
- Bộ nhớ flash với khả năng ghi xóa đƣợc 100.000 lần.
- Bộ nhớ EEPROM với khả năng ghi xóa đƣợc 1.000.000 lần.
- Dữ liệu bộ nhớ EEPROM có thể lƣu trữ trên 40 năm.
- Khả năng tự nạp chƣơng trình với sự điều khiển của phần mềm.
- Nạp đƣợc chƣơng trình ngay trên mạch điện ICSP (In Circuit Serial
Programming) thông qua 2 chân.
- Watchdog Timer với bộ dao động trong.
- Chức năng bảo mật mã chƣơng trình.
- Chế độ Sleep.
- Có thể hoạt động với nhiều dạng Oscillator khác nhau.

ĐƢỜNG KHÁNH SƠN Trang 15


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

CÁC DẠNG SƠ ĐỒ CHÂN VI ĐIỀU KHIỂN PIC16F877A

Hình 2.1: Các dạng sơ đồ chân của vi điều khiển PIC16F877A/ PIC16F874A

ĐƢỜNG KHÁNH SƠN Trang 16


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

SƠ ĐỒ KHỐI VI ĐIỀU KHIỂN PIC16F877A

Hình 2.2: Sơ đồ khối của vi điều khiển PIC16F877A

- Khối ALU – Arithmetic Logic Unit.


- Khối bộ nhớ chứa chƣơng trình – Flash Program Memory.
- Khối bộ nhớ chứa dữ liệu EPROM – Data EPROM.
- Khối bộ nhớ file thanh ghi RAM – RAM file Register.
- Khối giải mã lệnh và điều khiển – Instruction Decode Control.

ĐƢỜNG KHÁNH SƠN Trang 17


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

- Khối thanh ghi đặc biệt.


- Khối ngoại vi timer.
- Khối giao tiếp nối tiếp.
- Khối chuyển đổi tín hiệu tƣơng tự sang số - ADC.
- Khối các port xuất nhập.

CHỨC NĂNG CÁC CHÂN CỦA PIC16F877A

Hình 2.3: Chức năng các chân của vi điều khiển PIC16F877A

• Chân OSC1/CLK1(13): ngõ vào kết nối với dao động thạch anh hoặc ngõ vào
nhận xung clock từ bên ngoài.
• Chân OSC2/CLK2(14): ngõ ra dao động thạch anh hoặc ngõ ra cấp xung
clock.
• Chân MCLR / V pp (1) có 2 chức năng:

 MCLR : ngõ vào reset tích cực ở mức thấp.


 V pp : ngõ vào nhận điện áp lập trình khi lập trình cho PIC.

• Chân RA0/AN0(2), RA1/AN1(3), RA2/AN2(3): có 2 chức năng


 RA0,1,2: xuất/ nhập số.
ĐƢỜNG KHÁNH SƠN Trang 18
GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

 AN 0,1,2: ngõ vào tƣơng tự của kênh thứ 0,1,2.


• Chân RA2/AN2/VREF-/CVREF+(4): xuất nhập số/ ngõ vào tƣơng tự của kênh
thứ 2/ nhõ vào điện áp chuẩn thấp của bộ AD/ ngõ vào điện áp chẩn cao của bộ
AD.
• Chân RA3/AN3/VREF+(5): xuất nhập số/ ngõ vào tƣơng tự kênh 3/ ngõ vào
điện áp chuẩn (cao) của bộ AD.
• Chân RA4/TOCK1/C1OUT(6): xuất nhập số/ ngõ vào xung clock bên ngoài cho
Timer 0/ ngõ ra bộ so sánh 1.
• Chân RA5/AN4/ SS / C2OUT(7): xuất nhập số/ ngõ vào tƣơng tự kênh 4/ ngõ
vào chọn lựa SPI phụ/ ngõ ra bộ so sánh 2.
• Chân RB0/INT (33): xuất nhập số/ ngõ vào tín hiệu ngắt ngoài.
• Chân RB1(34), RB2(35): xuất nhập số.
• Chân RB3/PGM(36): xuất nhập số/ cho phép lập trình điện áp thấp ICSP.
• Chân RB4(37), RB5(38): xuất nhập số.
• Chân RB6/PGC(39): xuất nhấp số/ mạch gỡ rối và xung clock lập trình ICSP.
• Chân RB7/PGD(40): xuất nhập số/ mạch gỡ rối và dữ liệu lập trình ICSP.
• Chân RC0/T1OCO/T1CKI(15): xuất nhập số/ ngõ vào bộ giao động Timer 1/ngõ
vào xung clock bên ngoài Timer 1.
• Chân RC1/T1OSI/CCP2(16) : xuất nhập số/ ngõ vào bộ dao động Timer 1/ngõ
vào Capture2, ngõ ra compare2, ngõ ra PWM2.
• Chân RC2/CCP1(17): xuất nhập số/ ngõ vào Capture1 ,ngõ ra compare1, ngõ ra
PWM1.
• Chân RC3/SCK/SCL(18): xuất nhập số/ ngõ vào xung clock nối tiếp đồng bộ,
ngõ ra chế độ SPI./ ngõ vào xung clock nối tiếp đồng bộ, ngõ ra của chế độ I2C.
• Chân RC4/SDI/SDA(23): xuất nhập số/ dữ liệu vào SPI/ xuất nhập dữ liệu I2C.
• Chân RC5/SDO(24): xuất nhập số/ dữ liệu ra SPI.
• Chân RC6/TX/CK(25): xuất nhập số/ truyền bất đồng bộ USART/ xung đồng bộ
USART.
• Chân RC7/RX/DT(26): xuất nhập số/ nhận bất đồng bộ USART.
• Chân RD0-7/PSP0-7(19-30): xuất nhập số/ dữ liệu port song song.

ĐƢỜNG KHÁNH SƠN Trang 19


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

• Chân RE0/ RD /AN5(8): xuất nhập số/ điều khiển port song song/ ngõ vào tƣơng
tự 5.
• Chân RE1/ WR /AN6(9): xuất nhập số/ điều khiển ghi port song song/ ngõ vào
tƣơng tự kênh thứ 6.
• Chân RE2/ CS /AN7(10): xuất nhấp số/ Chân chọn lụa điều khiển port song
song/ ngõ vào tƣơng tự kênh thứ 7.
• Chân VDD(11, 32) và VSS(12, 31): là các chân nguồn của PIC.
2.3. Tổ chức bộ nhớ
Cấu trúc bộ nhớ của vi điều khiển PIC16F877A bao gồm bộ nhớ chƣơng trình
(Program memory) và bộ nhớ dữ liệu (Data Memory).
2.3.1. Bộ nhớ chương trình
Bộ nhớ chƣơng trình của vi điều khiển PIC16F877A là bộ nhớ flash, dung lƣợng
bộ nhớ 8K word (1 word = 14 bit) và đƣợc phân thành nhiều trang (từ page 0 đến page 3)
Nhƣ vậy bộ nhớ chƣơng trình có khả năng chứa đƣợc 8*1024 = 8192 lệnh (vì một
lệnh sau khi mã hóa sẽ có dung lƣợng 1 word (14bit).
Để mã hóa đƣợc địa chỉ của 8K word bộ nhớ chƣơng trình, bộ đếm chƣơng trình
có dung lƣợng 13 bit (PC<12:0>).
Khi vi điều khiển đƣợc reset, bộ đếm chƣơng trình sẽ chỉ đến địa chỉ 0000h (Reset
vector). Khi có ngắt xảy ra, bộ đếm chƣơng trình sẽ chỉ đến địa chỉ 0004h (Interrupt
vector).
Bộ nhớ chƣơng trình không bao gồm bộ nhớ stack và không đƣợc địa chỉ hóa bởi
bộ đếm chƣơng trình. Bộ nhớ stack sẽ đƣợc đề cập cụ thể trong phần sau.

ĐƢỜNG KHÁNH SƠN Trang 20


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Hình 2.4: Bộ nhớ chương trình PIC16F877A

2.3.2. Bộ nhớ dữ liệu


Bộ nhớ dữ liệu của PIC là bộ nhớ EEPROM đƣợc chia ra làm nhiều bank. Đối với
PIC16F877A bộ nhớ dữ liệu đƣợc chia ra làm 4 bank. Mỗi bank có dung lƣợng 128 byte,
bao gồm các thanh ghi có chức năng đặc biệt SFR nằm ở các vùng địa chỉ thấp và các
thanh ghi mục đích chung GPR (General Purpose Register) nằm ở vùng địa chỉ còn lại
trong bank. Các thanh ghi SFR thƣờng xuyên đƣợc sử dụng (ví dụ nhƣ thanh ghi
STATUS) sẽ đƣợc đặt ở tất cả các bank của bộ nhớ dữ liệu giúp thuận tiện trong quá
trình truy xuất và làm giảm bớt lệnh của chƣơng trình.
Sơ đồ cụ thể của bộ nhớ dữ liệu PIC16F877A nhƣ sau:

ĐƢỜNG KHÁNH SƠN Trang 21


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Hình 2.5: Bộ nhớ dữ liệu PIC16F877A

2.3.2.1. Thanh ghi chức năng đặc biệt SFR


Đây là các thanh ghi đƣợc sử dụng bởi CPU hoặc đƣợc dùng để thiết lập và điều
khiển các khối chức năng đƣợc tích hợp bên trong vi điều khiển. Có thể phân thanh ghi
SFR làm hai loại: thanh ghi SFR liên quan đến các chức năng bên trong (CPU) và thanh
ghi SFR dùng để thiết lập và điều khiển các khối chức năng bên ngoài (ví dụ nhƣ ADC,
PWM, …). Phần này sẽ đề cập đến các thanh ghi liên quan đến các chức năng bên trong.
Các thanh ghi dùng để thiết lập và điều khiển các khối chức năng sẽ đƣợc nhắc đến khi ta
đề cập đến các khối chức năng đó.

ĐƢỜNG KHÁNH SƠN Trang 22


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Thanh ghi STATUS(03h, 83h, 103h, 183h): thanh ghi chứa kết quả thực hiện phép
toán của khối ALU, trạng thái reset và các bit chọn bank cần truy xuất trong bộ nhớ dữ
liệu.

Thanh ghi OPTION_REG(81h, 181h): thanh ghi này cho phép đọc và ghi, cho
phép điều khiển chức năng pull-up của các chân trong PORTB, xác lập các tham số về
xung tác động, cạnh tác động của ngắt ngoại vi và bộ đếm Timer 0.

Thanh ghi INTCON(0Bh, 8Bh,10Bh, 18Bh): thanh ghi cho phép đọc và ghi, chứa
các bit điều khiển và các bit cờ hiệu khi timer 0 bị tràn, ngắt ngoại vi RB0/INT và ngắt
interrput- on-change tại các chân của PORTB.

Thanh ghi PIE1(8Ch): chứa các bit điều khiển chi tiết các ngắt của các khối chức
năng ngoại vi.

Thanh ghi PIR1(0Ch) chứa cờ ngắt của các khối chức năng ngoại vi, các ngắt này
đƣợc cho phép bởi các bit điều khiển chứa trong thanh ghi PIE1.

Thanh ghi PIE2(8Dh): chứa các bit điều khiển các ngắt của các khối chức năng
CCP2, SSP bus, ngắt của bộ so sánh và ngắt ghi vào bộ nhớ EEPROM.

Thanh ghi PIR2(0Dh): chứa các cờ ngắt của các khối chức năng ngoại vi, các ngắt
này đƣợc cho phép bởi các bit điều khiển chứa trong thanh ghi PIE2.
ĐƢỜNG KHÁNH SƠN Trang 23
GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Thanh ghi PCON(8Eh): chứa các cờ hiệu cho biết trạng thái các chế độ reset của
vi điều khiển.

2.3.2.2. Thanh ghi mục đích chung GPR


Các thanh ghi này có thể đƣợc truy xuất trực tiếp hoặc gián tiếp thông qua thanh
ghi FSR (File Select Register). Đây là các thanh ghi dữ liệu thông thƣờng, ngƣời sử dụng
có thể tùy theo mục đích chƣơng trình mà có thể dùng các thanh ghi này để chứa các biến
số, hằng số, kết quả hoặc các tham số phục vụ cho chƣơng trình.
2.3.3. Stack
Stack không nằm trong bộ nhớ chƣơng trình hay bộ nhớ dữ liệu mà là một vùng
nhớ đặc biệt không cho phép đọc hay ghi. Khi lệnh CALL đƣợc thực hiện hay khi một
ngắt xảy ra làm chƣơng trình bị rẽ nhánh, giá trị của bộ đếm chƣơng trình PC tự động
đƣợc vi điều khiển cất vào trong stack. Khi một trong các lệnh RETURN, RETLW hay
RETFIE đƣợc thực thi, giá trị PC sẽ tự động đƣợc lấy ra từ trong stack, vi điều khiển sẽ
thực hiện tiếp chƣơng trình theo đúng qui trình định trƣớc.
Bộ nhớ Stack trong vi điều khiển PIC họ 16F87xA có khả năng chứa đƣợc 8 địa
chỉ và hoạt động theo cơ chế xoay vòng. Nghĩa là giá trị cất vào bộ nhớ Stack lần thứ 9 sẽ
ghi đè lên giá trị cất vào Stack lần đầu tiên và giá trị cất vào bộ nhớ Stack lần thứ 10 sẽ
ghi đè lên giá trị 6 cất vào Stack lần thứ 2.
Cần chú ý là không có cờ hiệu nào cho biết trạng thái stack, do đó ta không biết
đƣợc khi nào stack tràn. Bên cạnh đó tập lệnh của vi điều khiển dòng PIC cũng không có
lệnh POP hay PUSH, các thao tác với bộ nhớ stack sẽ hoàn toàn đƣợc điều khiển bởi
CPU.
2.4. Các cổng xuất nhập của PIC 16F877A
Cổng xuất nhập (I/O port) chính là phƣơng tiện mà vi điều khiển dùng để tƣơng
tác với thế giới bên ngoài. Sự tƣơng tác này rất đa dạng và thông qua quá trình tƣơng tác
đó, chức năng của vi điều khiển đƣợc thể hiện một cách rõ ràng.

ĐƢỜNG KHÁNH SƠN Trang 24


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Một cổng xuất nhập của vi điều khiển bao gồm nhiều chân (I/O pin), tùy theo cách
bố trí và chức năng của vi điều khiển mà số lƣợng cổng xuất nhập và số lƣợng chân trong
mỗi cổng có thể khác nhau. Bên cạnh đó, do vi điều khiển đƣợc tích hợp sẵn bên trong
các đặc tính giao tiếp ngoại vi nên bên cạnh chức năng là cổng xuất nhập thông thƣờng,
một số chân xuất nhập còn có thêm các chức năng khác để thể hiện sự tác động của các
đặc tính ngoại vi nêu trên đối với thế giới bên ngoài. Chức năng của từng chân xuất nhập
trong mỗi cổng hoàn toàn có thể đƣợc xác lập và điều khiển đƣợc thông qua các thanh
ghi SFR liên quan đến chân xuất nhập đó.
Vi điều khiển PIC16F877A có 5 cổng xuất nhập, bao gồm PORTA, PORTB,
PORTC, PORTD và PORTE. Cấu trúc và chức năng của từng cổng xuất nhập sẽ đƣợc đề
cập cụ thể trong phần sau.
2.4.1. PORT A
PORTA (RPA) bao gồm 6 I/O pin. Đây là các chân “hai chiều” (bidirectional pin),
nghĩa là có thể xuất và nhập đƣợc. Chức năng I/O này đƣợc điều khiển bởi thanh ghi
TRISA (địa chỉ 85h). Muốn xác lập chức năng của một chân trong PORTA là input, ta
“set” bit điều khiển tƣơng ứng với chân đó trong thanh ghi TRISA và ngƣợc lại, muốn
xác lập chức năng của một chân trong PORTA là output, ta “clear” bit điều khiển tƣơng
ứng với chân đó trong thanh ghi TRISA. Thao tác này hoàn toàn tƣơng tự đối với các
PORT và các thanh ghi điều khiển tƣơng ứng TRIS (đối với PORTA là TRISA, đối với
PORTB là TRISB, đối với PORTC là TRISC, đối với PORTD là TRISD và đối với
PORTE là TRISE).
Bên cạnh đó PORTA còn là ngõ ra của bộ ADC, bộ so sánh, ngõ vào analog, ngõ
vào xung clock của Timer 0 và ngõ vào của bộ giao tiếp MSSP (Master Synchronous
Serial Port). Đặc tính này sẽ đƣợc trình bày cụ thể trong phần sau.
Các thanh ghi SFR liên quan đến PORTA bao gồm:
- PORTA (địa chỉ 05h) : chứa giá trị các pin trong PORTA.
- TRISA (địa chỉ 85h) : điều khiển xuất nhập.
- CMCON (địa chỉ 9Ch) : thanh ghi điều khiển bộ so sánh.
- CVRCON (địa chỉ 9Dh) : thanh ghi điều khiển bộ so sánh điện áp.
- ADCON1 (địa chỉ 9Fh) : thanh ghi điều khiển bộ ADC.

ĐƢỜNG KHÁNH SƠN Trang 25


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

2.4.2. PORT B
PORTB (RPB) gồm 8 pin I/O. Thanh ghi điều khiển xuất nhập tƣơng ứng là
TRISB. Bên cạnh đó một số chân của PORTB còn đƣợc sử dụng trong quá trình nạp
chƣơng trình cho vi điều khiển với các chế độ nạp khác nhau. PORTB còn liên quan đến
ngắt ngoại vi và bộ Timer 0. PORTB còn đƣợc tích hợp chức năng điện trở kéo lên đƣợc
điều khiển bởi chƣơng trình.
Các thanh ghi SFR liên quan đến PORTB bao gồm:
- PORTB (địa chỉ 06h,106h) : chứa giá trị các pin trong PORTB
- TRISB (địa chỉ 86h,186h) : điều khiển xuất nhập
- OPTION_REG (địa chỉ 81h,181h) : điều khiển ngắt ngoại vi và bộ Timer 0.
2.4.3. PORT C
PORTC (RPC) gồm 8 pin I/O. Thanh ghi điều khiển xuất nhập tƣơng ứng là
TRISC. Bên cạnh đó PORTC còn chứa các chân chức năng của bộ so sánh, bộ Timer 1,
bộ PWM và các chuẩn giao tiếp nối tiếp I2C, SPI, SSP, USART.
Các thanh ghi điều khiển liên quan đến PORTC:
- PORTC (địa chỉ 07h) : chứa giá trị các pin trong PORTC.
- TRISC (địa chỉ 87h) : điều khiển xuất nhập.
2.4.4. PORT D
PORTD (RPD) gồm 8 chân I/O, thanh ghi điều khiển xuất nhập tƣơng ứng là
TRISD. PORTD còn là cổng xuất dữ liệu của chuẩn giao tiếp PSP (Parallel Slave Port).
Các thanh ghi liên quan đến PORTD bao gồm:
- Thanh ghi PORTD : chứa giá trị các pin trong PORTD.
- Thanh ghi TRISD : điều khiển xuất nhập.
2.4.5. PORT E
PORTE (RPE) gồm 3 chân I/O. Thanh ghi điều khiển xuất nhập tƣơng ứng là
TRISE. Các chân của PORTE có ngõ vào analog. Bên cạnh đó PORTE còn là các chân
điều khiển của chuẩn giao tiếp PSP.
Các thanh ghi liên quan đến PORTE bao gồm:
- PORTE : chứa giá trị các chân trong PORTE.
- TRISE : điều khiển xuất nhập và xác lập các thông số cho chuẩn giao tiếp PSP.
- ADCON1 : thanh ghi điều khiển khối ADC.

ĐƢỜNG KHÁNH SƠN Trang 26


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

2.5. Hoạt động Reset


Có nhiều chế độ reset vi điều khiển, bao gồm:
Power-on Reset - POR (Reset khi cấp nguồn hoạt động cho vi điều khiển).
MCLR reset trong quá trình hoạt động.

MCLR từ chế độ sleep.


WDT reset (reset do khối WDT tạo ra trong quá trình hoạt động).
WDT wake up từ chế độ sleep.
Brown-out reset (BOR).
Ngoại trừ reset POR trạng thái các thanh ghi là không xác định và WDT wake up
không ảnh hƣởng đến trạng thái các thanh ghi, các chế độ reset còn lại đều đƣa giá trị các
thanh ghi về giá trị ban đầu đƣợc ấn định sẵn. Các bit TO và PD chỉ thị trạng thái hoạt
động, trạng thái reset của vi điều khiển và đƣợc điều khiển bởi CPU.
MCLR reset: Khi pin MCLR ở mức logic thấp, vi điều khiển sẽ đƣợc reset. Tín
hiệu reset đƣợc cung cấp bởi một mạch ngoại vi với các yêu cầu cụ thể sau:
Không nối pin MCLR trực tiếp lên nguồn VDD. R1 phải nhỏ hơn 40 K để đảm bảo
các đặc tính điện của vi điều khiển. R2 phải lớn hơn 1 K để hạn dòng đi vào vi điều
khiển.

Hình 2.6: Mạch reset qua pin MCLR

MCLR reset còn đƣợc chống nhiễu bởi một bộ lọc để tránh các tín hiệu nhỏ tác

động lên pin MCLR .


Power-on reset (POR): Đây là xung reset do vi điều khiển tạo ra khi phát hiện
nguồn cung cấp VDD. Khi hoạt động ở chế độ bình thƣờng, vi điều khiển cần đƣợc đảm

ĐƢỜNG KHÁNH SƠN Trang 27


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

bảo các thông số về dòng điện, điện áp để hoạt động bình thƣờng. Nhƣng nếu các tham
số này không đƣợc đảm bảo, xung reset do POR tạo ra sẽ đƣa vi điều khiển về trạng thái
reset và chỉ tiếp tục hoạt động khi nào các tham số trên đƣợc đảm bảo.
Power-up Timer (PWRT): đây là bộ định thời hoạt động dựa vào mạch RC bên
trong vi điều khiển. Khi PWRT đƣợc kích hoạt, vi điều khiển sẽ đƣợc đƣa về trạng thái
reset.
PWRT sẽ tạo ra một khoảng thời gian delay (khoảng 72 ms) để V DD tăng đến giá
trị thích hợp.
Oscillator Start-up Timer (OST): OST cung cấp một khoảng thời gian delay bằng
1024 chu kì xung của oscillator sau khi PWRT ngƣng tác động (vi điều khiển đã đủ điều
kiện hoạt động) để đảm bảo sự ổn định của xung do oscillator phát ra. Tác động của OST
còn xảy ra đối với POR reset và khi vi điều khiển đƣợc đánh thức từ chế độ sleep. OST
chỉ tác động đối với các lọai oscillator là XT, HS và LP.
Brown-out reset (BOR): Nếu VDD hạ xuống thấp hơn giá trị V BOR (khoảng 4V) và
kéo dài trong khoảng thời gian lớn hơn T BOR (khoảng 100 us), BOR đƣợc kích hoạt và vi
điều khiển đƣợc đƣa về trạng thái BOR reset. Nếu điện áp cung cấp cho vi điều khiển hạ
xuống thấp hơn VBOR trong khoảng thời gian ngắn hơn T BOR, vi điều khiển sẽ không đƣợc
reset. Khi điện áp cung cấp đủ cho vi điều khiển hoạt động, PWRT đƣợc kích hoạt để tạo
ra một khoảng thời gian delay (khoảng 72ms). Nếu trong khoảng thời gian này điện áp
cung cấp cho vi điều khiển lại tiếp tục hạ xuống dƣới mức điện áp VBOR, BOR reset sẽ lại
đƣợc kích hoạt khi vi điều khiển đủ điện áp hoạt động. Một điểm cần chú ý là khi BOR
reset đƣợc cho phép, PWRT cũng sẽ hoạt động bất chấp trạng thái của bit PWRT.
Tóm lại để vi điều khiển hoạt động đƣợc từ khi cấp nguồn cần trải qua các bƣớc
sau:
POR tác động.
PWRT (nếu đƣợc cho phép hoạt động) tạo ra khoảng thời gian delay TPWRT để
ổn định nguồn cung cấp.
OST (nếu đƣợc cho phép) tạo ra khoảng thời gian delay bằng 1024 chu kì xung
của oscillator để ổn định tần số của oscillator.
Đến thời điểm này vi điều khiển mới bắt đầu hoạt động bình thƣờng. Thanh ghi
điều khiển và chỉ thị trạng thái nguồn cung cấp cho vi điều khiển là thanh ghi PCON.

ĐƢỜNG KHÁNH SƠN Trang 28


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Hình 2.7: Sơ đồ các chế độ reset của PIC 16F877A

2.6. Chế độ tiết kiệm năng lượng


Đây là chế độ hoạt động của vi điều khiển khi lệnh SLEEP đƣợc thực thi. Khi đó
nếu đƣợc cho phép hoạt động, bộ đếm của WDT sẽ bị xóa nhƣng WDT vẫn tiếp tục hoạt
động, bit PD (STATUS<3>) đƣợc reset về 0, bit TO đƣợc set, oscillator ngƣng tác
động và các PORT giữ nguyên trạng thái nhƣ trƣớc khi lệnh SLEEP đƣợc thực thi.
Do khi ở chế độ SLEEP, dòng cung cấp cho vi điều khiển là rất nhỏ nên ta cần
thực hiện các bƣớc sau trƣớc khi vi điều khiển thực thi lệnh SLEEP:
- Đƣa tất cả các pin về trạng thái V DD hoặc V SS
- Cần bảo đảm rằng không có mạch ngoại vi nào đƣợc điều khiển bởi dòng điện
của vi điều khiển vì dòng điện nhỏ không đủ khả năng cung cấp cho các mạch ngoại vi
hoạt động.
- Tạm ngƣng hoạt động của khối A/D và không cho phép các xung clock từ bên
ngoài tác động vào vi điều khiển.
- Để ý đến chức năng kéo lên điện trở ở PORTB.
- Pin MCLR phải ở mức logic cao.
 “ĐÁNH THỨC” VI ĐIỀU KHIỂN
Vi điều khiển có thể đƣợc “đánh thức” dƣới tác động của một trong số các hiện

ĐƢỜNG KHÁNH SƠN Trang 29


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

tƣợng sau:
- Tác động của reset ngoại vi thông qua pin
- Tác động của WDT khi bị tràn.
- Tác động từ các ngắt ngoại vi từ PORTB (PORTB Interrupt on change hoặc pin
INT).
Các bit PD và TO đƣợc dùng để thể hiện trạng thái của vi điều khiển và để phát
hiện nguồn tác động làm reset vi điều khiển. Bit đƣợc set khi vi điều khiển đƣợc cấp
nguồn và đƣợc reset về 0 khi vi điều khiển ở chế độ sleep. Bit đƣợc reset về 0 khi WDT
tác động do bộ đếm bị tràn.
Ngoài ra còn có một số nguồn tác động khác từ các chức năng ngoại vi bao gồm:
1) Đọc hay ghi dữ liệu thông qua PSP (Parallel Slave Port).
2) Ngắt Timer 1 khi hoạt động ở chế độ đếm bất đồng bộ.
3) Ngắt CCP khi hoạt động ở chế độ Capture.
4) Các hiện tƣợng đặc biệt làm reset Timer 1 khi hoạt động ở chế độ đếm bất đồng
5) bộ dùng nguồn xung clock ở bên ngoài).
6) Ngắt SSP khi bit Start/Stop đƣợc phát hiện.
7) SSP hoạt động ở chế độ Slave mode khi truyền hoặc nhận dữ liệu.
8) Tác động của USART từ các pin RX hay TX khi hoạt động ở chế độ Slavemode
đồng bộ.
9) Khối chuyển đổi A/D khi nguồn xung clock hoạt động ở dạng RC.
10) Hoàn tất quá trình ghi vào EEPROM.
11) Ngõ ra bộ so sánh thay đổi trạng thái.
Các tác động ngoại vi khác không có tác dụng đánh thức vi điều khiển vì khi ở chế
độ sleep các xung clock cung cấp cho vi điều khiển ngƣng hoạt động. Bên cạnh đó cần
cho phép các ngắt hoạt động trƣớc khi lệnh SLEEP đƣợc thực thi để bảo đảm tác động
của các ngắt.
Việc đánh thức vi điều khiển từ các ngắt vẫn đƣợc thực thi bất chấp trạng thái của
bit GIE. Nếu bit GIE mang giá trị 0, vi điều khiển sẽ thực thi lệnh tiếp theo sau lệnh
SLEEP của chƣơng trình (vì chƣơng trình ngắt không đƣợc cho phép thực thi). Nếu bit
GIE đƣợc set trƣớc khi lệnh SLEEP đƣợc thực thi, vi điều khiển sẽ thực thi lệnh tiếp theo
của chƣơng trình và sau đó nhảy tới địa chỉ chứa chƣơng trình ngắt (0004h).

ĐƢỜNG KHÁNH SƠN Trang 30


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Trong trƣờng hợp lệnh tiếp theo không đóng vai trò quan trọng trong chƣơng
trình, ta cần đặt thêm lệnh NOP sau lệnh SLEEP để bỏ qua tác động của lệnh này, đồng
thời giúp ta dễ dàng hơn trong việc kiểm soát hoạt động của chƣơng trình ngắt. Tuy nhiên
cũng có một số điểm cần lƣu ý nhƣ sau:
- Nếu ngắt xảy ra trƣớc khi lệnh SLEEP đƣợc thực thi, lệnh SLEEP sẽ không đƣợc
thực thi và thay vào đó là lệnh NOP, đồng thời các tác động của lệnh SLEEP cũng sẽ
đƣợc bỏ qua.
- Nếu ngắt xảy ra trong khi hay sau khi lệnh SLEEP đƣợc thực thi, vi điều khiển
lập tức đƣợc đánh thức từ chế độ sleep, và lệnh SLEEP sẽ đƣợc thực thi ngay sau khi vi
điều khiển đƣợc đánh thức.
Để kiểm tra xem lệnh SLEEP đã đƣợc thực thi hay chƣa, ta kiểm tra bit PD .
Nếu bit PD vẫn mang giá trị 1 tức là lệnh SLEEP đã không đƣợc thực thi và thay vào đó
là lệnh NOP.
Bên cạnh đó ta cần xóa WDT để chắc chắn rằng WDT đã đƣợc xóa trƣớc khi thực
thi lệnh SLEEP, qua đó cho phép ta xác định đƣợc thời điểm vi điều khiển đƣợc đánh
thức do tác động của WDT.
 BỘ DAO ĐỘNG (OSCILLATOR)
PIC16F877A có khả năng sử dụng một trong 4 loại oscillator, đó là:
- LP: (Low Power Crystal).
- XT: Thạch anh bình thƣờng.
- HS: (High-Speed Crystal).
- RC: (Resistor/Capacitor) dao động do mạch RC tạo ra.
Đối với các loại oscillator LP, HS, XT, oscillator đƣợc gắn vào vi điều khiển
thông qua các pin OSC1/CLKI và OSC2/CLKO.
Đối với các ứng dụng không cần các loại oscillator tốc độ cao, ta có thể sử dụng
mạch dao động RC làm nguồn cung cấp xung hoạt động cho vi vi điều khiển. Tần số tạo
ra phụ thuộc vào các giá trị điện áp, giá trị điện trở và tụ điện, bên cạnh đó là sự ảnh
hƣởng của các yếu tố nhƣ nhiệt độ, chất lƣợng của các linh kiện qua các pin OSC1/CLKI
vào OSC2/CLKO.
Các linh kiện sử dụng cho mạch RC oscillator phải bảo đảm các giá trị sau:
3 K < REXT< 100 K CEXT >20 pF

ĐƢỜNG KHÁNH SƠN Trang 31


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Hình 2.8: RC oscillator

ĐƢỜNG KHÁNH SƠN Trang 32


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Chương 3: LẬP TRÌNH CHO VI ĐIỀU KHIỂN

3.1.Giới thiệu các phần mềm lập trình và mô phỏng


Vi điều khiển là một IC lập trình, vì vậy vi điều khiển cần đƣợc lập trình trƣớc
khi sử dụng. Mỗi phần cứng nhất định phải có chƣơng trình phù hợp kèm theo, do đó
trƣớc khi viết chƣơng trình đòi hỏi ngƣời viết phải nắm bắt đƣợc cấu tạo phần cứng và
các yêu cầu mà mạch điện cần thực hiện.
Chƣơng trình là tập hợp các lệnh đƣợc tổ chức theo một trình tự hợp lí để giải
quyết các yêu cầu của ngƣời lập trình. Tập hợp tất cả các lệnh gọi là tập lệnh.
Lệnh của vi điều khiển là các số nhị phân 8 bit hay còn gọi là mã máy. Các lệnh
mang mã 00000000b đến 11111111b. Các mã lệnh này đƣợc đƣa vào lƣu trữ trong ROM,
khi thực hiện chƣơng trình Vi điều khiển đọc các mã lệnh này, giải mã, và thực hiện lệnh.
Vì các lệnh của vi điều khiển có dạng số nhị phân quá dài và khó nhớ, hơn nữa
việc gỡ lỗi khi chƣơng trình phát sinh lỗi rất phức tạp và khó khăn. Khó khăn này đƣợc
giải quyết với sự hỗ trợ của máy vi tính, ngƣời viết chƣơng trình có thể viết chƣơng trình
cho vi điều khiển bằng các ngôn ngữ lập trình cấp cao, sau khi việc viết chƣơng trình
đƣợc hoàn tất, các trình biên dịch sẽ chuyển các câu lệnh cấp cao thành mã máy một cách
tự động. Các mã máy này sau đó đƣợc đƣa vào bộ nhớ ROM của vi điều khiển, vi điều
khiển sẽ tìm đến đọc các lệnh từ ROM để thực hiện chƣơng trình . Bản thân máy tính
không thể thực hiện các mã máy này vì chúng không phù hợp với phần cứng máy tính,
muốn thực hiện phải có các chƣơng trình mô phỏng dành riêng.
Chƣơng trình cho vi điều khiển có thể viết bằng Assembly, C++,C,Visual Basic,
hoặc bằng các ngôn ngữ cấp cao khác.
Assembly là một ngôn ngữ cấp thấp, trong đó mỗi câu lệnh chƣơng trình tƣơng
ứng với một chỉ lệnh mà bộ xử lý có thể thực hiện đƣợc. Ƣu điểm của hợp ngữ
Assembly là: mã gọn, ít chiếm dung lƣợng bộ nhớ, hoạt động với tốc độ nhanh, và nó có
hiệu suất tốt hơn so với các chƣơng trình viết bằng ngôn ngữ bậc cao khác. Assembly là
một ngôn ngữ lập trình cấp thấp gần với ngôn ngữ máy, chƣơng trình sau khi viết bằng
assembly cần đƣợc chuyển đổi qua mã lệnh (hay còn gọi là mã máy) của vi điều khiển,
quá trình chuyển đổi đƣợc thực hiện bằng chƣơng trình dịch Assembler. Các mã lệnh sau
đó đƣợc nạp vào Rom của vi điều khiển để thực hiện chƣơng trình. Chƣơng trình dịch
Assembler đƣợc dùng phổ biến hiện nay là chƣơng trình Macro Assembler sử dụng trên
ĐƢỜNG KHÁNH SƠN Trang 33
GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Dos. Để soạn thảo chƣơng trình có thể sử dụng Notepad hoặc bất cứ chƣơng trình soạn
thảo có sử dụng bộ kí tự chuẩn ASCII và lƣu tên đuôi nhƣ sau: "tên.asm". Ngoài ra có thể
sử dụng các phần mềm hỗ trợ soạn thảo dành riêng cho vi điều khiển đã tích hợp sẵn
chƣơng trình dịch Assembler.
Đối với các họ vi điều khiển khác nhau cũng sẽ có các phần mềm hỗ trợ lập trình
và mô phỏng khác nhau, chẳng hạn để lập trình cho AVR có thể dùng các phần mềm hỗ
trợ ngôn ngữ cấp cao nhƣ BascomAVR (Basic) hay CodevisionAVR (C), AvrStudio,
WinAVR … lập trình cho họ vi điều khiển PIC bằng ngôn ngữ C có thể dùng CCS,
MPLAB, PIC C compiler … lập trình cho họ vi điều khiển 8051 có thể dùng Keil C…
Đa số các trình biên dịch đều tích hợp sẵn 1 chƣơng trình nạp chip hỗ trợ nhiều
loại mạch nạp. Trong trƣờng hợp khác, bạn có thể sử dụng các chƣơng trình nạp khác.
3.2.Trình biên dịch, ngôn ngữ lập trình cho vi điều khiển
Ngôn ngữ lập trình cho vi điều khiển PIC có 2 loại:
- Ngôn ngữ lập trình cấp thấp-Hợp ngữ: có phần mềm MPLAB
- Ngôn ngữ lập trình bậc cao: có nhiều loại, đƣợc phát triển theo ngôn ngữ C, nhƣ:
CCS, HTPIC, PIC BASIC v.v
Ƣu điểm của hợp ngữ là giúp ngƣời học và lập trình hiểu rõ hơn về cấu trúc bên
trong của vi điều khiển PIC, cũng nhƣ tối ƣu hóa bộ nhớ chƣơng trình. Tuy nhiên,
nhìn chung phƣơng pháp tiếp cận hợp ngữ là khó và khả năng phát triển ứng dụng là
hạn chế, mất thời gian. Vì vậy, giáo trình này sẽ tập trung vào sử dụng ngôn ngữ bậc cao
mà cụ thể là CCS để nghiên cứu và phát triển các ứng dụng trên PIC.
Ƣu điểm của CCS là:
- Kế thừa tất cả đặc điểm của ngôn ngữ C- là ngôn ngữ cơ bản, quen thuộc mà
sinh viên đã đƣợc đào tạo.
- Xây dựng sẵn các hàm phục vụ cho việc sử dụng dễ dàng các khối chức năng
đặc biệt của Vi điều khiển PIC nhƣ khối ADC, PWM, RS232, SPI.
- Có khả năng kết hợp với ngôn ngữ hợp ngữ, tạo sự mềm dẻo trong phát triển
ứng dụng.
- Khả năng phát triển, nâng cấp ứng dụng là dễ dàng.
- Ngày càng đƣợc cập nhật với nhiều tính năng ƣu việt và hiệu quả hơn.

ĐƢỜNG KHÁNH SƠN Trang 34


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

 Ví dụ về một chương trình viết trên ngôn ngữ CCS:


// Đây là chú thích chƣơng trình
//Bắt đầu các chỉ thị tiền xử lý của chƣơng trình
#include<16f877a.h> // cho file định nghĩa thiết bị16f877a.h vào chƣơng trình
#fuses HS,NOLVP,NOWDT// Cấu hình cho vi điều khiển PIC
#use delay (clock=4000000) // dùng thạch anh tần số4MHz
// Khai báo biến hằng
byte const MAP[10]= {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
//===========================================
//===========================================
// Bắt đầu chƣơng trình con hiển thị
void display(int n)
{
char b; // khai báo biến b
b=((MAP[n/10]) ^0x00);
if ((n/10)==(0)) b=0xff;
output_b(b); // sửdụng hàm xuất giá trị ra cổng B
output_low(PIN_A4);// sử dụng hàm đƣa giá trị chân RA4 xuống mức thấp
delay_ms(2);// Sử dụng hàm tạo trễ 2 ms
output_high(PIN_A4); // sử dụng hàm đƣa giá trị chân RA4 lên mức cao
output_b((MAP[n%10]) ^ 0x00);
output_low(PIN_A5);
delay_ms(2);
output_high(PIN_A5);
}
// Kết thúc chƣơng trình con hiển thị
//============================================
// Bắt đầu chƣơng trình chính
// Đây là nơi vi điều khiển bắt đầu chạy lệnh
//============================================
void main()

ĐƢỜNG KHÁNH SƠN Trang 35


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

{
int i,count;
count=0;
while(TRUE)
{
for (i=0;i<=50;i++)
display(count); // dispay 50 times
count=(count==99) ? 1: count+1;
}
}

3.3.Cấu trúc một chương trình vi điều khiển và các bước lập trình
3.3.1.Khai báo tiền xử lý
Bắt đầu một chƣơng trình viết bằng ngôn ngữ CCS là phần khai báo tiền xử lý:
1. Đầu tiên là phần khai báo file header: #include <tên chip dùng.h>
Ví dụ: # include <16f877a.h>
Việc khai báo này thực chất là chép cả file 16f877a.h vào chƣơng trình này.
Vậy nội dung của file .h này là gì? Nội dung của file này sẽ định nghĩa tất cả các
tên cũng nhƣ định nghĩa các hằng sẽ đƣợc dùng trong các hàm chức năng của
CCS.
Ví dụ trong chƣơng trình cho ở trên, trong dòng lệnh :
output_low(PIN_A4);// sử dụng hàm đƣa giá trị chân RA4 xuống mức thấp thì
hằng PIN_A4 đƣợc định nghĩa trong file 16f877a.h là #define PIN_A4 44, CCS hiểu
đây là bit thứ 4 của thanh ghi có địa chỉ 04h (thanh ghi PORTA).
2. Thứ hai là phần khai báo cấu hình: #fuses HS,NOLVP,NOWDT
Vi điều khiển PIC có thể hoạt động ở nhiều chế độ khác nhau, cũng nhƣ cách cấu
hình phần cứng của nó cũng có nhiều chế độ. Mỗi chế độ nhƣ vậy đƣợc khai báo và dùng
sẽ ảnh hƣởng đến hoạt động của các khối chức năng, cũng nhƣ các chân của vi điều
khiển. Vì vậy, đối với mỗi ứng dụng, ta phải khai báo cấu hình cho phù hợp.
Trong ví dụ trên, khai báo cấu hình cho bộ dao động kiểu HS, không sử
dụng chức năng Watchdog Timer, và lập trình điện áp thấp.

ĐƢỜNG KHÁNH SƠN Trang 36


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

3. Thứ ba là phần khai báo tần số của thạch anh dùng cho ứng dụng, tốc độ này
phải phù hợp với thạch anh ta dùng trong mạch.
# USE Delay(clock=tần sốthạch anh)
Ví dụ: # USE Delay(clock=4000000)//Khai báo dùng thạch anh 4 MHz
Điều lƣu ý là chúng ta chỉ dùng đƣợc hàm tạo thời gian trễ delay_ms(),
delay_us() sau khi có khai báo này trong chƣơng trình.
4. Ngoài ra, khi sử dụng bất cứ khối chức năng đặc biệt nào trong vi điều khiển
PIC ta phải dùng chỉ thị tiền xử lý #USE để khai báo. Các khối chức năng đặc biệt là
RS232, PWM, SPI, I2C ..v.v
Ví dụ: #use rs232(baud=9600, xmit=PIN_C6,rcv=PIN_C7)

3.3.2.Phần khai báo biến toàn cục


Sau phần khai báo tiền xử lý là phần khai báo biến toàn cục nếu có.
Cũng nhắc lại biến toàn cục là biến đƣợc sử dụng trong toàn bộ chƣơng trình, cả
chƣơng trình chính và chƣơng trình con. Điều này khác với biến cục bộ là biến
đƣợc khai báo trong các chƣơng trình con, hàm con, chƣơng trình chính, các biến này
chỉ đƣợc tạo ra và sử dụng trong chính mỗi chƣơng trình khai báo nó.
Nhân đây cũng giới thiệu qua dạng dữ liệu dùng trong CCS. Có một số các dạng
cơ bản nhƣ sau:
Khai báo biến:
Int1,short: dạng logic 1,0
Int,Int8,byte: dạng số nguyên 8 bit, nếu khai báo dạng số nguyên 8 bit có dấu thêm
signed
Int16,long: dạng sốnguyên 16 bit
Int32: dạng sốnguyên 32 bit
Char: dạng kí tự8 bit
Float: dạng sốthực 32 bit
Ví dụ:int8 a; // Khai báo a là biến số nguyên 8 bit
Khai báo hằng số:
Ví dụ: int8 consta=231;
Khai báo mảng hằng số:

ĐƢỜNG KHÁNH SƠN Trang 37


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Ví dụ: int const a[5]= {1, 2, 3, 4, 5}


3.3.3.Phần khai báo, định nghĩa các chương trình con
Chƣơng trình con là chƣơng trình sẽ đƣợc gọi từ chƣơng trình chính hoặc
chƣơng trình con khác.
Chƣơng trình con phải đƣợc khai báo và định nghĩa trong một file
chƣơng trình ứng dụng.
Phần khai báo phải đặt trƣớc chƣơng trình chính (trong file).
Phần định nghĩa có thể định nghĩa ngay trong khai báo hoặc đƣợc đặt bất kì nơi
nào sau phần khai báo biến toàn cục nếu có.
Ngoài các chƣơng trình con bình thƣờng ra, còn có chƣơng trình con phục vụ
ngắt đƣợc đặt sau khai báo tiền xử lý: # int_tên ngắt.
3.3.4.Phần chương trình chính:
Bắt đầu bằng:
void main() {
}

Cũng nhắc lại là trong một chƣơng trình CCS , vi điều khiển sẽ chạy từ
chƣơng trình chính, hay nói cách khác là từ dòng lệnh đầu tiên sau void main().
Các chƣơng trình con chỉ đƣợc gọi tại các lời gọi chƣơng trình con trong chƣơng
trình chính hoặc từ các chƣơng trình con khác. Chƣơng trình con phục vụ ngắt chỉ đƣợc
chạy khi có ngắt xảy ra, và ngắt đó đƣợc cho phép (sẽ bàn kĩ hơn trong các bài học sau).
3.3.5.Các cấu trúc thuật toán của ngôn ngữ CCS

Cấu trúc thuật toán của ngôn ngữ CCS kế thừa 100% từ ngôn ngữ C. Ở đây xin
nhắc lại một số các cấu trúc hay dùng:
- Cấu trúc IF:
o If (biểu thức)
Lệnh1;
Else lệnh2;
Ví dụ: if (x==25)
x=1;
else

ĐƢỜNG KHÁNH SƠN Trang 38


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

x=x+1;
- Cấu trúc lặp While:
o While (biểu thức)
{
Các lệnh;
}
Ví dụ: While (count<20)
{
Output_B(count);
Count=count+1;
}
Chú ý: while(1) sẽ thực hiện các lệnh trong khối while này mãi mãi
- Cấu trúc lặp FOR:
o For (biểu thức 1, biểu thức 2, biểu thức 3)
{
Các lệnh;
}
Ví dụ: for (i=1;i<=10;++i)
A=a+i;
- Cấu trúc lựa chọn SWITCH:
o SWITCH (biến)
{
Case giá trị 1: lệnh 1;
Break;
Case giá trị 2: lệnh 2;
Break;
………
Case giá trị n: lệnh n
Break;
[default: lệnh n+1; break;]
}

ĐƢỜNG KHÁNH SƠN Trang 39


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Ví dụ: switch (cmd)


{ case 0:printf("cmd 0");
break;
case 1:printf("cmd 1");
break;
default:printf("bad cmd");
break;
}
Chú ý: lệnh break đƣợc dùng để thoát lập tức khỏi một vòng lặp For, While,
Switch
3.3.6.Các toán tử cơ bản trong CCS
Hoàn toàn tƣơng tự trong C.
Nhắc lại một số toán tử hay dùng:
+= ý nghĩa là cộng thêm một giá trị và lấy kết quả
Ví dụ: a+= 2 nghĩa là a= a+2
Tƣơng tự đối với các phép toán trừ, chia, nhân
++ ý nghĩa là cộng thêm 1 đơn vị vào biến
Ví dụ: a++; tức là a=a+1
&&: phép AND
||: phép OR
!: phép NOT
!=: không bằng
>>n: dị ch trái n bit
<<n: dị ch phải n bit
3.3.7.Các hàm số học cơ bản trong CCS
Hoàn toàn giống trong C.
Nhắc lại một số hàm cơ bản:
Abs (): lấy trị tuyệt đối
Ceil(): làm tròn theo hƣớng tăng
Floor(): làm tròn theo hƣớng giảm
Pow(): lũy thừa

ĐƢỜNG KHÁNH SƠN Trang 40


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Sqrt(): lấy căn


Chi tiết tra help CCS : trong tab contents, chọn Built-In-Function
Chú ý là khi sử dụng các hàm này cần khai báo file header tƣơng ứng
3.3.8.Các hàm vào ra cơ bản trong CCS
- Output_low (chân): cho chân xuống mức logic thấp (mức điện áp 0V), chân
có thể là: PIN_A0, PIN_A1, ..PIN_B0, PIN_B1,.. PIN_C0,..v.v Nói chung là các chân
có tên trong file C:\Program Files\PICC\Devices\16f877a.h
Ví dụ: Output_low(PIN_D0) đƣa chân RD0 của PIC xuống mức thấp
- Output_high(chân): cho chân lên mức logic thấp (mức điện áp 0V), chân có
thể là: PIN_A0, PIN_A1, ..PIN_B0, PIN_B1,.. PIN_C0,..v.v Nói chung là các chân có
tên trong file C:\Program Files\PICC\Devices\16f877a.h
Ví dụ: Output_high(PIN_a5) đƣa chân Ra5 của PIC lên mức cao
- Output_bit(chân,giá trị): là lệnh tổng hợp 2 lệnh trên, xuất giá trị ra chân.
Giá trị có thể là 0 (m ức thâp) hoặc là 1 (mức cao). Tên chân tƣơng tự nhƣ 2 lệnh trên
Ví dụ: output_bit(PIN_E0,1); đƣa chân E0 lên mức 1
- Output_X(giá trị): l ệnh này đƣa giá trị ra cổng X. X có thể là A, B, C, D, E.
Ví dụ: Output_A(0x21); đƣa giá trị 0x21 ra cổng A
- Biến=Input_X(): đƣa giá trị của cổng X vào Biến. X là A, hoặc B, C, D, E
Ví dụ: bien1= Input_A()
- Biến=Input(chân): lệnh này đƣa giá trị của chân vào biến. Chân tƣơng tự
nhƣ trong các lệnh.
Ví dụ: bien2= Input(PIN_A2);
3.3.9.Các hàm tạo trễ
Các hàm tạo trễ gồm delay_cycles(), delay_us(), delay_ms. Tạo một khoảng thời
gian trễ từ lúc lệnh đƣợc thực hiện. Chú ý là phải sử dụng khai báo tiền xử lý
# use delay(clock=tần số) thì mới dùng đƣợc các lệnh này.
- delay_cycles(số chu kỳ): tạo trễ một khoảng thời gian bằng số chu kỳ. Số chu
kỳ=0-255
- delay_us(sốmicro giây): tạo trễ số micro giây. Số micro giây =0-65535
- delay_ms(số mili giây): tạo trễ số mili giây. Số mili giây= 0-65535

ĐƢỜNG KHÁNH SƠN Trang 41


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

3.4.Điều khiển xuất nhập dữ liệu (input, output, GPIO)


Trong vi điều khiển PIC16F877A có 5 cổng:

Mỗi cổng thực chất đƣợc quản lý bởi các thanh ghi PORTA, PORTB, PORTC,
PORTD, PORTE nằm trong bộ nhớ RAM của vi điều khiển. Xem hình sau:

ĐƢỜNG KHÁNH SƠN Trang 42


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Bộ nhớ RAM của vi điều khiển PIC 16F877A gồm 4 bank nhớ. Nhìn vào các bank
nhớ ta có thể thấy các thanh ghi đƣợc đặt tên và các thanh ghi đa mục đích (General
Purpose Register).

lý hoặc thể hiện trạng thái của các khối chức năng trong vi điều khiển ví dụ PORTA là
đại diện cho các chân cổng A, PORTB là đại diện cho các chân cổng B v.v. Các thanh ghi
này có địa chỉ xác định và không đƣợc dùng cho các mục đích khác.

ĐƢỜNG KHÁNH SƠN Trang 43


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

ứng dụng của vi điều khiển. Nhìn vào bản đồ bộ nhớ RAM, ta thấy biến có thể đặt từ địa
chỉ 20F đến 7Fh trong bank nhớ 0, A0h-EFh, 120h-16Fh, 1A0h-1EFh.
Trở lại vấn đề về các cổng, tới đây ta có thể đƣa ra nhận xét:
Thanh ghi PORTA phản ánh trạng thái của các chân cổng A,nghĩa là muốn tín hiệu đầu
ra của các chân cổng A nhƣ thế nào ta chỉ việc đƣa giá trị vào các bit tƣơng ứng trên
thanh ghi PORTA. Cũng nhƣ khi đọc giá trị của thanh ghi PORTA ta sẽ biết đƣợc trạng
thái của các chân cổng A.
Ví dụ:
Muốn RA0 ở mức logic 1 (mức 5V), RA1 ở mức logic 0 (mức 0V), RA2 ở mức
logic 1, RA3 ở mức logic 0, RA4 ở mức logic 1, RA5 ở mức logic 1, ta chỉ việc
gán giá trị 000110101 cho thanh ghi PORTA.

X: không quan tâm.


Tƣơng tự nhƣ vậy với PORTB, PORTC, PORTD, PORTE.
Tính đa chức năng của một chân trên vi điều khiển:
Nhìn vào sơ đồ chân của vi điều khiển, ta có thể thấy một số chân của vi điều
khiển có tên gồm nhiều phần với dấu gạch chéo. Ví dụ: RA0/AN0, RC7/RX/DT,
RC6/TX/CK Đây chính là tính đa chức năng của một chân trên vi điều khiển hay còn gọi
là sự dồn kênh.
Ý nghĩa của nó là:
Bình thƣờng nếu không đƣợc cài đặt thì tất cả các chân trên 5 cổng A, B, C, D, E
là các chân vào ra số I/O.
Nếu trong chƣơng trình ta có cài đặt một chức năng nào đó nhƣ RS232, ADC hoặc
PWM v.v thì các chân tƣơng ứng với chức năng đó sẽ hoạt động theo chức năng đó.
Khi đó chân này sẽ không đƣợc dùng làm chân vào ra số nhƣ bình thƣờng nữa.
Ví dụ:bình thƣờng chân RA0/ANO là chân vào ra số RA0, nếu chức năng ADC
với kênh vào tín hiệu analog là kênh 0 đƣợc cài đặt khi đó chân RA0 /AN0 sẽ là chân
vào của bộ ADC, tức là hoạt động theo chức năng AN0.

ĐƢỜNG KHÁNH SƠN Trang 44


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Tƣơng tự nhƣ vậy, khi cài đặt giao tiếp với thiết bị ngoại vi theo chuẩn RS232,
chân vào ra số RC7/RX/DT sẽ hoạt động nhƣ đầu vào dữ liệu RS232 tức là chức
năng RX của chân này.
Cài đặt vào/ra cho các chân vào ra số trên các cổng:
Các chân vào/ra số trên vi điều khiển PIC phải đƣợc cài đặt là chân vào hoặc chân
ra thì mới hoạt động đúng chức năng. Việc một chân trên cổng X (X=A,B,..E) đƣợc qui
định là đầu ra hay đầu vào phụ thuộc vào bit tƣơng ứng trên thanh ghi TRISX
(X=A,B,..E) là 0 hay 1.
Ví dụ: Muốn 4 chân thấp (bit thấp) trên cổng B (RB0-RB3) là chân vào, 4 chân
cao (bit cao) trên cổng B (RB4-RB7) là chân ra thì giá trị các bit trên thanh ghi TRISB sẽ
là:

Gợi ý dễ nhớ là:


Để chân RB.m (m=0-7) là đầu ra, tức Output thì giá trị TRISB.m là 0
Là đầu vào, tức Input thì giá trị TRISB.m là 1
Tƣơng tự nhƣ vậy đối với các chân trên các cổng còn lại.
Ví dụ : Chƣơng trình bật tắt 8 đèn led ở port b của vi điều khiển với thời gian 1s
viết bằng ccs c:
#include <16f877a.h>
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,
NOLVP
#use delay(clock=20000000)
#use fast_io (b)
void main() {
// Enter code here!
set_tris_b(0x00); // Tat ca PORTB deu la cong xuat du lieu
output_b(0x00);//tat het cac LED
While(1)
{
output_b(0xff); // Cho các LED sáng

ĐƢỜNG KHÁNH SƠN Trang 45


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

delay_ms(1000); // Tao thoi gian tre 1s


output_b(0x00);
delay_ms(1000);
}
}

Hình 3.1: Mô phỏng chương trình bật tắt 8 đèn led ở port B bằng proteus

3.5.Các bộ chuyển đổi tín hiệu ADC, COMPARATOR, CCP


ADC (Analog to Digital Converter) là bộ chuyển đổi tín hiệu giữa hai dạng tƣơng
tự và số.
PIC16F877A có 8 ngõ vào analog (RA4:RA0 và RE2:RE0). Hiệu điện thế chuẩn
VREF có thể đƣợc lựa chọn là V DD, V SS hay hiệu điện thể chuẩn đƣợc xác lập trên hai
chân RA2 và RA3.
Kết quả chuyển đổi từ tín tiệu tƣơng tự sang tín hiệu số là 10 bit số tƣơng ứng và
đƣợc lƣu trong hai thanh ghi ADRESH:ADRESL. Khi không sử dụng bộ chuyển đổi
ADC, các thanh ghi này có thể đƣợc sử dụng nhƣ các thanh ghi thông thƣờng khác. Khi
quá trình chuyển đổi hoàn tất, kết quả sẽ đƣợc lƣu vào hai thanh ghi
ADRESH:ADRESL, bit (ADCON0<2>) đƣợc xóa về 0 và cờ ngắt ADIF đƣợc set.
Qui trình chuyển đổi từ tƣơng tự sang số bao gồm các bƣớc sau:

ĐƢỜNG KHÁNH SƠN Trang 46


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

1. Thiết lập các thông số cho bộ chuyển đổi ADC: Chọn ngõ vào analog, chọn
điện áp mẫu (dựa trên các thông số của thanh ghi ADCON1)
Chọnh kênh chuyển đổi AD (thanh ghi ADCON0). Chọn xung clock cho kênh
chuyển đổi AD (thanh ghi ADCON0). Cho phép bộ chuyển đổi AD hoạt động (thanh ghi
ADCON0).
2. Thiết lập các cờ ngắt cho bộ AD Clear bit ADIF.
Set bit ADIE.
Set bit PEIE.
Set bit GIE.
3. Đợi cho tới khi quá trình lấy mẫu hoàn tất.
4. Bắt đầu quá trình chuyển đổi (set bit GO / DONE ).
5. Đợi cho tới khi quá trình chuyển đổi hoàn tất bằng cách:
Kiểm tra bit GO / DONE . Nếu GO / DONE = 0, quá trình chuyển đổi đã hoàn tất.
Kiểm tra cờ ngắt.
6. Đọc kết quả chuyển đổi và xóa cờ ngắt, set bit GO / DONE (nếu cần tiếp tục
chuyển đổi).

ĐƢỜNG KHÁNH SƠN Trang 47


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Hình 3.2: Sơ đồ khối bộ chuyển đổi ADC

7. Tiếp tục thực hiện các bƣớc 1 và 2 cho quá trình chuyển đổi tiếp theo.

Hình 3.3: Các cách lưu kết quả chuyển đổi AD

Cần chú ý là có hai cách lƣu kết quả chuyển đổi AD, việc lựa chọn cách lƣu đƣợc
điều khiển bởi bit ADFM và đƣợc minh họa cụ thể trong hình sau:
Các thanh ghi liên quan đến bộ chuyển đổi ADC bao gồm:
INTCON (địa chỉ 0Bh, 8Bh, 10Bh, 18Bh): cho phép các ngắt (các bit GIE, PEIE).
PIR1 (địa chỉ 0Ch): chứa cờ ngắt AD (bit ADIF). PIE1 (địa chỉ 8Ch): chứa bit điều
khiển AD (ADIE). ADRESH (địa chỉ 1Eh) và ADRESL (địa chỉ 9Eh): các thanh ghi
chứa kết quả chuyển đổi AD.
ADCON0 (địa chỉ 1Fh) và ADCON1 (địachỉ 9Fh): xác lập các thông số cho bộ
chuyển đổi AD.
PORTA (địa chỉ 05h) và TRISA (địa chỉ 85h): liên quan đến các ngõ vào analog ở
PORTA.
PORTE (địa chỉ 09h) và TRISE (địa chỉ 89h): liên quan đến các ngõ vào analog ở
PORTE.
 COMPARATOR
Bộ so sánh bao gồm hai bộ so so sánh tín hiệu analog và đƣợc đặt ở PORTA. Ngõ
vào bộ so sánh là các chân RA3:RA0, ngõ ra là hai chân RA4 và RA5. Thanh ghi điều
khiển bộ so sánh là CMCON. Các bit CM2:CM0 trong thanh ghi CMCON đóng vai trò
chọn lựa các chế độ hoạt động cho bộ Comparator (hình 3.3).
ĐƢỜNG KHÁNH SƠN Trang 48
GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Cơ chế hoạt động của bộ Comparator nhƣ sau:


Tín hiệu analog ở chân VIN + sẽ đƣợc só sánh với điện áp chuẩn ở chân VIN và
tín hiệu ở ngõ ra bộ so sánh sẽ thay đổi tƣơng ứng nhƣ hình vẽ. Khi điện áp ở chân VIN+
lớn hơn điện áp ở chân VIN+ ngõ ra sẽ ở mức 1 và ngƣợc lại.
Dựa vào hình vẽ ta thấy đáp ứng tại ngõ ra không phải là tức thời so với thay đổi
tại ngõ vào mà cần có một khoảng thời gian nhất định để ngõ ra thay đổi trạng thái (tối đa
là 10 us). Cần chú ý đến khoảng thời gian đáp ứng này khi sử dụng bộ so sánh.

Hình 3.4: Nguyên lý hoạt động của một bộ so sánh đơn giản

Cực tính của các bộ so sánh có thể thay đổi dựa vào các giá trị đặt vào các bit
C2INV và C1INV (CMCON<4:5>).

ĐƢỜNG KHÁNH SƠN Trang 49


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Hình 3.5: Các chế độ hoạt động của bộ comparator

Các bit C2OUT và C1OUT (CMCON<7:6>) đóng vai trò ghi nhận sự thay đổi tín
hiệu analog so với điện áp đặt trƣớc. Các bit này cần đƣợc xử lí thích hợp bằng chƣơng
trình để ghi nhận sự thay đổi của tín hiệu ngõ vào. Cờ ngắt của bộ so sánh là bit CMIF
(thanh ghi PIR1). Cờ ngắt này phải đƣợc reset về 0. Bit điều khiển bộ so sánh là bit
CMIE(Thanh ghi PIE).

ĐƢỜNG KHÁNH SƠN Trang 50


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Các thanh ghi liên quan đến bộ so sánh bao gồm:


CMCON (địa chỉ 9Ch) và CVRCON (địa chỉ 9Dh): xác lập các thông số cho bộ so
sánh.
Thanh ghi INTCON (địa chỉ 0Bh, 8Bh, 10Bh, 18Bh): chứa các bit cho phép các
ngắt (GIE và PEIE).
Thanh ghi PIR2 (địa chỉ 0Dh): chứa cờ ngắt của bộ so sánh (CMIF). Thanh ghi
PIE2 (địa chỉ 8Dh): chứa bit cho phép bộ so sánh (CNIE).
Thanh ghi PORTA (địa chỉ 05h) và TRISA (địa chỉ 85h): các thanh ghi điều khiển
PORTA.
 BỘ TẠO ĐIỆN ÁP SO SÁNH
Bộ so sánh này chỉ hoạt động khi bộ Comparator đựơc định dạng hoạt động ở chế
độ „110‟.
Khi đó các pin RA0/AN0 và RA1/AN1 (khi CIS = 0) hoặc pin RA3/AN3 và
RA2/AN2 (khi CIS = 1) sẽ là ngõ vào analog của điện áp cần so sánh đƣa vào ngõ VIN -
của 2 bộ so sánh C1 và C2 (xem chi tiết ở hình 2.10). Trong khi đó điện áp đƣa vào ngõ
VIN+ sẽ đƣợc lấy từ một bộ tạo điện áp so sánh. Sơ đồ khối của bộ tạo điện áp so sánh
đƣợc trình bày trong hình vẽ sau:

Hình 3.6: Sơ đồ khối bộ tạo điện áp so sánh


Bộ tạo điện áp so sánh này bao gồm một thang điện trở 16 mức đóng vai trò là cầu
phân áp chia nhỏ điện áp VDD thành nhiều mức khác nhau (16 mức). Mỗi mức có giá trị
điện áp khác nhau tùy thuộc vào bit điều khiển CVRR (CVRCON<5>). Nếu CVRR ở

ĐƢỜNG KHÁNH SƠN Trang 51


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

mức logic 1, điện trở 8R sẽ không có tác dụng nhƣ một thành phần của cầu phân áp (BJT
dẫn mạnh và dòng điện không đi qua điện trở 8R), khi đó 1 mức điện áp có giá trị
VDD/24. Ngƣợc lại khi CVRR ở mức logic 0, dòng điện sẽ qua điện trở 8R và1 mức điện
áp có giá trị VDD/32. Các mức điện áp này đƣợc đƣa qua bộ MUX cho phép ta chọn đƣợc
điện áp đƣa ra pin RA2/AN2/VREF-/CVREF để đƣa vào ngõ VIN+ của bộ so sánh bằng
cách đƣa các giá trị thích hợp vào các bit CVR3:CVR0.
Bộ tạo điện áp so sánh này có thể xem nhƣ một bộ chuyển đổi D/A đơn giản. Giá
trị điện áp cần so sánh ở ngõ vào Analog sẽ đƣợc sosánh với các mức điện áp do bộ tạo
điện áp tạo ra cho tới khi hai điện áp này đạt đƣợc giá trị xấp xỉ bằng nhau. Khi đó kết
quả chuyển đổi xem nhƣ đƣợc chứa trong các bit CVR3:CVR0.
Các thanh ghi liên quan đến bộ tạo điện áp so sánh này bao gồm:
Thanh ghi CVRCON (địa chỉ 9Dh): thanh ghi trực tiếp điều khiển bộ so sánh điện
áp.
Thanh ghi CMCON (địa chỉ 9Ch): thanh ghi điều khiển bộ Comparator.
 CCP
CCP (Capture/Compare/PWM) bao gồm các thao tác trên các xung đếm cung cấp
bởi các bộ đếm Timer 1 và Timer 2. PIC16F877A đƣợc tích hợp sẵn hai khối CCP :
CCP1 và CCP2. Mỗi CCP có một thanh ghi 16 bit (CCPR1H:CCPR1L và
CCPR2H:CCPR2L), pin điều khiển dùng cho khối CCPx là RC2/CCP1 và
RC1/T1OSI/CCP2. Các chức năng của CCP bao gồm:
- Capture.
- So sánh (Compare).
- Điều chế độ rộng xung PWM (Pulse Width Modulation).
Cả CCP1 và CCP2 về nguyên tắc hoạt động đều giống nhau và chức năng của
từng khối là khá độc lập. Tuy nhiên trong một số trƣờng hợp ngoại lệ CCP1 và CCP2 có
khả năng phối hợp với nhau để để tạo ra các hiện tƣợng đặc biệt (Special event trigger)
hoặc các tác động lên Timer 1 và Timer 2. Các trƣờng hợp này đƣợc liệt kê trong bảng
sau:

ĐƢỜNG KHÁNH SƠN Trang 52


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Hình 3.7: Sơ đồ khối bộ CCP

Khi hoạt động ở chế độ Capture thì khi có một “hiện tƣợng” xảy ratại pin
RC2/CCP1 (hoặc RC1/T1OSI/CCP2), giá trị của thanh ghi TMR1 sẽ đƣợc đƣa vào thanh
ghi CCPR1 (CCPR2). Các “hiện tƣợng” đƣợc định nghĩa bởi các bit CCPxM3:CCPxM0
(CCPxCON<3:0>) và có thể là một trong các hiện tƣợng sau:
Mỗi khi có cạnh xuống tại các pin CCP.
Mỗi khi có cạnh lên.
Mỗi cạnh lên thứ 4.
Mỗi cạnh lên thứ 16.
Sau khi giá trị của thanh ghi TMR1 đƣợc đƣa vào thanh ghi CCPRx, cờ ngắt
CCPIF đƣợc set và phải đƣợc xóa bằng chƣơng trình. Nếu hiện tƣợng tiếp theo xảy ra mà
giá trị trong thanh ghi CCPRx chƣa đƣợc xử lí, giátrị tiếp theo nhận đƣợc sẽ tự động
đƣợc ghi đè lên giá trị cũ.
Một số điểm cần chú ý khi sử dụng CCP nhƣ sau:
Các pin dùng cho khối CCP phải đƣợc ấn định là input (set các bit tƣơng ứng
trong thanh ghi TRISC). Khi ấn định các pin dùng cho khối CCP là output, việc đƣa giá

ĐƢỜNG KHÁNH SƠN Trang 53


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

trị vào PORTC cũng có thể gây ra các “hiện tƣợng” tác động lên khối CCP do trạng thái
của pin thay đổi.
Timer 1 phải đƣợc hoạt động ở chế độ Timer hoặc chế độ đếm đồng bộ. Tránh
sử dụng ngắt CCP bằng cách clear bit CCPxIE (thanh ghi PIE1), cờ ngắt CCPIF nên
đƣợc xóa bằng phần mềm mỗi khi đƣợc set để tiếp tục nhận định đƣợc trạng thái hoạt
động của CCP.
CCP còn đƣợc tích hợp bộ chia tần số prescaler đƣợc điều khiển bởi các bit
CCPxM3:CCPxM0. Việc thay đổi đối tƣợng tác động của prescaler có thể tạo ra hoạt
động ngắt. Prescaler đƣợc xóa khi CCP không hoạt động hoặc khi reset.
Khi hoạt động ở chế độ Compare, giá trị trong thanh ghi CCPRx sẽ thƣờng xuyên
đƣợc so sánh với giá trị trong thanh ghi TMR1. Khi hai thanh ghi chứa giá trị bằng nhau,
các pin của

Hình 3.8: Sơ đồ khối bộ CCP (Compare mode)

CCP đƣợc thay đổi trạng thái (đƣợc đƣa lên mức cao, đƣa xuống mức thấp hoặc
giữ nguyên trạng thái), đồng thời cờ ngắt CCPIF cũng sẽ đƣợc set. Sự thay đổi trạng thái
của pin có thể đƣợc điều khiển bởi các bit CCPxM3:CCPxM0 (CCPxCON <3:0>).
Tƣơng tự nhƣ ở chế độ Capture, Timer 1 phải đƣợc ấn định chế độ hoạt động là
timer hoặc đếm đồng bộ. Ngoài ra, khi ở chế độ Compare, CCP có khả năng tạo ra hiện
tƣợng đặc biệt (Special Event trigger) làm reset giá trị thanh ghi TMR1 và khởi động bộ

ĐƢỜNG KHÁNH SƠN Trang 54


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

chuyển đổi ADC. Điều này cho phép ta điều khiển giátrị thanh ghi TMR1 một cách linh
động hơn.
Khi hoạt động ở chế độ PWM (Pulse Width Modulation - khối điều chế độ rộng
xung), tín hiệu sau khi điều chế sẽ đƣợc đƣa ra các pin của khối CCP (cần ấn định các pin
này là output). Để sử dụng chức năng điều chế này trƣớc tiên ta cần tiến hành các bƣớc
cài đặt sau:
1. Thiết lập thời gian của 1 chu kì của xung điều chế cho PWM (period) bằng
cách đƣa giá trị thích hợp vào thanh ghi PR2.
2. Thiết lập độ rộng xung cần điều chế (duty cycle) bằng cách đƣa giá trị vào
thanh ghi CCPRxL và các bit CCP1CON<5:4>.
3. Điều khiển các pin của CCP là output bằng cách clear các bit tƣơng ứng trong
thanh ghi TRISC.
4. Thiết lập giá trị bộ chia tần số prescaler của Timer 2 và cho phép Timer 2 hoạt
động bằng cách đƣa giá trị thích hợp vào thanh ghi T2CON.
5. Cho phép CCP hoạt động ở chế độ PWM.

Hình 3.9: Sơ đồ khối bộ CCP (PWM mode)

ĐƢỜNG KHÁNH SƠN Trang 55


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Hình 3.10: Các tham số của PWM

Trong đó giá trị 1 chu kì (period) của xung điều chế đƣợc tính bằng công thức:

Bộ chia tần số prescaler của Timer 2 chỉ có thể nhận các giá trị 1,4 hoặc 16 (xem
lại Timer 2 để biết thêm chi tiết). Khi giá trị thanh ghi PR2 bằng với giá trị thanh ghi
TMR2 thì quá trình sau xảy ra:
Thanh ghi TMR2 tự động đƣợc xóa. Pin của khối CCP đƣợc set. Giá trị thanh
ghi CCPR1L (chứa giá trị ấn định độ rộng xung điều chế duty cycle) đƣợc đƣa vào thanh
ghi CCPRxH.
Độ rộng của xung điều chế (duty cycle) đƣợc tính theo công thức:

Nhƣ vậy 2 bit CCPxCON<5:4> sẽ chứa 2 bit LSB. Thanh ghi CCPRxL chứa byte
cao của giá trị quyết định độ rộng xung. Thanh ghi CCPRxH đóng vai trò là buffer cho
khối PWM. Khi giá trị trong thanh ghi CCPRxH bằng với giá trị trong thanh ghi TMR2
và hai bit CPxCON<5:4> bằng với giá trị 2 bit của bộ chiatần số prescaler, pin của khối
CCP lại đƣợc đƣa về mức thấp, nhƣ vậy ta có đƣợc hình ảnh của xung điều chế tại ngõ ra
của khối PWM nhƣ hình 2.14.
Một số điểm cần chú ý khi sử dụng khối PWM:
Timer 2 có hai bộ chia tần số prescaler và postscaler. Tuy nhiên bộ postscaler
không đƣợc sử dụng trong quá trình điều chế độ rộng xung của khối PWM.

ĐƢỜNG KHÁNH SƠN Trang 56


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Nếu thời gian duty cycle dài hơn thời gian chu kì xung period thì xung ngõ ra tiếp
tục đƣợc giữ ở mức cao sau khi giá trị PR2 bằng với giá trị TMR2.

ĐƢỜNG KHÁNH SƠN Trang 57


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Chương 4: HOẠT ĐỘNG ĐỊNH THỜI (TIMER/COUNTER)

4.1. Mở đầu
Trong các ứng dụng của vi điều khiển trong thực tế, việc định thời (tạo một
khoảng thời gian giữa 2 sự kiện) các thao tác là việc thƣờng xuyên xảy ra.
Để thực hiện việc này, ta có 2 cách:
- Dùng các lệnh thực hiện các vòng lặp để tạo ra khoảng thời gian.
Nguyên tắc tạo ra khoảng thời gian này đơn giản nhƣ sau: nếu vi điều khiển mất một
khoảng thời gian x để thực hiện một lệnh, việc lặp lại một lệnh n lần sẽ mất n*x thời gian.
Trong chƣơng trình, cách này đƣợc dùng nhiều với thể hiện là các lệnh
Delay_ms(), Delay_us()
- Dùng các bộ định thời Timer để tạo ra khoảng thời gian trễ.
Trong chƣơng này, ta sẽ đi vào nguyên cứu các bộ timer. Một chế độ quan trọng
nữa của timer là khi nó hoạt động nhƣ bộ đếm. Trong ứng dụng này, timer hoạt động
nhƣ một bộ đếm, có nhiệm vụ đếm số các xung đi vào một chân cụ thể trên vi điều khiển.
Chế độ bộ đếm này có nhiều ứng dụng trong thực tế nhƣ đếm số vòng quay của
động cơ (phản hồi từ bộ đo tốc độ động cơ-encoder), đếm số sản phẩm trên một dây
chuyền v.v.
Vi điều khiển PIC16F877A có 3 bộ timer:
- Timer 0: 8 bit (số đếm tối đa của nó là 255), hoạt động ở 2 chế độ định thời và
bộ đếm.
- Timer 1: 16 bit (số đếm tối đa của nó là 65535), hoạt động ở 2 chế độ định thời
và bộ đếm.
- Timer 2: 8 bit, hoạt động phục vụ chức năng PWM (Pulse Width Modulation-
Điều chế độ rộng xung).
4.2. Nguyên lý hoạt động cơ bản của một bộ định thời
4.2.1.Chế độ định thời:
Mỗi bộ timer có một hoặc nhiều thanh ghi chứa giá trị đếm của nó (tùy thuộc
vào độ dài của timer), ta giả sử tên thanh ghi là TMR có độ dài là n byte, hay giá trị đếm
tối đa là 2 1 . Khi giá trị của TMR đạt đến giá trị này, vi điều khiển sẽ set bit cờ của
8n

bộ timer đó lên mức 1. Ngƣời dùng sẽ biết đƣợc thời điểm này bằng cách kiểm tra bit cờ.
Đồng thời TMR sẽ tự động xóa về giá trị 0.

ĐƢỜNG KHÁNH SƠN Trang 58


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Khi đƣợc cài đặt hoạt động trong chế độ định thời, giá trị của thanh ghi TMR sẽ tự
động tăng lên 1 đơn vị sau mỗi chu kì lệnh của vi điều khiển. Khi giá trị của TMR đạt
đến giá trị tối đa, bit cờ của Timer sẽ đƣợc set lên mức 1 và TMR bị xóa, TMR=0.
Giả sử vi điều khiển dùng thạch anh tần số 4MHz, nhƣ vậy:
4
Chu kỳ lệnh = 4 chu kỳ thạch anh =  1 s
4 x106
Vậy TMR sẽ tự động tăng lên 1 đơn vị sau 1 s .
Nếu ban đầu ta cho TMR= x. Thì sau khoảng thời gian 28n 1  x( s) giá trị TMR
sẽ đạt giá trị tối đa của nó là 28n 1 . Thời điểm này đƣợc xác định thông qua trạng thái
của bit cờ.
Ngƣợc lại, ta muốn thực hiện định thời khoảng thời gian t sau một sự kiện 1 nhƣ
sau:
- Sự kiện 1
- Tạo khoảng thời gian trễ t
- Sự kiện 2
Ta làm các bƣớc:
- Sự kiện 1
- Gán giá trị ban đầu cho TMR = 2  1  t
8n

- Kiểm tra bit cờ.


- Khi bit cờ = 1, thực hiện sự kiện 2.
Thật vậy, sau 1 (µs) TMR tăng lên 1 đơn vị, để tăng giá trị cho TMR từ 28n  1  t
đến giá trị tối đa 28n 1 (khi bit cờ đƣợc set lên 1) mất 28n 1  t  (28n 1  t )  t ( s)
Vậy khoảng thời gian từ sau sự kiện 1 (khi TMR bắt đầu đƣợc gán) đến sự kiện 2
(ngay sau khi bit cờ đƣợc set) là t đúng nhƣ yêu cầu của ta.
Ví dụ: Để định thời 200 (µs) dùng Timer 0 (8 bit; n=1; giá trị tối đa là 255) ta cho
TMR0= 255-200=55 rồi bắt đầu cho đếm lên.
4.2.2.Chế độ bộ đếm
Khi đƣợc cài đặt trong chế độ này, một chân chức năng trên vi điều khiển sẽ trở
thành chân đầu vào xung của bộ đếm. Ví dụ: chân RA4 đối với timer 0 và RC0 đối với
timer 1. Hoạt động của nó có nét giống với chế độ định thời.

ĐƢỜNG KHÁNH SƠN Trang 59


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Khi đƣợc cài đặt hoạt động trong chế độ bộ đếm, Giá trị của thanh ghi TMR sẽ tự
động tăng lên 1 đơn vị khi có một xung vào chân đầu vào xung của timer đó. Khi giá trị
của TMR0 đạt đến giá trị tối đa, bit cờ của timer sẽ đƣợc set lên mức 1 và TMR bị xóa,
TMR=0.
Nhƣ vậy, về cách hoạt động trong chế độ này chỉ khác với chế độ định thời ở chỗ,
thay vì TMR tự động tăng lên sau mỗi chu kì lệnh, thì TMR tăng lên khi có một xung đi
vào chân đầu vào xung của Timer đó.
Dạng xung đƣợc xác định là sƣờn âm hay sƣờn dƣơng phụ thuộc vào việc cài đặt
bit chọn dạng xung tƣơng ứng trên thanh ghi của vi điều khiển.
Nguyên lý hoạt động định thời và bộ đếm này cũng đúng với các bộ vi điều khiển,
vi xử lý khác.
4.3. TIMER 0
Đây là một trong ba bộ đếm hoặc bộ định thời của vi điều khiển PIC16F877A.
Timer 0 là bộ đếm 8 bit đƣợc kết nối với bộ chia tần số (prescaler) 8 bit. Cấu
trúc của timer 0 cho phép ta lựa chọn xung clock tác động và cạnh tích cực của xung
clock.
Ngắt timer 0 sẽ xuất hiện khi timer 0 bị tràn. Bit TMR0IE (INTCON<5>) là bit
điều khiển của timer 0. TMR0IE=1 cho phép ngắt Timer 0 tác động, TMR0IF= 0 không
cho phép ngắt timer 0 tác động. Sơ đồ khối của Timer 0 nhƣ sau:

ĐƢỜNG KHÁNH SƠN Trang 60


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Hình 4.1: Sơ đồ khối của timer 0

Muốn timer 0 hoạt động ở chế độ timer ta clear bit TOSC


(OPTION_REG<5>),khi đó giá trị thanh ghi TMR0 sẽ tăng theo từng chu kì xung đồng
hồ (tần số vào Timer 0 bằng ¼ tần số oscillator). Khi giá trị thanh ghi TMR0 từ FFh trở
về 00h, ngắt timer 0 sẽ xuất hiện.
Thanh ghi TMR0 cho phép ghi và xóa đƣợc giúp ta ấn định thời điểm ngắt Timer
0 xuất hiện một cách linh động. Muốn timer 0 hoạt động ở chế độ counter ta set bit TOSC
(OPTION_REG<5>). Khi đó xung tác động lên bộ đếm đƣợc lấy từ chân RA4/TOCK1.
Bit TOSE (OPTION_REG<4>) cho phép lựa chọn cạnh tác động vào bộ đếm. Cạnh tác
động sẽ là cạnh lên nếu TOSE=0 và cạnh tác động sẽ là cạnh xuống nếu TOSE=1.
Khi thanh ghi TMR0 bị tràn, bit TMR0IF (INTCON<2>) sẽ đƣợc set. Đây chính
là cờ ngắt của timer 0. Cờ ngắt này phải đƣợc xóa bằng chƣơng trình trƣớc khi bộ đếm
bắt đầu thực hiện lại quá trình đếm. Ngắt timer 0 không thể “đánh thức” vi điều khiển từ
chế độ sleep.
Bộ chia tần số (prescaler) đƣợc chia sẻ giữa timer 0 và WDT (Watchdog Timer).

ĐƢỜNG KHÁNH SƠN Trang 61


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Điều đó có nghĩa là nếu prescaler đƣợc sử dụng cho timer 0 thì WDT sẽ không có
đƣợc hỗ trợ của prescaler và ngƣợc lại. Prescaler đƣợc điều khiển bởi thanh ghi
OPTION_REG. Bit PSA (OPTION_REG<3>) xác định đối tƣợng tác động của
prescaler. Các bit PS2:PS0 (OPTION_REG<2:0>) xác định tỉ số chia tần số của
prescaler. Xem lại thanh ghi OPTION_REG để xác định lại một cách chi tiết về các bit
điều khiển trên.
Các lệnh tác động lên giá trị thanh ghi TMR0 sẽ xóa chế độ hoạt động của
prescaler. Khi đối tƣợng tác động là Timer 0, tác động lên giá trị thanh ghi TMR0 sẽ xóa
prescaler nhƣng không làm thay đổi đối tƣợng tác động của prescaler. Khi đối tƣợng tác
động là WDT, lệnh CLRWDT sẽ xóa prescaler, đồng thời prescaler sẽ ngƣng tác vụ hỗ
trợ cho WDT.
Các thanh ghi điều khiển liên quan đến timer 0 bao gồm:
- TMR0 (địa chỉ 01h, 101h) : chứa giá trị đếm của timer 0.
- INTCON (địa chỉ 0Bh, 8Bh, 10Bh, 18Bh): cho phép ngắt hoạt động (GIE
và PEIE).
- OPTION_REG (địa chỉ 81h, 181h): điều khiển prescaler.

T0CS: Bit chọn chế độ


= 0: TMR0 hoạt động chế độ định thời
= 1: TMR0 hoạt động chế độ bộ đếm
T0SE: Bit chọn dạng xung cho chế độ bộ đếm
= 0: Xung sƣờn lên
= 1: Xung sƣờn xuống
PSA: Bit chọn chế độ cho bộ chia tần số PresCale là WatchDog_Timer hay Timer
0.
= 0: Bộ chia tần số dành cho timer 0
= 1: Bộ chia tần số dành cho Watch_Dog Timer
PS2-PS0: 3 bit chọn tỉ lệ chia tần số nhƣ đã giới thiệu ở phần trên.
Thanh ghi INTCON (0Bh):
ĐƢỜNG KHÁNH SƠN Trang 62
GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Bit TMR0IE: Bit này bằng 1 cho phép ngắt timer 0. Sự kiện ngắt xảy ra khi có sự
tràn TMR0 từ 255 xuống 0.
Bit TMR0IF: Bit cờ xác nhận giá trị TMR0 đã bị tràn từ 255 về 0.
4.4. TIMER 1
Timer 1 có độ dài 16 bit. Giá trị của bộ đếm timer 1 đƣợc lƣu trong 2 thanh ghi 8
bit TMR1H và TMR1L. Timer 1 cũng có 2 chế độ đƣợc cài đặt bởi bit TMR1CS (bit 1
của thanh ghi T1CON):
- TMR1CS = 0: Chế độ định thời
- TMR1CS = 1: Chế độ bộ đếm. Có 2 dạng đƣợc phân biệt bởi bit T1SYNC (bit
2 của
T1CON)
o T1SYNC = 0: Bộ đếm đồng bộ
o T1SYNC = 1: Bộ đếm không đồng bộ
Trong chế độ bộ đếm, đầu vào cho xung có thể nối vào chân RC0 hoặc RC1 tùy
thuộc vào bit T1OSCEN (bit 3 của T1CON)
- T1OSCEN = 1: Đầu vào xung nối với RC1
- T1OSCEN = 0: Đầu vào xung nối với RC0
Chú ý là khác với timer 0, đầu vào xung ở timer 1 phải có dạng sƣờn xuống.
Chế độ đồng bộ của chế độ bộ đếm nghĩa là nếu nhƣ vi điều khiển đang ở chế độ
ngủ thì giá trị của thanh ghi TMR1L và TMR2L không tăng lên.
Tỉ lệ bộ chia tần số Prescal của timer 1 đƣợc chọn bởi 2 bit T1CKPS1-T1CKPS0
(Bit 5-4 của T1CON). Tỉ lệ chia lớn nhất là 1:8.
Các thanh ghi liên quan
Thanh ghi TMR1L (Địa chỉ0Eh) và TMR1H (Địa chỉ0Fh):
Thanh ghi chứa 8 bit thấp và 8 bit cao của giá trị đếm 16 bit của timer 1.
Thanh ghi điều khiển timer 1-T1CON (Địa chỉ10h):

ĐƢỜNG KHÁNH SƠN Trang 63


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

T1CKPS1-T1CKPS0: Chọn tỉ lệ bộ chia tần số:

T1OSCEN: bit chọn đầu vào xung là RC1 hay RC0


- =1: RC1
- =0: RC0
T1SYNC: bit chọn chế độ bộ đếm đồng bộ
- =1: Không đồng bộ
- =0: Không đồng bộ
TMR1CS: bit chọn chế độ định thời hay chế độ bộ đếm
- =1: Chế độ bộ đếm
- =0: Chế độ bộ định thời
TMR1ON: bit bật hay tắt timer 1
- =1: Bật timer 1
- =0: Tắt timer 1
Thanh ghi PIR1:

Bit TMR1IF là bit cờ của timer 1. Bit đƣợc set lên giá trị 1 khi xảy ra tràn 2 thanh
ghi TMR1L và TMR2H từ 65535 về 0.
4.5. TIMER 2
Timer 2 là bộ định thời 8 bit và đƣợc hỗ trợ bởi hai bộ chia tần số prescaler và
postscaler. Thanh ghi chứa giá trị đếm của timer 2 là TMR2. Bit cho phép ngắt timer 2

ĐƢỜNG KHÁNH SƠN Trang 64


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

tác động là TMR2ON (T2CON<2>). Cờ ngắt của timer 2 là bit TMR2IF (PIR1<1>).
Xung ngõ vào (tần số bằng ¼ tần số oscillator) đƣợc đƣa qua bộ chia tần số prescaler 4
bit (với các tỉ số chia tần số là 1:1, 1:4 hoặc 1:16 và đƣợc điều khiển bởi các bit
T2CKPS1:T2CKPS0 (T2CON<1:0>)).

Hình 4.2: Sơ đồ khối của timer 2

Timer 2 còn đƣợc hỗ trợ bởi thanh ghi PR2. Giá trị đếm trong thanh ghi TMR2 sẽ
tăng từ 00h đến giá trị chứa trong thanh ghi PR2, sau đó đƣợc reset về 00h. Khi reset
thanh ghi PR2 đƣợc nhận giá trị mặc định FFh.
Ngõ ra của timer 2 đƣợc đƣa qua bộ chia tần số postscaler với các mức chia từ 1:1
đến 1:16. Postscaler đƣợc điều khiển bởi 4 bit T2OUTPS3:T2OUTPS0. Ngõ ra của
postscaler đóng vai trò quyết định trong việc điều khiển cờ ngắt.
Ngoài ra ngõ ra của timer 2 còn đƣợc kết nối với khối SSP, do đó timer 2 còn
đóng vai trò tạo ra xung clock đồng bộ cho khối giao tiếp SSP.
Các thanh ghi liên quan đến timer 2 bao gồm:
- INTCON (địa chỉ 0Bh, 8Bh, 10Bh, 18Bh): cho phép toàn bộ các ngắt (GIE và
PEIE).
- PIR1 (địa chỉ 0Ch): chứa cờ ngắt timer 2 (TMR2IF).
- PIE1 (địa chị 8Ch): chứa bit điều khiển timer 2 (TMR2IE).
- TMR2 (địa chỉ 11h): chứa giá trị đếm của timer 2.
- T2CON (địa chỉ 12h): xác lập các thông số cho timer 2.

ĐƢỜNG KHÁNH SƠN Trang 65


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

- PR2 (địa chỉ 92h): thanh ghi hỗ trợ cho timer 2.


timer 0, timer 1 và timer 2 nhƣ sau:
Timer 0 và timer 2 là bộ đếm 8 bit (giá trị đếm tối đa là FFh), trong khi timer 1 là
bộ đếm 16 bit (giá trị đếm tối đa là FFFFh).
Timer 0, timer 1 và timer 2 đều có hai chế độ hoạt động là timer và counter. Xung
clock có tần số bằng ¼ tần số của oscillator. Xung tác động lên Timer 0 đƣợc hỗ trợ bởi
prescaler và có thể đƣợc thiết lập ở nhiều chế độ khác nhau (tần số tác động, cạnh tác
động) trong khi các thông số của xung tác động lên timer 1 là cố định. Timer 2 đƣợc hỗ
trợ bởi hai bộ chia tần số prescaler và postcaler độc lập, tuy nhiên cạnh tác động vẫn
đƣợc cố định là cạnh lên.
Timer 1 có quan hệ với khối CCP, trong khi timer 2 đƣợc kết nối với khối SSP.
4.6 Một số ứng dụng định thời
Nhƣ đã trình bày ở trên các bộ định thời đƣợc dùng để tạo ra khoảng thời gian
trễ hoặc hoạt động nhƣ bộ đếm, ứng dụng trong thực tế nhƣ đếm số vòng quay của
động cơ, đếm sản phẩm, số xe ra vào kho/bãi.v.v..
Ví dụ 1 : Chƣơng trình dùng ngắt Timer 0 định thì 1s. Đầu tiên led ở chân RB0
sáng, sau 1s sẽ dịch sang trái, nghĩa là led 1 trên chân RB1 sáng , lần lƣợt nhƣ vậy cho
các led trên port B và lặp lại mãi mãi. Chƣơng trình viết bằng ccs c:

#include <16F877A.h>
#fuses NOWDT,PUT,XT,NOPROTECT
#use delay(clock=2000000)
#byte PORTB = 0x06

int16 count;
int8 a;
//Chuong trinh ngat TMR0
#int_timer 0
void interrupt_timer 0()
{
set_timer 0(6);
++count;
if(count == 2000) // 2000*500us = 500000us = 1s
{
count=0;
rotate_left(&a,1);
}

ĐƢỜNG KHÁNH SƠN Trang 66


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

}
//Chuong trinh chinh
void main(void)
{
set_tris_b(0);
enable_interrupts(int_timer 0);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
enable_interrupts(global);
set_timer 0(6);// T_dinhthi = 2*(256 - 6)*1us = 500us
a = 0x01;

while(true)
{
PORTB = a;
}
}

Hình 4.3: Mô phỏng dùng ngắt timer 0 định thì 1s

Ví dụ 2: Chƣơng trình dùng timer 1 để đo tốc độ động cơ từ encoder, hiển thị giá trị đo
đƣợc trên lcd. Chƣơng trình viết bằng ccs c:
#include
#device PIC16F877*=16 ADC=10 // Su dung con tro 16bit (cho MCU 14bit)
// Su dung ADC 10bit
#fuses hs, nowdt, noprotect, nolvp, put, brownout
#use delay(clock=20000000)
#include

ĐƢỜNG KHÁNH SƠN Trang 67


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

#include

// Dung ngat ngoai kenh A de do xung kenh B de xac dinh chieu quay
// Kenh A B0
// Kenh B B4
float32 w = 0.0;//kp=0.2 kd=0.02 ki=0.01
signed int32 Pulse=0,PrePulse=0,DeltaPulse=0;// Dem xung Encoder

float32 Get_W(void);
// Ngat kenh A
#int_ext
void kenh_A()
{
if (input_state(PIN_B4))
//chieu='T';
Pulse++;
else
//chieu='N';
Pulse--;
}

// Sau 100ms thi ngat timer 1, do so xung dem duoc


#int_timer 1
void ngat_timer 1()
{
// Tinh van toc w (vong/phut)
w = get_W();
set_timer 1(3036); // reset timer
}
void main()
{
char so[8];
// Cai dat thong so ban dau
LCD_Init();
delay_ms(10);

// Cai dat timer 1


// Prescale = 8; tran sau 100ms
// 4*Prescale*[(2^16 - TMR1]
// T_interrupt = -------------------------- x counter = 100 ms
// Fosc
// 4*8*[(2^16-1)-3036]
// T_interrupt = ----------------------- x 1 = 100 ms
// 20MHz
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
ext_int_edge( L_TO_H );

ĐƢỜNG KHÁNH SƠN Trang 68


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

// Khai bao ngat


enable_interrupts(global);
enable_interrupts(int_ext);
enable_interrupts(int_timer 1);
set_timer 1(3036);

while(1)
{
sprintf(so,"%5.2f",w);
LCD_Gotoxy(1,0);
LCD_Puts(so);
// Truyen du lieu len RS232
}
}
// Ham tinh van toc goc vong/phut
float32 Get_W(void)
{
float32 rpm;
DeltaPulse = Pulse - PrePulse;
PrePulse = Pulse;
/*
PulsesPerRev: so xung/vong cua encoder
DeltaPulse: so xung doc duoc giua hai lan ngat lien tiep
Sampling_time: thoi gian(s) lay mau (thoi gian giua 2 lan ngat lien tiep)
n: la so vong quay cua dong co trong mot phut
Quy tac tam xuat:
Xung giay
n x PulsesPerRev 60
DeltaPulse Sampling_time

=&gt; n x PulsesPerRev x Sampling_time = DeltaPulse x 60


DeltaPulse x 60
=&gt; n = ----------------------------
PulsesPerRev x Sampling_time
*/
// PulsesPerRev = 100 xung/vong
// Sampling_time = 0.1 s
//n = rpm = 6.0*(float32)DeltaPulse
rpm = 6.0*(float32)DeltaPulse;
return(rpm);
}

ĐƢỜNG KHÁNH SƠN Trang 69


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Hình 4.4: Mô phỏng đo tốc độ động cơ sử dụng timer 1

ĐƢỜNG KHÁNH SƠN Trang 70


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Chương 5: GIAO TIẾP VÀ TRUYỀN DỮ LIỆU VỚI VI ĐIỀU KHIỂN

5.1.GIAO TIẾP NỐI TIẾP


5.1.1. USART
USART (Universal Synchronous Asynchronous Receiver Transmitter) là một
trong hai chuẩn giao tiếp nối tiếp. USART còn đƣợc gọi là giao diện giao tiếp nối tiếp
SCI (Serial Communication Interface). Có thể sử dụng giao diện này cho các giao tiếp
với các thiết bị ngoại vi, với các vi điều khiển khác hay với máy tính. Các dạng của giao
diện USART ngoại vi bao gồm:
Bất động bộ (Asynchronous).
Đồng bộ_ Master mode.
Đồng bộ_ Slave mode.
Hai pin dùng cho giao diện này là RC6/TX/CK và RC7/RX/DT, trong đó
RC6/TX/CK dùng để truyền xung clock (baud rate) và RC7/RX/DT dùng để truyền data.
Trong trƣờng hợp này ta phải set bit TRISC<7:6> và SPEN (RCSTA<7>) để cho phép
giao diện USART.
PIC16F877A đƣợc tích hợp sẵn bộ tạo tốc độ baud BRG (Baud Rate Genetator) 8
bit dùng cho giao diện USART. BRG thực chất là một bộ đếm có thể đƣợc sử dụng cho
cả hai dạng đồng bộ và bất đồng bộ và đƣợc điều khiển bởi thanh ghi PSBRG. Ở dạng
bất đồng bộ, BRG còn đƣợc điều khiển bởi bit BRGH ( TXSTA<2>). Ở dạng đồng bộ tác
động của bit BRGH đƣợc bỏ qua. Tốc độ baud do BRG tạo ra đƣợc tính theo công thức
sau:

Trong đó X là giá trị của thanh ghi RSBRG ( X là số nguyên và 0<X<255).


Các thanh ghi liên quan đến BRG bao gồm:
TXSTA (địa chỉ 98h): chọn chế độ đòng bộ hay bất đồng bộ ( bit SYNC) và chọn
mức tốc độ baud (bit BRGH).
RCSTA (địa chỉ 18h): cho phép hoạt động cổng nối tiếp (bit SPEN). RSBRG
(địa chỉ 99h): quyết định tốc độ baud.

ĐƢỜNG KHÁNH SƠN Trang 71


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

5.1.1.1 USART BẤT ĐỒNG BỘ


Ở chế độ truyền này USART hoạt động theo chuẩn NRZ (None-Return-to-Zero),
nghĩa là các bit truyền đi sẽ bao gồm 1 bit Start, 8 hay 9 bit dữ liệu (thông thƣờng là 8
bit) và 1 bit Stop. Bit LSB sẽ đƣợc truyền đi trƣớc. Các khối truyền và nhận data độc lập
với nhau sẽ dùng chung tần số tƣơng ứng với tốc độ baud cho quá trình dịch dữ liệu (tốc
độ baud gấp 16 hay 64 lần tốc độ dịch dữ liệu tùy theo giá trị của bit BRGH), và để đảm
bảo tính hiệu quả của dữ liệu thì hai khối truyền và nhận phải dùng chung một định dạng
dữ liệu.
 TRUYỀN DỮ LIỆU QUA CHUẨN GIAO TIẾP USART BẤT ĐỒNG BỘ
Thành phần quan trọng nhất của khối truyền dữ liệu là thanh ghi dịch dữ liệu TSR
(Transmit Shift Register). Thanh ghi TSR sẽ lấy dữ liệu từ thanh ghi đệm dùng cho quá
trình truyền dữ liệu TXREG. Dữ liệu cần truyền phải đựơc đƣa trƣớc vào thanh ghi
TXREG. Ngay sau khi bit Stop của dữ liệu cần truyền trƣớc đó đƣợc truyền xong, dữ liệu
từ thanh ghi TXREG sẽ đƣợc đƣa vào thanh ghi TSR, thanh ghi TXREG bị rỗng, ngắt
xảy ra và cờ hiệu TXIF (PIR1<4>) đƣợc set. Ngắt này đƣợc điều khiển bởi bit TXIE
(PIE1<4>). Cờ hiệu TXIF vẫn đƣợc set bất chấp trạng thái của bit TXIE hay tác động của
chƣơng trình (không thể xóa TXIF bằng chƣơng trình) mà chỉ reset về 0 khi có dữ liệu
mới đƣợc đƣa vào thanhh ghi TXREG.

Hình 5.1: Sơ đồ khối của khối truyền dữ liệu USART

Trong khi cờ hiệu TXIF đóng vai trò chỉ thị trạng thái thanh ghi TXREG thì cờ
hiệu TRMT (TXSTA<1>) có nhiệm vụ thể hiện trạng thái thanh ghi TSR. Khi thanh ghi
ĐƢỜNG KHÁNH SƠN Trang 72
GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

TSR rỗng, bit TRMT sẽ đƣợc set. Bit này chỉ đọc và không có ngắt nào đƣợc gắn với
trạng thái của nó.
Một điểm cần chú ý nữa là thanh ghi TSR không có trong bộ nhớ dữ liệu và chỉ
đƣợc điều khiển bởi CPU.
Khối truyền dữ liệu đƣợc cho phép hoạt động khi bit TXEN (TXSTA<5>) đƣợc
set. Quá trình truyền dữ liệu chỉ thực sự bắt đầu khi đã có dữ liệu trong thanh ghi
TXREG và xung truyền baud đƣợc tạo ra. Khi khối truyền dữ liệu đƣợc khởi động lần
đầu tiên, thanh ghi TSR rỗng. Tại thời điểm đó, dữ liệu đƣa vào thanh ghi TXREG ngay
lập tức đƣợc load vào thanh ghi TSR và thanh ghi TXREG bị rỗng. Lúc này ta có thể
hình thành một chuỗi dữ liệu liên tục cho quá trình truyền dữ liệu. Trong quá trình truyền
dữ liệu nếu bit TXEN bị reset về 0, quá trình truyền kết thúc, khối truyền dữ liệu đƣợc
reset và pin RC6/TX/CK chuyển đến trạng thái high-impedance.
Trong trƣờng hợp dữ liệu cần truyền là 9 bit, bit TX9 (TXSTA<6>) đƣợc set và
bit dữ liệu thứ 9 sẽ đƣợc lƣu trong bit TX9D (TXSTA<0>). Nên ghi bit dữ liệu thứ 9 vào
trƣớc, vì khi ghi 8 bit dữ liệu vào thanh ghi TXREG trƣớc có thể xảy ra trƣờng hợp nội
dung thanh ghi TXREG sẽ đƣợc load vào thanh ghi TSG trƣớc, nhƣ vậy dữ liệu truyền đi
sẽ bị sai khác so với yêu cầu.
Tóm lại, để truyền dữ liệu theo giao diện USART bất đồng bộ, ta cần thực hiện
tuần tự các bƣớc sau:
1. Tạo xung truyền baud bằng cách đƣa các giá trị cần thiết vào thanh ghi RSBRG
và bit điều khiển mức tốc độ baud BRGH.
2. Cho phép cổng giao diện nối tiếp nối tiếp bất đồng bộ bằng cách clear bit
SYNC và set bit PSEN.
3. Set bit TXIE nếu cần sử dụng ngắt truyền.
4. Set bit TX9 nếu định dạng dữ liệu cần truyền là 9 bit.
5. Set bit TXEN để cho phép truyền dữ liệu (lúc này bit TXIF cũng sẽ đƣợc set).
6. Nếu định dạng dữ liệu là 9 bit, đƣa bit dữ liệu thứ 9 vào bit TX9D.
7. Đƣa 8 bit dữ liệu cần truyền vảo thanh ghi TXREG.
8. Nếu sử dụng ngắt truyền, cần kiểm tra lại các bit GIE và PEIE (thanh ghi
INTCON).
Các thanh ghi liên quan đến quá trình truyền dữ liệu bằng giao diện USART bất

ĐƢỜNG KHÁNH SƠN Trang 73


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

đồng bộ:
- Thanh ghi INTCON (địa chỉ 0Bh, 8Bh, 10Bh, 18Bh): cho phép tất cả các ngắt.
- Thanh ghi PIR1 (địa chỉ 0Ch): chứa cờ hiệu TXIF.
- Thanh ghi PIE1 (địa chỉ 8Ch): chứa bit cho phép ngắt truyền TXIE.
- Thanh ghi RCSTA (địa chỉ 18h): chứa bit cho phép cổng truyền dữ liệu (hai pin
RC6/TX/CK và RC7/RX/DT).
- Thanh ghi TXREG (địa chỉ 19h): thanh ghi chứa dữ liệu cần truyền.
- Thanh ghi TXSTA (địa chỉ 98h): xác lập các thông số cho giao diện. Thanh ghi
SPBRG (địa chỉ 99h): quyết định tốc độ baud.
 NHẬN DỮ LIỆU QUA CHUẨN GIAO TIẾP USART BẤT ĐỒNG BỘ

Hình 5.2: Sơ đồ khối của khối nhận dữ liệu USART

Dữ liệu đƣợc đƣa vào từ chân RC7/RX/DT sẽ kích hoạt khối phục hồi dữ liệu.
Khối phục hồi dữ liệu thực chất là một bộ dịch dữ liệu tốc độ cao và có tần số hoạt động
gấp 16 lần hoặc 64 lần tần số baud. Trong khi đó tốc độ dịch của thanh ghi nhận dữ liệu
sẽ bằng với tần số baud hoặc tần số của oscillator.
Bit điều khiển cho phép khối nhận dữ liệu là bit RCEN (RCSTA<4>). Thành phần
quan trọng nhất của khối nhận dữ liệu là thanh ghi nhận dữ liệu RSR (Receive Shift
Register). Sau khi nhận diện bit Stop của dữ liệu truyền tới, dữ liệu nhận đƣợc trong
thanh ghi RSR sẽ đƣợc đƣa vào thanh ghi RCGER, sau đó cờ hiệu RCIF (PIR1<5>) sẽ

ĐƢỜNG KHÁNH SƠN Trang 74


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

đƣợc set và ngắt nhận đƣợc kích hoạt. Ngắt này đƣợc điều khiển bởi bit RCIE
(PIE1<5>). Bit cờ hiệu RCIF là bit chỉ đọc và không thể đƣợc tác động bởi chƣơng trình.
RCIF chỉ reset về 0 khi dữ liệu nhận vào ở thanh ghi RCREG đã đƣợc đọc và khi đó
thanh ghi RCREG rỗng. Thanh ghi RCREG là thanh ghi có bộ đệm kép (double-buffered
register) và hoạt động theo cơ chế FIFO (First In First Out) cho phép nhận 2 byte và byte
thứ 3 tiếp tục đƣợc đƣa vào thanh ghi RSR. Nếu sau khi nhận đƣợc bit Stop của byte dữ
liệu thứ 3 mà thanh ghi RCREG vẫn còn đầy, cờ hiệu báo tràn dữ liệu (Overrun Error bit)
OERR(RCSTA<1>) sẽ đƣợc set, dữ liệu trong thanh ghi RSR sẽ bị mất đi và quá trình
đƣa dữ liệu từ thanh ghi RSR vào thanh ghi RCREG sẽ bị gián đoạn.
Trong trƣờng hợp này cần lấy hết dữ liệu ở thanh ghi RSREG vào trƣớc khi tiếp
tục nhận byte dữ liệu tiếp theo. Bit OERR phải đƣợc xóa bằng phần mềm và thực hiện
bằng cách clear bit RCEN rồi set lại. Bit FERR (RCSTA<2>) sẽ đƣợc set khi phát hiện
bit Stop dủa dữ liệu đƣợc nhận vào. Bit dữ liệu thứ 9 sẽ đƣợc đƣa vào bit RX9D
(RCSTA<0>). Khi đọc dữ liệu từ thanh ghi RCREG, hai bit FERR và RX9Dsẽ nhận các
giá trị mới. Do đó cần đọc dữ liệu từ thanh ghi RCSTA trƣớc khi đọc dữ liệu từ thanh ghi
RCREG để tránh bị mất dữ liệu.
Tóm lại, khi sử dụng giao diện nhận dữ liệu USART bất đồng bộ cần tiến hành
tuần tự các bƣớc sau:
1. Thiết lập tốc độ baud (đƣa giá trị thích hợp vào thanh ghi SPBRG và bit
BRGH.
2. Cho phép cổng giao tiếp USART bất đồng bộ (clear bit SYNC và set bit
SPEN).
3. Nếu cần sử dụng ngắt nhận dữ liệu, set bit RCIE.
4. Nếu dữ liệu truyền nhận có định dạng là 9 bit, set bit RX9.
5. Cho phép nhận dữ liệu bằng cách set bit CREN.
6. Sau khi dữ liệu đƣợc nhận, bit RCIF sẽ đƣợc set và ngắt đƣợc kích hoạt (nếu
bit
RCIE đƣợc set).
7. Đọc giá trị thanh ghi RCSTA để đọc bit dữ liệu thứ 9 và kiểm tra xem quá trình
nhận dữ liệu có bị lỗi không.
8. Đọc 8 bit dữ liệu từ thanh ghi RCREG.

ĐƢỜNG KHÁNH SƠN Trang 75


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

9. Nếu quá trình truyền nhận có lỗi xảy ra, xóa lỗi bằng cách xóa bit CREN.
10. Nếu sử dụng ngắt nhận cần set bit GIE và PEIE (thanh ghi INTCON).
Các thanh ghi liên quan đến quá trình nhận dữ liệu bằng giao diện USART bất
đồng bộ:
- Thanh ghi INTCON (địa chỉ 0Bh, 8Bh, 10Bh, 18Bh): chứa các bit cho phép toàn
bộ các ngắt (bit GIER và PEIE).
- Thanh ghi PIR1 (địa chỉ 0Ch): chứa cờ hiệu RCIE.
- Thanh ghi PIE1 (địa chỉ 8Ch): chứa bit cho phép ngắt RCIE.
- Thanh ghi RCSTA (địa chỉ 18h): xác định các trang thái trong quá trình nhận dữ
liệu.
- Thanh ghi RCREG (địa chỉ 1Ah): chứa dữ liệu nhận đƣợc.
- Thanh ghi TXSTA (địa chỉ 98h): chứa các bit điều khiển SYNC và BRGH.
- Thanh ghi SPBRG (địa chỉ 99h): điều khiển tốc độ baud.
5.1.1.2 USART ĐỒNG BỘ
Giao diện USART đồng bộ đƣợc kích hoạt bằng cách set bit SYNC. Cổng giao
tiếp nối tiếp vẫn là hai chân RC7/RX/DT, RC6/TX/CK và đƣợc cho phép bằng cách set
bit SPEN. USART cho phép hai chế độ truyền nhận dữ liệu là Master mode và Slave
mode. Master mode đƣợc kích hoạt bằng cách set bit CSRC (TXSTA<7>), Slave mode
đƣợc kích hoạt bằng cách clear bit CSRC. Điểm khác biệt duy nhất giữa hai chế độ này là
Master mode sẽ lấy xung clock đồng bộ từ bộ tao xung baud BRG còn Slave mode lấy
xung clock đồng bộ từ bên ngoài qua chân RC6/TX/CK. Điều này cho phép Slave mode
hoạt động ngay cả khi vi điều khiển đang ở chế độ sleep.
 TRUYỀN DỮ LIỆU QUA CHUẨN GIAO TIẾP USART ĐỒNG BỘ
MASTER MODE
Tƣơng tự nhƣ giao diện USART bất đồng bộ, thành phần quan trọng nhất của khối
truyền dữ liệu là thanh ghi dịch TSR (Transmit Shift Register). Thanh ghi này chỉ đƣợc
điều khiển bởi CPU. Dữ liệu đƣa vào thanh ghi TSR đƣợc chứa trong thanh ghi TXREG.
Cờ hiệu của khối truyền dữ liệu là bit TXIF (chỉ thị trang thái thanh ghi TXREG), cờ hiệu
này đƣợc gắn với một ngắt và bit điều khiển ngắt này là TXIE. Cờ hiệu chỉ thị trạng thái
thanh ghi TSR là bit TRMT. Bit TXEN cho phép hay không cho phép truyền dữ liệu.
Các bƣớc cần tiến hành khi truyền dữ liệu qua giao diện USART đồng bộ Master mode:

ĐƢỜNG KHÁNH SƠN Trang 76


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

1. Tạo xung truyền baud bằng cách đƣa các giá trị cần thiết vào thanh ghi RSBRG
và bit điều khiển mức tốc độ baud BRGH.
2. Cho phép cổng giao diện nối tiếp nối tiếp đồng bộ bằng cách set bit SYNC,
PSEN và CSRC.
3. Set bit TXIE nếu cần sử dụng ngắt truyền.
4. Set bit TX9 nếu định dạng dữ liệu cần truyền là 9 bit.
5. Set bit TXEN để cho phép truyền dữ liệu.
6. Nếu định dạng dữ liệu là 9 bit, đƣa bit dữ liệu thứ 9 vào bit TX9D.
7. Đƣa 8 bit dữ liệu cần truyền vào thanh ghi TXREG.
8. Nếu sử dụng ngắt truyền, cần kiểm tra lại các bit GIE và PEIE (thanh ghi
INTCON).
Các thanh ghi liên quan đến quá trình truyền dữ liệu bằng giao diện USART đồng bộ
Master mode:
- Thanh ghi INTCON (địa chỉ 0Bh, 8Bh, 10Bh, 18Bh): cho phép tất cả các ngắt.
- Thanh ghi PIR1 (địa chỉ 0Ch): chứa cờ hiệu TXIF.
- Thanh ghi PIE1 (địa chỉ 8Ch): chứa bit cho phép ngắt truyền TXIE.
- Thanh ghi RCSTA (địa chỉ 18h): chứa bit cho phép cổng truyền dữ liệu (hai pin
RC6/TX/CK và RC7/RX/DT).
- Thanh ghi TXREG (địa chỉ 19h): thanh ghi chứa dữ liệu cần truyền.
- Thanh ghi TXSTA (địa chỉ 98h): xác lập các thông số cho giao diện.
- Thanh ghi SPBRG (địa chỉ 99h): quyết định tốc độ baud.
 NHẬN DỮ LIỆU QUA CHUẨN GIAO TIẾP USART ĐỒNG BỘ
MASTER MODE
Cấu trúc khối truyền dữ liệu là không đổi so với giao diện bất đồng bộ, kể cả các
cờ hiệu, ngắt nhận và các thao tác trên các thành phần đó. Điểm khác biệt duy nhất là
giao diện này cho phép hai chế độ nhận dữ liệu, đó là chỉ nhận 1 word dữ liệu (set bit
SCEN) hay nhận một chuỗi dữ liệu (set bit CREN) cho tới khi ta clear bit CREN. Nếu cả
hai bit đều đƣợc set, bit điều khiển CREN sẽ đƣợc ƣu tiên.
Các bƣớc cần tiến hành khi nhận dữ liệu bằng giao diện USART đồng bộ Master mode:
1. Thiết lập tốc độ baud (đƣa giá trị thích hợp vào thanh ghi SPBRG và bit
BRGH).

ĐƢỜNG KHÁNH SƠN Trang 77


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

2. Cho phép cổng giao tiếp USART bất đồng bộ (set bit SYNC, SPEN và CSRC).
3. Clear bit CREN và SREN.
4. Nếu cần sử dụng ngắt nhận dữ liệu, set bit RCIE.
5. Nếu dữ liệu truyền nhận có định dạng là 9 bit, set bit RX9.
6. Nếu chỉ nhận 1 word dữ liệu, set bit SREN, nếu nhận 1 chuỗi word dữ liệu, set
bit CREN.
7. Sau khi dữ liệu đƣợc nhận, bit RCIF sẽ đƣợc set và ngắt đƣợc kích hoạt (nếu
bit
RCIE đƣợc set).
8. Đọc giá trị thanh ghi RCSTA để đọc bit dữ liệu thứ 9 và kiểm tra xem quá trình
nhận dữ liệu có bị lỗi không.
9. Đọc 8 bit dữ liệu từ thanh ghi RCREG.
10. Nếu quá trình truyền nhận có lỗi xảy ra, xóa lỗi bằng cách xóa bit CREN.
11. Nếu sử dụng ngắt nhận cần set bit GIE và PEIE (thanh ghi INTCON).
Các thanh ghi liên quan đến quá trình nhận dữ liệu bằng giao diện USART đồng
bộ Master mode:
- Thanh ghi INTCON (địa chỉ 0Bh, 8Bh, 10Bh, 18Bh): chứa các bit cho phép toàn
bộ các ngắt (bit GIER và PEIE).
- Thanh ghi PIR1 (địa chỉ 0Ch): chứa cờ hiệu RCIE.
- Thanh ghi PIE1 (địa chỉ 8Ch): chứa bit cho phép ngắt RCIE.
- Thanh ghi RCSTA (địa chỉ 18h): xác định các trang thái trong quá trình nhận dữ
liệu.
- Thanh ghi RCREG (địa chỉ 1Ah): chứa dữ liệu nhận đƣợc.
- Thanh ghi TXSTA (địa chỉ 98h): chứa các bit điều khiển SYNC và BRGH. T
- Thanh ghi SPBRG (địa chỉ 99h): điều khiển tốc độ baud.
 TRUYỀN DỮ LIỆU QUA CHUẨN GIAO TIẾP USART ĐỒNG BỘ
SLAVE MODE
Quá trình này không có sự khác biệt so với Master mode khi vi điều khiển hoạt
động ở chế độ bình thƣờng. Tuy nhiên khi vi điều khiển đang ở trạng thái sleep, sự khác
biệt đƣợc thể hiện rõ ràng. Nếu có hai word dữ liệu đƣợc đƣa vào thanh ghi TXREG
trƣớc khi lệnh sleep đƣợc thực thi thì quá trình sau sẽ xảy ra:

ĐƢỜNG KHÁNH SƠN Trang 78


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

1. Word dữ liệu đầu tiên sẽ ngay lập tức đƣợc đƣa vào thanh ghi TSR để truyền
đi.
2. Word dữ liệu thứ hai vẫn nằm trong thanh ghi TXREG.
3. Cờ hiệu TXIF sẽ không đƣợc set.
4. Sau khi word dữ liệu đầu tiên đã dịch ra khỏi thanh ghi TSR, thanh ghi
TXREG
tiếp tục truyền word thứ hai vào thanh ghi TSR và cờ hiệu TXIF đƣợc set.
5. Nếu ngắt truyền đƣợc cho phép hoạt động, ngắtnày sẽ đánh thức vi điều khiển
và nếu toàn bộ các ngắt đƣợccho phép hoạt động, bộ đếm chƣơng trình sẽ chỉ tới
địa chỉ chứa chƣơng trình ngắt (0004h).
Các bƣớc cần tiến hành khi truyền dữ liệu bằng giao diện USART đồng bộ Slave mode:
1. Set bit SYNC, SPEN và clear bit CSRC.
2. Clear bit CREN và SREN.
3. Nếu cần sử dụng ngắt, set bit TXIE.
4. Nếu định dạng dữ liệu là 9 bit, set bit TX9.
5. Set bit TXEN.
6. Đƣa bit dữ liệu thứ 9 vào bit TX9D trƣớc (nếu định dạng dữ liệu là 9 bit).
7. Đƣa 8 bit dữ liệu vào thanh ghi TXREG.
8. Nếu ngắt truyền đƣợc sử dụng, set bit GIE và PEIE (thanh ghi INTCON).
Các thanh ghi liên quan đến quá trình truyền dữ liệu bằng giao diện USART đồng bộ
Slave mode:
- Thanh ghi INTCON (địa chỉ 0Bh, 8Bh, 10Bh, 18Bh): cho phép tất cả các ngắt.
- Thanh ghi PIR1 (địa chỉ 0Ch): chứa cờ hiệu TXIF.
- Thanh ghi PIE1 (địa chỉ 8Ch): chứa bit cho phép ngắt truyền TXIE.
- Thanh ghi RCSTA (địa chỉ 18h): chứa bit cho phép cổng truyền dữ liệu (hai pin
RC6/TX/CK và RC7/RX/DT).
- Thanh ghi TXREG (địa chỉ 19h): thanh ghi chứa dữ liệu cần truyền.
- Thanh ghi TXSTA (địa chỉ 98h): xác lập các thông số cho giao diện.
- Thanh ghi SPBRG (địa chỉ 99h): quyết định tốc độ baud.
 NHẬN DỮ LIỆU QUA CHUẨN GIAO TIẾP USART ĐỒNG BỘ SLAVE
MODE

ĐƢỜNG KHÁNH SƠN Trang 79


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Sự khác biệt của Slave mode so với Master mode chỉ thể hiện rõ ràng khi vi điều
khiển hoạt động ở chế độ sleep. Ngoài ra chế độ Slave mode không quan tâm tới bit
SREN.
Khi bit CREN (cho phép nhận chuỗi dữ liệu) đƣợc set trƣớc khi lệnh sleep đƣợc thực thi,
1 word dữ liệu vẫn đƣợc tiếp tục nhận, sau khi nhận xong bit thanh ghi RSR sẽ chuyển
dữ liệu vào thanh ghi RCREG và bit RCIF đƣợc set. Nếu bit RCIE (cho phép ngắt nhận)
đã đƣợc set trƣớc đó, ngắt sẽ đƣợc thực thi và vi điều khiển đƣợc “đánh thức, bộ đếm
chƣơng trình sẽ chỉ đến địa chỉ 0004h và chƣơng trình ngắt sẽ đƣợc thực thi.
Các bƣớc cần tiến hành khi nhận dữ liệu bằng giao diện USART đồng bộ Slave mode:
1. Cho phép cổng giao tiếp USART bất đồng bộ (set bit SYNC, SPEN clear bit
CSRC).
2. Nếu cần sử dụng ngắt nhận dữ liệu, set bit RCIE.
3. Nếu dữ liệu truyền nhận có định dạng là 9 bit, set bit RX9.
4. Set bit CREN để cho phép quá trình nhận dữ liệu bắt đầu.
5. Sau khi dữ liệu đƣợc nhận, bit RCIF sẽ đƣợc set và ngắt đƣợc kích hoạt (nếu
bit
RCIE đƣợc set).
6. Đọc giá trị thanh ghi RCSTA để đọc bit dữ liệu thứ 9 và kiểm tra xem quá trình
nhận dữ liệu có bị lỗi không.
7. Đọc 8 bit dữ liệu từ thanh ghi RCREG.
8. Nếu quá trình truyền nhận có lỗi xảy ra, xóa lỗi bằng cách xóa bit CREN.
9. Nếu sử dụng ngắt nhận cần set bit GIE và PEIE (thanh ghi INTCON).
Các thanh ghi liên quan đến quá trình nhận dữ liệu bằng giao diện USART đồng bộ Slave
mode:
- Thanh ghi INTCON (địa chỉ 0Bh, 8Bh, 10Bh, 18Bh): chứa các bit cho phép toàn
bộ các ngắt (bit GIER và PEIE).
- Thanh ghi PIR1 (địa chỉ 0Ch): chứa cờ hiệu RCIE.
- Thanh ghi PIE1 (địa chỉ 8Ch): chứa bit cho phép ngắt RCIE.
- Thanh ghi RCSTA (địa chỉ 18h): xác định các trang thái trong quá trình nhận dữ
liệu.
- Thanh ghi RCREG (địa chỉ 1Ah): chứa dữ liệu nhận đƣợc.

ĐƢỜNG KHÁNH SƠN Trang 80


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

- Thanh ghi TXSTA (địa chỉ 98h): chứa các bit điều khiển SYNC và BRGH.
- Thanh ghi SPBRG (địa chỉ 99h): điều khiển tốc độ baud.
5.2 MSSP
MSSP ( Master Synchronous Serial Port) là giao diện đồng bộ nối tiếp dùng để
giao tiếp với các thiết bị ngoại vi (EEPROM, ghi dịch, chuyển đổi ADC,…) hay các vi
điều khiển khác. MSSP có thể hoạt động dƣới hai dạng giao tiếp:
- SPI (Serial Pheripheral Interface).
- I2C (Inter-Intergrated Circuit).
Các thanh ghi điều khiển giao chuẩn giao tiếp này bao gồm thanh ghi trạng thái
SSPSTAT và hai thanh ghi điều khiển SSPSON và SSPSON2. Tùy theo chuẩn giao tiếp
đƣợc sử dụng (SPI hay I2C) mà chức năng các thanh ghi này đƣợc thể hiện khác nhau.

ĐƢỜNG KHÁNH SƠN Trang 81


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Hình 5.3: Sơ đồ khối MSSP (giao diện SPI)

5.2.1. SPI
Chuẩn giao tiếp SPI cho phép truyền nhận đồng bộ. Ta cần sử dụng 4 pin cho
chuẩn giao tiếp này:
 RC5/SDO: ngõ ra dữ liệu dạng nối tiếp (Serial Data output).
 RC4/SDI/SDA: ngõ vào dữ liệu dạng nối tiếp (Serial Data Input).
 RC3/SCK/SCL: xung đồng bộ nối tiếp (Serial Clock).
 RA5/AN4/SS/C2OUT: chọn đối tƣợng giao tiếp (Serial Select) khi giao tiếp ở
chế độ Slave mode.
Các thanh ghi liên quan đến MSSP khi hoạt động ở chuẩn giao tiếp SPI bao gồm:

ĐƢỜNG KHÁNH SƠN Trang 82


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

- Thanh ghi điều khiển SSPCON, thanh ghi này cho phép đọc và ghi.
- Thanh ghi trạng thái SSPSTAT, thanh ghi này chỉ cho phép đọc và ghi ở 2 bit trên,
6 bit còn lại chỉ cho phép đọc.
- Thanh ghi đóng vai trò là buffer truyền nhận SSPBUF, dữ liệu truyền đi hoặc nhận
đƣợc sẽ đƣợc đƣa vào tranh ghi này. SSPBUFkhông có cấu trúc đệm hai lớp
(doubled buffer), do đó dữ liệu ghi vào thanh ghi SSPBUF sẽ lập tức đƣợc ghi vào
thanh ghi SSPSR.
- Thanh ghi dịch dữ liệu SSPSR dùng để dịch dữ liệu vào hoặc ra. Khi 1 byte dữ
liệu đƣợc nhận hoàn chỉnh, dữ liệu sẽ từ thanh ghiSSPSR chuyển qua thanh ghi
SSPBUF và cờ hiệu đƣợc set, đồng thời ngắt sẽ xảy ra.
Khi sử dụng chuẩn giao tiếp SPI trƣớc tiên ta cần thiết lập các chế độ cho giao diện bằng
cách đƣa các giá trị thích hợp vào hai thanh ghi SSPCON và SSPSTAT. Các thông số
cần thiết lập bao gồm:
- Master mode hay Slave mode. Đối với Master mode, xung clock đồng bộ sẽ đi ra
từ chân RC3/SCK/SCL. Đối với Slave mode, xung clock đồng bộ sẽ đƣợc nhận
từ bên ngoài qua chân RC3/SCK/SCL.
- Các chế độ của Slave mode. Mức logic của xung clock khi ở trạng thái tạm ngƣng
quá trình truyền nhận (Idle).Cạnh tác động của xung clock đồng bộ (cạnh lên hay
cạnh xuống).
- Tốc độ xung clock (khi hoạt động ở Master mode). Thời điểm xác định mức logic
của dữ liệu (ở giữa hay ở cuối thời gian 1 bit dữ liệu đƣợc đƣa vào).
Master mode, Slave mode và các chế độ của Slave mode đƣợc điều khiển bởi các bit
SSPM3:SSPM0 (SSPCON<3:0>). MSSP bao gồm một thanh ghi dịch dữ liệu SSPSR và
thanh ghi đệm dữ liệu SSPBUF. Hai thanh ghi này tạo thành bộ đệm dữ liệu kép
(doubled-buffer). Dữ liệu sẽ đƣợc dịch vào hoặc ra qua thanh ghi SSPSR, bit MSB đƣợc
dịch trƣớc. Đây là một trong những điểm khác biệt giữ hai giao diện MSSP và USART
(USART dịch bit LSB trƣớc).
Trong quá trình nhận dữ liệu, khi dữ liệu đƣa vào từ chân RC4/SDI/SDA trong thanh
ghi SSPSR đã sẵn sàng (đã nhận đủ 8 bit), dữ liệu sẽ đƣợc đƣa vào thanh ghi SSPBUF,
bit chỉ thị trạng thái bộ đệm BF (SSPSTAT<0>) sẽ đƣợc set để báo hiệu bộ đệm đã đầy,
đồng thời cờ ngắt SSPIF (PIR1<3>) cũng đƣợc set. Bit BF sẽ tự động reset về 0 khi dữ

ĐƢỜNG KHÁNH SƠN Trang 83


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

liệu trong thanh ghi SSPBUF đƣợc đọc vào. Bộ đệm kép cho phép đọc tiếp byte tiếp theo
trƣớc khi byte dữ liệu trƣớc đó đƣợc đọc vào. Tuy nhiên ta nên đọc trƣớc dữ liệu từ thanh
ghi SSPBUF trƣớc khi nhận byte dữ liệu tiếp theo.
Quá trình truyền dữ liệu cũng hoàn toàn tƣơng tự nhƣng ngƣợc lại. Dữ liệu cần
truyền sẽ đƣợc đƣa vào thanh ghi SSPBUF đồng thời đƣa vào thanh ghi SSPSR, khi đó
cờ hiệu BF đƣợc set. Dữ liệu đƣợc dịch từ thanh ghi SSPSR và đƣa ra ngoài qua chân
RC5/SDO. Ngắt sẽ xảy ra khi quá trình dịch dữ liệu hoàn tất. Tuy nhiên dữ liệu trƣớc khi
đƣợc đƣa ra ngoài phải đƣợc cho phép bởi tín hiệu từ chân RA5 / AN 4 / SS / C 2OUT .
Chân này đóng vai trò chọn đối tƣợng giao tiếp khi SPI ở chế độ Slave mode.
Khi quá trình truyền nhận dữ liệu đang diễn ra, ta không đƣợc phép ghi dữ liệu vào
thanh ghi SSPBUF. Thao tác ghi dữ liệu này sẽ set bit WCON (SSPCON<7>). Một điều
cần chú ý nữa là thanh ghi SSPSR không cho phép truy xuất trực tiếp mà phải thông qua
thanh ghi SSPBUF.
Cổng giao tiếp của giao diện SPI đƣợc điều khiển bởi bit SSPEN (SSPSON<5>).
Bên cạnh đó cần điều khiển chiều xuất nhập của PORTC thông qua thanh ghi TRISC sao
cho phù hợp với chiều của giao diện SPI. Cụ thể nhƣ sau:
- RC4/SDI/SDA sẽ tự động đƣợc điều khiển bởi khối giao itếp SPI. RS5/SDO là
ngõ ra dữ liệu, do đó cần clear bit TRISC<5>. Khi SPI ở dạng Master mode, cần
clear bit TRISC<3> để cho phép đƣa xung clock đồng bộ ra chân RC3/SCK/SCL.
- Khi SPI ở dạng Slave mode, cần set bit TRISC<3> để cho phép nhận xung clock
đồng bộ từ bên ngoài qua chân RC3/SCK/SCL.
- Set bit TRISC<4> để cho phép chân RA5 / AN 4 / SS / C 2OUT nhận tín hiệu điều
khiển truy xuất dữ liệu khi SPI ở chế độ Slave mode.
Sơ đồ kết nối của chuẩn giao tiếp SPI nhƣ sau:

ĐƢỜNG KHÁNH SƠN Trang 84


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Hình 5.4: Sơ đồ khối của chuẩn giao tiếp SPI

Theo sơ đồ kết nối này, khối Master sẽ bắt đầu quá trình truyền nhận dữ liệu bằng
cách gửi tín hiệu xung đồng bộ SCK. Dữ liệu sẽ dịch từ cả hai thanh ghi SSPSR đƣa ra
ngoài nếu có một cạnh của xung đồng bộ tác động và ngƣng dịch khi có tác động của
cạnh còn lại.
Cả hai khối Master và Slave nên đƣợc ấn định chung các qui tắc tác động của xung clock
đồng bộ để dữ liệu có thể dịch chuyển đồng thời.
 SPI MASTER MODE.
Ở chế độ Master mode, vi điều khiển có quyền ấn định thời điểm trao đổi dữ liệu
(và đối tƣợng trao đổi dữ liệu nếu cần) vì nó điều khiển xung clock đồng bộ. Dữ liệu sẽ
đƣợc truyền nhận ngay thời điểm dữ liệu đƣợc đƣa vào thanh ghi SSPBUF. Nếu chỉ cần
nhận dữ liệu, ta có thể ấn định chân SDO là ngõ vào (set bit TRISC<5>). Dữ liệu sẽ đƣợc
dịch vào thanh ghi SSPSR theo một tốc độ đƣợc định sẵn cho xung clock đồng bộ. Sau
khi nhận đƣợc một byte dữ liệu hoàn chỉnh, byte dữ liệu sẽ đƣợc đƣa dào thanh ghi
SSPBUF, bit BF đƣợc set và ngắt xảy ra.
Khi lệnh SLEEP đƣợc thực thi trong quá trình truyền nhận, trạng thái của quá
trình sẽ đƣợc giữ nguyên và tiếp tục sau khi vi điều khiển đƣợc đánh thức.
Giản đồ xung của Master mode và các tác động của các bit điều khiển đƣợc trình
bày trong hình vẽ sau:

ĐƢỜNG KHÁNH SƠN Trang 85


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Hình 5.5: Giản đồ xung SPI ở chế độ Master mode

 SPI SLAVE MODE


Ở chế độ này SPI sẽ truyền và nhận dữ liệu khi có xung đồng bộ xuất hiện ở chân
SCK. Khi truyền nhận xong bit dữ liệu cuối cùng, cờ ngắt SSPIF sẽ đƣợc set. Slave mode
hoạt động ngay cả khi vi điều khiển đang ở chế độ sleep, và ngắt truyền nhận cho phép
“đánh thức” vi điều khiển. Khi chỉ cần nhận dữ liệu, ta có thể ấn định RC5/SDO là ngõ
vào (set bit TRISC<5>).
Slave mode cho phép sự tác động của chân điều khiển RA5 / AN 4 / SS / C 2OUT
(SSPCON<3:0> = 0100). Khi chân RA5 / AN 4 / SS / C 2OUT ở mức thấp, chân RC5/SDO
đƣợc cho phép xuất dữ liệu và khi RA5 / AN 4 / SS / C 2OUT ở mức cao, dữ liệu ra ở chân
RC5/SDO bị khóa, đồng thời SPI đƣợc reset (bộ đếm bit dữ liệu đƣợc gán giá trị 0).

ĐƢỜNG KHÁNH SƠN Trang 86


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Hình 5.6: Giản đồ xung SPI ở chế độ Slave mode

Các thanh ghi liên quan đến chuẩn giao tiếp SPI bao gồm:
- Thanh ghi INTCON (địa chỉ 0Bh, 8Bh, 10Bh, 18Bh): chứa bit cho phép toàn bộ
các ngắt (GIE và PEIE).
- Thanh ghi PIR1 (địa chỉ 0Ch): chứa ngắt SSPIE.
- Thanh ghi PIE1 (địa chỉ 8Ch): chứa bit cho phép ngắt SSPIE.
- Thanh ghi TRISC (địa chỉ 87h): điều khiển xuất nhập PORTC.
- Thanh ghi SSPBUF (địa chỉ 13h): thanh ghi đệm dữ liệu.
- Thanh ghi SSPCON (địa chỉ 14h): điều khiển chuẩn giao tiếp SPI.
- Thanh ghi SSPSTAT (địa chỉ 94h): chứa các bit chỉ thị trạng thái chuẩn giao tiếp
SPI.
- Thanh ghi TRISA (địa chỉ 85h):điều khiển xuất nhập chân
RA5 / AN 4 / SS / C 2OUT .
5.2.2.I2C
Đây là một dạng khác của MSSP. Chuẩn giao tiếp I2C cũng có hai chế độ

ĐƢỜNG KHÁNH SƠN Trang 87


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Master, slave và cũng đƣợc kết nối với ngắt.


I2C sẽ sử dụng 2 pin để truyền nhận dữ liệu:
- RC3/SCK/SCL: chân truyền dẫn xung clock.
- RC4/SDI/SDA: chân truyền dẫn dữ liệu.
Các khối cơ bản trong sơ đồ khối của I2C không có nhiều khác biệt so với SPI.
Tuy nhiên I2C còn có thêm khối phát hiện bit Start và bit Stop của dữ liệu (Start
and Stop bit detect) và khối xác định địa chỉ (Match detect).
Các thanh ghi liên quan đến I2C bao gồm:
- Thanh ghi SSPCON và SSPCON2: điều khiển MSSP.
- Thanh ghi SSPSTAT: thanh ghi chứa các trạng thái hoạt động của MSSP.
- Thanh ghi SSPBUF: buffer truyền nhận nối tiếp.
- Thanh ghi SSPSR: thanh ghi dịch dùng để truyền nhận dữ liệu.
- Thanh ghi SSPADD: thanh ghi chứa địa chỉ của giao diện MSSP.
Các thanh ghi SSPCON, SSPCON2 cho phép đọc và ghi. Thanh ghi SSPSTAT chỉ
cho phép đọc và ghi ở 2 bit đầu, 6 bit còn lại chỉ cho phép đọc.
Thanh ghi SSPBUF chứa dữ liệu sẽ đƣợc truyền đi hoặc nhận đƣợc và đóng vai
trò nhƣ một thanh ghi đệm cho thanh ghi dịch dữ liệu SSPSR.
Thanh ghi SSPADD chứa địa chỉ của thiết bị ngoại vi cần truy xuất dữ liệu của
I2C khi hoạt động ở Slave mode. Khi hoạt động ở Master mode, thanh ghi SSPADD
chứa giá trị tạo ra tốc độ baud cho xung clock dùng để truyền nhận dữ liệu.
Trong quá trình nhận dữ liệu, sau khi nhận đƣợc 1 byte dữ liệu hoàn chỉnh, thanh
ghi SSPSR sẽ chuyển dữ liệu vào thanh ghi SSPBUF. Thanh ghi SSPSR không đọc và
ghi đƣợc, quá trình truy xuất thanh ghi này phải thông qua thanh ghi SSPBUF.
Trong quá trình truyền dữ liệu, dữ liệu cần truyền khi đƣợc đƣa vào thanh ghi SSPBUF
cũng sẽ đồng thời đƣa vào thanh ghi SSPSR.
I2C có nhiều chế độ hoạt động và đƣợc điều khiển bởi các bit SSPCON<3:0>, bao
gồm:
- I2C Master mode, xung clock = fosc/4*(SSPADD+1).
- I2C Slave mode, 7 bit địa chỉ. I2C Slave mode, 10 bit địa chỉ. I2C Slvae mode,
7 bit địa chỉ, cho phép ngắ tkhi phát hiện bit Start và bit Stop.
- I2C Slave mode, 10 bit địa chỉ, cho phép ngắt khi phát hiện bit Start và bit Stop.

ĐƢỜNG KHÁNH SƠN Trang 88


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

- I2C Firmware Control Master mode.


Địa chỉ truyền đi sẽ bao gồm các bit địa chỉ và một bit R / W để xác định thao tác
(đọc hay ghi dữ liệu) với đối tƣợng cần truy xuất dữ liệu.
Khi lựa chọn giao diện I2C và khi set bit SSPEN, các pin SCL và SDA sẽ ở trạng
thái cực thu hở. Do đó trong trƣờng hợp cần thiết ta phải sử dụng điện trở kéo lên ở bên
ngoài vi điều khiển, bên cạnh đó cần ấn định các giá trị phù hợp cho các bit TRISC<4:3>
(bit điều khiển xuất nhập các chân SCL và SDA).

Hình 5.7: Sơ đồ khối MSSP (I2C Slave mode)

 I2C SLAVE MODE


Việc trƣớc tiên là phải set các pin SCL và SDA là input (set bit TRISC<4:3>). I2C
của vi điều khiển sẽ đƣợc điều khiển bởi một vi điều khiển hoặc một thiết bị ngoại vi
khác thông qua các địa chỉ. Khi địa chỉ này chỉ đến vi điều khiển, thì tại thời điểm này và
tại thời điểm dữ liệu đã đƣợc truyền nhận xong sau đó, vi điều khiển sẽ tạo ra xung ACK
để báo hiệu kết thúc dữ liệu, giá trị trong thanh ghi SSPSR sẽ đƣợc đƣa vào thanh ghi
SSPBUF. Tuy nhiên xung ACK sẽ không đƣợc tạo ra nếu một trong các trƣờng hợp sau
xảy ra:

ĐƢỜNG KHÁNH SƠN Trang 89


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Bit BF (SSPSTAT<0>) báo hiệu buffer đầy đã đƣợc set trƣớc khi quá trình truyền
nhận xảy ra.
Bit SSPOV (SSPCON<6>) đƣợc set trƣớc khi quá trình truyền nhận xảy ra
(SSPOV đƣợc set trong trƣờng hợp khi một byte khác đƣợcnhận vào trong khi dữ liệu
trong thanh ghi SSPBUF trƣớc đó vẫn chƣa đƣợc lấy ra).
Trong các trƣờng hợp trên, thanh ghi SSPSR sẽ không đƣa giá trị vào thanh ghi SSPBUF,
nhƣng bit SSPIF (PIR1<3>)sẽ đƣợc set. Để quátrình truyền nhận dữ liệu đƣợc tiếp tục,
cần đọc dữ liệu từ thanh ghi SSPBUF vào trƣớc, khi đó bit BF sẽ tự động đƣợc xóa, còn
bit SSPOV phải đƣợc xóa bằng chƣơng trình.
Khi MSSP đƣợc kích hoạt, nó sẽ chờ tín hiệu để bắt đầu hoạt động. Sau khi nhận
đƣợc tín hiệu bắt đầu hoạt động (cạnh xuống đầu tiên của pin SDA), dữ liệu 8 bit sẽ đƣợc
dịch vào thanh ghi SSPSR. Các bit đƣa vào sẽ đƣợc lấy mẫu tại cạnh lên của xung clock.
Giá trị nhận đƣợc từ thanh ghi SSPSR sẽ đƣợc so sánh với giá trị trong thanh ghi
SSPADD tại cạnh xuống của xung clock thứ 8. Nếu kết quả so sánh bằng nhau, tức là
I2C Master chỉ định đối tƣợng giao tiếp là vi điều khiển đang ở chế độ Slave mode (ta gọi
hiện tƣợng này là address match), bit BF và SSPOV sẽ đƣợc xóa về 0 và gây ra các tác
động sau:
- Giá trị trong thanh ghi SSPSR đƣợc đƣa vào thanh ghi SSPBUF.
- Bit BF tự động đƣợc set.
- Một xung ACK đƣợc tạo ra.
- Cờ ngắt SSPIF đƣợc set (ngắt đƣợc kích hoạt nếu đƣợc cho phép trƣớc đó) tại
cạnh xuống của xung clock thứ 9.
Khi MSSP ở chế độ I2C Slave mode 10 bit địa chỉ, vi điều khiển cần phải nhận vào
10 bit địa chỉ để so sánh. Bit R / W (SSPSTAT<2>) phải đƣợc xóa về 0 để cho phép
nhận 2 byte địa chỉ. Byte đầu tiên có định dạng là „11110 A9 A8 0„ trong đó A9, A8 là
hai bit MSB của 10 bit địa chỉ. Byte thứ 2 là 8 bit địa chỉ còn lại.
Quá trình nhận dạng địa chỉ của MSSP ở chế độ I2C Slave mode 10 bit địa chỉ
nhƣ sau:
1. Đầu tiên 2 bit MSB của 10 bit địa chỉ đƣợc nhận trƣớc, bit SSPIF, BF và UA
(SSPSTAT<1>) đƣợc set (byte địa chỉ đầu tiên có định dạng là „11110 A9 A8 0‟) .
2. Cập nhật vào 8 bit địa chỉ thấp của thanh ghi SSPADD, bit UA sẽ đƣợc xóa bởi

ĐƢỜNG KHÁNH SƠN Trang 90


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

vi điều khiển để khởi tạo xung clock ở pin SCL sau khi quá trình cập nhật hoàn
tất.
3. Đọc giá trị thanh ghi SSPBUF (bit BF sẽ đƣợc xóa về 0) và xóa cờ ngắt SSPIF.
4. Nhận 8 bit địa chỉ cao, bit SSPIF, BF và UA đƣợc set.
5. Cập nhật 8 bit địa chỉ đã nhận đƣợc vào 8 bit địa chỉ cao của thanh ghi
SSPADD, nếu địa chỉ nhận đƣợc là đúng (address match), xung clock ở chân SCL
đƣợc khởi tạo và bit UA đƣợc set.
6. Đọc giá trị thanh ghi SSPBUF (bit BF sẽ đƣợc xóa về 0) và xóa cờ ngắt SSPIF.
7. Nhận tín hiệu Start.
8. Nhận byte địa chỉ cao (bit SSPIF và BF đƣợc set).
9. Đọc giá trị thanh ghi SSPBUF (bit BF đƣợc xóa về 0) và xóa cờ ngắt SSPIF.
Trong đó các bƣơc 7,8,9 xảy ra trong quá trình truyền dữ liệu ở chế độ Slave
mode.
Xem giản đồ xung của I2C để có đƣợc hình ảnh cụ thể hơn về các bƣớc tiến hành
trong quá trình nhận dạng địa chỉ.
Xét quá trình nhận dữ liệu ở chế độ Slave mode, các bit địa chỉ sẽ đƣợc I2C
Master đƣa vào trƣớc. Khi bit R / W trong các bit địa chỉ có giá trị bằng 0 (bit này đƣợc
nhận dạng sau khi các bit địa chỉ đã đƣợc nhận xong) và địa chỉ đƣợc chỉ định đúng
(address match), bit R / W của thanh ghi SSPSTAT đƣợc xóa về 0 và đƣờng dữ liệu SDI
đƣợc đƣa về mức logic thấp (xung ACK ). Khi bit SEN (SSPCON<0>) đƣợc set, sau khi
1 byte dữ liệu đƣợc nhận, xung clock từ chân RC3/SCK/SCL sẽ đƣợc đƣa xuống mức
thấp, muốn khởi tạo lại xung clock ta set bit CKP (SSPCON<4>). Điều này sẽ làm cho
hiện tƣợng tràn dữ liệu không xảy ra vì bit SEN cho phép ta điều khiển đƣợc xung clock
dịch dữ liệu thông qua bit CKP (tham khảo giản đồ xung để biết thêm chi tiết). Khi hiện
tƣợng tràn dữ liệu xảy ra, bit BF hoặc bit SSPOV sẽ đƣợc set. Ngắt sẽ xảy ra khi một
byte dữ liệu đƣợc nhận xong, cờ ngắt SSPIF sẽ đƣợc set và phải đƣợc xóa bằng chƣơng
trình.

ĐƢỜNG KHÁNH SƠN Trang 91


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Hình 5.8: Giản đồ xung của I2C Slave mode 7 bit địa chỉ trong quá trình nhận dữ liệu (bit SEN=0)

Hình 5.9: Giản đồ xung của I2C Slave mode 10 bit địa chỉ trong quá trình nhận dữ liệu (bit SEN=0)

ĐƢỜNG KHÁNH SƠN Trang 92


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Hình 5.10: Giản đồ xung của I2C Slave mode 7 bit địa chỉ trong quá trình nhận dữ liệu (bit SEN=1)

Hình 5.11: Giản đồ xung của I2C Slave mode 10 bit địa chỉ trong quá trình nhận dữ liệu (bit SEN=1)

ĐƢỜNG KHÁNH SƠN Trang 93


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Xét quá trình truyền dữ liệu, khi bit R / W trong các bit dữ liệu mang giá trị 1 và
địa chỉ đƣợc chỉ định đúng (address match), bit R / W của thanh ghi SSPSTAT sẽ đƣợc
set. Các bit địa chỉ đƣợc nhận trƣớc và đƣa vào thanh ghi SSPBUF. Sau đó xung ACK
đƣợc tạo ra, xung clock ở chân RC3/SCK/SCL đƣợc đƣa xuống mức thấp bất chấp trạng
thái của bit SEN. Khi đó I2C Master sẽ không đƣợc đƣa xung clock vào I2C Slave cho
đến khi dữ liệu ở thanh ghi SSPSR ở trạng thái wsẵn sảng cho quá trình truyền dữ liệu
(dữ liệu đƣa vào thanh ghi SSPBUF sẽ đồng thời đƣợc đƣa vào thanh ghi SSPSR). Tiếp
theo cho phép xung ở pin RC3/SCK/SCL bằng cách set bit CKP (SSPCON<4>). Từng
bit của byte dữ liệu sẽ đƣợc dịch ra ngoài tại mỗi cạnh xuống của xung clock. Nhƣ vậy
dữ liệu sẽ sẵn sàng ở ngõ ra khi xung clock ở mức logic cao, giúp cho I2C Master nhận
đƣợc dữ liệu tại mỗi cạnh lên của xung clock. Nhƣ vậy trong quá trình truyền dữ liệu bit
SEN không đóng vai trò quan trọng nhƣ trong quá trình nhận dữ liệu.
Tại cạnh lên xung clock thứ 9, dữ liệu đã đƣợc dịch hoàn toàn vào I2C Master,
xung ACK sẽ đƣợc tạo ra ở I2C Master, đồng thời pin SDA sẽ đƣợc giữ ở mức logic cao.
Trong trƣờng hợp xung ACK đƣợc chốt bởi I2C Slave, thanh ghi SSPSTAT sẽ đƣợc
reset. I2C Slave sẽ chờ tín hiệu của bit Start để tiếp tục truyền byte dữ liệu tiếp theo (đƣa
byte dữ liệu tiếp theo vào thanh ghi SSPBUF và set bit CKP.
Ngắt MSSP xảy ra khi một byte dữ liệu kết thúc quá trình truyền, bit SSPIF đƣợc
set tại cạnh xuống của xung clock thứ 9 và phải đƣợc xóa bằng chƣơng trình để đảm bảo
sẽ đƣợc set khi byte dữ liệu tiếp theo truyền xong.

ĐƢỜNG KHÁNH SƠN Trang 94


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Hình 5.12: Giản đồ xung của I2C Slave mode 7 bit địa chỉ trong quá trình truyền dữ liệu

Hình 5.13: Giản đồ xung của I2C Slave mode 10 bit địa chỉ trong quá trình truyền dữ liệu

Quá trình truyền nhận các bit địa chỉ cho phép I2C Master chọn lựa đối tƣợng I2C
Slave cần truy xuất dữ liệu. Bên cạnh đó I2C còn cung cấp thêm một địa chỉ GCA
(General Call Address) cho phép chọn tất cả các I2C Slave. Đây là một trong 8 địa chỉ
đặc biệt của protocol I2C. Địa chỉ này đƣợc định dạng là một chuỗi „0‟ với R / W =0 và
đƣợc cho phép bằng cách set bit GCEN (SSPCON2<7>). Khi đó địa chỉ nhận vào sẽ
đƣợc so sánh với thanh ghi SSPADD và với địa chỉ GCA.
ĐƢỜNG KHÁNH SƠN Trang 95
GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Hình 5.14: Giản đồ xung của I2C Slave khi nhận địa chỉ GCA

Quá trình nhận dạng địa chỉ GCA cũng tƣơng tự nhƣ khi nhận dạng các địa chỉ
khác và không có sự khác biệt rõ ràng khi I2C hoạt động ở chế độ địa chỉ 7 bit hay 10 bit.
 I2C MASTER MODE

Hình 5.15: Sơ đồ khối MSSP ( I2C Master mode)

I2C Master mode đƣợc xác lập bằng cách đƣa các giá trị thích hợp vào các bit
SSPM của thanh ghi SSPCON và set bit SSPEN. Ở chế độ Master, các pin SCK và SDA
sẽ đƣợc điều khiển bởi phần cứng của MSSP.

ĐƢỜNG KHÁNH SƠN Trang 96


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

I2C Master đóng vai trò tích cực trong quá trình giao tiếp và điều khiển các I2C
Slave thông qua việc chủ động tạo ra xung giao tiếp và các điều kiện Start, Stop khi
truyền nhận dữ liệu.
Một byte dữ liệu có thể đƣợc bắt đầu bằng điềukiện Start, kết thúc bằng điều kiện
Stop hoặc bắt đầu và kết thúc với cùng một điều kiện khởi động lặp lại (Repeated Start
Condition).

Hình 5.16: Sơ đồ khối BRG (Baud Rate Benerator) của I2C Master mode

Xung giao tiếp nối tiếp sẽ đƣợc tạo ra từ BRG (Baud Rate Generator), giá trị
ấn định tần số xung clock nối tiếp đƣợc lấy từ 7 bit thấp của thanh ghi SSPADD. Khi
dữ liệu đƣợc đƣa vào thanh ghi SSPBUF, bit BF đƣợc set và BRG tự động đếm ngƣợc
về 0 và dừng lại, pin SCL đƣợc giữ nguyên trạng thái trƣớc đó.Khi dữ liệu tiếp theo
đƣợc đƣa vào, BRG sẽ cần một khoảng thời gian TBRG tự động reset lại giá trị để
tiếp tục quá trình đếm ngƣợc. Mỗi vòng lệnh (có thời gian TCY ) BRG sẽ giảm giá trị
2 lần.
Các giá trị cụ thể của tần số xung nối tiếp do BRG tạo ra đƣợc liệt kê trong bảng
sau:

Trong đó giá trị BRG là giá trị đƣợc lấy từ 7 bit thấp của thanh ghi SSPADD. Do

ĐƢỜNG KHÁNH SƠN Trang 97


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

I2C ở chế độ Master mode, thanh ghi SSPADD sẽ không đƣợcsử dụng để chứa địa chỉ,
thay vào đó chức năng của SSPADD là thanh ghi chứa giá trị của BRG.
Để tạo đƣợc điều kiện Start, trƣớc hết cần đƣa hai pin SCL và SDA lên mức logic
cao và bit SEN (SSPCON2<0>) phải đƣợc set. Khi đó BRG sẽ tự động đọc giá trị 7 bit
thấp của thanh ghi SSPADD và bắt đầu đếm. Sau khoảng thời gian TBRG, pin SDA
đƣợc đƣa xuống mức logic thấp. Trạng thái pin SDA ở mức logic thấp và pin SCL ở mức
logic cao chính là điều kiện Start của I2C Master mode. Khi đó bit S (SSPSTAT<3>) sẽ
đƣợc set. Tiếp theo BRG tiếp tục lấy giá trị từ thanh ghi SSPADD để tiếp tục quá trình
đếm, bit SEN đƣợc tự động xóa và cờ ngắt SSPIF đƣợc set.

Hình 5.17: Giản đồ xung I2C Master mode trong quá trình tạo điều kiện Start

Trong trƣờng hợp pin SCL và SDA ở trạng thái logic thấp, hoặc là trong quá trình
tạo điều kiện Start, pin SCL đƣợc đƣa về trạng thái logic thấp trƣớc khi pin SDA đƣợc
đƣa về trang thái logic thấp, điều kiện Start sẽ không đƣợchình thành, cờ ngắt BCLIF sẽ
đƣợc set và I2C sẽ ở trạng thái tạm ngƣng hoạt động (Idle).
Tín hiệu Stop sẽ đƣợc đƣa ra pin SDA khi kết thức dữ liệu bằng cách set bit PEN
(SSPCON2<2>). Sau cạnh xuống của xung clock thứ 9 và với tác động của bit điều khiển
PEN, pin SDA cũng đƣợc đƣa xuống mức thấp, BRG lại bắt đầu quá trình đếm. Sau một
khoảng thời gian TBRG, pin SCL đƣợc đƣa lên mức logic cao và sau một khoảng thời
gian TBRGnữa pin SDA cũng đƣợc đƣa lên mức cao. Ngay tại thời điểm đó bit P
(SSPSTAT<4>) đƣợc set, nghĩa là điều kiện Stop đã đƣợctạo ra. Sau một khoảng thời
gian TBRG nữa, bit PEN tự động đƣợc xóa và cờ ngắt SSPIF đƣợc set.

ĐƢỜNG KHÁNH SƠN Trang 98


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Hình 5.18: Giản đồ xung I2C Master mode trong quá trình tạo điều kiện Stop

Để tạo đƣợc diều kiện Start lặp lại liên tục trong quá trình truyền dữ liệu, trƣớc hết
cần set bit RSEN (SSPCON2<1>). Sau khi set bit RSEN, pin SCL đƣợc đƣa xuống mức
logic thấp, pin SDA đƣợc đƣa lên mức logic cao, BRG lấy giá trị từ thanh ghi SSPADD
vào để bắt đầu quá trình đếm. Sau khoảng thời gian TBRG, pin SCL cũng đƣợc đƣa lên
mức logic cao trong khoảng thời gian TBRG tiếp theo. Trong khoảng thời gian TBRG kế
tiếp, pin SDA lại đƣợc đƣa xuống mức logic thấp trong khi SCL vẫn đƣợc giữ ở mức
logic cao. Ngay thời điểm đó bit S (SSPSTAT<3>) đƣợc set để báo hiệu điều kiện Start
đƣợc hình thành, bit RSEN tự động đƣợc xóa và cờ ngắt SSPIF sẽ đƣợcset sau một
khoảng thời gian TBRG nữa. Lúc này địa chỉ của I2C Slave có thể đƣợc đƣa vào thanh
ghi SSPBUF, sau đó ta chỉ việc đƣa tiếp địa chỉ hoặc dữ liệu tiếp theo vào thanh ghi
SSPBUF mỗi khi nhận đƣợc tín hiệu ACK từ I2C Slave, I2C Master sẽ tự động tạo tín
hiệu Start lặp lại liên tục cho quá trình truyền dữ liệu liên tục. Cần chú ý là bất cứ một
trình tự nào sai trong quá trình tạo điều kiện Start lặp lại sẽ làm cho bit BCLIF đƣợc set
và I2C đƣợc đƣa về trạng thái “Idle”.

ĐƢỜNG KHÁNH SƠN Trang 99


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Hình 5.19: Giản đồ I2C Master mode trong quá trình tạo điều kiện Start liên tục

Xét quá trình truyền dữ liệu, xung clock sẽ đƣợc đƣa ra từ pin SCL và dữ liệu
đƣợc đƣa ra từ pin SDA. Byte dữ liệu đầu tiên phải là byte địa chỉ xác định I2C Slave cần
giao tiếp và bit R / W (trong trƣờng hợp này R / W = 0). Đầu tiên các giá trị địa chỉ sẽ
đƣợc đƣa vào thanh ghi SSPBUF, bit BF tự động đƣợc set lên 1 và bộ đếm tạo xung
clock nối tiếp BRG (Baud Rate Generator) bắt đầu hoạt động. Khi đó từng bit dữ liệu
(hoặc địa chỉ và bit R / W ) sẽ đƣợc dịch ra ngoài theo từng cạnh xuống của xung clock
sau khi cạnh xuống đầu tiên của pin SCL đƣợc nhận diện (điều kiện Start), BRG bắt đầu
đếm ngƣợc về 0. Khi tất cả các bit của byte dữ liệu đƣợc đã đƣợc đƣa ra ngoài, bộ đếm
BRG mang giá trị 0. Sau đó, tại cạnh xuống của xung clock thứ 8, I2C Master sẽ ngƣng
tác động lên pin SDA để chờ đợi tín hiệu từ I2C Slave (tín hiệu xung ACK ). Tại cạnh
xuống của xung clock thứ 9, I2C Master sẽ lấy mẫu tín hiệu từ pin SDA để kiểm tra xem
địa chỉ đã đƣợc I2C Slave nhận dạng chƣa, trạng thái ACK đƣợc đƣa vào bit ACKSTAT
(SSPCON2<6>). Cũng tại thời điểm cạnh xuống của xung clock thứ 9, bit BF đƣợc tự
động clear, cờ ngắt SSPIF đƣợc set và BRG tạm ngƣng hoạt động cho tới khi dữ liệu
hoặc địa chỉ tiếp theo đƣợc đƣavào thanh ghi SSPBUF, dữ liệu hoặc địa chỉ sẽ tiếp tục
đƣợc truyền đi tại cạnh xuống của xung clock tiếp theo.

ĐƢỜNG KHÁNH SƠN Trang 100


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Hình 5.20: Giản đồ xung I2C Master mode trong quá trình truyền dữ liệu

Xét quá trình nhận dữ liệu ở chế độ I2C Master mode. Trƣớc tiên ta cần set bit cho
phép nhận dữ liệu RCEN (SSPCON2<3>). Khi đó BRG bắt đầu quá trình đếm, dữ liệu sẽ
đƣợc dịch vào I2C Master qua pin SDA tạicạnh xuống của pin SCL. Tại cạnh xuống của
xung clock thứ 8, bit cờ hiệu cho phép nhận RCEN tự động đƣợc xóa, dữ liệu trong thanh
ghi SSPSR đƣợc đƣa vào thanh ghi SSPBUF, cờ hiệu BFđƣợc set, cờ ngắt SSPIF đƣợc
set, BRG ngƣng đếm và pin SCL đƣợc đƣa về mức logic thấp. Khi đó MSSP ở trạng thái
tạm ngƣng hoạt động để chờ đợi lệnh tiếp theo. Sau khi đọcgiá trị thanh ghi SSPBUF, cờ
hiệu BF tự động đƣợc xóa. Ta còn có thể gửi tín hiệu ACK bằng cách set bit ACKEN
(SSPCON2<4>).

ĐƢỜNG KHÁNH SƠN Trang 101


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Hình 5.21: Giản đồ xung I2C Master mode trong quá trình nhận dữ liệu

 CỔNG GIAO TIẾP SONG SONG PSP (PARALLEL SLAVE PORT)


Ngoài các cổng nối tiếp và các giao điện nối tiếp đƣợc trình bày ở phần trên, vi
điều khiển PIC16F877A còn đƣợc hỗ trợ một cổng giao tiếp song song và chuẩn giao tiếp
song song thông qua PORTD và PORTE. Do cổng song song chỉ hoạt động ở chế độ
Slave mode nên vi điều khiển khi giao tiếp qua giao diện này sẽ chịu sự điều khiển của
thiết bị bên ngoài thông qua các pin của PORTE, trong khi dữ liệu sẽ đƣợc đọc hoặc ghi
theo dạng bất đồng bộ thông qua 8 pin của PORTD.
Bit điều khiển PSP là PSPMODE (TRISE<4>). PSPMODE đƣợc set sẽ thiết lập
chức năng các pin của PORTE là các pin cho phép đọc dữ liệu RD(RE 0 / RD / AN 0) , cho

phép ghi dữ liệu WR(RE1/ WR / AN 6) và pin chọn vi điều khiển CS (RE 2 / CS / AN 7) phục
vụ cho việc truyền nhận dữ liệu song song thông qua bus dữ liệu 8 bit của PORTD.
PORTD lúc này đóng vai trò là thanh ghi chốt dữ liệu 8 bit, đồng thời tácđộng của thanh
ghi TRISD cũng sẽ đƣợc bỏ qua do PORTD lúc này chịu sự điều khiển của các thiết bị
bên ngoài. PORTE vẫn chịu sự tác động của thanh ghi TRISE, do đó cần xác lập trạng

ĐƢỜNG KHÁNH SƠN Trang 102


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

thái các pin PORTE là input bằng cách set các bit TRISE<2:0>. Ngoài ra cần đƣa giá trị
thích hợp các bit PCFG3:PCFG0 (thanh ghi ADCON1<3:0>) để ấn định các pin của
PORTE là các pin I/O dạng digital (PORTE còn là các pin chức năng của khối ADC).
Khi các pin CS và WR cùng ở mức thấp, dữ liệu từ bên ngoài sẽ đƣợc ghi lên
PORTD. Khi một trong hai pin trên chuyển lên mức logic cao, cờ hiệu báo dữ liệu trong
buffer đã đầy BIF (TRISE<7>) đƣợc set va cờ ngắt PSPIF (PIR1<7>) đƣợc set để báo
hiệu kết thúc ghi dữ liệu. Bit BIF chỉ đƣợc xóa về 0 khi dữ liệu vừa nhận đƣợc ơ PORTD
đƣợc đọc vào. Bit báo hiệu dữ liệu nhận đƣợc trong buffer bị tràn IBOV (TRISE<5>) sẽ
đƣợc set khi vi điều khiển nhận tiếp dữ liệu tiếp theo trong khi chƣa đọc vào dữ liệu đã
nhận đƣợc trƣớc đó.
Khi các pin CS và RD cùng ở mức logic thấp, bit báo hiệu buffer truyền dữ liệu
đa đầy BOF (TRISE<6>) sẽ đƣợc xóa ngay lập tức để báo hiệu PORTD đã sẵn sàng cho
qua trình đọc dữ liệu. Khi một trong hai pin trên chuyển sang mức logic cao, cờ ngắt
PSPIF sẽ đƣợc set để báo hiệu quá trình đọc dữ liệu hoàn tất. Bit BOF vẫn đƣợc giữ ở
mức logic 0 cho đến khi dữ liệu tiếp theo đƣợc đƣa vào PORTD. Cần chú ý là ngắt
SSPIF đƣợc điều khiển bởi bit PSPIE (PIE1<7>) và phải đƣợc xóa bằng chƣơng trình.
Các thanh ghi liên quan đến PSP bao gồm:
- Thanh ghi PORTD (địa chỉ 08h): chứa dữ liệu cần đọc hoặc ghi.
- Thanh ghi PORTE (địa chỉ 09h): chứa giá trị các pin PORTE.
- Thanh ghi TRISE (địa chỉ 89h): chứa các bit điều khiển PORTE và PSP.
- Thanh ghi PIR1 (địa chỉ 0Ch): chứa cờ ngắt PSPIF.
- Thanh ghi PIE1 (địa chỉ 8Ch): chứa bit cho phép ngắt PSP.
- Thanh ghi ADCON1 (địa chỉ 9Fh): điều khiển khối ADC tại PORTE.

ĐƢỜNG KHÁNH SƠN Trang 103


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Hình 5.22: Sơ đồ của PortD và PortE khi hoạt động ở chế độ PSP Slave mode

ĐƢỜNG KHÁNH SƠN Trang 104


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Chương 6: HOẠT ĐỘNG NGẮT


6.1 Mở đầu
Ngắt là một khái niệm mang tính trừu tƣợng cao nhƣng cũng đƣợc thiết lập dựa
trên các hiện tƣợng và tình huống có thực trong thực tế. Chẳng hạn nhƣ trong cuộc sống
hằng ngày, đôi khi ta phải tạm ngƣng một công việc nào đó để làm một công việc khác
cần thiết hơn, chẳng hạn nhƣ tạm ngƣng một công việc nào đó đang làm để nghe điện
thoại. Sự tạm ngƣng này cần đƣợc báo hiệu bởi một tínhiệu (trong trƣờng hợp trên là
chuông điện thoại chẳng hạn) và phải đƣợc ta cho phép trƣớc đó (nếu ta không cho phép
điện thoại reo thì điện thoại sẽ không reo). Từ ví dụ thực tế trên ta có thể liên tƣởng đến
ngắt và cách xử lí ngắt của một vi điều khiển. Một ngắt là một tín hiệu điều khiển bắt
buộc vi điều khiển tạm ngƣng công việc đang làm để tiến hành các thao tác mà ngắt đó
qui định thông qua chƣơng trình ngắt. Tín hiệu điều khiển này đƣợc báo hiệu bởi cờ ngắt
(tƣơng ứng với chuông điện thoại ở ví dụ trên) và phải đƣợc ta cho phép trƣớc đó thông
qua các bit điều khiển cho phép hoặc không cho phép ngắt. Một chƣơng trình ngắt thông
thƣờng sẽ đƣợc tách riêng với chƣơng trình chính để bảo đảm tính độc lập của chƣơng
trình ngắt.
6.2 Tổ chức và xử lý ngắt
PIC16F877A có đến 15 nguồn tạo ra hoạt động ngắt đƣợc điều khiển bởi thanh ghi
INTCON (bit GIE). Bên cạnh đó mỗi ngắt còn có một bit điều khiển và cờ ngắt riêng.
Các cờ ngắt vẫn đƣợc set bình thƣờng khi thỏa mãn điều kiện ngắt xảy ra bất chấp trạng
thái của bit GIE, tuy nhiên hoạt động ngắt vẫn phụ thuôc vào bit GIE và các bit điều
khiển khác. Bit điều khiển ngắt RB0/INT và TMR0 nằm trong thanh ghi INTCON, thanh
ghi này còn chứa bit cho phép các ngắt ngoại vi PEIE. Bit điều khiển các ngắt nằm trong
thanh ghi PIE1 và PIE2. Cờ ngắt của các ngắt nằm trong thanh ghi PIR1 và PIR2.
Trong một thời điểm chỉ có một chƣơng trình ngắt đƣợc thực thi, chƣơng trình
ngắt đƣợc kết thúc bằng lệnh RETFIE. Khi chƣơng trình ngắt đƣợc thực thi, bit GIE tự
động đƣợc xóa, địa chỉ lệnh tiếp theo của chƣơng trình chính đƣợc cất vào trong bộ nhớ
Stack và bộ đếm chƣơng trình sẽ chỉ đến địa chỉ 0004h. Lệnh RETFIE đƣợc dùng để
thoát khỏi chƣơng trình ngắt và quay trở về chƣơng trình chính, đồng thờibit GIE cũng sẽ
đƣợc set để cho phép các ngắt hoạt động trở lại. Các cờ hiệu đƣợc dùng để kiểm tra ngắt
vào đang xảy ra và phải đƣợc xóa bằng chƣơng trình trƣớc khi cho phép ngắt tiếp tục

ĐƢỜNG KHÁNH SƠN Trang 105


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

hoạt động trở lại để ta có thể phát hiện đƣợc thời điểm tiếp theo mà ngắt xảy ra.
Đối với các ngắt ngoại vi nhƣ ngắt từ chân INT hay ngắt từ sự thay đổi trạng thái
các pin của PORTB (PORTB Interrupt on change), việc xác định ngắt nào xảy ra cần 3
hoặc 4 chu kì lệnh tùy thuộc vào thời điểm xảy ra ngắt.

Hình 6.1: Sơ đồ logic của tất cả các ngắt trong vi điều khiển PIC 16F877A

Cần chú ý là trong quá trình thực thi ngắt, chỉ có giá trị của bộ đếm chƣơng trình đƣợc
cất vào trong Stack, trong khi một số thanh ghi quan trọng sẽ không đƣợc cất và có thể bị
thay đổi giá trị trong quá trình thực thi chƣơng trình ngắt. Điều này nên đƣợc xử lí bằng
chƣơng trình để tránh hiện tƣợng trên xảy ra.
6.3 Thiết kế chương trình xử lý ngắt
Ví dụ một chƣơng trình có ngắt nhƣ sau:
#INCLUDE <16F877A.H>
#FUSES NOLVP, NOWDT, HS
#USE DELAY(CLOCK=8000000)
BYTE CONST MAP[10]= {0xC0, 0xF9, 0xA4,0xB0, 0x99,0x92,0x82, 0xF8,
0x80, 0x90} ;
VOID HIENTHI(INT A);
INT SODEM;

ĐƢỜNG KHÁNH SƠN Trang 106


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

//CHUONG TRINH CON PHUC VU NGAT DAT SAU #INT_EXT


#INT_EXT
VOID NGATNGOAI()
{
// XOA CO NGAT NGOAI
CLEAR_INTERRUPT(INT_EXT);
//CAM NGAT TRONG CHUONG TRINH CON PHUC VU NGAT
DISABLE_INTERRUPTS(GLOBAL);
SODEM++;
// CHO PHEP NGAT TOAN CUC
ENABLE_INTERRUPTS(GLOBAL);
}
VOID HIENTHI(INT A)
{
INT HC, HDV;
HC=A/10;
HDV=A%10;
OUTPUT_LOW(PIN_A4);
OUTPUT_D(MAP[HC]);
DELAY_MS(15);
OUTPUT_HIGH(PIN_A4);
OUTPUT_LOW(PIN_A5);
OUTPUT_D(MAP[HDV]);
DELAY_MS(15);
OUTPUT_HIGH(PIN_A5);
}
VOID MAIN()
{
// CAI DAT VAO RA CHO CONG B
SET_TRIS_B(0xFF);
// CHO PHEP NGAT NGOAI

ĐƢỜNG KHÁNH SƠN Trang 107


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

ENABLE_INTERRUPTS(INT_EXT);
// CAI DAT SUON NGAT
EXT_INT_EDGE(H_TO_L);
// CHO PHEP NGAT TOAN CUC
ENABLE_INTERRUPTS(GLOBAL);
// VONG LAP DOI NGAT
WHILE(1)
{
HIENTHI(SODEM);
}
}

Nhƣ vậy, lúc viết chƣơng trình có dùng ngắt bằng CCS, ta có những lƣu ý sau:
- Trong chƣơng trình chính (main), chúng ta cài đặt ngắt: cho phép ngắt cụ thể,
cho phép ngắt toàn cục. Đợi ngắt.
- Chƣơng trình con xử lý ngắt là chƣơng trình con nằm ngay sau chỉ thị biên dịch
#INT_XXX, trong đó XXX là tên của ngắt cụ thể.
Ví dụ: #INT_EXT: ngắt ngoài.
- Trong chƣơng trình con xử lý ngắt: xóa cờ ngắt, cấm ngắt toàn cục đề phòng khi
đang xử lý ngắt có ngắt xảy ra. Sau khi xử lý dữ liệu trong chƣơng trình con xử lý ngắt,
ta cho phép ngắt toàn cục lại.
Tên một số ngắt của PIC nhƣ sau:
- INT_EXT: ngắt ngoài
- INT_TIMER 0: ngắt timer 0
- INT_TIMER 1: ngắt timer 1
- INT_TIMER 2: ngắt timer 2
- INT_RDA: ngắt nhận đủ kí tự trong truyền thông máy tính
- INT_RB: ngắt thay đổi trạng thái các chân RB7-RB4
6.5 Các ngắt bộ định thời
- Nguồn ngắt: là trạng thái tràn của thanh ghi bộ đếm timer 0, TMR0 vi điều
khiển PIC.

ĐƢỜNG KHÁNH SƠN Trang 108


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

- Sự kiện ngắt: sự kiện ngắt xảy ra khi có sự tràn của TMR0, tức là khi
TMR0=255 rồi bị xóa.
- Bit cho phép ngắt: Để cho phép ngắt này, bit cho phép ngắt TMR0IE (bit 5 của
thanh ghi INTCON) phải đƣợc set lên 1. Ngoài ra, bit cho phép ngắt toàn cục GIE (bit 7
của thanh ghi INTCON) cũng phải đƣợc set lên 1.
- Cờ ngắt: bit cờ ngắt ngoài là bit TMR0IF (bit 2 của thanh ghi INTCON) đƣợc tự
động set lên 1 khi có sự kiện ngắt ngoài xảy ra. Cờ này phải đƣợc xóa bằng chƣơng trình
(cụ thể là trong chƣơng trình con phục vụ ngắt) để vi điều khiển quản lý chính xác các
lần ngắt kế tiếp.
 Quản lý ngắt Timer 0 trong chƣơng trình CCS:
Trong chƣơng trình chính, cài đặt ngắt:
- Gán giá trị ban đầu cho thanh ghi TMR0, tùy thuộc vào thời gian mà ngƣời lập
trình muốn : SET_TIMER 0(giá trị)
- Cho phép ngắt timer 0: ENABLE_INTERRUPTS(INT_TIMER 0)
- Cho phép ngắt toàn cục: ENABLE_INTERRUPTS(GLOBAL)
Chƣơng trình con phục vụ ngắt đặt sau chỉ định biên dịch #INT_TIMER 0:
#INT_TIMER 0
Định nghĩa chƣơng trình con
Trong chƣơng trình con phục vụ ngắt:
- Xóa cờ ngắt: CLEAR_INTERRUPT(INT_TIMER 0)
- Cấm ngắt toàn cục, đề phòng lúc đang xử lý ngắt, lại có ngắt xảy ra:
DISABLE_INTERRUPTS(GLOBAL)
- Xử lý ngắt đó: tùy thuộc vào ý đồ của ngƣời lập trình, chú ý đến số lần ngắt.
- Gán lại giá trị ban đầu cho thanh ghi TMR0 (tùy thuộc vào ý đồ của ngƣời lập
trình):
SET_TIMER 0(giá trị)
- Cho phép ngắt toàn cục: ENABLE_INTERRUPTS(GLOBAL).
6.6 Các ngắt port nối tiếp
- Nguồn ngắt: là trạng thái của một trong các chân RB7-RB4 của vi điều khiển
PIC.
- Sự kiện ngắt: sự kiện ngắt xảy ra khi có sự thay đổi trạng thái (1-0 hay 0-1) của

ĐƢỜNG KHÁNH SƠN Trang 109


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

một trong các chân RB7-RB4 của PortB


- Bit cho phép ngắt: Để cho phép ngắt này, bit cho phép ngắt RBIE (bit 3 của
thanh ghi INTCON) phải đƣợc set lên 1. Ngoài ra, bit cho phép ngắt toàn cục GIE (bit 7
của thanh ghi INTCON) cũng phải đƣợc set lên 1.
- Cờ ngắt: bit cờ ngắt ngoài là bit RBIF (bit 0 của thanh ghi INTCON) đƣợc tự
động set lên 1 khi có sự kiện ngắt ngoài xảy ra. Cờ này phải đƣợc xóa bằng chƣơng trình
(cụ thể là trong chƣơng trình con phục vụ ngắt) để vi điều khiển quản lý chính xác các
lần ngắt kế tiếp.
Lƣu ý quan trọng: Khi sử dụng ngắt này trong các ứng dụng xử lý các xung đầu
vào RB4-RB7, ví dụ nhƣ phím bấm chẳng hạn, ta cần lƣu ý điểm sau. Giả sử nhƣ ban đầu
phím bấm chƣa bấm, đầu vào RB ở mức 1, khi bấm phím RB xuống mức 1, nhƣ vậy có 1
sự kiện ngắt xảy ra. Tuy nhiên, khi thả phím bấm ra, RB lên mức 1, tức cũng có một sự
thay đổi trạng thái của chân RB7-RB4, nên cũng có ngắt xảy ra. Vì vậy, việc ấn và nhả
phím bấm đƣợc tính 2 lần ngắt. Cần để ý điều này khi lập trình.
Vấn đề thứ 2 là cần sử dụng một lệnh đọc cổng B để loại bỏ trạng thái mismatch
lúc xảy ra ngắt ở các chân này.
 Quản lý ngắt RB trong chƣơng trình CCS:
Trong chƣơng trình chính, cài đặt ngắt:
- Cài đặt chân RB4-RB7 là chân vào: SET_TRIS_B(0xF0)
- Cho phép ngắt RB: ENABLE_INTERRUPTS(INT_RB)
- Cho phép ngắt toàn cục: ENABLE_INTERRUPTS(GLOBAL)
Chƣơng trình con phục vụ ngắt đặt sau chỉ định biên dịch #INT_RB:
#INT_RB
Định nghĩa chƣơng trình con
Trong chƣơng trình con phục vụ ngắt:
- Xóa cờ ngắt: CLEAR_INTERRUPT(INT_RB)
- Cấm ngắt toàn cục, đề phòng lúc đang xử lý ngắt, lại có ngắt xảy ra:
DISABLE_INTERRUPTS(GLOBAL)
- Đoc cổng B để loại bỏ trạng thái mismatch
- Xử lý ngắt đó: tùy thuộc vào ý đồ của ngƣời lập trình, chú ý đến số lần ngắt
- Cho phép ngắt toàn cục: ENABLE_INTERRUPTS(GLOBAL)

ĐƢỜNG KHÁNH SƠN Trang 110


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

6.7 Các ngắt ngoài


- Nguồn ngắt: là xung đi vào chân RB0 của vi điều khiển PIC
- Sự kiện ngắt: sự kiện ngắt xảy ra khi có xung đi vào chân RB0 của vi điều
khiển. Xung là xung sƣờn dƣơng hay sƣờn âm phụ thuộc bit cài đặt chọn dạng xung, bit
INTEDG ( bit 6 của thanh ghi PTION_REG) là 1 hay không.
- Bit cho phép ngắt: Để cho phép ngắt ngoài, bit cho phép ngắt ngoài INTIE (bit
4 của thanh ghi INTCON) phải đƣợc set lên 1. Ngoài ra, bit cho phép ngắt toàn cục GIE
(bit 7 của thanh ghi INTCON) cũng phải đƣợc set lên 1.
- Cờ ngắt: bit cờ ngắt ngoài là bit INTIF (bit 1của thanh ghi INTCON) đƣợc tự
động set lên 1 khi có sự kiện ngắt ngoài xảy ra. Cờ này phải đƣợc xóa bằng chƣơng trình
(cụ thể là trong chƣơng trình con phục vụngắt) đểvi điều khiển quản lý chính xác các lần
ngắt kế tiếp.
 Quản lý ngắt ngoài trong chương trình CCS:
Trong chƣơng trình chính, cài đặt ngắt:
- Cài đặt chân RB0 là chân vào: SET_TRIS_B(0x01)
- Cài đặt dạng xung đầu vào là sƣờn dƣơng hay sƣờn âm:
EXT_INT_EDGE(H_TO_L) hoặc EXT_INT_EDGE(L_TO_H).
- Cho phép ngắt ngoài: ENABLE_INTERRUPTS(INT_EXT)
- Cho phép ngắt toàn cục: ENABLE_INTERRUPTS(GLOBAL)
Chƣơng trình con phục vụ ngắt đặt sau chỉ định biên dịch #INT_EXT:
#INT_EXT
Định nghĩa chƣơng trình con
Trong chƣơng trình con phục vụ ngắt:
- Xóa cờ ngắt: CLEAR_INTERRUPT(INT_EXT)
- Cấm ngắt toàn cục, đề phòng lúc đang xử lý ngắt, lại có ngắt xảy ra:
DISABLE_INTERRUPTS(GLOBAL)
- Xử lý ngắt đó: tùy thuộc vào ý đồ của ngƣời lập trình
- Cho phép ngắt toàn cục: ENABLE_INTERRUPTS(GLOBAL)
Ví dụ : Chƣơng trình nháy led theo nhiều kiểu khác nhau, sử dụng 1 phím bấm nối
với chân ngắt ngoài RB0 để chọn kiểu nháy. Có 8 kiểu nháy LED khác nhau, Khi đến
kiểu nháy thứ 8, nếu ta nhấn thì sẽ trở về chế độ ban đầu. Ban đầu biến mode = 0 và tất

ĐƢỜNG KHÁNH SƠN Trang 111


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

cả các LED đều tắt. Mỗi khi nhấn phím bấm, biến mode sẽ tăng lên 1 đơn vị. Giá trị biến
mode tƣơng ứng với chƣơng trình nháy đƣợc thực hiện. Khi mode = 9 thì sẽ đƣợc gán về
mode = 0. Các kiểu nháy khác nhau là do ta bật tắt các LED trên cổng D theo các
cách khác nhau. Lấy ví dụ khi ta muốn các LED nháy xen kẽ nhau ta chỉ việc gửi ra cổng
D giá trị AAh (10101010) và 55h (01010101).

#include <16F877A.h>
#include <def_877a.h>
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,
NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
int8 mode,i;
byte temp;
#INT_EXT
EXT_ISR() {
mode++;
if (mode==9) mode = 0;
}
// End of INT
void program1();
void program2();
void program3();
void program4();
void program5();
void program6();
void program7();
void program8();
void main() {
trisd = 0x00;
trisb = 0xFF;
portd=0xff;

ĐƢỜNG KHÁNH SƠN Trang 112


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

enable_interrupts(int_EXT);
ext_int_edge(H_TO_L); // Chọn ngắt theo sƣờn âm
enable_interrupts(GLOBAL);
mode = 0;
while (1) {
switch(mode) {
case 1: program1(); break;
case 2: program2(); break;
case 3: program3(); break;
case 4: program4(); break;
case 5: program5(); break;
case 6: program6(); break;
case 7: program7(); break;
case 8: program8(); break;
}
}
}
void program1() {
PortD = 0x00;
delay_ms(250);
Portd = 0xFF;
delay_ms(250);
}
void program2() { // LED sáng chạy từ trái qua phải
temp = 0xFF;
for (i=0;i<=8;i++) {
portd = temp;
delay_ms(250);
temp >>= 1;
}
}

ĐƢỜNG KHÁNH SƠN Trang 113


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

void program3() { // LED sáng chạy từ phải qua trái


temp = 0xFF;
for (i=0;i<=8;i++) {
portd = temp;
delay_ms(250);
temp <<= 1;
}
}
void program4() {
portd = 0xAA;
delay_ms(500);
portd = 0x55;
delay_ms(500);
}
void program5() {
Portd = 0x7E; delay_ms(150);
Portd = 0xBD; delay_ms(150);
Portd = 0xDB; delay_ms(150);
Portd = 0xE7; delay_ms(150);
Portd = 0xDB; delay_ms(150);
Portd = 0xBD; delay_ms(150);
Portd = 0x7E; delay_ms(150);
}
void program6() {
temp = 0xFF;
for (i=0;i<=8;i++) {
portd = temp;
delay_ms(250);
temp = temp >> 1;
}
}

ĐƢỜNG KHÁNH SƠN Trang 114


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

void program7() {
Portd = 0xFE; delay_ms(150);
Portd = 0xFD; delay_ms(150);
Portd = 0xFB; delay_ms(150);
Portd = 0xF7; delay_ms(150);
Portd = 0xEF; delay_ms(150);
PortD = 0xDF; delay_ms(150);
Portd = 0xBF; delay_ms(150);
Portd = 0x7F; delay_ms(150);
}
void program8() {
Portd = 0x7F; delay_ms(150);
Portd = 0xBF; delay_ms(150);
PortD = 0xDF; delay_ms(150);
Portd = 0xEF; delay_ms(150);
Portd = 0xF7; delay_ms(150);
Portd = 0xFB; delay_ms(150);
Portd = 0xFD; delay_ms(150);
Portd = 0xFE; delay_ms(150);
}

ĐƢỜNG KHÁNH SƠN Trang 115


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

Hình 6.2: Mô phỏng ngắt ngoài với PIC 16F877A

ĐƢỜNG KHÁNH SƠN Trang 116


GIÁO TRÌNH VI ĐIỀU KHIỂN DRAFT

TÀI LIỆU THAM KHẢO

[1] Nguyễn Tăng Cƣờng, Phan Quốc Thắng, Cấu trúc và lập trình họ vi điều khiển 8051,
NXB Khoa học & Kỹ thuật, 2004
[2] Kiều Xuân Thực, Vũ Thị Thu Hƣơng, Vũ Trung Kiên, VI ĐIỀU KHIỂN Cấu trúc -
Lập trình và ứng dụng, NXB Giáo Dục, 2009
[3] Ngô Diên Tập, Vi điều khiển với lập trình C, NXB Khoa Học & Kỹ Thuật, 2006.
[4] Phạm Quang Huy, Nguyễn Trọng Hiếu, Vi điều khiển và ứng dụng Arduino cho người
tự học, NXB Khoa Học & Kỹ Thuật, 2015.

ĐƢỜNG KHÁNH SƠN Trang 117

You might also like