Professional Documents
Culture Documents
Bai Thuc Tap VDK Final Khanh Son
Bai Thuc Tap VDK Final Khanh Son
----- -----
VI ĐIỀU KHIỂN
MỤC LỤC
MỤC LỤC ..................................................................................................................... 1
THIẾT BỊ THỰC HÀNH ............................................................................................ 2
BÀI 1 : LED ĐƠN ......................................................................................................... 8
BÀI 2 : HIỂN THỊ KÝ TỰ TRÊN LCD ................................................................... 10
BÀI 3 : XỬ LÝ NGẮT................................................................................................ 21
BÀI 4 : XỬ LÝ ADC .................................................................................................. 25
BÀI 5 : TIMER ........................................................................................................... 30
BÀI 6: GIAO TIẾP I2C ............................................................................................. 34
BÀI 7: GIAO TIẾP RS232 ......................................................................................... 38
BÀI 8: ĐIỀU KHIỂN ĐỘNG CƠ DC....................................................................... 46
BÀI 9: ĐO KHOẢNG CÁCH BẰNG CẢM BIẾN SIÊU ÂM SRF05 ................... 51
Hình 1: Thiết bị thực hành Kit BOOK 1 do công ty R&P phát triển.
1.4.Thực hiện
Kết nối cáp USB từ mạch nạp trên kit BOOK 1 với máy tính, cấp nguồn cho
mạch PIC qua adapter.
Viết chƣơng trình cho PIC bằng CCS C, sau đó biên dịch ra file hex.
Nạp file hex xuống PIC bằng phần mềm PIC kit 2 v2.61 đƣợc cài trên máy.
Chạy thực nghiệm và kiểm tra kết quả.
1.5. Bài tập
Bài tập 1.1: Viết chƣơng trình chớp tắt led ở port e với thời gian delay 250 ms:
Chƣơng trình mẫu gợi ý :
#include <16F887.h>
#include <def_887.h>
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD,
NOWRT
#use delay(clock=20000000)
void main() {
trise = 0x00;
porte=0xff;
while (1) {
Porte = 0x00;
delay_ms(250);
Porte = 0xFF;
delay_ms(250);
}
}
Bài tập 1.2 : Viết chƣơng trình chớp tắt các led ở port e với thời gian delay 1s.
Bài tập 1.3 : Viết chƣơng trình chớp tắt led D4 ở port e với thời gian delay 1s,
led D5 với thời gian delay 0,5 s.
* Ghi chú : Ở chế độ“đọc”, nghĩa là MCU sẽ đọc thông tin từ LCD thông qua các
chân DBx.
Còn khi ở chế độ“ghi”, nghĩa là MCU xuất thông tin điều khiển cho LCD thông qua
các chân DBx.
Sơ đồ khối của HD44780: Để hiểu rõ hơn chức năng các chân và hoạt động của
chúng, ta tìm hiểu sơ qua chíp HD44780 thông qua các khối cơ bản của nó.
* Với mỗi lệnh, LCD cần một khoảng thời gian để hoàn tất, thời gian này có thể
khá lâu đối với tốc độ của MCU, nên ta cần kiểm tra cờ BF hoặc đợi (delay) cho LCD
thực thi xong lệnh hiện hành mới có thể ra lệnh tiếp theo.
* Địa chỉ của RAM (AC) sẽ tự động tăng (giảm) 1 đơn vị, mỗi khi có lệnh ghi vào
RAM. (Điều này giúp chƣơng trình gọn hơn).
* Các lệnh của LCD có thể chia thành 4 nhóm nhƣ sau :
• Các lệnh về kiểu hiển thị. VD : Kiểu hiển thị(1 hàng / 2 hàng), chiều dài dữ
liệu (8 bit / 4 bit), …
• Chỉ định địa chỉRAM nội.
• Nhóm lệnh truyền dữ liệu trong RAM nội.
• Các lệnh còn lại . (!!!)
CÁC LỆNH CỦA LCD
2.4.Thực hiện
Kết nối cáp USB từ mạch nạp trên kit BOOK 1 với máy tính, cấp nguồn cho
mạch PIC qua adapter, kết nối LCD với kit.
Viết chƣơng trình cho PIC bằng CCS C, sau đó biên dịch ra file hex.
Nạp file hex xuống PIC bằng phần mềm PICkit 2 v2.61 đƣợc cài trên máy.
Chạy thực nghiệm và kiểm tra kết quả.
// prototype statements
#separate void LCD_Init ( void );// ham khoi tao LCD
#separate void LCD_SetPosition ( unsigned int cX );//Thiet lap vi tri con tro
#separate void LCD_PutChar ( unsigned int cX );// Ham viet1kitu/1chuoi len LCD
#separate void LCD_PutCmd ( unsigned int cX) ;// Ham gui lenh len LCD
#separate void LCD_PulseEnable ( void );// Xung kich hoat
#separate void LCD_SetData ( unsigned int cX );// Dat du lieu len chan Data
// D/n Cong
#use standard_io (C)
#use standard_io (D)
Bài tập 2.2 : Viết chƣơng trình hiển thị trên LCD theo yêu cầu sau : Hàng thứ
nhất hiển thị họ tên sinh viên, hàng thứ hai hiển thị mã số sinh viên.
Bài tập 2.3 : Viết chƣơng trình đếm số từ 0 đến 999 và hiển thị trên LCD.
BÀI 3 : XỬ LÝ NGẮT
3.1.Nhiệm vụ
Thực hành lập trình ứng dụng trên máy tính, biên dịch chƣơng trình, nạp vào
VĐK và sử dụng mô hình thí nghiệm để kiểm chứng.
• Điều khiển thiết bị ngoại vi bằng các nút nhấn.
• Lâp trình xử lý ngắt ngoài của VĐK PIC 16F887.
3.2.Yêu cầu
• Nắm vững các tập lệnh của VĐK PIC 16F887.
• Biết cách viết các chƣơng trình điều khiển thiết bị ngoại vi bằng các nút nhấn.
• Nắm đƣợc sơ đồ và nguyên lý hoạt động của khối nút nhấn .
• Nắm đƣợc nguyên lý hoạt động của ngắt ngoài.
• Biết cách viết các chƣơng trình xử lý ngắt ngoài của VĐK PIC 16F887.
3.3. Giới thiệu chung
Trong VĐK PIC có nhiều nguồn ngắt. Mỗi dòng VĐK có số lƣợng ngắt khác
nhau, PIC 14 có 14 ngắt, PIC 18 có 35 ngắt. Để biết cụ thể ta có thể vào mục View
>> Valid Interrupts . Khi đó một của sổ sẽ hiện ra liệt kê đầy đủ các nguồn ngắt của
từng con PIC.
Để viết một hàm phục vụ ngắt ta chỉ việc thêm khai báo #INT_tên_ngắt vào
trƣớc hàm phục vụ cho ngắt đó. Khi đó trình dịch sẽ hiểu đó là địa chỉ hàm cho ngắt,
khi có ngắt tƣơng ứng xảy ra thì nó sẽ nhảy đến vị trí đó. Lấy ví dụ khi ta muốn xử lý
ngắt ngoài, hàm sẽ đƣợc viết nhƣ sau:
#INT_EXT
Ext_isr()
{
// Nhập mã tại đây
}
Sau đây là danh sách 1 số ngắt với chức năng tƣơng ứng :
#INT_GLOBAL : ngắt chung , nghĩa là khi có ngắt xảy ra , hàm theo sau chỉ
thị này đƣợc thực thi , bạn sẽ không đƣợc khai báo thêm chỉ thị ngắt nào khác khi sử
dụng chỉ thị này . CCS không sinh bất kỳ mã lƣu nào, hàm ngắt bắt đầu ngay tại
vector ngắt . Nếu bật nhiều cờ cho phép ngắt , có thể bạn sẽ phải hỏi vòng để xác định
ngắt nào. Dùng chỉ thị này tƣơng đƣơng viết hàm ngắt 1 cách thủ công mà thôi , nhƣ
là viết hàm ngắt với ASM vậy .
#INT_AD : chuyển đổi A /D đã hoàn tất.
#INT_BUSCOL : xung đột bus .
#INT_BUTTON : nút nhấn.
#INT_CCP1 : có Capture hay compare trên CCP1.
3.4.Thực hiện
Kết nối cáp USB từ mạch nạp trên kit BOOK 1 với máy tính, cấp nguồn cho
mạch PIC qua adapter.
Viết chƣơng trình cho PIC bằng CCS C, sau đó biên dịch ra file hex.
Nạp file hex xuống PIC bằng phần mềm PICkit 2 v2.61 đƣợc cài trên máy.
Chạy thực nghiệm và kiểm tra kết quả.
3.5. Bài tập
Bài tập 3.1 : Viết chƣơng trình nhận nút nhấn ở chân B0 của PIC 16F887, cứ
mỗi lần ấn phím sẽ đảo trạng thái của các led ở port e.
Chƣơng trình mẫu gợi ý :
#include <16F887.h>
#include <def_887.h>
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP,
NOCPD, NOWRT
#use delay(clock=20000000)
#int_ext
ext_isr()
{
porte=~porte;
}
void main() {
trisb = 0xff;
Port_B_pullups (1 );
trise = 0x00;
porte=0b00000000;
enable_interrupts(int_EXT);
ext_int_edge(H_TO_L);
enable_interrupts(GLOBAL);
while (1) {
}
Bài tập 3.2 : Viết chƣơng trình hiển thị số lần nhấn phím ở chân B0 của PIC
16F887 lên màn hính LCD 16x02.
Bài tập 3.3 : Viết chƣơng trình nhận nút nhấn ở các chân B3-5 của PIC
16F887, hiển thị lên màn hính LCD 16x02.
Bài tập 3.4 : Viết chƣơng trình nhận nút nhấn ở chân B0 của PIC 16F887 có xử
lý chống nhiễu.
BÀI 4 : XỬ LÝ ADC
4.1.Nhiệm vụ
Thực hành lập trình ứng dụng trên máy tính, biên dịch chƣơng trình, nạp vào
VĐK và sử dụng mô hình thí nghiệm để kiểm chứng.
• Điều khiển thiết bị ngoại vi bằng các nút nhấn.
• Lâp trình xử lý ngắt ngoài của VĐK PIC 16F887.
4.2.Yêu cầu
• Nắm vững các tập lệnh của VĐK PIC 16F887.
• Biết cách viết các chƣơng trình xử lý tín hiệu ADC.
• Nắm đƣợc sơ đồ và nguyên lý hoạt động của khối ADC .
• Nắm đƣợc nguyên lý hoạt động của ADC trong PIC 16F887.
• Biết cách viết các chƣơng trình xử lý ADC của VĐK PIC 16F887.
4.3. Giới thiệu chung
PIC có nhiều chân phục vụ xử lý ADC với nhiều cách thức khác nhau . Để
dùng ADC , bạn phải có khai báo #DEVICE cho biết dùng ADC mấy bit ( tuỳ chip hỗ
trợ , thƣờng là 8 hay 10 bit hoặc hơn) . Bạn cần lƣu ý là: 1 VĐK hỗ trợ ADC 10 bit thì
giá trị vào luôn là 10 bit , nhƣng chia cho 4 thì còn 8 bit . Do đó 1 biến trở chiết áp cấp
cho ngõ vào ADC mà bạn chọn chế độ 10 bit thì sẽ rất nhạy so với chế độ 8 bit ( vì 2
bit cuối có thay đổi cũng không ảnh hƣởng giá trị 8 bit cao và do đó kết quả 8 bit
ADC ít thay đổi ), nếu chƣơng trình có chế độ kiểm tra ADC để cập nhật tính toán ,
hay dùng ngắt ADC, thì nó sẽ chạy hoài thôi . Dùng ADC 8 bit sẽ hạn chế điều này .
Do đó mà CCS cung cấp chọn lựa ADC 8 hay 10 bit tùy mục đích sử dụng .
Cấu hình bộ ADC :
+ Thông dụng nhất khi dùng ADC là sử dụng 1 biến trở , điều chỉnh bởi 1 nút
vặn , qua đó thu đƣợc 1 điện áp nhỏ hơn điện áp tham chiếu ( Vref – áp max ) , đƣa
vào chân biến đổi ADC , kết quả cho 1 giá trị số ADC 8 bit ( 0-255 ) hay ADC 10 bit
(0-1023 ) . Thƣờng thì áp Vref lấy bằng Vdd ( 5V ).
+ Trên các PIC có ngõ AVdd và AVss ( PIC 18 ) , thƣờng thì bạn luôn nối AVdd
tới Vdd , AVss tới Vss để đảm bảo họat động cho lập trình qua ICD 2 .
Các hàm sau phục vụ ADC :
1 / Setup_ADC ( mode ) :
+ Không trả về trị . Dùng xác định cách thức hoạt động bộ biến đổi ADC .
Tham số mode tuỳ thuộc file thiết bị *.h có tên tƣơng ứng tên chip bạn đang dùng ,
nằm trong thƣ mục DEVICES của CCS . Muốn biết có bao nhiêu tham số có thể dùng
cho chip đó , bạn mở file tƣơng ứng đọc , tìm tới chỗ các định nghĩa cho chức năng
ADC dùng cho chip đó tƣơng ứng với hàm này . Sau đây là các giá trị mode của
16F877A , ( 1 số khác có thể không có hoặc có thêm nhƣ 16F877A có thêm 1 số thứ
là ADC_CLOCK_DIV_2/4/8/16/32/64 . . .) :
ADC_OFF : tắt hoạt động ADC ( tiết kiệm điện , dành chân cho hoạt động
khác ) .
ADC_CLOCK_INTERNAL : thời gian lấy mẫu bằng xung clock IC ( mất 2-6
us ) thƣờng là chung cho các chip .
ADC_CLOCK_DIV_2 : thời gian lấy mẫu bằng xung clock / 2 ( mất 0.4 us
trên thạch anh 20MHz )ADC_CLOCK_DIV_8 : thời gian lấy mẫu bằng xung clock /
8 ( 1.6 us ).
ADC_CLOCK_DIV_32 : thời gian lấy mẫu bằng xung clock / 32 ( 6.4 us ).
2 / Setup_ADC_ports ( value )
+ Xác định chân lấy tín hiệu analog và điện thế chuẩn sử dụng . Tùy thuộc bố
trí chân trên chip , số chân và chân nào dùng cho ADC và số chức năng ADC mỗi
chip mà value có thể có những giá trị khác nhau. Xem file tƣơng ứng trong thƣ mục
DEVICES để biết số chức năng tƣơng ứng chip đó . Để tƣơng thích chƣơng trình viết
cho phiên bản cũ , 1 số tham số có 2 tên khác nhau ( nhƣng cùng chức năng do định
nghĩa cùng địa chỉ ) , ở đây dùng phiên bản 3.227 . Lƣu ý : Vref : áp chuẩn , Vdd : áp
nguồn .
Sau đây là các giá trị cho value ( chỉ dùng 1 trong các giá trị ):
ALL_ANALOGS : dùng tất cả chân sau làm analog : A0 A1 A2 A3 A5 E0 E1
E2 (Vref=Vdd).
NO_ANALOG : không dùng analog , các chân đó sẽ là chân I /O .
AN0_AN1_AN2_AN4_AN5_AN6_AN7_VSS_VREF : A0 A1 A2 A5 E0 E1
E2 Vref=A3.
AN0_AN1_AN2_AN3_AN4 : A0 A1 A2 A3 A5 ( tên thì giống nhau cho tất
cả thiết bị nhƣng 16F877 chỉ có portA có 5 chân nên A0 , A1 , A2 , A5 đƣợc dùng ,
A6 , A7 không có ) .
AN0_AN1_AN3 : A0 A1 A3 , Vref = Vdd
AN0_AN1_VSS_VREF : A0 A1 VRefh = A3
AN0_AN1_AN4_AN5_AN6_AN7_VREF_VREF : A0 A1 A5 E0 E1 E2
VRefh=A3 , VRefl=A2 .
AN0_AN1_AN2_AN3_AN4_AN5 : A0 A1 A2 A3 A5 E0
AN0_AN1_AN2_AN4_AN5_VSS_VREF : A0 A1 A2 A5 E0 VRefh=A3
AN0_AN1_AN4_AN5_VREF_VREF : A0 A1 A5 E0 VRefh=A3 VRefl=A2
AN0_AN1_AN4_VREF_VREF : A0 A1 A5 VRefh=A3 VRefl=A2
AN0_AN1_VREF_VREF : A0 A1 VRefh=A3 VRefl=A2
AN0 : A0
AN0_VREF_VREF : A0 VRefh=A3 VRefl=A2
VD : setup_adc_ports (AN0_AN1_AN3 ) ; // A0 , A1 , A3 nhận analog , áp
nguồn +5V cấp cho IC sẽ là điện áp chuẩn .
ĐƢỜNG KHÁNH SƠN Trang 26
TÀI LIỆU THỰC TẬP VI ĐIỀU KHIỂN DRAFT
3 / Set_ADC_channel ( channel ) :
+ Chọn chân để đọc vào giá trị analog bằng lệnh Read_ADC ( ) . Giá
trị channel tuỳ số chân chức năng ADC mỗi chip .Với 16F877 ,channel có giá trị từ 0
-7 : 0-chân A0, 1-chân A1, 2-chân A2, 3-chân A3, 4-chân A5, 5-chân E0, 6-chân E1,
7-chân E2.
+Hàm không trả về trị . Nên delay 10 us sau hàm này rồi mới dùng
hàm read_ADC ( ) để bảo đảm kết quả đúng . Hàm chỉ hoạt động với A /D phần cứng
trên chip.
4 / Read_ADC ( mode ) :
+ Dùng đọc giá trị ADC từ thanh ghi (/ cặp thanh ghi ) chứa kết quả biến đổi
ADC . Lƣu ý hàm này sẽ hỏi vòng cờ cho tới khi cờ này báo đã hoàn thành biến đổi
ADC ( sẽ mất vài us ) thì xong hàm .
+ Nếu giá trị ADC là 8 bit nhƣ khai báo trong chỉ thị #DEVICE , giá trị trả về
của hàm là 8 bit , ngƣợc lại là 16 bit nếu khai báo #DEVICE sử dụng ADC 10 bit trở
lên.
+ Khi dùng hàm này, nó sẽ lấy ADC từ chân bạn chọn trong hàm
Set_ADC_channel( ) trƣớc đó. Nghĩa là mỗi lần chỉ đọc 1 kênh Muốn đổi sang đọc
chân nào, dùng hàm set_ADC_channel( ) lấy chân đó. Nếu không có đổi chân,
dùng read_ADC( ) bao nhiêu lần cũng đƣợc .
+ mode có thể có hoặc không , gồm có :
ADC_START_AND_READ : giá trị mặc định.
ADC_START_ONLY : bắt đầu chuyển đổi và trả về.
ADC_READ_ONLY : đọc kết quả chuyển đổi lần cuối.
#DEVCE 8 bit 10 bit 11 bit 16 bit
ADC=8 0-255 0-255 00-255 00-255
ADC=10 x 0-1023 x x
ADC=11 x x 0-2047 x
ADC=16 0-65280 0-65472 0-65504 0-65535
+ 16F877 chỉ hỗ trợ ADC 8 và 10 bit .
4.4.Thực hiện
Kết nối cáp USB từ mạch nạp trên kit BOOK 1 với máy tính, cấp nguồn cho
mạch PIC qua adapter.
Nối jump cho 2 chân POT của J7 trên kit BOOK 1.
Viết chƣơng trình cho PIC bằng CCS C, sau đó biên dịch ra file hex.
Nạp file hex xuống PIC bằng phần mềm PICkit 2 v2.61 đƣợc cài trên máy.
Điều chỉnh biến trở R7 và quan sát kết quả.
4.5. Bài tập
Bài tập 4.1 : Viết chƣơng trình đọc giá trị ADC từ biến trở R7 và hiển thị lên
LCD 16x02
Chƣơng trình mẫu gợi ý :
#include <16f887.h>
#include <def_887.h>
#device *=16 ADC=10
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#include <lcd_lib_4bit.c>
Int16 adc ;
void main()
{
output_low(LCD_RW);
LCD_init();
// Delay_us (100);
setup_adc(adc_clock_internal);
// Setup_ADC_ports (sAN3);
Set_ADC_channel (3) ;
Delay_us (10 ); // delay 10 us
while(true)
{
adc = read_adc () ;
lcd_putcmd(0x80);
lcd_putcmd(0x01);//xoa man hinh
delay_ms(100);
Printf(lcd_putchar,"GIA TRI ADC LA:");
lcd_putcmd(Line_2);
Printf(lcd_putchar,"%04lu " , adc );
delay_ms(1000);
}
Bài tập 4.2 : Viết chƣơng trình đọc giá trị ADC từ biến trở R7 và xuất ra giá trị
các led ở port e.
Bài tập 4.3 : Viết chƣơng trình đọc giá trị ADC từ biến trở R7 và gởi lên máy
tính.
BÀI 5 : TIMER
5.1.Nhiệm vụ
• Thực hành lập trình ứng dụng trên máy tính, biên dịch chƣơng trình, nạp vào
VĐK và sử dụng mô hình thí nghiệm để kiểm chứng.
• Viết chƣơng trình ứng dụng timer ở chế độ định thời.
• Viết chƣơng trình ứng dụng timer ở chế độ bộ đếm.
5.2.Yêu cầu
• Nắm vững các tập lệnh của VĐK PIC 16F887.
• Nắm đƣợc sơ đồ và nguyên lý hoạt động của các bộ timer của PIC 16F887.
• Biết cách viết các chƣơng trình sử dụng các bộ timer của PIC 16F887 ở các
chế độ khác nhau.
• Biết cách viết các chƣơng trình tạo thời gian trễ với các khoảng thời gian bất
kỳ.
5.3. Giới thiệu chung
CÁC LỆNH CỦA TIMER – COUNTER
Các lệnh của ngôn ngữ lập trình C liên quan đến timer/counter bao gồm:
Lệnh SETUP_TIMER_X()
Lệnh SET_TIMER_X()
Lệnh SETUP_COUNTERS()
Lệnh SETUP_WDT()
Lệnh RESTART_WDT()
Lệnh GET_TIMER_X()
LỆNH SETUP_TIMER_1(MODE)
- Cú pháp: setup_timer_1(mode)
- Thông số: mode có thể là 1 hoặc 2 hằng số định nghĩa trong file device.h.
Các thông số gồm:
T1_DISABLED, T1_INTERNAL, T1_EXTERNAL, T1_EXTERNAL_SYNC
TC_CLK_OUT, T1_DIV_BY_1, T1_DIV_BY_2, T1_DIV_BY_4,
T1_DIV_BY_8.
Các hằng số từ nhiều nhóm khác nhau thì có thể or với nhau.
- Chức năng:
Khởi tạo cho TIMER1.
Với tần số thạch anh là 20MHz và khởi tạo T1_DIV_BY_8 thì timer sẽ tăng
giá trị sau mỗi khoảng thời gian 1.6µs. Timer sẽ tràn sau 104.8576 ms.
- Có hiệu lực: cho tất cả các VĐK PIC có timer 1.
LỆNH SET_TIMERx(value)
- Cú pháp: set_timerX(value) ; x là 0, 1, 2
- Thông số: value là hằng số nguyên 8 hoặc 16 bit dùng để thiết lập giá trị
mới cho timer.
- Chức năng: thiết lập giá trị bắt đầu cho TIMER.
- Có hiệu lực: cho tất cả các VĐK PIC có timer.
LỆNH GET_TIMERx()
- Cú pháp: value = get_timerX() ; x là 0, 1, 2
- Thông số: không có.
- Chức năng: đọc giá trị của TIMER/COUNTER.
- Có hiệu lực: cho tất cả các VĐK PIC có timer.
Timer0
Các lệnh:
setup_TIMER_0(mode);
setup_COUNTERS (rtcc_state, ps_state); // hay setup_WDT().
set_TIMER0(value); // hay set_RTCC(value) :xác định giá trị ban đầu (8bit)
cho Timer0.
get_TIMER0(); // hay get_RTCC() :trả về số nguyên (8bit) của Timer0.
Trong đó mode là một hoặc hai constant (nếu dùng hai thì chèn dấu "|"ở giữa)
đƣợc định nghĩa trong file 16F877A.h gồm :
RTCC_INTERNAL : chọn xung clock nội
RTCC_EXT_L_TO_H : chọn bit cạnh lên trên chân RA4
RTCC_EXT_H_TO_L : chọn bit cạnh xuống trên chân RA4
RTCC_DIV_2 :chia prescaler 1:2
RTCC_DIV_4 1:4
RTCC_DIV_8 1:8
RTCC_DIV_16 1:16
RTCC_DIV_32 1:32
RTCC_DIV_64 1:64
RTCC_DIV_128 1:128
RTCC_DIV_256 1:256
rtcc_state là một trong những constant sau:
RTCC_INTERNAL
RTCC_EXT_L_TO_H
RTCC_EXT_H_TO_L
ps_state là một trong những constant sau:
RTCC_DIV_2
RTCC_DIV_4
RTCC_DIV_8
RTCC_DIV_16
ĐƢỜNG KHÁNH SƠN Trang 31
TÀI LIỆU THỰC TẬP VI ĐIỀU KHIỂN DRAFT
RTCC_DIV_32
RTCC_DIV_64
RTCC_DIV_128
RTCC_DIV_256
WDT_18MS
WDT_36MS
WDT_72MS
WDT_144MS
WDT_288MS
WDT_576MS
WDT_1152MS
WDT_2304MS
Timer1
Các lệnh:
setup_TIMER_1(mode);
set_TIMER1(value); // xác định giá trị ban đầu (16bit) cho Timer1
get_TIMER1(); // trả về số nguyên (16bit) của Timer1
mode gồm (có thể kết hợp bằng dấu "|"):
T1_DISABLED : tắt Timer1
T1_INTERNAL : xung clock nội (Fosc/4)
T1_EXTERNAL : xung clock ngoài trên chân RC0
T1_EXTERNAL_SYNC : xung clock ngoài đồng bộ
T1_CLK_OUT
T1_DIV_BY_1
T1_DIV_BY_2
T1_DIV_BY_4
T1_DIV_BY_8
Timer2
Các lệnh:
setup_TIMER_2(mode, period, postscale);
set_TIMER2(value); // xác định giá trị ban đầu (8bit) cho Timer2
get_TIMER2(); // trả về số nguyên 8bit
Với mode gồm (có thể kết hợp bằng dấu "|"):
T2_DISABLED
T2_DIV_BY_1
T2_DIV_BY_4
T2_DIV_BY_16
period là số nguyên từ 0-255, xác định giá trị xung reset
postscale là số nguyên 1-16, xác định reset bao nhiêu lần trƣớc khi ngắt.
5.4.Thực hiện
Kết nối cáp USB từ mạch nạp trên kit BOOK 1 với máy tính, cấp nguồn cho
mạch PIC qua adapter.
ĐƢỜNG KHÁNH SƠN Trang 32
TÀI LIỆU THỰC TẬP VI ĐIỀU KHIỂN DRAFT
Viết chƣơng trình cho PIC bằng CCS C, sau đó biên dịch ra file hex.
Nạp file hex xuống PIC bằng phần mềm PICkit 2 v2.61 đƣợc cài trên máy.
Chạy thực nghiệm và kiểm tra kết quả.
5.5. Bài tập
Bài tập 1 : Viết chƣơng trình chớp tắt led ở port e với thời gian delay 1s sử
dụng timer của PIC 16F887.
Chƣơng trình mẫu gợi ý :
#include <16F887.h>
#include <def_887.h>
#fuses NOWDT,PUT,XT,NOPROTECT
#use delay(clock=2000000)
#byte PORTB = 0x06
int16 count;
//Chuong trinh ngat TMR0
#int_timer0
void interrupt_timer0()
{
set_timer0(6);
++count;
if(count == 2000) // 2000*500us = 1000000us = 1s
{
count=0;
porte=~porte;
}
}
//Chuong trinh chinh
void main(void)
{
trise = 0x00;
enable_interrupts(int_timer0);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
enable_interrupts(global);
set_timer0(6);// T_dinhthi = 2*(256 - 6)*1us = 500us
porte=0x00;
while(true)
{
}
}
Bài tập 5.2 : Viết chƣơng trình đếm từ 0 đến 9999 sử dụng timer của PIC
16F887, hiển thị trên LCD 16x02.
Bài tập 5.3 : Viết chƣơng trình đếm số lần ấn phím sử dụng timer của PIC
16F887, hiển thị trên LCD 16x02.
Hình 6.2: Kết nối thiết bị vào bus I2C ở chế độ chuẩn (Standard mode)
và chế độ nhanh (Fast mode)
Mỗi dây SDA hay SCL đều đƣợc nối với điện áp dƣơng của nguồn cấp thông
qua một điện trở kéo lên (pull‐up resistor). Sự cần thiết của các điện trở kéo này là vì
chân giao tiếp I2C của các thiết bị ngoại vi thƣờng là dạng cực máng hở (open‐drain
or open‐collector).
Giá trị của các điện trở này khác nhau tùy vào từng thiết bị và chuẩn giao tiếp,
thƣờng dao động trong khoảng 1KΩ đến 4.7KΩ.
Một thiết bị hay một IC khi kết nối với bus I2C, ngoài một địa chỉ (duy nhất)
để phân biệt, nó còn đƣợc cấu hình là thiết bị chủ (master) hay tớ (slave). Tại sao lại
có sự phân biệt này ? Đó là vì trên một bus I2C thì quyền điều khiển thuộc về thiết bị
chủ (master). Thiết bị chủ nắm vai trò tạo xung đồng hồ cho toàn hệ thống, khi giữa
hai thiết bị chủ/tớ giao tiếp thì thiết bị chủ có nhiệm vụ tạo xung đồng hồ và quản lý
địa chỉ của thiết bị tớ trong suốt quá trình giao tiếp. Thiết bị chủ giữ vai trò chủ động,
còn thiết bị tớ giữ vai trò bị động trong viêc giao tiếp.
Về dữ liệu truyền trên bus I2C, một bus I2C chuẩn truyền 8‐bit dữ liệu có
hƣớng trên đƣờng truyền với tốc độ là 100Kbits/s – Chế độ chuẩn (Standard mode).
Tốc độ truyền có thể lên tới 400Kbits/s – Chế độ nhanh (Fast mode) và cao nhất là
3,4Mbits/s – Chế độ cao tốc (High‐speed mode).
Một bus I2C có thể hoạt động ở nhiều chế độ khác nhau:
- Một chủ một tớ (one master – one slave)
- Một chủ nhiều tớ (one master – multi slave)
- Nhiều chủ nhiều tớ (Multi master – multi slave)
Dù ở chế độ nào, một giao tiếp I2C đều dựa vào quan hệ chủ/tớ. Giả thiết một
thiết bị A muốn gửi dữ liệu đến thiết bị B, quá trình đƣợc thực hiện nhƣ sau:
‐ Thiết bị A (Chủ) xác định đúng địa chỉ của thiết bị B (tớ), cừng với việc xác
định địa chỉ, thiết bị A sẽ quyết định việc đọc hay ghi vào thiết bị tớ.
‐ Thiết bị A gửi dữ liệu tới thiết bị B
6.4.Thực hiện
Kết nối cáp USB từ mạch nạp trên kit BOOK 1 với máy tính, cấp nguồn cho
mạch PIC qua adapter.
Viết chƣơng trình cho PIC bằng CCS C, sau đó biên dịch ra file hex.
Nạp file hex xuống PIC bằng phần mềm PICkit 2 v2.61 đƣợc cài trên máy.
6.5. Bài tập
Bài tập 6.1 : Viết chƣơng trình đọc giá trị nhiệt độ từ TC 74 và hiển thị trên
LCD 16x02.
Chƣơng trình mẫu gợi ý :
#include <16f887.h>
#include <def_887.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use i2c(Master, sda = PIN_C4, scl=PIN_C3)
#use delay(clock=20000000)
#include <lcd_lib_4bit.c>
int temp;
void main()
{
output_low(LCD_RW);
LCD_init();
while(true)
{
lcd_putcmd(0x80);
lcd_putcmd(0x01);//xoa man hinh
delay_ms(100);
i2c_start();
i2c_write(0x90);
i2c_write(0x00);
i2c_start();
i2c_write(0x91);
temp=i2c_read(0);
i2c_stop();
Printf(lcd_putchar,"nhiet do :%i oC",temp);
delay_ms(1000);
}
}
Bài tập 6.2 : Viết chƣơng trình đọc giá trị thứ, ngày, tháng, năm từ ic RTC
DS1307 và hiển thị trên LCD 16x02.
Bài tập 6.3 : Viết chƣơng trình đồng hồ số hiển thị trên LCD 16x02 bao gồm
giờ, phút, giây, nhiệt độ môi trƣờng.
+ Tốc độ truyền nhận dữ liệu cực đại là 100kbps ( ngày nay có thể lớn hơn)
+ Các lối vào phải có điện dung nhỏ hơn 2500pF.
+ Trở kháng tải phải lớn hơn 3000 ôm nhƣng phải nhỏ hơn 7000 ôm.
+ Độ dài của cáp nối giữa máy tính và thiết bị ngoại vi ghép nối qua cổng nối tiếp
RS232 không vƣợt qua 15m nếu chúng ta không sử model.
+ Các giá trị tốc độ truyền dữ liệu chuẩn :
50,75,110,750,300,600,1200,2400,4800,9600,19200,28800,38400....56600,115
200 bps.
Các mức điện áp đƣờng truyền
RS 232 sử dụng phƣơng thức truyền thông không đối xứng, tức là sử dụng tín
hiệu điện áp chênh lệch giữa một dây dẫn và đất. Do đó ngay từ đầu tiên ra đời nó đã
mang vẻ lỗi thời của chuẩn TTL, nó vấn sử dụng các mức điện áp tƣơng thích TTL để
mô tả các mức logic 0 và 1. Ngoài mức điện áp tiêu chuẩn cũng cố định các giá trị trở
kháng tải đƣợc đấu vào bus của bộ phận và các trở kháng ra của bộ phát.
Mức điện áp của tiêu chuẩn RS232C ( chuẩn thƣờng dùng bây giờ) đƣợc mô tả
nhƣ sau:
+ Mức logic 0 : +3V , +12V.
+ Mức logic 1 : -12V, -3V.
Các mức điện áp trong phạm vi từ -3V đến 3V là trạng thái chuyển tuyến.
Chính vì từ - 3V tới 3V là phạm vi không đƣợc định nghĩa, trong trƣờng hợp thay đổi
giá trị logic từ thấp lên cao hoặc từ cao xuống thấp, một tín hiệu phải vƣợt qua quãng
quá độ trong một thơì gian ngắn hợp lý. Điều này dẫn đến việc phải hạn chế về điện
dung của các thiết bị tham gia và của cả đƣờng truyền. Tốc độ truyền dẫn tối đa phụ
thuộc vào chiều dài của dây dẫn. Đa số các hệ thống hiện nay chỉ hỗ trợ với tốc độ
19,2 kBd .
Cổng RS232 trên PC
Hầu hết các máy tính cá nhân hiện nay đều đƣợc trang bị ít nhất là 1 cổng Com
hay cổng nối tiếp RS232. Số lƣợng cổng Com có thể lên tới 4 tùy từng loại main máy
tính. Khi đó các cổng Com đó đƣợc đánh dấu là Com 1, Com 2, Com 3...Trên đó có 2
loại đầu nối đƣợc sử dụng cho cổng nối tiếp RS232 loại 9 chân (DB9) hoặc 25 chân
(DB25). Tuy hai loại đầu nối này có cùng song song nhƣng hai loại đầu nối này đƣợc
phân biệt bởi cổng đực (DB9) và cổng cái (DB25).
Ta xét sơ đồ chân cổng Com 9 chân:
phần tử báo hiệu sự mã hóa một bit nên khi đó hai tốc độ bit và tốc độ baud là phải
đồng nhất
Một số tốc độ Baud thƣờng dùng: 50, 75, 110, 150, 300, 600, 1200, 2400, 4800, 9600,
19200, 28800, 38400, 56000, 115200 … Trong thiết bị họ thƣờng dùng tốc độ là
19200
Khi sử dụng chuẩn nối tiếp Cáp cổng Com RS232 thì yêu cầu khi sử dụng chuẩn là
thời gian chuyển mức logic không vƣợt quá 4% thời gian truyền 1 bit. Do vậy, nếu tốc
độ bit càng cao thì thời gian truyền 1 bit càng nhỏ thì thời gian chuyển mức logic càng
phải nhỏ. Điều này làm giới hạn tốc Baud và khoảng cách truyền.
Bit chẵn lẻ hay Parity bit
Đây là bit kiểm tra lỗi trên đƣờng truyền. Thực chất của quá trình kiểm tra lỗi
khi truyền dữ liệu là bổ xung thêm dữ liệu đƣợc truyền để tìm ra hoặc sửa một số lỗi
trong quá trình truyền . Do đó trong chuẩn RS232 sử dụng một kỹ thuật kiểm tra chẵn
lẻ.
Một bit chẵn lẻ đƣợc bổ sung vào dữ liệu đƣợc truyền để ch thấy số lƣợng các bit "1"
đƣợc gửi trong một khung truyền là chẵn hay lẻ.
Một Parity bit chỉ có thể tìm ra một số lẻ các lỗi chả hạn nhƣ 1,3,,5,7,9... Nếu
nhƣ một bit chẵn đƣợc mắc lỗi thì Parity bit sẽ trùng giá trị với trƣờng hợp không mắc
lỗi vì thế không phát hiện ra lỗi. Do đó trong kỹ thuật mã hóa lỗi này không đƣợc sử
dụng trong trƣờng hợp có khả năng một vài bit bị mắc lỗi.
Việc giao tiếp giữa VĐK và máy tính là bài lập trình khá quan trọng khi ta làm
việc với các dòng VĐK khác nhau. Với VĐK PIC cũng vậy, trong mỗi IC PIC đều có
tích hợp một khối giao tiếp máy tính USART. Ta sử dụng khối giao tiếp này để truyền
dữ liệu lên máy tính và xử lý dữ liệu đó tùy vào mục đích của ngƣời lập trình.
Để truyền nhận dữ liệu giữa VĐK truyền lên với máy tính ta có thể sử dụng
các phần mềm giao tiếp COM có sẵn hay viết một chƣơng trình mới, sử dụng các
ngôn ngữ lập trình nhƣ C++, VB, Delphi, MATLAB…
Sơ đồ nguyên lý trên kit BOOK 1
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
trise=0x00;
ENABLE_INTERRUPTS(INT_RDA);
enable_interrupts(GLOBAL);
while (1) {
}
}
s=serial('com1','BaudRate',9600);
fopen(s);
fprintf(s,'b');
fclose(s)
delete(s)
clear s
clear all
s=serial('com1','BaudRate',9600);
fopen(s);
fprintf(s,'t');
fclose(s)
delete(s)
clear s
Bài tập 7.2 : Viết chƣơng trình truyền chuỗi “ THUC TAP VI DIEU KHIEN”
từ PC xuống PIC 16F887 sau đó hiển thị chuỗi nhận đƣợc lên LCD 16x02.
Bài tập 7.3 : Viết chƣơng trình đọc giá trị nhiệt độ từ IC TC 74 sau đó truyền
giá trị đọc đƣợc lên PC qua cổng RS232.
Khi đầu vào „Direction‟ ở trạng thái cao thì motor sẽ chuyển sang chế độ
hƣớng bình thƣờng. Nếu đầu vào „Direction‟ ở trạng thái thấp thì motor sẽ quay
ngƣợc chiều.
IC L298:
Có rất nhiều loại IC dùng cho mạch cầu H. Loại phổ thông dùng cho motor
dòng thấp là L293B và motor dòng cao là L298.
IC L298 là một IC tích hợp nguyên khối gồm 2 mạch cầu H bên trong. Với
điện áp làm tăng công suất đầu ra từ 5V – 47V , dòng lên đến 4A, L298 rất thích hợp
trong những ứng dụng công suất nhỏ nhƣ động cơ DC loại vừa …
Chức năng các chân của L298:
- 4 chân INPUT: IN1, IN2, IN3, IN4 đƣợc nối lần lƣợt với các chân 5, 7, 10, 12
của L298. Đây là các chân nhận tín hiệu điều khiển.
- 4 chân OUTPUT: OUT1, OUT2, OUT3, OUT4 (tƣơng ứng với các chân
INPUT) đƣợc nối với các chân 2, 3, 13, 14 của L298. Các chân này sẽ đƣợc nối với
động cơ.
- Hai chân ENA và ENB dung để điều khiển các mạch cầu H trong L298. Nếu
ở mức logic “1” (nối với nguồn 5V) thì cho phép mạch cầu H hoạt động, nếu ở mức
logic “0” thì mạch cầu H không hoạt động.
Với bài toán của mình ở trên, các bạn chỉ cần lƣu ý đến cách điều khiển chiều
quay với L298:
- Khi ENA = 0: Động cơ không quay với mọi đầu vào .
- Khi ENA = 1:
- INT1 = 1; INT2 = 0: động cơ quay thuân.
- INT1 = 0; INT2 = 1: động cơ quay nghịch.
- INT1 = INT2: động cơ dừng ngay tức thì.(tƣơng tự với các chân ENB, INT3,
INT4).
Sơ đồ nguyên lý trên kit BOOK 1:
Điều khiển tốc độ DC Motor dùng chỉnh độ rộng xung (Pulse Width
Modulation -PWM):
Điều khiển độ rộng của xung là cách bật tắt nhanh nguồn điện lên motor. Nếu
tần số bật tắt mà đủ cao, motor sẽ chạy ở một tốc độ ổn định nhờ mômen quay của
bánh xe.
Bằng cách thay đổi chu kỳ hoạt động của tín hiệu (thay đổi độ rộng xung –
PWM), tức là khoảng thời gian “Bật”, nguồn điện trung bình đặt lên motor sẽ thay đổi
và dẫn đến thay đổi tốc độ.
SƠ ĐỒ KHỐI PWM của PIC16F887
Khối PWM gồm có 2 mạch so sánh: mạch so sánh 8 bit với mạch so sánh 10
bit. Mạch so sánh 8 bit sẽ so sánh giá trị đếm của timer 2 với giá trị của thanh ghi PR2
(period register), giá trị trong timer 2 tăng từ giá trị đặt trƣớc cho đến khi bằng giá trị
của PR2 thì mạch so sánh sẽ set flip flop RS làm ngõ ra CCPx lên mức 1. Đồng thời
nạp giá trị 10 bit từ thanh ghi CCPRxL sang thanh ghi CCPRxH, timer2 bị reset và bắt
đầu đếm lại cho đến khi giá trị của timer 2 bằng giá trị của CCPRxH thì mạch so
sánh sẽ reset flip flop RS làm ngõ ra CCPx về mức 0. Quá trình này lặp lại.
Dạng sóng điều chế PWM nhƣ sau:
Chu kỳ không thay đổi, muốn thay đổi thời gian xung ở mức 1 thì ta thay đổi
hệ số chu kỳ (duty cycle). Khi hệ số chu kỳ thay đổi thì điện áp hay dòng trung bình
thay đổi. Hệ số chu kỳ càng lớn thì dòng trung bình càng lớn, nếu điều khiển động cơ
sẽ làm thay đổi tốc độ.
TÍNH CHU KỲ XUNG PWM:
Chu kỳ PWM của PIC16F877A đƣợc tính theo công thức:
PERIODPWM = [(PR2) +1] * 4 * TOSC * PVTMR2
Trong đó: TOSC là chu kỳ của tụ thạch anh tạo dao động.
PVTMR2 (prescale value) giá trị chia trƣớc của timer2.
Khi giá trị của timer 2 (TMR2) bằng giá trị của thanh ghi PR2 thì 3 sự kiện
theo sau sẽ xảy ra:
· Thanh ghi TMR2 bị xóa
· Tín hiệu ngõ ra CCPx lên mức 1, ngoại trừ hệ số chu kỳ bằng 0% thì CCPx
vẫn ở mức 0.
· Hệ số chu kỳ PWM đƣợc chuyển từ thanh ghi CCPRxL sang thanh ghi
CCPRxH.
HỆ SỐ CHU KỲ XUNG PWM
Hệ số chu kỳ đƣợc thiết lập bởi giá trị lƣu trong thanh ghi 10 bit gồm CCPRxL
8 bit và 2 bit còn lại là bit thứ 4 và thứ 5 ở trong thanh ghi CCPxCON – kí hiệu
là CCPxCON<5:4>.
Giá trị của hệ số chu kỳ là 10 bit nên có thể thay đổi từ 0 đến 1023 tạo ra 1024
cấp giá trị điều khiển. Giá trị 10 bit thì 8 bit có trọng số lớn lƣu trong thanh ghi
CCPRxL và 2 bit còn lại có trọng số thấp thì ở CCPxCON<5:4>.
Hệ số chu kỳ của PIC16F877A đƣợc tính theo công thức:
DUTY_ CYCLEPWM = (CCPRxL:CCPxCON < 5 : 4 >) * TOSC* PVTMR2.
8.4.Thực hiện
Kết nối cáp USB từ mạch nạp trên kit BOOK 1 với máy tính, cấp nguồn cho
mạch PIC qua adapter.
Kết nối động cơ DC với kit BOOK 1.
Viết chƣơng trình cho PIC bằng CCS C, sau đó biên dịch ra file hex.
Nạp file hex xuống PIC bằng phần mềm PICkit 2 v2.61 đƣợc cài trên máy.
Tiến hành chạy thực nghiệm và quan sát kết quả.
8.5. Bài tập
Bài tập 8.1 : Viết chƣơng trình điều khiển động cơ DC bằng nút nhấn nối với
ngắt ngoài của PIC 16F887.
void main()
{
trisb = 0xff;
Port_B_pullups (1 );
enable_interrupts(int_ext);
ext_int_edge(H_TO_L);
enable_interrupts(GLOBAL);
while (true) {
}
}
Bài tập 8.2 : Viết chƣơng trình điều khiển tốc độ và chiều quay của động cơ
DC.
Bài tập 8.3 : Viết chƣơng trình đo tốc độ động cơ DC hiển thị lên LCD 16x02.
Bài tập 8.4 : Viết chƣơng trình điều khiển tốc độ động cơ DC bằng PC qua
cổng RS 232.
- Khi phát ra xung, và chờ xung phản xạ về, chân ECHO của SRF05 sẽ đƣợc
kéo lên cao. khi có xung phản xạ về chân ECHO sẽ đƣợc kéo xuống thấp, hoặc sau
30ms nếu không có xung phản xạ về.
SRF05 có thể thiết lập 2 mode hoạt động khác nhau thông qua các chân điều
khiển MODE.
Nối hoặc không nối chân MODE xuống GND cho phép cảm biến đƣợc điều
khiển thông qua giao tiếp dùng 1 chân hay 2 chân IO. Trong demo này, ta sẽ sử dụng
mode thứ 2.
ng:
Trong mode này,SRF05sử dụng cả 2 chân trigger và echo cho việc giao tiếp
với MCU.
Để sử dụng mode này,ta chỉ cần để trống chân Mode của module,điện trở bên
trong module sẽ kéo chân pin này lên mức 1.
Đƣợc thiết kế nhằm cho mục đích tiết kiệm chân pin cho MCU, nên trong
mode này, SRF05 chỉ sử dụng 1 chân pin cho 2 chức năng TRIGGER và ECHO. Để
sử dụng mode này, ta kết nối chân Mode xuống GND (0v).
int1 echo = 0;
int16 value = 0;
void Trigger()
{
output_high(PIN_TRIGGER);
delay_us(12);
output_low(PIN_TRIGGER);
}
#int_CCP1
void CCP1_isr(void)
{
if(echo == 1)
{
setup_ccp1(CCP_CAPTURE_FE); // falling fulse
set_timer1(0);
echo = 0;
}
else
{
setup_ccp1(CCP_CAPTURE_RE); // rising fulse
value = CCP_1;
echo = 1;
}
}
void main()
{
output_low(LCD_RW);
LCD_init();
setup_adc_ports(NO_ANALOGS);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_4);
setup_ccp1(CCP_CAPTURE_RE); // raising fulse
enable_interrupts(INT_CCP1);
enable_interrupts(GLOBAL);
float distance = 0;
while(TRUE)
{
Trigger();
while(echo == 0)
{}
distance = value * 0.8 / 58;
lcd_putcmd(0x85);
lcd_putcmd(0x01);//xoa man hinh
printf(LCD_PutChar, "KHOANG CACH : ");
lcd_putcmd(Line_2);
printf(LCD_PutChar, "%fcm", distance);
delay_ms(100);
}
}
}
Bài tập 9.2 : Viết chƣơng trình đo khoảng cách bằng cảm biến siêu âm SRF 05
kết nối với VĐK PIC 16F887, gởi giá trị đo đƣợc lên máy tính.
Bài tập 9.3 : Viết chƣơng trình điều khiển robot di chuyển song song cách
tƣờng một khoảng cách không đổi là 40 cm sử dụng cảm biến siêu âm SRF 05
kết nối với VĐK PIC 16F887.