Professional Documents
Culture Documents
Giáo trình vi điều khiển pic 16f877a
Giáo trình vi điều khiển pic 16f877a
Giáo trình vi điều khiển pic 16f877a
KHOA CƠ KHÍ
BỘ MÔN CƠ ĐIỆN TỬ
KỸ THUẬT
VI ĐIỀU KHIỂN PIC
Firma convenzione
Politecnico di Milano e Veneranda Fabbrica
TS. Đặng
del Duomo Phước Vinh
di Milano
Aula Magna – Rettorato
Mercoledì 27 maggio 2015
Email: dangphuocvinh@gmail.com
Phone: 0908 217 415
2
Nội dung
2. CCS C Compiler
CỔNG
CPU CỔNG
RAM ROM TIMER NỐI
Vi xử lý I/O
TIẾP
ADC Bộ nhớ
Thạch anh SPI
USART T0 T1 T2 RAM
0 – 20Mhz I2C SFR
(368 byte)
Thạch anh Truyền thông Bộ định thời
nội nối tiếp Bộ nhớ
chương trình
(8k)
CPU EEPROM
CCP1 , CCP2 (35 tập lệnh) (256 byte)
Bộ ADC
PWM
Khối Bộ nhớ
Khối CCP/ WDT
Vref ngắt
PWM
RESET
Vi điều khiển
TS. Đặng Phước Vinh Khoa Cơ khí
12
Vi xử lý & Vi điều khiển
Vi xử lý Vi điều khiển
CPU chip riêng biệt. RAM, ROM, I/O, CPU, RAM, ROM, I/O và Timer nằm
Timer nằm bên ngoài trên cùng 1 chip
Lượng ROM, RAM, I/O Ports tùy ý Cố định lượng ROM, RAM, I/O
Ports trên chip
✓ "Programmable Intelligent
Computer" là một sản phẩm của
hãng General Instruments
✓ Có đầy đủ tính năng của một VĐK khi hoạt động độc lập
✓ 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…
✓ Các tính năng đa dạng của VĐK liên tục được cập nhật
TS. Đặng Phước Vinh Khoa Cơ khí
16
Các loại chip PIC
✓ Bên cạnh đó một số vi điều khiển có ký hiệu xxFxxx thì bộ nhớ chương trình
là EEPROM, nếu có thêm chữ A ở cuối thì bộ nhớ chương trình là flash (ví dụ
PIC16F877 là EEPROM, còn PIC16F877A là flash).
✓ Ở Việt Nam phổ biến nhất là các họ vi điều khiển PIC do Microchip sản xuất
Bộ nhớ Flash
▪ Là một loại EEPROM, đọc/ghi bằng điện và không mất
dữ liệu khi ngừng cung cấp điện
▪ Cho phép đọc/ghi từng khối nhỏ hoặc theo từ của máy
TS. Đặng Phước Vinh Khoa Cơ khí
19
Các loại bộ nhớ
Mất dữ Giá
Xoá
liệu Khả năng thành
Loại Cỡ xoá ? nhiều Tốc độ ?
khi mất ghi ? (theo
lần ?
điện? byte)
Không sẵn Không sẵn
ROM Không Không Nhanh Không đắt
sàng sàng
Có, nhưng
EPROM cần thiết bị
Không Toàn bộ Giới hạn Nhanh Vừa phải
chuyên
dụng
Nhanh cho
đọc
EEPROM Không Có Byte Giới hạn Đắt
Chậm cho
xoá và ghi
Nhanh cho
đọc
Flash Không Có Sector Giới hạn Vừa phải
Chậm cho
TS. Đặng Phước Vinh xoá và
Khoa Cơghi
khí
20
Trình biên dịch
✓ Được cung cấp miễn phí bởi nhà sản xuất Microchip
✓ 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
✓ Ngày càng được cập nhật với nhiều tính năng ưu việt và
TS. hiệu quảVinh
Đặng Phước hơn. Khoa Cơ khí
24
Trình biên dịch CCS
PICkit 2
Giao tiếp
máy tính
Điều khiển
động cơ
EEPROM
Nguồn
Chân nạp
TS. Đặng Phước Vinh Khoa Cơ khí
CHƯƠNG 2
CẤU TRÚC PHẦN CỨNG
Firma convenzione
PIC 16F877A
Politecnico di Milano e Veneranda Fabbrica
del Duomo di Milano
Aula Magna – Rettorato
Mercoledì 27 maggio 2015
30
Tổng quan về PIC16F877A
✓ Chế độ sleep
Reset
Port A Port B
Port E Power
Power
Port D
Oscillator
Port C Port C
Port D
TS. Đặng Phước Vinh Khoa Cơ khí
36
Giới hạn hoạt động
1 3
2 4
TS. Đặng Phước Vinh Khoa Cơ khí
45
Chức năng các chân
Chân OSC1/CLKIN (13)
Chân OSC2/CLKOUT (14)
→Là các chân nối với thạch anh để tạo ra xung dao động cho
PIC
→Thêm 2 tụ lọc C1, C2 để xung tạo ra từ thạch anh ổn định
→Giá trị của tụ dựa theo datasheet của PIC
✓ 2 bộ CCP (Capture/Compare/PWM)
▪ Capture có độ rộng 16 bit, độ phân giải 12.5 ns
▪ Compare có độ rộng 16 bit, độ phân giải 200ns
▪ Độ phân giải lớn nhất của PWM là 10 bit
TS. Đặng Phước Vinh Khoa Cơ khí
54
Các đặc tính ngoại vi
Output
Output
Output
Output
CPU Input
Input
Input
Input
1 1 0 1 0 1 0 1 PORT
TS.RBPU
Đặng Phước Vinh
INTEDG T0CS T0SE PSA PS2 KhoaPS1
Cơ khí PS0
65
Các thanh ghi liên kết với Port B
✓ Là port 2 chiều. Có
8 bit: RD0 – RD7
✓ Thanh ghi định
hướng dữ liệu:
TRISD.
0: OUTPUT
1: INPUT.
✓ Port D được đa
hợp với giao tiếp
song song
Xử lý (Process)
Dữ liệu ra (Output)
Kiểu tiêu chuẩn của C Kiểu mặc định của trình biên dịch CCS
short int1
char unsigned int8
int int8
long int16
long long int32
float float32
double Không có
Ví dụ:
int a = 10, b = 20;
Max = (a>b)?a:b; → max = b = 20
Min = (a<b)?a:b; → min = a = 10
Dùng để chuyển một kiểu dữ liệu bất kỳ sang một kiểu dữ liệu
mong muốn
Cú pháp: <kiểu>biến
Ví dụ:
int a = 9, b = 2;
int c = a/b; →c=4
float d = (float)a/b; → d = 4.5
Ra Ra
TS. Đặng Phước Vinh Khoa Cơ khí
85
Cấu trúc điều kiện – Lệnh switch
Tương tự như lệnh if; nhưng mềm dẻo, linh động hơn
switch (biểu thức) ✓ Biểu thức phải là kết quả có giá trị
{ nguyên (char, int, long…)
case giá trị 1: khối lệnh 1; ✓ Nếu khối lệnh từ 2 lệnh trở lên thì
break; đặt trong dấu { }
case giá trị 2: khối lệnh 2; ✓ Các từ khóa switch, case, break
break; phải viết bằng chữ thường
……………. ✓ Sau lệnh i, nếu không có lệnh
case giá trị n: khối lệnh n; break thì chương trình thực hiện
lệnh i+1. Nếu có thì thoát ra ngoài
break;
} ✓ Sau lệnh switch không có dấu ;
Không
break;
Đúng
Giá trị = 2? Lệnh/khối lệnh 2
case giá trị 2: khối lệnh 2;
break; break?
Có
Sai
……………. Không
Đúng
case giá trị n: khối lệnh n; Giá trị = n? Lệnh/khối lệnh n
break; Có
break?
Sai
} Không
Ra
break; Có
break?
Sai
……………. Không
Đúng
case giá trị n: khối lệnh n; Giá trị = n? Lệnh/khối lệnh n
break; Có
break?
Sai
default: khối lệnh n+1; Không
int main()
{
for (g.trị bắt đầu ; điều kiện kết thúc ; thay đổi giá trị) int i;
{ for (i = 1; i <= 10; i++)
{
khối lệnh; printf("%-5d", i);
}
} }
Thay đổi biến điều khiển từ 1
đến 100, mỗi lần tăng 1:
✓ Nếu điều kiện để kết thúc vòng lặp không for(i = 1; i <=100; i++)
có → vòng lặp luôn lặp
Thay đổi biến điều khiển từ
✓ Để kết thúc vòng lặp → break; return; 100 đến 1, mỗi lần giảm 1:
for(i = 100; i >= 1; i--)
goto
Thay đổi biến điều khiển từ 7
✓ Trong thân for (khối lệnh) có thể chứa một đến 77, mỗi lần tăng 7:
hoặc nhiều cấu trúc điều khiển khác, vòng for(i = 7; i <= 77; i+=7)
lặp khác.
Thay đổi biến điều khiển từ 20
TS. Đặng Phước Vinh đến 2, mỗi
Khoa lần giảm 2:
Cơ khí
for(i = 20; i >= 2; i –= 2)
90
Vòng lặp while
while(biểu thức) ✓ Trước tiên biểu thức được kiểm tra.
✓ Nếu sai → thoát khỏi vòng lặp (khối lệnh chưa được
{ thực thi một lần nào.
✓ Nếu đúng → thực hiện khối lệnh + kiểm tra biểu thức.
khối lệnh; ✓ Khối lệnh có thể 1 hoặc nhiều lệnh.
✓ Nếu biểu thức là một hằng khác không thì nó luôn đúng
} và vòng lặp diễn ra vô hạn. Muốn thoát khỏi vòng lặp
while tùy ý có thể dùng các lệnh break, goto, return.
void main()
TS. Đặng {… Vinh
Phước } Khoa Cơ khí
// chương trình chính
93
Các hàm trong CCS
#INCLUDE
#include <filename>
▪ Filename : tên file cho thiết bị *.h , *.c
▪ Khai báo chỉ định đường dẫn cho trình biên dịch
▪ Luôn phải có để khai báo chương trình viết cho VĐK
nào , và luôn đặt ở dòng đầu tiên
▪ Ví dụ: #include <16F877A.h>
#include < I2C.h>
#BIT
#bit name = x.y
▪ Tạo biến 1bit có tên là name đặt ở byte x vị trí y.
▪ Thường dùng để kiểm tra hoặc gán giá trị cho thanh
ghi.
▪ Ví dụ: #bit TMR1IF = 0x0B.2; => tạo biến 1bit tên
TMR1IF đặt ở byte có địa chỉ 0x0B ở vị trí thứ 2.
#BYTE
#byte name = x
▪ Gán tên biến name cho địa chỉ x
▪ Name thường trùng với tên thanh ghi có địa chỉ x
▪ Ví dụ: #byte portB = 0x06;
#DEFINE
#define name text
▪ Dùng để khai báo một chuỗi, một biến, hoặc số có tên
là name
▪ Ví dụ: #define constant 123456;
#define LED_D5 PIN_E2
#use I2C(options)
▪ Thiết lập giao tiếp I2C
▪ #use i2c(master , SDA = PIN_B1 , SCL = PIN_B4)
#USE
#use fast_io(port)
▪ Port là các cổng vào ra của PIC (từ A -> E)
▪ Có chỉ thị này thì chúng ta có thể điều chỉnh các port
chỉ với 1 lệnh như output_low() , input_high()
▪ Trong hàm main → phải dùng hàm set_tris_x() để
chỉ rõ chân vào ra thì chỉ thị trên mới có hiệu lực,
nếu không chương trình sẽ chạy sai
▪ Ví dụ: #use fast_io(A)
#use fast_io(all)
✓ output_low(pin), output_high(pin)
▪ Thiết lập 1 chân vi điều khiển là OUTPUT, điện áp xuất ra là
mức 0 hoặc mức 1.
▪ output_low(PIN_B0); // chân 0 của PORTB xuất ra điện áp
0V (mức 0)
output_high(PIN_A0); // chân 0 của PORTA xuất ra điện áp
5V (mức 1)
✓ output_x(byte)
▪ Thiết lập PORT x là OUTPUT, giá trị xuất ra là byte.
▪ output_b(0x35); // giá trị xuất ra ở PORTB là 0x00110101
output_d(0x76); // giá trị xuất ra ở PORTD là 0x01110110
output_bit(pin,value)
▪ Thiết lập 1 chân vi điều khiển là OUTPUT, mức logic
thiết lập là value (0 hoặc 1).
▪ Thường dùng khi giá trị ra tùy thuộc giá trị của 1
biến nào đó
output_bit(PIN_B1,0);
→ chân 1 của PORTB xuất ra mức logic 0 (0V)
→ output_bit(PIN_C2,input(PIC_B2));
→ chân C2 xuất ra mức logic = giá trị đầu vào của chân B2
✓ output_float(pin)
▪ Hàm này thiết lập chân chỉ định đến chế độ input
(nhập),với trạng thái trở kháng cao.
▪ output_float(PIN_B3); // chân B3 trở thành input
✓ output_drive(pin)
▪ Thiết lập chân chân chỉ định đến chế độ OUTPUT (TRIS
bit 0).
▪ output_drive(PIN_B1); // chân B1 trở thành output
TS. Đặng Phước Vinh Khoa Cơ khí
104
Các hàm xử lý I/O
✓ input(pin)
▪ Trả về trạng thái của một chân vi điều khiển, giá trị trả về có
kiểu bit (0 hoặc 1).
▪ if(input(PIN_C5)) output_b(0xFF); // nếu chân C5 ở mức
cao → PORTB = 0xff
if(!input(PIN_C5)) output_b(0x00); // nếu chân C5 ở mức
thấp → PORTB = 0x00
✓ input_x()
▪ trả về trạng thái của PORT x, giá trị trả về là 1 byte
▪ int8 DATA;
DATA = input_a(); // biến DATA sẽ chứa giá trị trạng thái
của PORTA
TS. Đặng Phước Vinh Khoa Cơ khí
105
Các hàm xử lý I/O
✓ port_b_pullups(value)
▪ value = 1 → thiết lập điện trở kéo lên cho PORTB khi sử
dụng là chức năng INPUT (đối với 16F877A thì chỉ có
PORTB có điện trở nội kéo lên).
✓ set_tris_x(byte)
▪ Thiết lập hướng IN/OUT cho PORT x trong đó 0: OUTPUT, 1:
INPUT.
▪ set_tris_a(0xF0); // chân 0,1,2,3 là OUTPUT ; chân 4,5,6,7
là INPUT
▪ Giá trị thanh ghi TMR0 sẽ tăng theo từng chu kỳ xung
đồng hồ
✓ Tần số vào của Timer0 = ¼ tần số thạch anh
TOSE (Timer0 Source Edge Select bit): bit lựa chọn cạnh
tích cực
T = 4 × (1/Fosc) * Prescaler
▪ Fosc : tần số dao động thạch anh
▪ Prescaler: giá trị bộ chia trước
Trong CCS
setup_timer_0(int8 mode)
set_timer0(int8 value)
Ví dụ: setup_timer_0(T0_INTERNAL|T0_DIV_64);
set_timer0(1);
TS. Đặng Phước Vinh Khoa Cơ khí
120
Ví dụ
Viết chương trình nhấp nháy LED với chu kỳ 1s dùng Timer0
00 1:1
01 1:2
10 1:4
11 1:8
✓Timer1 tăng lên 1 khi có cạnh lên của xung bên ngoài
✓Counter phải nhận 1 xung cạnh xuống trước khi có xung
đếm
✓Ngõ vào xung clock bên ngoài sẽ đồng bộ với xung clock bên
trong
✓Timer1 không tăng giá trị khi có xung đếm trong chế độ
SLEEP do mạch đồng bộ ngừng hoạt động → không thể
đánh thức VĐK ở chế độ SLEEP
✓Bộ đếm tiếp tục tăng bất đồng bộ với xung clock bên trong
✓Bộ đếm hoạt động ở chế độ SLEEP → có thể phát sinh ngắt
để khởi động lại VĐK
✓ Mạch dao động thạch anh được thiết kế và tích hợp bên trong
giữa chân T1OSI (ngõ vào) và T1OSO (ngõ ra có khuyếch đại)
T = 4 × (1/Fosc) * Prescaler
▪ Fosc : tần số dao động thạch anh
▪ Prescaler: giá trị bộ chia trước
Trong CCS
setup_timer_1(int16 mode)
set_timer1(int16 value)
Ví dụ: setup_timer_1(T1_INTERNAL|T1_DIV_1); Tràn bộ định
thời sau 10ms
set_timer1(55536);
TS. Đặng Phước Vinh Khoa Cơ khí
BỘ ĐỊNH THỜI
TIMER 2
Firma convenzione
Politecnico di Milano e Veneranda Fabbrica
del Duomo di Milano
Aula Magna – Rettorato
Mercoledì 27 maggio 2015
137
Timer 2 – Đặc điểm
Trong CCS
Prescaler Giá trị đỉnh Bao nhiêu lần đếm
tràn thì xảy ra ngắt
Viết chương trình nhấp nháy LED với chu kỳ 0.5s dùng Timer2
Viết chương trình khi nhấn nút SW1 thì LED 7 đoạn thực hiện vòng lặp
đếm lên từ 0 đến 9. Thời gian delay mỗi lần đếm là 2.5s. Dùng Timer2 để
thực hiện delay
U5 R6 Q4
13 33 NPN
OSC1/CLKIN RB0/INT
14 34
OSC2/CLKOUT RB1 330
35
RB2
2 36
RA0/AN0 RB3/PGM
3 37 LED_7_DOAN
RA1/AN1 RB4
4 38
RA2/AN2/VREF-/CVREF RB5
5 39
RA3/AN3/VREF+ RB6/PGC
6 40 R7
SW1
RA4/T0CKI/C1OUT RB7/PGD
7 10k
RA5/AN4/SS/C2OUT
15
RC0/T1OSO/T1CKI
8 16
RE0/AN5/RD RC1/T1OSI/CCP2
9 17
RE1/AN6/WR RC2/CCP1
10 18
RE2/AN7/CS RC3/SCK/SCL
23
RC4/SDI/SDA
1 24
MCLR/Vpp/THV RC5/SDO
25
RC6/TX/CK
26
RC7/RX/DT
19
LED_7_DOAN
RD0/PSP0
20
RD1/PSP1
21
RD2/PSP2
22
RD3/PSP3
27
RD4/PSP4
28
TS. Đặng Phước Vinh
RD5/PSP5
RD6/PSP6
29 Khoa Cơ khí
30
RD7/PSP7
149
CCP: Capture/Compare/PWM
- Phước Vinh
TS. Đặng - CCPxX CCPxY CCPxM3 Khoa CCPxM1
CCPxM2 Cơ khí CCPxM0
151
Chế độ Capture
✓ Cờ ngắt: CCPxIF
✓ Giá trị trong thanh ghi CCPRx sẽ thường xuyên được so sánh với
TMR1
✓ Khi CCPRx = TMR1
▪ Các chân CCP sẽ thay đổi trạng thái: tùy thuộc vào các bit
CCPxM3:CCPxM0 (CCPxCON<3:0>)
▪ Cờ ngắt CCPxIF được set
✓ 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ộ ADC
✓ CCPxX, CCPxY: 2 bit thấp nhất chứa giá trị tính độ rộng xung
(duty cycle) của khối PWM
1. Thiết lập thời gian của 1 chu kỳ của xung cần điều chế (period)
→ đưa giá trị thích hợp vào PR2
7 6 5 4 3 2 1 0 CCPxX CCPxY
Tạo ra xung có chu kỳ 10kHz, duty = 25%, dùng OSC = 4Mhz, T2CKPS: 1
−4 1
0.25 10 = Value 1
4 10 6
Tạo ra xung có chu kỳ 10kHz, duty = 25%, dùng OSC = 4Mhz, T2CKPS: 1
CCPR2L = 00011001;
CCP2CON = 00001100;
Tạo ra xung có chu kỳ 10kHz, duty = 25%, dùng OSC = 4Mhz, T2CKPS: 1
setup_timer_2(T2_DIV_BY_1,99,1);
setup_ccp2(CCP_PWM);
set_pwm2_duty(0);
set_pwm2_duty(value);
value
duty_cycle = value = 0.25 4 ( 99 + 1) = 100
4 ( PR2 + 1)
time
Main
time
(b) Thực thi chương trình có ngắt
✓ Các cờ báo ngắt được set lên 1 bất chấp trạng thái ngắt tương
ứng cho hay không cho phép ngắt
✓ Khi GIE được phép và bit cờ ngắt và bit cho phép ngắt độc lập
lên 1 → xảy ra ngắt
✓TS.Để kết
Đặng thúc
Phước chương trình ngắt → lệnh RETFIE
Vinh Khoa Cơ khí
167
Xử lý ngắt
PSPIE: bit cho phép ngắt đọc/ghi ở port nhánh song song (PSP)
ADIE: bit cho phép ngắt bộ chuyển đổi ADC
RCIE: bit cho phép ngắt nhận dữ liệu USART
TXIE: bit cho phép ngắt phát dữ liệu USART 1: cho phép ngắt
0: không cho
SSPIE: bit cho phép ngắt port nối tiếp đồng bộ phép ngắt
CCP1IE: bit cho phép ngắt CCP1
TMR2IE: bit cho phép ngắt tương thích TMR2 với PR2
TNR1IE: bit cho phép ngắt tràn TMR1
✓ Timer0
▪ Xảy ra khi thanh ghi TMR0 tràn từ FFh → 00h
▪ Bit cho phép ngắt TMR0IE (INTCON<5>)
▪ Cờ ngắt TMR0IF (INTCON<2>)
✓ Timer1
▪ Xảy ra khi thanh ghi TMR1H:TMR1L tràn từ FFFFh → 0000h
▪ Bit cho phép ngắt TMR1IE (PIE1<0>)
▪ Cờ ngắt TMR1IF (PIR1<0>)
✓ Timer2
▪ Thanh ghi TMR2 tăng đến giá trị PR2 và đi qua postscaler
▪ Bit cho phép ngắt TMR2IE (PIE1<1>)
▪ Cờ ngắt TMR2IF (PIR1<1>)
▪ Có thể tắt ngắt Timer2 bằng cách xóa bit TMR2ON(T2CON<2>)
Trong CCS
#int_TIMER0
void ngat_timer0(){
…
}
void main() {
enable_interrupts(INT_TIMER0);
enable_interrupts(GlOBAL);
}
✓ Ngắt xảy ra khi có xung tác động lên chân RB0/INT → INTF = 1
(INTCON<1>).
✓ Phải được xóa bằng phần mềm trước khi có phép ngắt trở lại
✓ Bit cho phép INTE (INTCON<4>)
✓ Bit điều khiển cạnh INTEDG (OPTION_REG<6>)
▪ INTEDG = 1: Kích bằng cạnh lên
▪ INTEDG = 0: Kích bằng cạnh xuống
Viết chương trình nhấp nháy LED đơn 1s khi nhấn nút SW
BỘ CHUYỂN ĐỔI
Firma convenzione
ADC
Politecnico di Milano e Veneranda Fabbrica
del Duomo di Milano
Aula Magna – Rettorato
Mercoledì 27 maggio 2015
187
Tổng quan về ADC
✓ Có 8 kênh chuyển đổi ADC với độ phân giải 10 bit → 𝟐𝟏𝟎 mức giá trị digital
✓ Có các ngõ vào điện áp chuẩn thấp và cao
▪ Phần mềm → Tạo tổ hợp VDD, VSS, RA2 hoặc RA3
✓ Có cấu trúc độ lập để có thể hoạt động khi VĐK ở chế độ sleep
✓ Xung cung cấp cho ADC được lấy từ dao động RC bên trong của khối
ADC
✓ Khối ADC có 4 thanh ghi:
▪ ADRESH (A/D Result High Register)
▪ ADRESL (A/D Result Low Register)
▪ ADCON0 (A/D Control Register 0)
▪ ADCON1 (A/D Control Register 1)
ADCON1
✓ Thời gian chuyển đổi ADC cho mỗi bit được xác định là TAD
✓ Để chuyển đổi 10 bit → cần tối thiểu 12 TAD
✓ Nguồn xung clock cho khối ADC được lựa chọn từ ADCS1:ADCS0
✓ Để chuyển đổi ADC được chính xác → TAD = 1.6µ
ADCON1 ADCON0
Clock Conversion
<ADCS2> <ADCS1:ADCS0>
0 00 FOSC/2
0 01 FOSC/8
0 10 FOSC/32
1 00 FOSC/4
1 01 FOSC/16
1 10 FOSC/64
TS. Đặng Phước Vinh Khoa Cơ khí
x 11 FRC (xung clock lấy từ bộ dao động nội RC)
199
Lưu ý
✓ Các chân dùng làm ngõ vào tương tự → thiết lập input
#device ADC = 10
SETUP_ADC(ADC_CLOCK_DIV_2);
SETUP_ADC_PORTS(AN0_AN1_AN2_AN3_AN4);
SET_ADC_CHANNEL(0);
DELAY_US(10);
VALUE = READ_ADC();
SDA
I2C bus Serial
Data
MCU Sensor ADC EEPROM MCU Line
Master Slave Slave Slave Slave
Mode Speed
Standard Mode: 100 kbit/s
1 Master – 1 Slave
Low-speed Mode: 10 kbit/s
Idle Idle
Status Status
Start Stop
Transper data
Start sequence
TS. Đặng Phước Vinh Khoa Cơ khí
210
Đọc 1 byte ▪ Master gởi cho Slave
▪ Bằng phần mềm
Stop
Start Re-Start Sequence
Sequence Write Sequence Read
NAK
ST Device Add. (7 bit) W Register Add (8 bit) SR Device Add. (7 bit) R NAK SP
Master
AK AK AK Data (8 bit)
Slave
AK AK AK
AK AK AK Data (8 bit)
Slave
AK AK AK
NAK Stop
AK AK NAK SP
Master
Start Stop
Sequence Write Sequence
Slave AK AK AK
AK AK AK
Start Stop
Sequence Write Sequence
ST Device Add. (7 bit) W Register Add (8 bit) Data (8 bit) Data (8 bit) SP
Master
AK AK AK AK
Slave
AK AK AK AK
1. SSPCON1, SSPCON2
❑ Điều khiển MSSP
❑ Cho phép đọc ghi
2. SSPSTAT
❑ Chứa các trạng thái hoạt động của MSSP
❑ Chỉ cho phép đọc & ghi ở 2 bit đầu, 6 bit còn lại chỉ đọc
3. SSPBUF: chứa dữ liệu truyền nhận nối tiếp
4. SSPSR: thanh ghi dịch dùng để truyền nhận dữ liệu
5. SSPADD: chứa giá trị tạo ra tốc độ baud cho xung clock dùng để truyền
nhận dữ liệu tại chân SCL
bit 4: CKP: không có tác dụng trong chế độ I2C Master Mode
bit 6: ACKSTAT: Acknowledge Status bit (chỉ có tác dụng khi truyền
dữ liệu ở chế độ I2C Master Mode)
1: chưa nhận được xung ACK từ I2C Slave
0: nhận được xung ACK từ I2C Slave
bit 5: ACKDT: Acknowledge Data bit (chỉ có tác dụng khi nhận dữ
liệu ở chế độ I2C Master Mode)
1: Not Acknowledge
0: Acknowledge
bit 4: ACKEN: Acknowledge Sequency Enable bit (chỉ có tác dụng khi
nhận dữ liệu ở chế độ I2C Master Mode)
1: Cho phép xung ACK xuất hiện ở chân SDA và SCL khi kết
thúc quá trình nhận dữ liệu. Tự động xóa bởi phần cứng
0: không cho phép chế độ trên
TS. Đặng Phước Vinh Khoa Cơ khí
219
SSPCON2 - MSSP CONTROL REGISTER 2
bit 3: RCEN: Receive Enable bit (chỉ có tác dụng khi ở chế độ Master)
1: cho phép nhận dữ liệu ở chế độ I2C
0: không cho phép
RC4
RC3
RSEN = 1
✓ Còn được gọi là giao tiếp truyền thông nối tiếp (Serial
Communications Interface - SCI)
✓ Chế độ:
▪ Bất đồng bộ (Asynchronous)
▪ Đồng bộ (Master mode)
▪ Đồng bộ (Slave mode)
TX RX
Bất đồng bộ
✓ Truyền một byte dữ liệu trong một thời điểm RX TX
✓ Giao tiếp theo chế độ full-duplex
✓ Không có chân tạo xung clock
✓ Có bit START và bit STOP, bit chẵn lẻ…
✓ Các khối truyền và nhận dữ liệu độc lập với nhau sẽ dùng chung
tần số tương ứng với tốc độ baud
✓ Khối truyền và nhận phải dùng chung một định dạng dữ liệu
TXSTA
RCSTA
✓ Thành phần quan trọng nhất: thanh ghi dịch TSR (Transmit
Shift Register)
✓ Dữ liệu cần truyền sẽ được đưa trước vào thanh ghi TXREG
✓ Thanh ghi TSR không có trong bộ nhớ dữ liệu và chỉ được điều
khiển bởi CPU
1. Tạo xung truyền tốc độ baud (đưa giá trị vào thanh ghi SPBRG)
2. Cho phép cổng giao tiếp nối tiếp bất đồng bộ hoạt động →
SYNC = 0 & SPEN = 1
3. Set bit TXIE nếu cần sử dụng ngắt
4. Set bit TX9 nếu cần truyền 9 bit dữ liệu
5. Set bit TXEN để cho phép truyền dữ liệu
6. Đưa bit thứ 9 vào TX9D (nếu truyền dữ liệu 9 bit)
7. Đưa 8 bit dữ liệu cần truyền vào thanh ghi TXREG
8. Kiểm tra bit GIE và PEIE nếu sử dụng ngắt truyền
✓ Xuất hiện khi khối nhận (thanh ghi RSR) không nhận được bit
STOP đúng thời điểm
→ Khối truyền và nhận hoạt động với tốc độ baud khác nhau
✓ Thành phần quan trọng nhất: thanh ghi dịch RSR (Receive Shift
Register)
✓ Dữ liệu nhận được trong thanh ghi RSR sẽ được đưa vào thanh
ghi RCREG → cờ RCIF = 1 (RCIF = 0 khi dữ liệu tại RCREG đã
được đọc)
TS. Đặng Phước Vinh Khoa Cơ khí
252
Nhận dữ liệu
✓ RCREG là thanh ghi có bộ đệm kép hoạt động theo cơ chế FIFO (First
In First Out)
▪ RCREG có thể nhận 2 byte dữ liệu
▪ Byte thứ 3 tiếp tục đưa vào thanh ghi RSR
✓ Nếu bit STOP của byte thứ 3 đã được nhận mà thanh ghi RCREG vẫn
đầy:
▪ Cờ báo tràn OERR sẽ được set
▪ Dữ liệu trong thanh ghi RSR sẽ bị mất
▪ Quá trình đưa dữ liệu từ RSR đến RCREG sẽ bị gián đoạn
→ Phải lấy hết dữ liệu của thanh ghi RCREG trước khi nhận dữ liệu
tiếp theo
✓ Bit OERR phải được xóa bằng phần mềm: xóa bit CREN rồi set lại
✓ Bit FERR và bit dữ liệu thứ 9 (RX9D) được đưa vào bộ đệm như 8
bit dữ liệu
✓ Đọc thanh ghi RCREG → cập nhật giá trị mới cho FERR và RX9D
→ Đọc thanh ghi RCSTA trước khi đọc thanh ghi RCREG
TS. Đặng Phước Vinh Khoa Cơ khí
254
Các bước thực hiện khi NHẬN
1. Tạo xung truyền tốc độ baud (đưa giá trị vào thanh ghi SPBRG)
2. Cho phép cổng giao tiếp nối tiếp bất đồng bộ hoạt động → SYNC = 0 &
SPEN = 1
3. Set bit RCIE nếu cần sử dụng ngắt
4. Set bit RX9 nếu cần truyền 9 bit dữ liệu
5. Set bit CREN để cho phép truyền dữ liệu
6. Cờ RCIF được set sau khi nhận được dữ liệu
7. Đọc 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 hay không
8. Đọc dữ liệu 8 bit từ thanh ghi RCREG
9. Nếu quá trình nhận dữ liệu bị lỗi → xóa bit CREN
10.
TS. Kiểm tra bit
Đặng Phước GIE và PEIE nếu sử dụng ngắt nhận
Vinh Khoa Cơ khí
255
Giao tiếp nối tiếp UART – RS232
14 25
13 1
25 14
RS232 cable
C1 10uF
U4
1 15 1 3 P1
RE3/MCLR/VPP RC0/T1OSO/T1CKI
16
RC1/T1OSI/CCP2
2 17 1
RA0/AN0/ULPWU/C12IN0- RC2/P1A/CCP1 C1+ C1- DCD
3 18 6
RA1/AN1/C12IN1- RC3/SCK/SCL DSR
4 23 11 14 2
RA2/AN2/VREF-/CVREF/C2IN+ RC4/SDI/SDA T1IN T1OUT RXD
5 24 12 13 7
RA3/AN3/VREF+/C1IN+ RC5/SDO R1OUT R1IN RTS
6 25 10 7 3
RA4/T0CKI/C1OUT RC6/TX/CK T2IN T2OUT TXD
7 26 9 8 8
RA5/AN4/SS/C2OUT RC7/RX/DT R2OUT R2IN CTS
14 4
RA6/OSC2/CLKOUT DTR
13 19 2 9
RA7/OSC1/CLKIN RD0 VS+ RI
20 6
RD1 VS-
33 21
RB0/AN12/INT RD2
34
RB1/AN10/C12IN3- RD3
22
C2+ C2- C4 C3 ERROR
35 27 10uF 10uF
RB2/AN8 RD4
36 28 COMPIM
RB3/AN9/PGM/C12IN2- RD5/P1B
37 29 4 5
RB4/AN11 RD6/P1C
38 30
RB5/AN13/T1G RD7/P1D C2
39 10uF
RB6/ICSPCLK
40 8
RB7/ICSPDAT RE0/AN5
9 D9
RE1/AN6
10
R9
RE2/AN7
270R
PIC16F877A LED
▪ #use rs232: cung cấp cho trình biên dịch thông tin về các tham
số cấu hình RS232 sẽ sử dụng để giao tiếp
▪ parity = N: khai báo có sử dụng bit kiểm tra chẳn lẻ hay không, ở
đây ta không kiểm tra nên thiết lập parity = N
char c;
c = getch();
Tab chức
năng
Thư mục
hiện hành
Tạo giao diện đồ họa người dùng GUI (Graphical User Interface) để
kết nối với vi điều khiển PIC thông qua cổng COM
Đọc các cổng COM trong bộ nhớ đến vùng làm việc của Matlab
(workspace)
object = instrfind;
Gửi dữ liệu
fwrite(tenbien, gia_tri gia_tri);
fwrite(s, 1);
TS. Đặng Phước Vinh Khoa Cơ khí
275
MATLAB GUI – Ví dụ