70
Giáo trình thí nghiệm vi điều khin ng dng 1 BÀI 1 : XUT NHP I/O PORT: I.MỤC ĐÍCH THÍ NGHIỆM : Kiến thc sinh viên cần đạt được sau khi thc tp: Liệt kê các thanh ghi liên quan đến vic xlý tính hiu scác chân vi điều khin . Khi to các chân của vi điều khin là ngõ ra , vào s. Gii thích được công dng ca hàm _delay(n) , cách dùng hàm delay để chng di cho nút nhn. Lập trình điều khin led theo yêu cu . Gii thích ưu khuyết điểm ca ngt . II.DNG CTHÍ NGHIM : Kít thí nghim + cáp USB. Máy tính . Ngun 12V/1A. III.CƠ SỞ LÝ THUYT : 1.Thanh ghi qui định tín hiu xchân vi điều khin là tín hiu shay tín hiệu tương t: Nhng chân có kí hiu ANX là nhng chân va có thxlý tín hiu sva có thxlý tín hiệu tương tự . Do đó khi làm việc vi nhng chân này ta cần chú ý đến hai thanh ghi :

Giao Trinh Thi Nghiem VDK

Embed Size (px)

Citation preview

Page 1: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

1

BÀI 1 : XUẤT NHẬP I/O PORT:

I.MỤC ĐÍCH THÍ NGHIỆM :

Kiến thức sinh viên cần đạt được sau khi thực tập:

Liệt kê các thanh ghi liên quan đến việc xử lý tính hiệu số ở các chân vi điều khiển .

Khởi tạo các chân của vi điều khiển là ngõ ra , vào số .

Giải thích được công dụng của hàm _delay(n) , cách dùng hàm delay để chống dội cho

nút nhấn.

Lập trình điều khiển led theo yêu cầu .

Giải thích ưu khuyết điểm của ngắt .

II.DỤNG CỤ THÍ NGHIỆM :

Kít thí nghiệm + cáp USB.

Máy tính .

Nguồn 12V/1A.

III.CƠ SỞ LÝ THUYẾT :

1.Thanh ghi qui định tín hiệu xử lý ở chân vi điều khiển là tín hiệu số hay tín hiệu tương

tự:

Những chân có kí hiệu ANX là những chân vừa có thể xử lý tín hiệu số vừa có thể xử lý tín

hiệu tương tự . Do đó khi làm việc với những chân này ta cần chú ý đến hai thanh ghi :

Page 2: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

2

Hai thanh ghi này có tổng cộng 14bit từ ANS0 đến ANS13 , sẽ quy định tín hiệu làm việc

của các chân từ AN0 đến AN13 là tín hiệu số hay tín hiệu analog .

ANSX=0 : Cho phép chân ANX xử lý tín hiệu số .

ANSX=1 : Cho phép chân ANX xử lý tín hiệu tương tự .

Trong đó : X= 0 – 13

2.Chức năng của thanh ghi TRIS :

Trong các chân xử lý tín hiệu số , hoạt động của chân có thể là ngõ ra (làm cho led chớp tắt,

kích transistor , điều khiển hoạt động IC....) , hay có thể là ngõ vào (đọc trạng thái nút nhấn , đọc

encoder , đọc tín hiệu từ cảm biến số....). Như vậy , để khởi tạo cho các chân là ngõ ra hay ngõ

vào tín hiệu số , chúng ta cần chú ý đến thanh ghi TRISX (X=A,B,C,D,E):

TRISXY=0:Quy định bit thứ Y của PORTX là ngõ ra (0 = Output)

TRISXY=1:Quy định bit thứ Y của PORTX là ngõ vào (1=Input)

(Trong đó :X=A,B,C,D,E ; Y=0-7)

Chú ý : PORTE chỉ có 4 bit thấp : TRISE0, TRISE1, TRISE2 ,TRISE3.

3. Chức năng của thanh ghi PORT :

Trong trường hợp xử lý tín hiệu số và là ngõ ra , thì có thể là ngõ ra mức cao (điện áp ở chân

đó là VH) , hay ngõ ra là mức thấp (điện áp là VL) sẽ do bit RXY của thanh ghi PORTX quy

định .

RXY=0 : Quy định chân thứ Y của PORTX là mức thấp(VL).

RXY=1: Quy định chân thứ Y của PORTX là mức cao(VH).

(Trong đó : X=A,B,C,D,E ; Y=0-7)

Page 3: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

3

Tóm lại ta có bảng tóm tắt sau :

ANSX TRISXY RXY Kết quả

0 0 0 Ngõ ra mức thấp(0V)

0 0 1 Ngõ ra mức cao(+5V)

0 1 0 Tổng trở cao (R=∞)

0 1 1 Ngõ vào , tác động mức thấp

1 x x Xử lý tín hiệu tương tự .

4.Những thanh ghi đặc biệt chỉ có riêng ở PORTB:

4.1.Thanh ghi hỗ trợ điện trở treo bên trong:

Để tránh trạng thái thả nổi (tín hiệu điện áp ở chân đó không rõ ràng) khi khởi tạo PORTB là

ngõ vào số , PIC16f887 tích hợp thêm vào cho PORTB các điện trở kéo lên (pull-up), để sử dụng

các điện trở này ta chú ý đến thanh ghi :

WPUBy=0: Không cho phép điện trở kéo lên ở chân thứ y của PORTB.

WPUBy=1: Cho phép điện trở kéo lên ở chân thứ y của PORTB.

Khi sử dụng điện trở kéo lên ngoài việc sử dụng thanh ghi WPUB còn phải khởi tạo bit:

RBPU Điện trở kéo lên nên khởi tạo khi PORTB là ngõ vào số , các PORT khác không có hỗ

trợ điện trở treo trong , do đó nếu có nhu cầu sử dụng ta có thể mắc thêm điện trở bên

ngoài.

4.2.Ngắt ngoài ở chân RB0:

Để xử lý được các tín hiệu tác động tức thời , chân RB0 có hỗ trợ xử lý ngắt (interrupt ) kí

hiệu ở chân là INT, khởi tạo ngắt ngoài ở chân RB0 ta cần chú ý đến các bit sau :

INTE(Interrupt enable ) : bit cho phép ngắt ở PORTB

Page 4: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

4

INTF(Interrupt flag): cờ ngắt , bit này tự động bằng 1 khi có sự kiện ngắt (cạnh lên hay

cạnh xuống) xảy ra ở chân RB0, ta phải xóa bít này trong khi lập trình .

GIE(Global interrupt ) : bit cho phép ngắt toàn cục.

INTEDG (interrupt edge select bit ) : Bit chọn cạnh tác động để sinh ra sự kiện ngắt ở

PORTB.

INTEDG=1: Xảy ra ngắt khi có tín hiệu cạnh lên ở PORTB

INTEDG=0: Xảy ra ngắt khi có tín hiệu cạnh xuống ở PORTB

Các bước khởi tạo ngắt INT:

Bước 1 : Khởi tạo chân RB0 là ngõ vào số , điện trở treo.

Bước 2 : Khởi tạo ngắt INT

INTE=1; //Cho phép ngắt hoạt động

INTF=0; //Xóa cờ ngắt thì ngắt lần tiếp theo mới có thể xảy ra.

INTEDG=....; //Chọn cạnh tác động ngắt.

GIE=1; //Cho phép ngắt toàn cục .

4.3.Ngắt on-change ở PORTB:

Ngoài ngắt INT chỉ có duy nhất ở chân RB0 , thì cả PORTB (từ RB0 đến RB7) còn hỗ trợ

ngắt on-change , ngắt on-change xảy ra khi tín hiệu logic ở chân của PORTB thay đổi trạng thái

logic.

Sơ đồ ngắt on-change:

Page 5: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

5

Các thanh ghi và các bit điều khiển ngắt on-change :

IOCBX=0 : Không cho phép ngắt on-change ở chân thứ X của PORTB.

IOCBX=1 : Cho phép ngắt on-change ở chân thứ X của PORTB.

Các bit khởi tạo khác :

RBIF : Cờ ngắt on-change ở PORTB, cần phải xóa bít này trong lập trình.

RBIE : Bit cho phép ngắt on-change của PORTB.

GIE : Bit cho phép ngắt toàn cục.

Các bước khởi tạo ngắt on-change :

Bước 1 : Khởi tạo PORTB là ngõ vào số , có điện trở treo.

Bước 2 : Khởi tạo ngắt on-change ở PORTB

IOCB=0xFF; //khởi tạo toàn bộ PORTB ngắt on-change(có thể khởi tạo

một hay cả PORTB).

RBIE=1; //Cho phép ngắt xảy ra .

RBIF=0; //Xóa cờ ngắt

GIE=1; //Cho phép ngắt toàn cục

Chú ý : Đối với ngắt on-change , việc xóa cờ ngắt (RBIF=0) không đủ để cho lần ngắt

tiếp theo được thực hiện , mà còn phải thêm điều kiện đọc hoặc viết vào thanh ghi PORTB.

Ví dụ :

unsigned char bien ;

bien = PORTB ; //đọc thanh ghi PORTB.

hoặc PORTB =5 ; //viết vào thanh ghi PORTB

4.4.Bảng so sánh giữa ngắt INT và ngắt on-change :

Ngắt ở chân INT(RB0) Ngắt on-change

Chí có duy nhất ở chân RB0 Xảy ra trên cả PORTB

Để xảy ra ngắt thì tín hiệu logic là cạnh lên

hoặc cạnh xuống.

Chỉ cần tín hiệu logic thay đổi là xảy ra ngắt,

không phân biệt cạnh lên hay cạnh xuống.

Các bit khởi tạo :

INTE , INTF , INTEDG , GIE

Các bit khởi tạo :

IOCBx , RBIE , RBIF , GIE

Để cho lần ngắt tiếp theo được thực hiện thì

cần phải xóa cờ ngắt INTF.

Để cho lần ngắt tiếp theo được thực hiện thì

cần phải xóa cờ ngắt INTF và đọc ( hoặc ghi)

vào thanh ghi PORTB.

Page 6: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

6

IV.BÀI TẬP THỰC HÀNH :

Bài 1: Viết chương trình điều khiển led theo yêu cầu sau :

Nhấn (không giữ) nút nhấn nối với chân RB0 : led RE1 và led RE2 chớp tắt xen kẽ trong

thời gian T=0.2(s).

Nhấn (không giữ) nút nhấn nối với chân RB1 : led RE1 và led RE2 cùng chớp tắt trong

thời gian T=0.5(s).

Nhấn (không giữ) nút nhấn nối với chân RB2 : led RE1 sáng và led RE2 tắt trong thời

gian T=0.1(s) , led RE1 tat và LED2 sáng T=0.7(s).

Sử dụng định thời bằng hàm _delay(n) ; thạch anh Fosc = 4 Mhz.

Sơ đồ phần cứng :

*Bước 1: Tạo một project mới với tên 01_01_MSSV .

*Bước 2: Nhập chương trình sau vào máy tính và hoàn thành các dấu …….

#include<htc.h>

__CONFIG(INTIO&WDTDIS&PWRTEN&MCLREN&UNPROTECT&DUNPROTECT&BO

RDIS&IESODIS&LVPDIS&FCMDIS);

void delay(unsigned char counter); //Khai báo chương trình con hàm delay

void RB_0( );void RB_1( );void RB_2( );

char so_lan_nhan;

void main( ) //Chương trình chính

{

//Disable analog ở các chân RE1,RE2,RB0,RB1,RB2

ANS6=ANS7=ANS12=ANS10=ANS8= …….;

//Khởi tạo các chân RE1,RE2 là ngõ ra , ban đầu led tắt

TRISE1=TRISE2= …….; RE1=RE2= ……. ;

//Khởi tạo chân RB0,RB1,RB2 là ngõ vào, tác động mức thấp

TRISB0=TRISB1=TRISB2= …….; RB0=RB1=RB2= …….;

//Khởi tạo điện trở kéo lên ở các chân RB0,RB1,RB2

WPUB0=WPUB1=WPUB2= …….; RBPU= ……. ;

Page 7: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

7

//(-------------1------------)

while(1)

{

//Xác định trạng thái các nút nhấn

if(!RB0)so_lan_nhan=0; //(------------2-----------)

else if(!RB1)so_lan_nhan=1; //(------------3-----------)

else if(!RB2)so_lan_nhan=2; //(------------4-----------)

//Hiển thị led

if (so_lan_nhan==0) RB_0( );//Chạy chương trình con RB_0

else if(so_lan_nhan==1) RB_1( ); //Chạy chương trình con RB_1

else if(so_lan_nhan==2) RB_2( ); //Chạy chương trình con RB_2

}

}

//(-------------5-----------)

void delay(unsigned char counter) //Chương trình con làm tăng thời gian delay

{

unsigned char value=0;

while(counter>value)

{

value++;

_delay(100000); //trễ 1ms với Fosc = 4MHz

}

}

void RB_0( )

{

RE1^=1;RE2= …….RE1; // led RE1 và led RE2 chớp tắt xen kẽ

delay(2); //delay 0.2s

}

void RB_1( )

{

RE1^=1;RE2 …….RE1; // led RE1 và led RE2 cùng chớp tắt

delay(5); //delay 0.5s

}

void RB_2( )

{

RE1= …….;RE2= …….; // led RE1 sáng và led RE2 tắt

delay(1); //delay 0.1s

RE1= …….;RE2= …….; // led RE1 tat và LED2 sáng

delay(7); //delay 0.7s

}

*Bước 3: Biên dịch chương trình, nạp xuống kít thí nghiệm , tiến hành nhấn các nút nhấn và

quan sát 2 led.

*Bước 4: Thay đổi chương trình như sau:

Thêm vào dòng : (-------------1------------) đoạn code sau:

Page 8: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

8

IOCB0=IOCB1=IOCB2=1; //Cho phép ngắt onchange ở chân B0,B1,B2

RBIE=1; //Cho phép ngắt onchange toàn PORTB

RBIF=0; //Reset cờ ngắt

PEIE=1; //Cho phép ngắt ngoại vi

GIE=1; //Cho phép ngắt toàn cục

Xóa các dòng 2,3,4.

Thêm vào dòng: (-------------5-----------) đoạn code sau:

void interrupt isr( ) //Chương trình con xử lý tất cả ngắt

{

if(RBIE&&RBIF) //Chương trình con cho ngắt on-change

{

if(!RB0) so_lan_nhan=0; //nhấn RB0

else if(!RB1) so_lan_nhan=1; //nhấn RB1

else if(!RB2) so_lan_nhan=2; //nhấn RB2

RBIF=0; //Reset cờ ngắt

}

}

*Bước 5: Biên dịch chương trình, nạp xuống kít thí nghiệm , tiến hành nhấn các nút nhấn và

quan sát 2 led.

*Bước 6: Nhận xét sự khác nhau về tốc độ đáp ứng khi nhấn nút nhấn trước và sau khi sửa code,

giải thích, rút ra kết luận:

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

Page 9: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

9

Bài 2 : Viết chương trình điều khiển led theo yêu cầu sau :

Nhấn (không giữ) nút nhấn nối với chân RB0 lần (2n+1) : 8 led dịch từ trái qua phải.

Nhấn (không giữ) nút nhấn nối với chân RB0 lần (2n) : 8 led dịch từ phải qua trái.

n = 0,1,3,4,5…k

Sử dụng định thời bằng hàm _delay(n) ; thạch anh Fosc = 4 Mhz.

Sơ đồ phần cứng :

*Bước 1: Tạo một project mới với tên 01_02_MSSV.

*Bước 2 : Nhập chương trình sau vào máy tính và hoàn thành vào dấu …….

#include<htc.h>

__CONFIG(INTIO&WDTDIS&PWRTEN&MCLREN&UNPROTECT&DUNPROTECT&BO

RDIS&IESODIS&LVPDIS&FCMDIS);

char count=0;

void display(char number);

void main( )

{

char i=0;

//Disable analog các chân RE1,RE2,RB0,RB3,RB4,RB5

ANS6=ANS7=ANS9=ANS11=ANS12=ANS13=…….;

//Khởi tạo RE1 , RE2 là ngõ ra , trạng thái ban đầu led tắt

TRISE1=TRISE2=…….; RE1=RE2=…….;

//Khởi tạo RB0 là ngõ vào , tác động mức thấp

TRISB0=…….; RB0=…….;

//Cho phép điện trở kéo lên ở chân RB0;

IOCB0=…….; RBPU=…….;

//Khởi tạo ngắt ngoài ở chân RB0 .

INTEDG=..........; //cạnh lên

INTE =…….;

INTF =…….;

GIE =…….;

Page 10: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

10

while(1)

{

while(count==1) //Chương trình dịch từ trái qua phải.

{

i++;

if(i>=9)

i=1;

display(i);

_delay(100000);

}

while(count==2) //Chương trình dịch từ phải qua trái.

{

i--;

if(i<=0)

i=9;

display(i);

_delay(100000);

}

}

}

void interrupt isr( )

{

if(INTE&&INTF)

{

count++;

if(count…….3)count=1;

INTF=…….;

}

}

void display(char number) //Chương trình con hiển thị led khi nhận vào một số tương ứng

{

RE1=RE2=…….; //Tắt led RE1, RE2

TRISB |= 0b00111000;

RB3=RB4=RB5=…….; //Khởi tạo chân RB3 , RB4 , RB5 là tổng trở cao

switch(number)

{

case 1:

RE2=…….; //RE2 sáng

break;

case 2:

RE1=…….; //RE1 sáng

break;

case 3: //led D6 sáng

TRISB3=0;RB3=…….;TRISB4=…….;RB4=0;

Page 11: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

11

break;

case 4: //led D7 sáng

TRISB3=…….;RB3=0;TRISB4=…….;RB4=1;

break;

case 5: //led D8 sáng

TRISB4=…….;RB4=1;TRISB5=…….;RB5=0;

break;

case 6: //led D9 sáng

TRISB4=…….;RB4=0;TRISB5=…….;RB5=1;

break;

case 7: //led D10 sáng

TRISB5=0;RB5=…….;TRISB3=0;RB3=…….;

break;

case 8: //led D11 sáng

TRISB5=0;RB5=…….;TRISB3=0;RB3=…….;

break;

}

}

*Bước 3: Biên dịch chương trình , nạp xuống kít thí nghiệm , tiến hành nhấn nút nhấn và quan

sát các led.

*Bước 4:Trả lời câu hỏi :

Đề ra các phương pháp xử lý khi ngõ vào tác động mức cao :

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

V.BÀI TẬP TỰ GIẢI :

Bài 3.Viết chương trình đọc giá trị phím và hiển thị giá trị lên led 7 đoạn theo sơ đồ phần

cứng sau : (Tạo một project mới với tên 01_03_MSSV)

(Phím từ 0-9 , led hiển thị số tương ứng , phím „*‟ thể hiện chữ „S‟, phím „#‟ thể hiện chữ

„H‟, lúc không nhấn thể hiện chữ „U‟ ).

Page 12: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

12

Bài 4.Viết chương trình theo yêu cầu sau , 16 led kết nối với PORTD, PORTC (tác động

mức cao) , 8 nút nhấn kết nối với PORTB : (Tạo một project mới với tên 01_04_MSSV)

Nhấn nút RB0 :16 led dịch từ phải qua trái.

Nhấn nút RB1:16 led dịch từ trái qua phải.

Nhấn nút RB2:16 led chớp tắt xen kẽ.

Nhấn nút RB3:16 led sáng dần từ trái qua phải .

Nhấn nút RB4 :16 led sáng dần từ phải qua trái.

Nhấn nút RB5:16 led sáng dần từ trong ra ngoài.

Nhấn nút RB6:16 led sáng dần từ ngoài vào trong .

Nhấn nút RB7:16 led cùng chớp tắt.

Bài 5.Viết chương trình đếm số lần nhấn nút (RB0) và hiển thị từ 000 đến 255 lên 3 led bảy

đoạn theo sơ đồ phần cứng sau : (Tạo một project mới với tên 01_05_MSSV)

Page 13: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

13

BÀI 2 : ADC MODULE

I.MỤC ĐÍCH THÍ NGHIỆM :

Kiến thức sinh viên cần đạt được sau khi thực tập :

Giải thích được khái niệm và chức năng của điện áp tham chiếu.

Thiết lập được điện áp tham chiếu trong và ngoài cho khối ADC của vi điều khiển.

Liệt kê được các bước thiết lập đo ADC cho một hoặc nhiều kênh.

Thiết lập được công thức tính ADC 8-bit , và ADC 10-bit ở chế độ định dạng canh trái và

canh phải .

Tín toán được giá trị tín hiệu tương tự thu được thông qua giá trị của thanh ghi ADRESL,

ADRESH.

Thiết lập và khởi tạo được một project có liên quan LCD , thay đổi file LCD.h phù hợp

với cấu hình phần cứng bên ngoài .

II.DỤNG CỤ THÍ NGHIỆM:

Kít thí nghiệm + cáp USB.

Vít (vặn biến trở).

Máy tính .

Nguồn 12V/1A.

III.CƠ SỞ LÝ THUYẾT :

1.Tín hiệu tương tự và tính hiệu số :

Tín hiệu tương tự Tín hiệu số

Đồ thị tín hiệu analog và tín hiệu số

Trong thực tế , tín hiệu cần xử lý xung quanh ta là tín hiệu tương tự , ví dụ : vận tốc , nhiệt

độ , độ ẩm , cường độ ánh sáng , áp suất v.v...Tuy nhiên vi xử lý chỉ có thể làm việc với tín hiệu

số (chỉ có hai trạng thái 0 và 1) do đó để xử lý được các tín hiệu tương tự , thì vi điều khiển cần

phải có bộ chuyển đổi tín hiệu tương tự sang số ADC (Analog to Digital Converter).

Page 14: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

14

Bộ ADC được tích hợp bên trong vi điều khiển

Đồ thị của bộ chuyển đổi ADC 8-bit:

Độ phân giải (Resolution) : Từ sơ đồ trên ta thấy bộ chuyển đổi ADC có độ phân giải 8-

bit thì sẽ có 255 giá trị dùng để chứa các giá trị điện áp từ VREF- đến VREF+ , như vậy nếu bộ

chuyển đổi ADC có độ phân giải n bit thì sẽ có 2n-1 giá trị . Độ phân giải có liên quan mật thiết

đến chất lượng chuyển đổi ADC , độ phân giải càng cao thì kết quả chuyển đổi càng chính xác .

Điện áp tham chiếu (Reference voltage) : điện áp tham chiếu là điện áp dùng để so sánh

với tín hiệu điện áp analog cần đo , VREF+ nên chọn bằng với mức điện áp lớn nhất cần đo ,

không nên chọn nhỏ hơn hay lớn hơn .

2.ADC của vi điều khiển PIC16F887:

2.1Các chân vi điều khiển có khả năng xử lý tín hiệu analog :

Các chân có thể làm việc với tín hiệu analog

VREF+ VREF-

255

0

Tín hiệu tương tự

Tín hiệu số

Page 15: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

15

Sơ đồ khối bộ ADC trong vi điều khiển PIC16F887.

2.2Các thanh ghi điều khiển hoạt động chuyển đổi của bộ ADC :

ADON : Bit cho phép bộ ADC hoạt động

ADON=1 : Cho phép bộ ADC hoạt động

ADON=0 : Không cho phép hoạt động

GO/𝐃𝐎𝐍𝐄 : Bit chỉ trạng thái chuyển đổi , bit này tự động bằng 0 khi bộ ADC chuyển đổi xong,

muốn cho lần chuyển đổi tiếp theo được thực hiện , cần phải đặt bit này lên bằng 1 trong lập

trình .

Page 16: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

16

CHS<3:0>: Dùng để chọn kênh cần chuyển đổi .

ADCS<1:0> : Bit lựa chọn tần số chuyển đổi .

VCFG1 : Dùng để chọn điện áp tham chiếu VREF- .

VCFG1=1: khi đó VREF-= điện áp ở chân số 4 (VREF-)

VCFG1=0: khi đó VREF- = Vss

VCFG0 : Dùng để chọn điện áp tham chiếu VREF+.

VCFG0=1: khi đó VREF+= điện áp ở chân số 5 (VREF+)

VCFG0=0: khi đó VREF+= VDD

ADFM : bit dùng để lựa chọn kiểu định dạng kết quả chuyển đổi :

Sau khi chuyển đổi hoàn tất , kết quả sẽ được lưu theo một trong hai kiểu

Page 17: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

17

Hai thanh ghi ADRESH và ADRESL là hai thanh ghi dùng để chứa kết quả khi bộ ADC

chuyển đổi hoàn tất , bộ ADC của vi điều khiển PIC16F887 có độ phân giải 10-bit do đó cần hai

byte để chứa kết quả , tuy nhiên kết quả có thể lưu theo hai kiểu : canh trái (ADFM=0) và canh

phải (ADFM=1).

Đối với định dạng kết quả bên trái : ADFM=0 thì ta có thể đọc kết quả như sau :

Độ phân giải 10-bit : Kết quả = ADRESH*4+ADRESL >> 6 (1)

Độ phân giải 8-bit : Kết quả = ADRESH (2)

Đối với định dạng kết quả bên phải : ADFM=1 thì ta có thể đọc kết quả như sau :

Độ phân giải 10-bit : Kết quả = ADRESH*256+ADRESL (3)

Độ phân giải 8-bit : Kết quả = ADRESH*64+ADRESL>>2 (4)

Rõ ràng ta thấy biểu thức (1) và (4) gây khó khăn trong việc lập trình và thời gian cần tín

toán lâu hơn , do đó ta rút ra kết luận:

Khi cần đọc ADC 8-bit thì cần định dạng kết quả bên trái(ADFM=0)

Khi cần đọc ADC 10-bit thì cần định dạng kết quả bên phải(ADFM=1)

2.3 Ngắt ADC :

Khối ADC cũng có thể tạo ra sự kiện ngắt (ngắt trong) , sự kiện ngắt xảy ra khi bộ ADC

chuyển đổi hoàn tất .

Sơ đồ khởi tạo ngắt ADC

ADIE : Bit cho phép bộ chuyển đổi ADC.

ADIF : Cờ ngắt ADC , bit này tự động bằng 1 khi bộ ADC chuyển đổi hoàn tất , để cho

lần chuyển đổi tiếp theo được thực hiện , chúng ta cần phải xóa bít này bằng phầm mềm lập

trình.

PEIE : Bit cho phép ngắt ngoại vi .

GIE : Bit cho phép ngắt toàn cục.

2.4 Các bước khởi tạo bộ chuyển đổi ADC:

Bước 1:Chọn tín hiệu xử lý

Khởi tạo chân là ngõ vào: TRISxy=1; //x:A,B,E , y:0-7

Khởi tạo chân xử lý tín hiệu tương tự : ANSx=1; //Trong đó : x=0-13

Bước 2:Khởi tạo khối ADC

Chọn tần số chuyển đổi ADCS1=.........;ADCS0=........;

Page 18: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

18

Chọn điện áp tham chiếu VCFG1=......; VCFG0=.........;

Chọn kênh cần đo .

CHS3=....;CHS2=.....;CHS1=.....;CHS0=.....;

Chọn định dạng kết quả ADFM=......;

Cho phép module ADC ADON=1;

Bước 3: Khởi tạo ngắt ADC(có thể bỏ qua bước này nếu không sử dụng ngắt):

Xóa cờ ngắt: ADIF=0;

Cho phép ngắt ADC: ADIE=1;

Cho phép ngắt ngoại vi: PEIE=1;

Cho phép ngắt toàn cục : GIE=1;

Bước 4:Chờ thời gian khởi tạo.

Bước 5:Bắt đầu cho phép chuyển đổi . GODONE=1;

Bước 6:Chờ cho bộ ADC chuyển đổi hoàn tất bằng các dấu hiệu sau :

Bit GODONE tự động xuống 0 , ta có thể sử dụng code sau để thực hiện việc chờ:

while(GODONE) ;

Ngắt ADC xảy ra.(Nếu bước 3 được thực hiện)

Bước 7 : Đọc kết quả

ADC 8-bit : kết quả = ADRESH //canh trái

ADC 10-bit : kết quả = ADRESH*64+ADRESL //canh phải

Bước 8:Xóa cờ ngắt cho lần chuyển đổi tiếp theo (Nếu bước 3 được thực hiện)

ADIF=0;

3.Làm việc với LCD 16x2 :

Để vi điều khiển PIC16F887 giao tiếp được với LCD đòi hỏi trong code chương trình cần

phải có những dòng lệnh phù hợp lcd , thường những yêu cầu lệnh này được quy định bởi chip

xử lý bên trong lcd , do đó để chương trình ngắn gọn và đơn giản , ta thường xây dựng file lcd.c

và lcd.h là những file chứa sẵn những chương trình con có những câu lệnh giao tiếp với lcd , ta

chỉ cần khai báo hai file lcd.c và lcd.h thì có thể dễ dàng giao tiếp với lcd bằng những câu lệnh

bên trong file đó .Các bước khởi tạo và làm việc với LCD :

− Bước 1 : Kiểm tra phần cứng , phải phù hợp với những khai báo trong file LCD.h

− Bước 2 : Copy 2 file LCD.c và LCD.h vào thư mục của project đang lập trình .

− Bước 3 : Add hai file trên vào Header file và Source file .

Page 19: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

19

− Bước 4 : Tối thiểu cần phải khai báo 2 dòng lệnh sau (tô đen) trong chương trình khi có

liên quan tới file LCD:

#include<htc.h>

__CONFIG(…….);

#include “lcd.h” //khai báo thư viện hàm lcd.h

void main( )

{

lcd_init( ); //lệnh khởi tạo lcd

while(1)

{

}

}

*Ngoài ra còn có thể sử dụng hàm printf nhưng cần khai báo như sau :

#include<htc.h>

#include<stdio.h> //khai báo thư viện cho hàm printf

__CONFIG(…….);

#include “lcd.h” //khai báo thư viện hàm lcd.h

void main( )

{

lcd_init( ); //lệnh khởi tạo lcd

//Các lệnh được sử dụng cho lcd có thể tham khảo trong file LCD.c ví dụ :

lcd_gotoxy(x,y); //Lệnh này dùng để di chuyển con trỏ đi đến các vị trí trên màn

hình lcd, trong đó x là giá trị của hàng ngang (x=[0,1]) , y là giá trị của hàng

dọc(y=[0,15]).

lcd_putc(„kí tự cần in‟); //Lệnh này dùng để in kí tự lên màn hình lcd tại vị trí con

trỏ .

lcd_puts(“chuỗi cần in”); //Lệnh này dùng để in chuỗi lên màn hình lcd tại vị trí con

trỏ , chú ý chuỗi cần in nằm giữa hai dấu “ ” và kí tự cần in nằm giữa hai dấu

„ ‟ . lcd_putc(„\f‟) ; //xóa màn hình lcd , sau đó con trỏ trở về vị trí (0,0).

char bien2=6;

float bien1=19.66667 ;

unsigned int bien3=60000;

printf(“In ra man hinh ”); //Hiển thị chuỗi In ra man hinh

printf(“In ra \n man hinh ”); //Hiển thị chuỗi In ra

man hinh

printf(“In gia tri :%d ”, bien2); //Hiển thị chuỗi In gia tri :6

printf(“In gia tri :%3d ”, bien2); //Hiển thị chuỗi In gia tri : 6

printf(“In gia tri :%03d ”, bien2); //Hiển thị chuỗi In gia tri :006

printf(“In gia tri :%5.3d ”, bien2); //Hiển thị chuỗi In gia tri : 006

printf(“In gia tri :%f ”, bien1); //Hiển thị chuỗi In gia tri :19.6666

printf(“In gia tri :%3.2f ”, bien1); //Hiển thị chuỗi In gia tri : 19.67

printf(“In gia tri :%d ”, bien3); //Hiển thị chuỗi In gia tri :-5536

printf(“In gia tri :%ld ”, bien3); //Hiển thị chuỗi In gia tri :60000

Page 20: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

20

while(1);

}

void putch(char ki_tu)

{

lcd_putc(ki_tu);

}

Chú ý : Khi viết chương trình có liên quan lcd mà phần cứng thực tế không có lcd hay

lcd kết nối không đúng với thư viên lcd.h thì con trỏ chương trình sẽ dừng ngay lệnh lcd_init();

IV.BÀI TẬP THỰC HÀNH :

Bài 1: Viết chương trình đọc ADC 8 bit ở chân AN3 và thực hiện theo yêu cầu sau :

Hiển thị giá trị thanh ghi ANSEL ở hàng (0,0) của LCD.

Hiển thị giá trị điện áp chân AN3 ở hàng (0,1) của LCD.

Định thời bằng hàm delay , điện áp tham chiếu trong , Fosc = 4Mhz , giao tiếp LCD

bằng thư viện LCD.h

Sơ đồ phần cứng :

printf(“In gia tri :%3d ”, bien2); //Hiển thị chuỗi In gia tri : 6

printf(“In gia tri :%03d ”, bien2); //Hiển thị chuỗi In gia tri :006

printf(“In gia tri :%5.3d ”, bien2); //Hiển thị chuỗi In gia tri : 006

printf(“In gia tri :%f ”, bien1); //Hiển thị chuỗi In gia tri :19.6666

printf(“In gia tri :%3.2f ”, bien1); //Hiển thị chuỗi In gia tri : 19.67

printf(“In gia tri :%d ”, bien3); //Hiển thị chuỗi In gia tri :-5536

printf(“In gia tri :%ld ”, bien3); //Hiển thị chuỗi In gia tri :60000

Page 21: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

21

*Bước 1 : Tạo một project mới với tên 02_01_ MSSV

*Bước 2: Nhập chương trình sau vào máy tính và hoàn thành vào dấu …….

#include<htc.h>

#include<stdio.h> //thư viện cho hàm printf( );

__CONFIG(INTIO&WDTDIS&PWRTEN&MCLREN&UNPROTECT&DUNPROTECT&BO

RDIS&IESODIS&LVPDIS&FCMDIS);

#include"lcd.h";

void main( )

{

lcd_init( ); //Khởi tạo LCD

ANS3=…….; //Enable analog ở chân RA3

TRISA3=…….;RA3=…….; //Khởi tạo RA3 là ngõ vào

VCFG0=VCFG1=…….; //Chọn điện áp tham chiếu trong

CHS3=CHS2=…….;CHS1=CHS0=…….; //Chọn kênh đo là AN3

ADFM=…….; //Định dạng dữ liệu canh trái , bởi vì chỉ sử dụng ADC 8 bit

ADCS0=ADCS1=…….; //Tần số chuyển đổi

ADON=…….; //Enable module ADC hoạt động

while(1)

{

GODONE=…….; //Cho phép ADC bắt đầu chuyển đổi

while(GODONE) ……. //Chờ bộ ADC chuyển đổi xong

lcd_gotoxy(0,0);

printf("\fADRESH :%d",ADRESH);

lcd_gotoxy(0,1);

printf("Dien ap :%3.2f",ADRESH*5.0/255.0);

_delay(100000);

}

}

void putch(char c) //Hỗ trợ cho hàm printf in ra LCD

{

lcd_putc(c);

}

*Bước 3: Biên dịch chương trình , nạp xuống kít thí nghiệm , jum header 3 ở vị trí POT , dùng

vít vặn biến trở và quan sát kết quả trên LCD.

*Bước 4:Thiết lập công thức quan hệ giữa điện áp và giá trị thanh ghi ADRESH .

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

Page 22: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

22

Bài 2: Viết chương trình đọc ADC 10 bit ở hai kênh AN3 , AN12 và thực hiện theo yêu cầu

sau :

Hiển thị giá trị điện áp tại chân AN3 ở hàng (0,0) của LCD.

Hiển thị giá trị điện áp tại chân AN12 ở hàng (0,1) của LCD.

Định thời bằng hàm delay , điện áp tham chiếu trong , Fosc = 4Mhz, giao tiếp LCD

bằng thư viện LCD.h

Sơ đồ phần cứng :

*Bước 1 : Tạo một project mới với tên 02_02_ MSSV

*Bước 2: Nhập chương trình sau vào máy tính và hoàn thành vào dấu …….

#include<htc.h>

#include<stdio.h>

__CONFIG(INTIO&WDTDIS&PWRTEN&MCLREN&UNPROTECT&DUNPROTECT&BO

RDIS&IESODIS&LVPDIS&FCMDIS);

#include "lcd.h"

void main( )

{

unsigned char old_ADRESH;

lcd_init( );

ANS3= …….;ANS12= …….; //Enable analog ở chân RA3 và chân RB0

TRISA3= …….;RA3= …….;TRISB0=1;RB0=1; //Khởi tạo RA3,RB0 là ngõ vào

VCFG0=VCFG1= …….; //Chọn điện áp tham chiếu trong

ADFM= …….; //Định dạng kết quả bên phải (ADC 10 bit)

ADCS0=ADCS1=0; //Tần số chuyển đổi

ADON= …….; //Enable module ADC

while(1)

{

CHS3=CHS2= …….;CHS1=CHS0= …….; //Chọn kênh AN3

Page 23: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

23

GODONE= …….;

while(GODONE);

lcd_gotoxy(0,0);

printf("\fAN3 la:%d",ADRESH*256+ADRESL);

_delay(100000);

CHS3=CHS2= …….;CHS1=CHS0= …….; //chon kenh AN12

GODONE= …….;

while(GODONE);

lcd_gotoxy(0,1);

printf("AN12 la:%d",ADRESH*256+ADRESL);

_delay(100000);

}

}

void putch(char c)

{

lcd_putc(c);

}

*Bước 3 : Jum header 3 ở vị trí BUTTON

Nhấn giữ nút nhấn SW2 và quan sát kết quả trên LCD ở vị trí (0,0) tức là kết quả đo kênh

AN3.

Nhấn giữ nút nhấn SW3và quan sát kết quả trên LCD ở vị trí (0,0) tức là kết quả đo kênh

AN3.

Nhấn giữ cả hai nút SW2,SW3 và quan sát kết quả trên LCD ở vị trí (0,0) tức là kết quả

đo kênh AN3.

Dựa vào mạch điện nguyên lý, chứng minh cả 3 kết quả quan sát được .

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

Page 24: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

24

*Bước 4 : Quan sát kết quả ở hàng (0,1) của lcd , tức là kết quả đo được ở kênh AN12 khi có

nhấn nút RB0 và khi không có nhấn nút và nhận xét :

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

V.BÀI TẬP TỰ GIẢI :

Bài 3 : Viết chương trình sử dụng khối ADC của vi điều khiển PIC16F887 đo nhiệt độ của

5 phòng và hiển thị lên LCD, sử dụng LM35 theo yêu cầu sau :

(Tạo một project mới với tên 02_03_ MSSV)

Khi nhấn (không giữ )RB0 thì LCD hiển thị giá trị giá trị nhiệt độ của phòng 1.

Khi nhấn (không giữ )RB1thì LCD hiển thị giá trị giá trị nhiệt độ của phòng 2.

Khi nhấn (không giữ )RB2 thì LCD hiển thị giá trị giá trị nhiệt độ của phòng 3.

Khi nhấn (không giữ )RB3 thì LCD hiển thị giá trị giá trị nhiệt độ của phòng 4.

Khi nhấn (không giữ )RB4 thì LCD hiển thị giá trị giá trị nhiệt độ của phòng 5.

Tần số hoạt động Fosc = 4MHz , phần cứng LCD được kết nối với PORTD của Vi Điều khiển

theo sơ đồ chân của thư viện lcd.h , điện áp tham chiếu bên trong , sử dụng ADC 8 bit .

Page 25: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

25

Bài 4:Viết chương trình đọc giá trị điện áp ở chân AN0 và hiển thị lên LCD 16x2 theo yêu

cầu sau : (Tạo một project mới với tên 02_04_ MSSV)

Hiển thị giá trị hai thanh ghi ADRESH và ADRESL ở vị trí (0,0) của LCD.

Hiển thị giá trị điện áp đo được ở vị trí (0,1) của LCD .

Tần số hoạt động Fosc = 4MHz , phần cứng LCD được kết nối với PORTD của Vi Điều

khiển theo sơ đồ chân của thư viện lcd.h , điện áp tham chiếu bên ngoài , sử dụng ADC 10 bit .

Bài 5 : Viết chương trình dùng vi điều khiển PIC16F887 thực hiện chức năng như một

máy tính theo sơ đồ phần cứng sau : (Tạo một project mới với tên 02_05_ MSSV)

Page 26: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

26

BÀI 3 :TIMER

I.MỤC ĐÍCH THÍ NGHIỆM :

Kiến thức sinh viên cần đạt được sau khi thực tập :

− Giải thích được nguyên tắc hoạt động của timer0 , timer1 , timer 2.

− Thiết lập công thức tính định thời của từng timer .

− Liệt kê các bit điều khiển từng hoạt động của timer .

− Phân biệt sự khác nhau và giống nhau giữa hai chế độ timer và counter trong timer 0 ,

timer1.

− Giải thích chức năng của bộ chia trong timer .

− Khởi tạo ngắt cho timer0 , timer 1 , timer 2 .

II.DỤNG CỤ THÍ NGHIỆM:

Kít thí nghiệm + cáp USB.

Máy tính .

Nguồn 12V/1A.

Oscilloscope

III.CƠ SỞ LÝ THUYẾT :

Timer là khối hoạt động độc lập với CPU , do đó nếu trong lập trình chúng ta sử dụng timer

thì sẽ làm giảm đi thời gian xử lý , giúp vi điều khiển hoạt động nhanh hơn . Ứng dụng chủ yếu

của timer là định thời trong khoảng thời gian ngắn , đếm số lượng xung clock bên ngoài cho các

ứng dụng như : đếm sản phẩm , đọc số xung encoder v.v... PIC16f887 có tích hợp 3 timer : timer

0(8-bit), timer 1(16-bit), timer 2(8-bit).

Sơ đồ khối các timer trong PIC16F887

Page 27: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

27

: Tràn timer

1.Nguyên tắc hoạt động của timer :

Nguyên tắc hoạt động chung của timer là tăng giá trị của thanh ghi đếm lên khi nhận được

một xung clock (đã qua bộ chia ) . Khi thanh ghi đếm đến giá trị lớn nhất , nếu có xung clock

tiếp tục tác động thì timer sẽ xảy ra sự kiện tràn timer (overflow) , sự kiện này có thể xảy ra

ngắt.

Ví dụ : Thanh ghi TMR0 là thanh ghi 8-bit chứa giá trị đếm của timer 0 :

0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 1

0 0 0 0 0 0 1 0

0 0 0 0 0 0 1 1

1 1 1 1 1 1 1 1

Quá trình hoạt động của một timer

2.Timer 0 :

Timer 0 có những đặc tính sau :

− Thanh ghi 8-bit timer/counter (TMR0).

− Bộ chia prescaler 8-bit (dùng chung với Watchdog timer )

− Hoạt động với xung clock bên trong hoặc bên ngoài .

− Hoạt động với việc lựa chọn cạnh của xung clock bên ngoài .

− Ngắt tràn timer .

Sơ đồ khối timer 0 và watchdog timer trong PIC16F887

TMR0=0

+∆𝑡 TMR0=1

+∆𝑡

TMR0=2

+∆𝑡 TMR0=3

+∆𝑡

TMR0=255

+∆𝑡

Shun
Note
TOSE đdi chung cong XOR co tac dung chon canh len hoac canh xuong
Shun
Note
khoi tap timer0 co 6bit
Page 28: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

28

2.1 Các thanh ghi khởi tạo timer 0 :

T0CS : bit lựa chọn chế độ hoạt động của timer 0

− T0CS=1: Timer 0 hoạt động với chế độ đếm counter .(clock được cấp từ chân T0CKI)

− T0CS=0:Timer 1 hoạt động với chế độ định thời timer.(clock được cấp từ thạch anh hoạt

động của vi điều khiển ).

T0SE : Bit chọn cạnh tác động khi timer hoạt động với chế độ đếm counter.

− T0SE=1: Thanh ghi TMR0 tăng khi có sự kiện cạnh xuống ở chân T0CKI.

− T0SE=0: Thanh ghi TMR0 tăng khi có sự kiện cạnh lên ở chân T0CKI.

PSA : Dùng để lựa chọn bộ chia Prescaler thuộc về của timer 0 hay của Watchdog.

− PSA=1:Bộ chia prescaler thuộc về Watchdog .

− PSA=0: Bộ chia prescaler thuộc về Timer 0.

PS<2:0> : Chọn tỉ lệ cho bộ chia prescaler

2.2 Công thức định thời timer 0:

Thời gian hoạt động của timer0 (8-bit)

TMR0‟ 255

Over flow

∆𝑡

0

Page 29: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

29

Từ sơ đồ trên ta thấy thời gian định thời của timer 0 :

T=(255-TMR0‟)*∆𝑡 = (255−𝑇𝑀𝑅0′)∗𝑃𝑟𝑒𝑠𝑐𝑎𝑙𝑒𝑟 ∗4

𝐹𝑜𝑠𝑐

Do đó để thay đổi thời gian định thời T ta có thể thay đổi một trong các thông số sau :

− TMR0‟ : Giá trị ban đầu của thanh ghi TMR0 cho timer 0 bắt đầu đếm. Khi trong

lập trình không gán giá trị đầu cho thanh ghi TMR0 thì timer bắt đầu đếm là 0.

(TMR0‟=0).

− Prescaler : Tỉ lệ bộ chia của timer 0.

− Fosc : Tần số hoạt động của vi điều khiển.(Ít khi thay đổi thông số này)

Chú ý : Trong quá trình tính toán tìm ra thời gian định thời T hợp lý , thường có sai số

xảy ra , do đó chúng ta chọn Prescaler và TMR0‟ sao cho sai số ít nhất .

2.3 Ngắt trong timer0 :

Timer 0 cũng có thể xảy ra ngắt , ngắt timer 0 xảy ra khi timer 0 tràn (tức là thanh ghi

TMR0=255 rồi sau đó trở về giá trị ban đầu).

Sơ đồ ngắt timer 0 :

Sơ đồ ngắt timer 0

T0IE : Bit cho phép xảy ra ngắt timer 0 , để ngắt timer 0 xảy ra thì bit này phải bằng 1.

T0IF : Cờ ngắt timer 0 , khi ngắt xảy ra bít này tự động bằng 1 , chúng ta cần phải xóa (=0) bít

này trong lập trình .

GIE : GIE bit cho phép ngắt toàn cục , để ngắt timer 0 xảy ra thì bit này phải bằng 1.

2.4 : Các bước khởi tạo timer 0:

2.4.1 : Khởi tạo timer 0 hoạt động với chế độ định thời timer:

T0CS=0; //Clock cấp cho timer 0 là Fosc (tần số hoạt động của vi điều khiển)

PSA=0 ; //Bộ chia prescaler được sử dụng cho timer 0 .

PS<2:0>=....; //Chọn tỉ lệ bộ chia . Nếu PSA=1 thì có thể bỏ qua dòng này .

//Khởi tạo ngắt nếu có sử dụng

INTE=1;

INTF=0;

GIE=1;

Page 30: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

30

2.4.2:Khởi tạo timer 0 hoạt động với chế độ đếm counter :

//Khởi tạo chân T0CKI là ngõ vào .

TRISA4=1;

RA4=1;

T0CS=1; // Clock cấp cho timer 0 từ chân T0CKI

PSA=0 ; //Bộ chia prescaler được sử dụng cho timer 0 .

PS<2:0>=....; //Chọn tỉ lệ bộ chia .Nếu PSA=1thì có thể bỏ qua dòng này .

//Khởi tạo ngắt nếu có sử dụng

INTE=1;

INTF=0;

GIE=1;

3.Timer 1 :

Timer 1 có hai thanh ghi chứa giá trị đếm , do đó có thể đếm lên đến 65535(2^16

-1) mới xảy

sự kiện tràn timer , timer 1 thích hợp nhất cho việc đếm xung encoder tốc độ cao , cũng giống

như timer 0 , timer 1 cũng hoạt động với hai chế độ : chế độ định thời và chế độ đếm counter.

Sơ đồ khối timer 1

Shun
Note
dong bo xung
Shun
Oval
Shun
Oval
Shun
Arrow
Shun
Arrow
Shun
Rectangle
Shun
Note
T1OSO T1OSI
Shun
Line
Shun
Line
Shun
Line
Shun
Line
Shun
Pencil
Shun
Pencil
Shun
Pencil
Shun
Pencil
Shun
Line
Shun
Line
Shun
Line
Shun
Line
Shun
Pencil
Page 31: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

31

3.1 Công thức định thời timer 1 :

T= [65535−(TMR 1H∗256+TMR 1L)]∗Prescaler ∗4

Fosc

Trong đó :

− T thời gian định thời timer 1

− TMR1L , TMR1H : thanh ghi chứa giá trị đếm của timer 1

− FOSC : tần số hoạt động của vi điều khiển

− Prescaler : tỉ lệ bộ chia .

3.2Thanh ghi điều khiển timer1 :

TMR1ON : Bit cho phép timer1 hoạt động

− 1: Cho phép timer 1 (điều kiện cần cho timer 1 hoạt động , chưa đủ)

− 0: Timer 1 ngừng hoạt động .

TMR1CS :Bit lựa chọn clock cho timer 1

− 1:Clock từ bên ngoài (từ chân T1CKI)

− 0:Clock bên trong (FOSC/4)

𝐓𝟏𝐒𝐘𝐍𝐂 : Bit điều khiển lựa chọn đồng bộ clock vào từ bên ngoài của timer 1

Nếu TMR1CS =1:

− 1:Clock vào từ bên ngoài không được đồng bộ

− 0:Clock vào từ bên ngoài được đồng bộ

Nếu TMR1CS = 0:

− Không cần quan tâm bit này , timer 1 sử dụng clock bên trong .

T1OSCEN : Bit điều khiển cho phép dao động LP

− 1: Dao động LP được cho phép cho clock timer 1 .

− 0: Tắt dao động LP .

T1CKPS<1:0> : Bit lựa chọn tỉ lệ bộ chia Prescale

11 = 1:8

10 = 1:4

01 = 1:2

00 = 1:1

TMR1GE : Bit cho phép cổng timer 1

Nếu TMR1ON=0 : bit này không cần quan tâm

Nếu TMR1ON=1 :

− 1 : Sự đếm lên của timer1 sẽ được điểu khiển bởi cổng Timer 1

− 0 : Timer 1 có thể đếm lên mà không cần quan tâm đến trạng thái của cổng timer 1 .

T1GINV : Bit đảo cổng timer1

Shun
Note
TMR1H=X1/256 (lam tron xuong) TMR1L=X1-TRM1H*256
Shun
Oval
Shun
Oval
Shun
Oval
Shun
Oval
Shun
Oval
Shun
Oval
Page 32: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

32

1 : Cổng timer1 tác động mức cao (Timer1 hoạt động khi cổng ở mức cao ).

0 : Cổng timer 1 tác động mức thấp (Timer 1 hoạt động khi cổng ở mức thấp).

3.3 Timer1 on :

Không giống với timer 0 , chúng ta cần khởi tạo một số bit thì timer 1 mới có thể hoạt động

được . Từ sơ đồ trên ta có thể thấy việc bật/tắt timer 1có hai dạng :

Cho phép timer 1 hoạt động mà không cần tác động từ bên ngoài :

TMR1ON=1;

TMR1GE=0;

Cho phép timer 1 hoạt động khi có tín hiệu logic ở chân T1G :

//Cho phép điện trở treo .

//Khởi tạo chân T1G là ngõ vào .

ANS13=0;

TRISB5=1;

RB5=1;

TMR1ON=1;

TMR1GE=1;

T1GINV=.....; //Tùy theo mức logic ở chân T1G là mức cao hay thấp.

T1GSS=1;

3.4 Ngắt trong timer 1 :

Timer 1 cũng có thể tạo ra sự kiện ngắt khi xảy ra tràn timer , các bit khởi tạo ngắt của

timer 1 :

TMR1IF : Cờ ngắt , bit này tự động bằng 1 khi có sự kiện tràn timer .

TMR1IE :Bit cho phép ngắt tràn timer .

PEIE :Bit cho phép ngắt ngoại vi .

GIE :Bit cho phép ngắt toàn cục .

Sơ đồ ngắt timer 1

3.5 Khởi tạo timer 1 hoạt động với chế độ đếm counter :

//Khởi tạo chân T1CKI là ngõ vào số ……

T1OSCEN=1;

TMR1CS=1;

T1CKPS1=…..;

T1CKPS0=…..;

T1SYNC=0;

//Cho phép timer 1 on

//Khởi tạo ngắt nếu có

Shun
Pencil
Shun
Pencil
Page 33: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

33

Ngoài ra , timer 1 còn có thể hoạt động với chế độ timer sử dụng thạch anh ngoài , độc

lập với tần số họat động của vi điều khiển , thạch anh ngoài ta có thể kết nối với hai chân :

OSC1 và OSC2 và khởi tạo tương tự như trên .

3.6 Khởi tạo timer 1 hoạt động với chế độ định thời timer :

TMR1CS=0;

T1CKPS1=…..;

T1CKPS0=…..;

T1SYNC=1;

//Cho phép timer 1 on

//Khởi tạo ngắt nếu có

4.Timer 2 :

Khác với timer 0 và timer 1 , timer 2 chỉ có thể hoạt động ở chế độ định thời timer , tuy nhiên

timer 2 có hai bộ chia và một giá trị đặt do đó thời gian định thời có thể linh hoạt hơn , và ít sai

số trong tín toán .

Sơ đồ khối timer 2

Nguyên tắc hoạt động timer 2 :

Khi có xung clock tần số Fosc/4 qua bộ chia Prescaler đi vào thanh ghi TMR2 , làm thanh

ghi TMR2 tăng lên , khi thanh ghi TMR2 bằng giá trị thanh ghi đặt PR2 thì sẽ có một xung clock

đi qua bộ chia Postscaler , đồng thời thanh ghi TMR2 trở về vị trí ban đầu , nếu tỉ lệ bộ chia

Postscaler được chọn 1:1 thì sẽ xảy ra sự kiện ngắt timer 2 .

4.1 Công thức tín định thời timer 2 :

T= PR 2−TMR 2′ ∗Postscaler ∗Prescaler ∗4

Fosc

Trong đó

T :Thời gian định thời timer 2

PR2 :giá trị thanh ghi đặt

TMR2‟ : giá trị bắt đầu đếm của thanh ghi TMR0

Prescaler : Tỉ lệ bộ chia prescaler

Postscaler : Tỉ lệ bộ chia Postscaler

Fosc :Tần số hoạt động của vi điều khiển .

Shun
Note
Post=1 thi chon TMR2 tuy y Post#1 thi chon TMR2 bang 0
Page 34: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

34

4.2. Thanh ghi điều khiển timer 2 :

T2CKPS<1:0>: Bit lựa chọn tỉ lệ bộ chia Prescaler

00 : 1:1

01 : 1:4

1x : 1:16

TMR2ON : Bit cho phép timer 2 hoạt động

0:Không cho phép timer2 hoạt động

1:Cho phép timer 2 hoạt động

TOUTPS<3:0>: Bit lựa chọn tỉ lệ bộ chia Postscaler

4.2.Khởi tạo timer 2 hoạt động với chế độ định thời timer :

//Tín toán lựa chọn tỉ lệ bộ chia Prescaler , Postscaler

//Chọn tỉ lệ bộ chia Prescaler

T2CKPS1=……..; T2CKPS0=……;

//Chọn tỉ lệ bộ chia Postscaler

TOUTPS3=…….; TOUTPS2=…….;

TOUTPS1=…….; TOUTPS0=…….;

//Đặt giá trị lớn nhất cho giá trị thanh ghi đếm TMR2

PR2=……;

//Cho phép timer 2 họat động

TMR2ON=1;

//Khởi tạo ngắt timer 2 nếu có sử dụng :

TMR2IE=1;

TMR2IF=0;

PEIE=1;

GIE=1;

Page 35: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

35

IV.BÀI TẬP THỰC HÀNH :

Bài 1: Viết chương trình đọc số lần nhấn nút tại chân T0CKI(RA4) và hiển thị kết quả lên

LCD:

Sơ đồ phần cứng :

*Bước 1: Tạo một project mới với tên 03_01_ MSSV

*Bước 2: Nhập chương trình sau vào máy tính và hoàn thành vào dấu …….

#include<htc.h>

#include<stdio.h>

__CONFIG(INTIO&WDTDIS&PWRTEN&MCLREN&UNPROTECT&DUNPROTECT&BO

RDIS&IESODIS&LVPDIS&FCMDIS);

#include "lcd.h";

void main( )

{

lcd_init( );

TRISA4=…….; RA4=…….; //Khởi tạo chân T0CKI là ngõ vào

T0CS =…….; //Chọn clock cấp cho Timer0 là từ chân T0CKI

T0SE =…….; //Chọn cạnh tác động là cạnh xuống

PSA =…….; //Xung clock không qua bộ chia (-------------1------------)

//(-------------2------------) while(1)

{

lcd_gotoxy(0,0);

printf("\fSo lan nhan nut la:\r\n %d",TMR0);

_delay(100000);

}

}

void putch(char c)

{

lcd_putc(c);

}

*Bước 3:Nhấn nút nhấn kết nối với chân T0CKI và quan sát kết quả trên LCD.

Page 36: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

36

*Bước 4:Xóa dòng (-------------1------------)

*Bước 5:Thêm vào dòng (-------------2------------) đoạn code sau :

PSA=0; //Chọn bộ chia thuộc về timer

PS2=0; //Chọn tỉ lệ chia

PS1=1;

PS0=1;

*Bước 6: Quan sát kết quả khi nhấn nút nhấn.

*Bước 7: So sánh hai kết quả trước và sau khi sửa code , giải thích ? Nêu chức năng của bộ chia

trong timer 0:

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

Bài 2: Viết chương trình chớp tắt led RE1 , định thời bằng timer 0,tần số Fosc/4:

*Bước 1: Tạo một project mới với tên 03_02_ MSSV

*Bước 2: Nhập chương trình sau vào máy tính và hoàn thành vào dấu …….

#include<htc.h>

__CONFIG(INTIO&WDTDIS&PWRTEN&MCLREN&UNPROTECT&DUNPROTECT&BO

RDIS&IESODIS&LVPDIS&FCMDIS);

void insothuc(unsigned char old_ADRESH) ;

void main( )

{

ANS6=…….;TRISE1=…….; //Khởi tạo chân RE1 là digital output

T0CS=…….; //Chọn xung clock cấp cho timer 0 là từ Fosc/4

PSA=…….; //Xung clock sẽ đi qua bộ chia

PS2=…….; PS1=…….; PS0=…….; //Tỉ lệ bộ chia là 128

//Khởi tạo ngắt cho timer 0

T0IE=…….; //Cho phép ngắt timer 0

T0IF=…….; //Reset cờ ngắt

GIE=…….; //Cho phép ngắt toàn cục

while(1); //Lặp vô tận

}

void interrupt isr()

{

if(T0IE&T0IF) //Chương trình con ngắt cho timer0

{

RE1^=1; //Chớp tắt led

TMR0=0; //Khởi tạo giá trị đếm ban đầu cho timer0(-------1--------)

Page 37: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

37

T0IF=0; //Reset cờ ngắt.

}

}

*Bước 3 : Biên dịch chương trình , nạp xuống kít thí nghiệm , quan sát trạng thái của led .

*Bước 4:Tăng giá trị TMR0 ở dòng (-------1--------) từ thấp đến cao(0-255) , biên dịch chương

trình và nạp xuống kit thí nghiệm , đến lúc mắt không còn nhìn thấy led RE1 chớp tắt , tính

tần số ứng với giá trị thanh ghi TMR0 vừa tìm được .

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

*Bước 5 : Sử dụng oscillocope đo tần số vừa tìm được và so sánh với kết quả tính toán , nhận

xét.

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

Bài 3:Viết chương trình hiển thị đồng hồ lên LCD , sử dụng timer 1 định thời , thạch anh

ngoài 32.768KHz.

*Bước 1 : Tạo một project mới với tên 03_03_ MSSV

*Bước 2: Nhập chương trình sau vào máy tính và hoàn thành vào dấu …….

#include<htc.h>

#include<stdio.h>

__CONFIG(INTIO&WDTDIS&PWRTEN&MCLREN&UNPROTECT&DUNPROTECT&BO

RDIS&IESODIS&LVPDIS&FCMDIS);void insothuc(unsigned char old_ADRESH);

#include "lcd.h"

unsigned char hh,mm,ss; //Khai báo biến chứa giờ , phút , giây

void main()

{

lcd_init();

//Khởi tạo các chân ngõ vào thạch anh 32.768KHz

TRISC0=TRISC1=1;RC0=RC1=0;

T1OSCEN= …….; //Cho phép timer 1 hoạt động clock ngoài

TMR1CS= …….; //Clock cấp cho timer 1 là clock ngoài

T1CKPS1=T1CKPS0=…….; //Tỉ lệ bộ chia 1:8(-------1--------)

T1SYNC= …….; //Qua khối đồng bộ

//Cho phép timer hoạt động không cần tác động bên ngoài

Page 38: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

38

TMR1ON= …….;

TMR1GE= …….;

TMR1IE= …….; //Khởi tạo ngắt timer1

TMR1IF= …….; //Reset cờ ngắt timer 1

PEIE= …….; //Cho phép ngắt ngoại vi

GIE= …….; //Cho phép ngắt toàn cục

while(1); //Lặp vô tận

}

void putch(char c) //Chương trình con cho hàm printf( )

{

lcd_putc(c);

}

void interrupt isr( )

{

if(TMR1IE&&TMR1IF) //Ngắt tràn timer 1

{

ss++;

if(ss==60)

{

ss=0;

mm++;

if(mm==60)

{

mm=0;

hh++;

}

}

lcd_gotoxy(0,0);

printf("\fBay Gio La :\r\n %02d:%02d:%02d",hh,mm,ss);

TMR1H=239; //Khởi tạo giá trị đếm ban đầu cho timer1 (-------2--------)

TMR1L=255; // (-------3--------)

TMR1IF=0;

}

}

*Bước 3 : Nạp chương trình xuống kit thí nghiệm , jumper J1(XTAL).Quan sát lcd , và so sánh

kết quả với đồng hồ thực, nhận xét :

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

Dựa vào công thức định thời của timer 1, chứng minh những thông số ở các dòng (1),(2),(3):

Page 39: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

39

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

Bài 4: Viết chương trình sử dụng timer 2 điều khiển led RE1 chớp tắt với chu kì T=0.1s ,

sử dụng thạch anh ngoài 20MHz.

*Bước 1 : Tạo một project mới với tên 03_04_ MSSV

*Bước 2: Nhập chương trình sau vào máy tính :

#include<htc.h>

#include<stdio.h>

__CONFIG(HS&WDTDIS&PWRTEN&MCLREN&UNPROTECT&DUNPROTECT&BORDI

S&IESODIS&LVPDIS&FCMDIS);

void main()

{

ANS6=…….;TRISE1=…….;RE1=…….; //Khởi tạo chân RE1 là ngõ ra số

T2CKPS1=…….;T2CKPS0=…….; //chọn tỉ lệ bộ chia prescaler 1:1

//Chọn tỉ lệ bộ chia postscaler 1:2 (-------1--------)

TOUTPS3=0;TOUTPS2=0;TOUTPS1=…….;TOUTPS0=…….;

PR2=…….; //Giá trị thanh ghi PR2 (-------2--------)

TMR2=…….; //Giá trị bắt đầu đếm của timer 2 (-------3--------)

//Cho phép timer 2 hoạt động

TMR2ON=…….;

//Khởi tạo ngắt timer 2

TMR2IE=…….; //Cho phép ngắt tràn timer 2

TMR2IF=…….; //Reset cờ ngắt

PEIE=…….; //Cho phép ngắt ngoại vi

GIE=…….; //Cho phép ngắt toàn cục

while(1)

{

}

}

void interrupt isr()

{

if(TMR2IE&&TMR2IF)

{

RE1^=1;

TMR2IF=…….; //Xóa cờ ngắt Timer2

TMR2=……. ; //Khởi tạo giá trị bắt đầu đếm timer2(-------4------)

Shun
Pencil
Shun
Pencil
Shun
Pencil
Shun
Pencil
Shun
Line
Shun
Line
Shun
Line
Shun
Line
Page 40: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

40

}

}

*Bước 3 : Tính toán các thông số ở dòng (1),(2),(3),(4)

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------------------------------------- *Bước 4 : Hoàn thành vào dấu .............và biên dịch chương trình , nạp xuống kít thí nghiệm ,

quan sát led .

V.BÀI TẬP TỰ GIẢI :

Bài 5 : Viết chương trình hiển thị tốc độ động cơ lên lcd theo sơ đồ phần cứng sau :

(Tạo một project mới với tên 03_05_ MSSV)

Page 41: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

41

BÀI 4: KHỐI CCP

(CAPTURE-COMPARE-PWM)

I.MỤC ĐÍCH THÍ NGHIỆM :

Kiến thức sinh viên cần đạt được sau khi thực tập:

− Giải thích nguyên tắc hoạt động và khởi tạo chế độ Capture.

− Giải thích nguyên tắc hoạt động và khởi tạo chế độ Compare .

− Giải thích nguyên tắc hoạt động và khởi tạo chế độ PWM.

− Phân biệt sự khác nhau và giống nhau giữa hai khối CCP1 và CCP2.

− Thiết lập được tần số PWM và điều chỉnh độ rộng xung PWM theo yêu cầu.

II.DỤNG CỤ THÍ NGHIỆM:

Kít thí nghiệm + cáp USB.

Động cơ DC12V.

Oscillocope.

Máy tính .

Nguồn 12V/1A.

III.CƠ SỞ LÝ THUYẾT :

Các chân được sử dụng cho khối CCP:

Các chân được sử dụng trong khối CCP

Để sử dụng khối CCP chúng ta cần phải biết khởi tạo và sử dụng thành thạo timer 0,1,2 bởi

vì một mình khối CCP không thể hoạt động được một ứng dụng mà phải sử dụng kết hợp với

một trong 3 timer , cụ thể là :

Page 42: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

42

1.Thanh ghi khởi tạo khối CCP1:

Khối CCP1 còn tích hợp thêm 4 chân mang kí hiệu : P1A, P1B, P1C, P1D hỗ trợ cho việc

điều khiển cầu H.

Các chân CCP1 hỗ trợ điều khiển cầu H

P1M<1:0> : Bit khởi tạo ngõ ra PWM

Nếu khối CCP1 được khởi tạo ở chế độ capture hoặc compare thì chân có kí hiệu P1A là

chân hoạt động ở chế độ capture hoặc compare , còn các chân có kí hiệu P1B, P1C, P1D là các

chân không liên quan đến khối CCP1 , chúng ta có thể gán cho chúng chức năng I/O thông

thường .

Nếu khối CCP1 được khởi tạo ở chế độ PWM thì 2 bit P1M<1:0> có 4 trạng thái điều khiển

cầu H như sau :

00:Ngõ ra đơn , P1A tạo xung , P1B , P1C, P1D hoạt động với chức năng I/O.

01:Chế độ Full – Bridge thuận , P1D tạo xung , P1A tác động , P1B , P1C không tác động

10:Chế độ hafl – Bridge , P1A ,P1B tạo xung , P1C, P1D hoạt động với chức năng I/O.

11: Chế độ Full – Bridge nghịch , P1B tạo xung , P1C tác động , P1A , P1D không tác

động .

DC1B<1:0> : Hai bit mang trọng số nhỏ nhất trong chế độ hoạt động PWM10bit .Ở chế độ

Capture và Compare thì không cần quan tâm đến hai bit này.

CCP1M<3:0> : Bit lựa chọn chế độ họat động khối CCP1

0000: Capture/Compare/PWM off(reset khối CCP1)

0001: Không sử dụng

0010: Chế độ Compare , đảo ngõ ra khi có sự kiện Compare (bit CCP1IF = 1).

0011: Không sử dụng

0100: Chế độ Capture , sự kiện Capture xảy ra khi ở chân CCP1 có 1 xung cạnh xuống .

0101: Chế độ Capture , sự kiện Capture xảy ra khi ở chân CCP1 có 1 xung cạnh lên .

0110: Chế độ Capture , sự kiện Capture xảy ra khi ở chân CCP1 có 4 xung cạnh lên .

0111: Chế độ Capture , sự kiện Capture xảy ra khi ở chân CCP1 có 16 xung cạnh lên .

Page 43: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

43

1000: Chế độ Compare , ngõ ra bằng 1 khi có sự kiện Compare (bit CCP1IF = 1).

1001: Chế độ Compare , ngõ ra bằng 0 khi có sự kiện Compare (bit CCP1IF = 1).

1010: Chế độ Compare , tạo ra sự kiện ngắt nội (bit CCP1IF = 1 , chân CCP1 không sử

dụng ).

1011: Chế độ Compare, tạo ra sự kiện trigger (CCP1IF =1; CCP1 resets TMR1 or

TMR2)

1100: Chế độ PWM , P1A , P1C tác động – mức cao , P1B , P1D tác động – mức cao

1101: Chế độ PWM , P1A , P1C tác động – mức cao , P1B , P1D tác động – mức thấp

1110: Chế độ PWM , P1A , P1C tác động – mức thấp , P1B , P1D tác động – mức cao

1111: Chế độ PWM , P1A , P1C tác động – mức thấp , P1B , P1D tác động – mức thấp

2.Thanh ghi khởi tạo khối CCP2:

Khác với khối CCP1 , khối CCP2 không có chức năng hỗ trợ điều khiển cầu H , trong chế

độ PWM , khối CCP2 chỉ có chức năng tạo ra xung PWM 10 bít ở chân CCP2.

DC2B<1:0> : Hai bit mang trọng số nhỏ nhất trong chế độ hoạt động PWM-10bit , ở chế độ

Capture và Compare thì không cần quan tâm đến hai bit này.

CCP2M<3:0> : Bit lực chọn chế độ họa động khối CCP1

0000: Capture/Compare/PWM off(reset khối CCP1)

0001:Không sử dụng

0010:Chế độ Compare , đảo ngõ ra khi có sự kiện Compare (bit CCP1IF = 1).

0011:Không sử dụng

0100:Chế độ Capture , sự kiện Capture xảy ra khi ở chân CCP1 có 1 xung cạnh xuống .

0101:Chế độ Capture , sự kiện Capture xảy ra khi ở chân CCP1 có 1 xung cạnh lên .

0110:Chế độ Capture , sự kiện Capture xảy ra khi ở chân CCP1 có 4 xung cạnh lên .

0111:Chế độ Capture , sự kiện Capture xảy ra khi ở chân CCP1 có 16 xung cạnh lên .

1000: Chế độ Compare , ngõ ra bằng 1 khi có sự kiện Compare (bit CCP1IF = 1).

1001: Chế độ Compare , ngõ ra bằng 0 khi có sự kiện Compare (bit CCP1IF = 1).

1010: Chế độ Compare , tạo ra sự kiện ngắt nội (bit CCP1IF = 1 , chân CCP1 không sử

dụng ).

1011: Chế độ Compare, tạo ra sự kiện trigger (CCP1IF =1; CCP1 resets TMR1 or

TMR2)

1100:Chế độ PWM , P1A , P1C tác động – mức cao , P1B , P1D tác động – mức cao

1101:Chế độ PWM , P1A , P1C tác động – mức cao , P1B , P1D tác động – mức thấp

1110:Chế độ PWM , P1A , P1C tác động – mức thấp , P1B , P1D tác động – mức cao

1111:Chế độ PWM , P1A , P1C tác động – mức thấp , P1B , P1D tác động – mức thấp

Page 44: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

44

3.Capture :

Sơ đồ khối chế độ capture

3.1 Nguyên tắc hoạt động của chế độ capture :

Khi có sự kiện (cạnh lên , cạnh xuống , 4 cạnh lên hoặc 16 cạnh lên ) ở chân CCPx (có thể là

CCP1 hay CCP2 tùy vào ta sử dụng khối CCP1 hay CCP2) thì giá trị thanh ghi đếm của timer 1

là TMR1H và TMR1L sẽ được cập nhật qua hai thanh ghi CCPRxH và CCPRxL của khối CCPx.

đồng thời có thể xảy ra ngắt nội bằng việc cho phép cờ ngắt CCPRxIF = 1 .(x=0,1)

3.2 Các bước khởi tạo chế độ capture :

Khởi tạo chân CCPx là ngõ vào : TRISCx=1;RCx=1;

Khởi tạo timer 1 hoạt động .

Khởi tạo khối CCPx hoạt động với chế độ capture :

CCPxCON = ......; //Chọn chế độ capture .

CCPRxH=CCPRxL=0; //reset hai thanh ghi của khối CCPx.

Khởi tạo ngắt (nếu có sử dụng):

CCPxIE=1; //Cho phép ngắt CCP

CCPxIF=0; //Reset cờ ngắt

PEIE=1; //Cho phép ngắt ngoại vi

GIE=1; //Cho phép ngắt toàn cục .

Page 45: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

45

4.Compare :

Sơ đồ khối chế độ compare

4.1Nguyên tắt hoạt động của chế độ compare :

Khi hai thanh ghi đếm TMR1H và TMR1L của timer 1 đếm đến giá trị của hai thanh ghi

CCPRxH và CCPRxL thì sẽ xảy ra một trong các sự kiện sau :

Đảo trạng thái ngõ ra của chân CCPx.

Tạo tín hiệu chân CCPx lên bằng 1 .

Xóa tín hiệu chân CCPx xuống bằng 0 .

Tạo ra ngắt .(CCPxIF =1 , chân CCPx không sử dụng )

Tạo ra sự kiện trigger .(CCP1IF=1,CCP1 reset timer 1 hoặc timer 2,CCP2IF=1,CCP2

reset timer 1 và ADC bắt đầu chuyển đổi nếu khối ADC được cho phép chuyển đổi , chân

CCP2 không sử dụng ).

4.2Các bước khởi tạo chế độ compare:

Khởi tạo chân CCPx là ngõ ra : TRISCx=0;

Khởi tạo timer 1 hoạt động .

Khởi tạo khối CCPx hoạt động với chế độ compare :

CCPxCON = ......; //Chọn chế độ compare .

CCPRxH=....;CCPRxL=.....; //Chọn giá trị đặt .

Khởi tạo ngắt (nếu có sử dụng) :

CCPxIE=1; //Cho phép ngắt CCP

CCPxIF=0; //Reset cờ ngắt

PEIE=1; //Cho phép ngắt ngoại vi

GIE=1; //Cho phép ngắt toàn cục .

5.PWM(Pulse-Width Modulated) :

Nói đến PWM thì ta phải nói đến hai đặc tính cơ bản là : tần số (do timer 2 tạo ra ) và độ

rộng xung (do thanh ghi CCPRxL:CCPxCON<5:4> tạo ra ).

Sơ đồ tạo xung PWM là sự kết hợp của khối CCPx với timer 2 :

Page 46: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

46

Sơ đồ điều chế PWM

5.1Nguyên tắt hoạt động của chế độ PWM :

Thanh ghi đếm của timer 2 là TMR2 đếm đến giá trị thanh ghi CCPRxL:CCPxCON<5:4>

của khối CCPx thì trạng thái logic chân CCPx bị đảo , khi giá trị của thanh ghi TMR2 đến giá trị

PR2 thì hoàn tất một chu kỳ tạo xung PWM .

Chú ý : Từ sơ đồ trên ta thấy để tạo xung PWM thì giá trị CCPRxL::CCPxCON<5:4>

phải nhỏ hơn hoặc bằng giá trị thanh ghi PR2 , và muốn thay đổi độ rộng xung ta chỉ cần thay

đổi giá trị thanh ghi CCPRxL::CCPxCON<5:4> trong lập trình .

Công thức tính chu kỳ PWM :

Công thức tính độ rộng xung PWM :

6.Các bước khởi tạo chức năng PWM:

Bước 1 : Cho phép chân PWM là ngõ vào:

TRISCx=1; //x= 1 , 2

Bước 2 : Khởi tạo tần số PWM bằng việc định giá trị thanh ghi PR2 của timer 2:

PR2=....; //Tính toán được từ công thức chu kỳ PWM

Bước 3: Đặt khối CCP hoạt động ở chế độ PWM

CCPxCON=0bxxxx11xx; //x=0;1

Bước 4 : Đặt độ rộng xung của khối PWM bằng việc đặt giá trị cho thanh ghi CCPRxL

và 2 bit DCxB<1:0> của thanh ghi CCPxCON

CCPRxL=.....; //Có thể điều chỉnh giá trị này trong khi vi điểu khiển hoạt động

để thay đổi độ rộng xung khi cần thiết .

DCxB1=.....; //Nếu sử dụng PWM 8 bit thì có thể bỏ qua dòng này

Page 47: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

47

DCxB0=.....; //Nếu sử dụng PWM 8 bit thì có thể bỏ qua dòng này

Bước 5 : Khởi tạo và cho phép timer 2 hoạt động :

TMR2IF=0; //Xóa cờ ngắt TMR2IF của thanh ghi PIR1

//Chọn tỉ lệ bộ chia của timer 2 :

T2CKPS1=.....; //Chọn tỉ lệ bộ chia Prescaler

T2CKPS0=.....;

TOUTPS3=....; //Chon tỉ lệ bộ chia Postscaler

TOUTPS2=....;

TOUTPS1=....;

TOUTPS0=....;

//Cho phép timer 2 hoạt động

TMR2ON=1;

Bước 6 : Cho phép ngõ ta PWM sau khi chu kỳ PWM mới được bắt đầu :

while(TMR2IF); // Chờ cho đến khi timer 2 tràn (bit TMR2IF của thanh ghi

PIR1 được bậc lên 1)

TRISCx = 0 ; //x = 1 , 2 .

IV.BÀI TẬP THỰC HÀNH :

Bài 1:Viết chương trình tạo xung PWM có tần số 20KHz ở hai chân : CCP1(RC2) và

CCP2(RC1) với độ rộng xung CCP1 là 50% xung , CCP2 là 80% xung .

Sơ đồ phần cứng :

*Bước 1 :Tạo một project mới với tên 04_01_ MSSV

*Bước 2: Nhập chương trình sau vào máy tính và hoàn thành vào dấu …….

#include <htc.h>

__CONFIG(INTIO&WDTDIS&PWRTEN&MCLREN&UNPROTECT&DUNPROTECT&BO

RDIS&IESODIS&LVPDIS&FCMDIS);

void main( )

{

//Khởi tạo tần số 20Khz PWM (timer 2)

PR2=…….; //Chọn tần số 20KHz

T2CKPS1=T2CKPS0=…….; //Bộ chia Prescales 1:1

TOUTPS3=TOUTPS2=TOUTPS1=TOUTPS0=…….;//Bộ chia Postcales1:1

//Khởi tạo khối CCP1

TRISC2=…….; //Disable ngõ ra của chân CCP1

CCP1CON=0b00001100; //(-------1--------)

CCPR1L=…….; //Tạo PWM 50% xung ỡ chân CCP1(-------2--------)

TMR1IF=…….; //Xóa cờ ngắt của khối CCP1

// Khởi tạo khối CCP2

Page 48: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

48

TRISC1=…….; // Disable ngõ ra của chân CCP1

CCP2CON=0b00001100; // Khởi tạo module CCP2 hoạt động chế độ PWM

CCPR2L=…….; //Tạo xung PWM 80% ở chân CCP2(-------3--------)

TMR2IF=…….; // Xóa cờ ngắt của khối CCP2

//Cho phép timer 2 hoạt động bắt đầu tạo xung PWM

TMR2ON =…….; //Cho phép timer 2 hoạt động

TRISC2 =…….; //Cho phép chân CCP1 là ngõ ra

TRISC1 =…….; //Cho phép chân CCP2 là ngõ ra .

while(1);

}

*Bước 3 : Nạp chương trình vào kit thí nghiệm , dùng oscillocope đo tín hiệu hai xung ở chân

CCP1 và CCP2 .

*Bước 4 : Thay đổi dòng (-------1--------) thành đoạn code sau :

CCP1CON=0b00001111;

Biên dịch chương trình nạp vào kít , dùng oscillocope đo ngõ ra PWM chân CCP1 , quan

sát xung được tạo ra , nhận xét sự khác nhau giữa xung trước và sau khi thay đổi code , và giải

thích sự khác nhau đó .

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

*Bước 5 : Tính toán giá trị thanh ghi CCPR1L cho CCP1 tạo ra PWM 90% .

Tính toán giá trị thanh ghi CCPR2L cho CCP2 tạo ra PWM 10% .

Thay vào (-------2--------) và (-------3--------) , biên dịch chương trình , nạp xuống kít

thí nghiệm , sử dụng oscillocope đo ngõ ra xung và hoàn thành vào bảng sau :

PWM 90% PWM 10%

CCPR1L

CCPR2L

Page 49: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

49

Bài 2 : Viết chương trình điều khiển tốc độ động cơ sử dụng IC chuyên dụng L298 theo

yêu cầu sau : (Tạo một project mới với tên 04_02_ MSSV)

− Nhấn RB0 tốc độ động cơ tăng dần (mỗi lần nhấn tăng 10% độ rộng xung).

− Nhấn RB1 tốc độ động cơ giảm dần(mỗi lần nhấn giảm 10% độ rộng xung).

− Nhấn RB2 động cơ đảo chiều quay .

Với PWM tần số 10Khz , độ phân giải 8 bit , thạch anh nội 4MHz.

Phần cứng :

*Bước 1 :Tạo một project mới với tên 04_02_ MSSV

*Bước 2 :Nhập chương trình sau vào máy tính và hoàn thành vào dấu …….

#include <htc.h>

__CONFIG(INTIO&WDTDIS&PWRTEN&MCLREN&UNPROTECT&DUNPROTECT&BO

RDIS&IESODIS&LVPDIS&FCMDIS);

void main( )

{

ANSEL=ANSELH=…….; //Tắt chức năng xử lý analog ở tất cả các chân

TRISB=…….; //Khởi tạo PORTB là ngõ vào

PORTB=…….;

WPUB=…….; //Cho phép điện trở treo tất cả PORTB

RBPU=…….;

IOCB =…….; //Cho phép ngắt on-change cả PORTB

RBIE =…….; //Enable ngắt on-change ở PORTB

RBIF =…….; //Xóa cờ ngắt on-change

GIE =…….; //Cho phép ngắt toàn cục

TRISE0=…….; //Khởi tạo chân RE0 là ngõ ra , mức cao

RE0 =…….;

T2CON = 0x04; //Timer 2 , prescaler 1:1 , postcaler 1:1 , TMR2ON=1

PR2 =…….; //tần số 10KHz

CCP1CON=0x0C; //Khởi tạo chế độ PWM cho module CCP1

Page 50: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

50

CCP2CON=0x0C; //Khởi tạo chế độ PWM cho module CCCP2

CCPR1L=0;

CCPR2L=0;

TRISC2=1;

TRISC1=1;

while(1)

{

}

}

void interrupt isr()

{

if(RBIE&&RBIF)

{

if(!RB0)

{

CCPR1L+=10;

CCPR2L+=10;

TMR2ON=1;

}

if(!RB1)

{

CCPR1L-=10;

CCPR2L-=10;

TMR2ON=1;

}

if(!RB2)

{

TRISC2^=1;

TRISC1=~TRISC2;

TMR2ON=1;

}

RBIF=0;

}

}

*Bước 3 : Jum header CCP2 (J2) , biên dịch chương trình nạp xuống kít thí nghiệm , kết nối

động cơ và cấp nguồn cho L298 , tiến hành nhấn nút và quan sát kết quả .

V.BÀI TẬP TỰ GIẢI :

*Bài 3 : Viết chương trình sử dụng chức năng capture đo tần số ở chân CCP1(RC2) và hiển thị

giá trị đó lên LCD theo sơ đồ phần cứng sau (Tạo một project mới với tên 04_03_ MSSV):

Page 51: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

51

*Bài 4 : Viết chương trình tạo xung PWM 8 bit ở chân CCP2(RC1) với tần số 15 KHz theo

yêu cầu sau (Tạo một project mới với tên 04_04_ MSSV)::

Nhấn nút nhấn (không giữ ) ở chân RB0 lần 1 : Độ rộng xung 15% .

Nhấn nút nhấn (không giữ ) ở chân RB0 lần 2 : Độ rộng xung 30% .

Nhấn nút nhấn (không giữ ) ở chân RB0 lần 3 : Độ rộng xung 45% .

Nhấn nút nhấn (không giữ ) ở chân RB0 lần 4 : Độ rộng xung 60% .

Nhấn nút nhấn (không giữ ) ở chân RB0 lần 5 : Độ rộng xung 75% .

Nhấn nút nhấn (không giữ ) ở chân RB0 lần 6 : Độ rộng xung 90% .

Nhấn nút nhấn (không giữ ) ở chân RB0 lần 7 : Trở lại trạng thái nhấn lần 1 .

*Bài 5 :Viết chương trình theo yêu cầu sau (Tạo một project mới với tên 04_05_ MSSV):

Nhấn RB0 động cơ quay cùng chiều kim đồng hồ , PWM 10Khz , độ rộng xung 90%.

Nhấn RB1 động cơ quay ngược chiều kim đồng hồ , PWM 15Khz , độ rộng xung 70%.

Page 52: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

52

Page 53: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

53

BÀI 5:GIAO TIẾP NỐI TIẾP BẤT ĐỒNG BỘ (USART)

I.MỤC ĐÍCH THÍ NGHIỆM :

Kiến thức sinh viên cần đạt được sau khi thực tập:

Giải thích nguyên lý truyền nhận tín hiệu UART.

Trình bày được khái niệm : baund , start bit , stop bit , frame truyền , parity .

Liệt kê được các thanh ghi liên quan truyền nhận UART.

Thiết lập các bit cho vi điều khiển truyền nhận dữ liệu qua chuẩn UART.

II.DỤNG CỤ THÍ NGHIỆM:

Kít thí nghiệm + cáp USB.

Động cơ DC12V.

Oscillocope.

Máy tính .

Nguồn 12V/1A.

III.CƠ SỞ LÝ THUYẾT :

Các chân liên quan đến chức năng giao tiếp nối tiếp :

Các chân truyền nhận UART

1.Khái niệm về giao tiếp nối tiếp bất đồng bộ :

Các thuật ngữ trong truyền nhận nối tiếp bất đồng bộ :

Thuật ngữ USART trong tiếng anh gọi là :Universal synchronous và Asynchronous serial

Receiver and Transmitter , nghĩa là bộ truyền nối tiếp đồng bộ và bất đồng bộ . USART hay

UART cần phải kết hợp với một thiết bị chuyển đổi điện áp để tạo nên một chuẩn giao tiếp nào

đó .Ví dụ chuẩn Rs232(COM Port ) trên máy tính là sự kết hợp của chip UART và chip chuyển

đổi mức điện áp .Tín hiệu từ chip UART thường theo mức điện áp : mức high là +5V , mức slow

là 0V .Trong khi đó tín hiệu theo chuẩn RS232 trên máy tính thường là -12v cho mức high , và

+12v cho mức slow .

Page 54: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

54

Cấu trúc một frame truyền

Sơ đồ điện áp trong giao tiếp RS232 .

Truyền thông nối tiếp :

Giả sử muốn truyền một dữ liệu 8-bit giữa hai vi điều khiển với nhau , chúng ta có thể

nghĩ đến cách đơn giản nhất là kết nối một PORT (8 bit) của mỗi vi điều khiển với nhau ,

mỗi đường trên PORT sẽ đảm nhiệm việc truyền/nhận một bit dữ liệu . Đây gọi là cách

giao tiếp song song , cách này đơn giản và truyền nhận dữ liệu cũng không qua bất cứ một

giải thuật truyền nhận nào , và tốc độ truyền nhận cũng rất nhanh .Tuy nhiên , nhược điểm

của cách truyền này là số đường truyền nhiều , dữ liệu truyền càng lớn thì số đường truyền

càng nhiều , do đó hệ thống truyền nhận song song thường rất cồng kềnh và kém hiệu quả .

Ngược lại trong truyền thông nối tiếp , dữ liệu được truyền theo từng bit trên một đừơng

truyền , chính vì vậy dữ liệu cho dù có lớn thì chúng ta cũng chỉ cần có một đường truyền

duy nhất .

Sơ đồ truyền nhận 8 bit theo giao thức song song và nối tiếp .

Các thông số cơ bản trong truyền nhận nối tiếp :

Baund rate (tốc độ baund ): để truyền nhận nối tiếp xảy ra thành công thì các thiết bị

phải thống nhất với nhau về khoảng thời gian giành cho một bit truyền , hay nói cách khác

là tốc độ truyền phải được cài đặt giống nhau , tốc độ này gọi là tốc độ baund .Tốc độ

Page 55: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

55

baund là số bit truyền trong 1 giây . Ví dụ nếu tốc độ baund là 9600 thì thời gian giành cho

một bit truyền là 1/9600(s).

Frame (khung truyền ) : Khung truyền quy định về số bit trong mỗi lần truyền , các bit

báo như start , stop , các bit kiểm tra như parity , ngoài ra số lượng các bit trong một dữ liệu

cũng được quy định bởi khung truyền . Hình trên mô tả ví dụ về một khung truyền theo

UART , khung truyền này được bắt đầu bằng một start bit , tiếp theo là 8 bit , sau đó là 1bit

parity dùng để kiểm tra dữ liệu và cuối cùng là 2 bits stop .

Start bit : start bit là bit đầu tiên được truyền trong một frame , bit này có nhiệm vụ báo

cho thiết bị nhận biết rằng có một gói dữ liệu sắp được truyền tới .Start bit là bit bắt buộc

phải có trong một khung truyền .

Data : là số dữ liệu mà chúng ta cần phải truyền nhận , data có thể là gói 8 bit hay 9 bit

tùy theo yêu cầu truyền nhận mà ta quy định .Trong truyền thông nối tiếp UART , bit có

trọng số nhỏ nhất LSB(Least significant bit ) sẽ được truyền trước , sau đó bit có trọng số

lớn nhất sẽ được truyền sau cùng MSB(Most signnificant bit ).

Parity bit : parity dùng để kiểm tra dữ liệu truyền có đúng không , có hai loại parity là

parity chẳn (event parity )và parity lẻ (odd parity ) .

Stop bit : stop bit là một hoặc các bit báo cho thiết bị rằng các bit đã được gởi xong. Sau

khi nhận được stop bit , thiết bị nhận sẽ tiến hành kiển ra khung truyền để đảm bảo tính

chính xác của dữ liệu .Stop bit là bit bắt buộc xuất hiện trong khung truyền .

Các thanh ghi điều khiển truyền UART:

Sơ đồ khối bộ truyền UART

Nguyên tắc hoạt động :

Dữ liệu cần truyền được đặt vào thanh ghi TXREG , baund rate được tạo ra , khi bit TXEN

được gán bằng một , dữ liệu từ thanh ghi TXREG đi vào thanh ghi TSR đồng thời baund rate tác

động đến thanh ghi TSR , đẩy dữ liệu cần truyền ra bộ điệm , sau đó xuất ra chân TX và đi ra

ngoài .

Bit TXIF dùng để báo trạng thái trong thanh ghi TXREG , nếu có dữ liệu trong thanh ghi

TXREG thì bít này sẽ có tín hiệu là 1 , ngược lại sau khi dữ liệu đã được truyền xuống thanh ghi

Page 56: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

56

TSR thì bít TXIF được xóa về không .Tương tự như bit TXIF , bit TRMT dùng để báo trạng thái

của thanh ghi TSR .Quá trình truyền cũng có thể tạo ra ngắt truyền , mỗi khi dữ liệu truyền đã

kết thúc bằng việc đặt bit TXIF=1.

Ngoải ra bộ truyền còn có thể truyền với chế độ 9 bit bằng việc cho bit TX9 =1 , và dữ liệu

của bit thứ 9 do bit TX9D quy định .

Thanh ghi quy định chế độ truyền :

Các bit liên quan đến chế độ truyền nhận bất đồng bộ.

TX9 :bit cho phép truyền nhận chế độ 9-bit

− 1:Cho phép hoạt động với chế độ 9 bit

− 0:Hoạt động với chế độ 8bit

TXEN:bit cho phép truyền UART

− 1:Cho phép truyền .

− 0:Không cho phép truyền .

SYNC :bit lực chọn chế độ truyền .

− 1:Truyền nhận chế độ đồng bộ.

− 0:Truyền nhận chế độ bất đồng bộ.

BRGH: bit lựa chọn chế độ baund rate

− 1: tốc độ cao (bất đổng bộ )

− 0:tốc độ thấp (bất đồng bộ)

TRMT : bit hiển thị trạng thái thanh ghi truyền

− 1:Thanh ghi TSR trống .

− 0:Thanh ghi TSR có dữ liệu .

TX9D : Dữ liệu bit thứ 9 trong chế độ truyền 9 bit

Ngắt truyền UART

Các bit khởi tạo ngắt truyền UART :

TXIF : cờ ngắt , sau khi thanh ghi TXREG truyền dữ liệu xuống thanh ghi TSR thì bit này tự

động bằng 1 .

TXIE : bit cho phép ngắt truyền , để tạo ra ngắt truyền ta cần phải cho phép bit này bằng 1 .

PEIE : bit cho pháp ngắt ngoại vi .

Page 57: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

57

GIE : bit cho phép ngắt toàn cục .

Các bước khởi tạo chế độ truyền UART :

*Bước 1 : Khởi tạo thanh ghi SPBRGH , SPBRG và các bit BRGH và BRG16 để tạo ra baund

rate cần thiết .

*Bước 2 : Cho phép giao tiếp bất đồng bộ :

SYNC=0;

SPEN=1;

*Bước 3 : Cho phép chế độ 9 bit (nếu sử dụng truyền nhận 9 bit ) :

TX9=1;

*Bước 4 : Cho phép truyền :

TXEN=1;

*Bước 5 : Nếu sử dụng ngắt thì cần phải khởi tạo :

TXIE=1;

PEIE=1;

GIE=1;

*Bước 6: Gởi dữ liệu cần truyền của bit thứ 9 (nếu sử dụng truyền nhận 9 bit ):

TX9D=…..;

*Bước 7 : Gởi dữ liệu cần truyền vào thanh ghi 8 bit:

TXREG=…..;

Các thanh ghi điều khiển nhận UART:

Sơ đồ khối bộ truyền UART

Nguyên tắc hoạt động :

Khi có dữ liệu được truyền tới chân RX , nếu bit SPEN được cho phép , thì dữ liệu sẽ được

đồng bộ với khối tạo xung , vì baund rate giữa hai khối truyền nhận bằng nhau, nên xung baund

mang dữ liệu từng bit vào thanh ghi RSR , khi một frame truyền hoàn tất (dấu hiệu từ bit stop) ,

thì dữ liệu được truyền xuống thanh ghi RCREG , bit thứ 9 được truyền xuống RX9D(nếu sử

Page 58: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

58

dụng chế độ 9 bit) , nếu trên đường truyền có lỗi thì các bit OERR, FERR sẽ được hiển thị để

báo .

Quá trình nhận củng có thể tạo ra ngắt sau khi kết thúc một frame truyền nhận, bằng việc làm

cho bit RCIF =1 .

Thanh ghi quy định chế độ nhận :

Các bit liên quan đến chế độ truyền nhận bất đồng bộ.

SPEN : Bit cho phép khởi tạo cổng nối tiếp :

− 1:Cho phép cổng nối tiếp

− 0: Không cho phép cổng nối tiếp

RX9: Bit cho phép nhận 9 bit

− 1: Chế độ nhận 9 bit

− 0: Chế độ nhận 8 bit

CREN : bit cho phép nhận liên tục

− 1: Cho phép .

− 0: Không cho phép .

ADDEN : bit cho phép phát hiện địa chỉ (sử dụng ở chế độ truyền nhận bất đồng bộ 9 bit )

− 1:Cho phép phát hiện địa chỉ , cho phép ngắt và tải bộ đệm nhận khi RSR<8> được set.

− 0:Không cho phép phát hiện địa chỉ , tất cả byte được nhận và bit thứ 9 dùng làm bit

parity

FERR : bit báo lỗi frame

− 1: Có lỗi

− 0:Không có lỗi .

OERR : lỗi OVERRUN

− 1:Có lỗi (có thể xóa bằng việc xóa bít CREN)

− 0:Không lỗi .

RX9D : Bit chứa dữ liệu nhận của bit thứ 9

Ngắt nhận UART

Các bit khởi tạo ngắt nhận UART :

RCIF : cờ ngắt , sau khi thanh ghi RCREG nhận được dữ liệu thì bit này tự động bằng 1.

RCIE : bit cho phép ngắt nhận , để tạo ra ngắt nhận ta cần phải cho phép bit này bằng 1 .

Page 59: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

59

PEIE : bit cho pháp ngắt ngoại vi .

GIE : bit cho phép ngắt toàn cục .

Các bước khởi tạo chế độ nhận UART :

*Bước 1 : Khởi tạo thanh ghi SPBRGH , SPBRG và các bit BRGH và BRG16 để tạo ra baund

rate cần thiết .

*Bước 2 : Cho phép giao tiếp bất đồng bộ :

SYNC=0;

SPEN=1;

*Bước 3 : Nếu sử dụng ngắt nhận :

RCIE=1;

PEIE=1;

GIE=1;

*Bước 4 : Cho phép chế độ 9 bit bằng (nếu sử dụng truyền nhận 9 bit ) :

RX9=1;

*Bước 5 : Cho phép nhận dữ liệu :

CREN=1;

*Bước 6 : Cờ ngắt RCIF = 1 khi dữ liệu chuyển đổi từ RSR tới bộ điệm nhận . Ngắt sẽ được tạo

ra nếu RCIE=1.

*Bước 7 : Đọc thanh ghi RCSTA để phát hiện các lỗi trong quá trình truyền nhận.

*Bước 8 : Nhận 8 bit dữ liệu từ bộ điệm nhận bằng cách đọc thanh ghi RCREG.

*Bước 9 : Nếu có lỗi overrun xảy ra , xóa cờ OERR bằng cách xóa bit CREN.

Công thức tính tốc độ baund rate :

Trong đó :

FOSC là tần số hoạt động của vi điều khiển .

n=SPBRGH:SPBRG

Ví dụ : Tính tốc độ baund 9600 ,với điều kiện các bit khởi tạo như sau :

SYNC=0 ; BRG16=1; BRGH=1; Fosc= 4Mhz

Khi đó theo bảng ta có :

9600= 𝐹𝑂𝑆𝐶

4(𝑛+1)

n=103

Page 60: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

60

Do đó : SPBRG=103 , SPBRGH=0;

IV:BÀI TẬP THỰC HÀNH :

Bài 1 :Viết chương trình truyền nhận UART của vi điều khiển với máy tính , điều khiển

hoạt động của led theo yêu cầu sau :

Vi điều khiển nhận một số từ máy tính và điều khiển hai led RE1 va RE2 với 4 trạng thái

Nhận số 1: Hai led tắt , gởi lên máy tính chuỗi "Number 1".

Nhận số 2: Hai led sáng, gởi lên máy tính chuỗi "Number 2".

Nhận số 3:Led RE1 sáng,RE2 tắt ,gởi lại máy tính chuỗi "Number 3".

Nhận số 4:Led RE1 tắt ,RE2 sáng ,gởi lại máy chuỗi "Number 4".

Số khác :Hai led cùng chớp tắt với chu kỳ _delay(100000);gởi lại máy tính chuỗi "Other

numbers".

Vi điều khiển sử dụng thạch anh nội 4MHz , tốc độ baund : 9600 , truyền nhận 8 bit .

Cấu hình phần cứng :

*Bước 1 : Tạo một project mới với tên 05_01_ MSSV

*Bước 2 : Nhập chương trình sau vào máy tính và hoàn thành vào dấu …….

#include <htc.h>

#include <stdio.h>

__CONFIG(INTIO&WDTDIS&PWRTEN&MCLREN&UNPROTECT&DUNPROTECT&FC

MDIS&IESODIS&LVPDIS&BORDIS);

void send_string(char *s);

void send_char(char c);

char data ;

void main()

{

ANS6=ANS7=…….;TRISE1=TRISE2=…….; //Khởi tạo RE1,RE2 là ngõ ra số

//Cấu hình truyền UART

TXEN=…….; //Cho phép truyền

SYNC=…….;

//Cấu hình nhận UART

Page 61: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

61

SPEN =…….; //Cấu hình chân RX,TX ở chế độ truyền nhận UART

CREN=…….;

//Khởi tạo tốc độ baund 9600=Fosc/(4*(n+1)) với n=SPBRGH:SPBRG

BRG16=1; //(--------1----------)

BRGH=1; //(--------2----------)

SPBRG=103;SPBRGH=0; //(--------3----------)

//Khởi tạo ngắt nhận

RCIE =…….;

PEIE =…….;

GIE =…….;

while(1)

{

switch(data)

{

case 1:

RE1=RE2=…….;send_string("Number 1\r"); //Hai led tắt

break;

case 2:

RE1=RE2=…….;send_string("Number 2\r"); //Hai led sáng

break;

case 3:

RE1=0;RE2=…….;

send_string("Number 3\r"); //RE1 tắt , RE2 sáng

break;

case 4:

RE1=…….;RE2=…….;

send_string("Numer 4\r"); //RE2 tắt , RE1 sáng

break;

default:

RE1^=…….;RE2=RE1; //Hai led cùng chớp tắt.

send_string("Other numbers\r");

break;

}

_delay(100000);

}

}

void interrupt isr()

{

if(RCIF)

{

data=RCREG;

}

}

void send_char(char c)

Page 62: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

62

{

while(!TXIF);

TXREG=c;

}

void send_string(char *s)

{

while(*s)

send_char(*s++);

}

*Bước 3 : Nạp chương trình vào kít thí nghiệm , kết nối máy tính với kít thí nghiệm bằng cổng

COM(Nếu sử dụng Laptop thì cần có cáp USB−>COM .

*Bước 4 : Sử dụng chương trình Terminal (chương trình dùng test cổng COM) truyền nhận kí tự

xuống kit thí nghiệm , đồng thời quan sát 2 led trên kit thí nghiệm .

*Bước 5 : Chứng minh thông số của dòng (1) , (2), (3).

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------------------------------------

Bài 2 : Làm lại bài 1 với tốc độ baund 14400 (Tạo một project mới với tên 05_02_ MSSV).

V.BÀI TẬP TỰ GIẢI :

Bài 3 : Viết chương trình truyền nhận UART của vi điều khiển với máy tính , hiển thị kết

quả lên lcd theo sơ đồ phần cứng sau (Tạo một project mới với tên 05_02_ MSSV):

Yêu cầu : Truyền một chuỗi số (tối đa 5 chữ số xxxxx) từ máy tính xuống vi điều khiển , vi điều

khiển hiển thị số vừa nhận được từ máy tính lên lcd , đồng thời gởi lại máy tính số vừa nhận

cộng thêm 10.Thạch anh 4Mhz , baund 9600 , truyền nhận 8-bit , phần cứng kết nối lcd theo thư

viện lcd.h .

Page 63: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

63

Bài 4 : Viết chương trình truyền nhận giữa vi điều khiển và máy tinh với các yêu cầu sau :

Máy tính truyền xuống vi điều khiển kí tự „S‟ , động cơ start.

Máy tính truyền xuống vi điều khiển kí tự „P‟ , động cơ stop.

Máy tính truyền xuống vi điều khiển kí tự „B-xxx‟ , động cơ quay thuận ,với xxx là độ

rộng xung PWM 8 bit .

Máy tính truyền xuống vi điều khiển kí tự „F-xxx‟ , động cơ quay nghịch , với xxx là độ

rộng xung PWM 8 bit .

Page 64: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

64

Bài 5 : Viết chương trình truyền nhận giữa máy tính và vi điều khiển với yêu cầu sau : máy tính

hiển thị vận tốc động cơ trên Terminal , baund 9600, Fosc = 4Mhz .

Page 65: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

65

TÀI LIỆU THAM KHẢO :

[1] PIC16F882/883/884/886/887 Data Sheet

[2]Dogan lbrahim , Advanced PIC Microcontroller Projects in C

[3] http://www.picvietnam.com/forum/

[4] http://www.microchip.com/

Page 66: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

66

Phụ Lục

I.Cửa sổ chương trình :

I.Khởi tạo một project mới :

1.Tạo một folder (A) chứa tất cả các file chương trình

2.Khởi động MPLAB : Chọn Project , Project Wizard

Thanh Menu

Thanh Công Cụ

Của sổ viết

chương trình

1 2

Page 67: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

67

3.Chọn Next :

4.Chọn dòng PIC muốn lập trình , Next :

5.Lựa chọn công cụ lập trình (ở đây chọn H-TECH) , Next:

Chú ý : Chỉ duy nhất có dòng H-TECH sau khi cài đặt thành công Hi-tech C.

3

4

5

6

7

Page 68: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

68

6.Browse tới folder (A) , đặt tên cho bài làm (main), Next :

7.Nhấn Next , chọn Finish:

9 9

10

Page 69: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

69

8.Chọn NewFile ở thanh công cụ , viết đoạn chương trình #include<htc.h> trong

MPLAB IDE Editor , chọn Save :

9.Đặt tên main.c (Chú ý : phải có “.c” và Save in ở thư mục A) ,chọn save :

11

12 13

15

14

16

Page 70: Giao Trinh Thi Nghiem VDK

Giáo trình thí nghiệm vi điều khiển ứng dụng

70

10.Right click vào Source file ở cửa sổ main.mcw chọn Add files , Browse tới

main.c chọn open :

11.Hoàn tất tạo một project , tiếp tục viết chương trình .

17 18