1. 7 Các dụng cụ đo kích thước cơ bản
4.5.2. Chương trình nạp cho PIC16F877A
Giới thiệu phần mền PICkit 2 v2.61
PICkit là phần của hãng microchip dùng cho việc nạp chương trình cho vi điều khiển
Như các dòng vi điều khiển như PIC, AT89S, Atmega…
Hình 4.4 Cửa sổ làm việc PICkit 2 v2.61
58
Hình 4.5 Mạch nạp pickit 2
Hình 4. 6 Đế cắm vi điều khiển
Giao tiếp PC qua cổng USB, không cần cài đặt driver.
Hỗ trợ Window XP/ Windows Vista/ Window7 /Window8 32-bit/64-bit OS
Tốc độ nạp/gỡ rối cực nhanh.
Chức năng giao tiếp UART và Logic Analyzer
Hỗ trợ tất cả các dòng PIC10F, PIC12F, PIC16F, PIC18F, PIC24, dsPIC30, dsPIC33, và PIC32 và một số sản phẩm Serial EEPROM của Microchip.
Hỗ trợ nạp cho cả PIC 5V và 3.3V
Có khả năng cung cấp nguồn 5V, 3.3V từ USB và nguồn trên board.
Tích hợp Socket đa năng có thể nạp cho tất cả các dòng PIC 8/14/18/20/28/40 chân.
Tự động cập nhật Firmware khi có phiên bản mới
Chip mới (New device) có thể được bổ sung bằng việc cập nhật phần mềm.
59 Chương trình điều khiển thiết bị đo
#include <16F877A.h> // khai báo pic sử dụng
#include <def_877a.h> //Thư viện do người dùng PIC16F877A #device *=16
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000) //tần số thạch anh 20MHz #include <lcd_lib_4bit.c> // Thư viện LCD tự tạo #define k1 RD5
#define k2 RD6 #define k3 RD7
#define TRIGGER pin_b0 // Chân phát sóng siêu âm //Chân ECHO nhận tín hiệu nối với RC2
#BIT RC2=0X7.2
float scan=0, dist, getvar; // Khai báo biến int1 has_echo=0;
int16 kc=0, low, high, high1; void convert_bcd();
//Chương trình con phục vụ ngắt CCP1 #int_CCP1
void ccp1_isr() {
if(input(pin_c2)) // Nếu là xung canh lên {
set_timer1(0); // Reset timer1 ve 0
setup_ccp1(CCP_CAPTURE_FE); // Chuyển Capture 1 đo xung cạnh xuống }
else // Nếu là xung cạnh xuống {
getvar=CCP_1; // Đọc giá trị timer 1
dist=(getvar*0.8)/58; // Mỗi 1 nhịp của timer 1 tương ứng với 0.8 us, lấy us chia cho 58 ra cm
60
has_echo = 1; // Ðã nhận xong echo } } //----Ngat timer 1---- #int_TIMER1 void TIMER1_isr(void) { if (has_echo == 0) {
has_echo = 1; // Tràn timer mà không có echo thì cho qua (SRF05 là 30ms, tràn timer là 52ms)
dist = -1; }
}
//----10us cho trigger---- void trig() { output_high(TRIGGER); delay_us(10); output_low(TRIGGER); }
//----Chuong trinh khoi tao---- void khoi_tao() { //Port su dung trisa = 0x00; trisb = 0x00; trisc = 0xff; trisd = 0xff;
// Khoi tao cho ngat ngoai
setup_timer_1(T1_INTERNAL|T1_DIV_BY_4); //20 MHz thì tràn trong 52ms (tối đa xung của SRF05 là 30ms)
setup_ccp1(CCP_CAPTURE_RE); // Thiết lập Capture 1 đo cạnh lên
enable_interrupts(int_TIMER1); // Ngắt timer 1, đề phòng trường hợp không có echo enable_interrupts(INT_CCP1); // Ngắt Capture 1
enable_interrupts(GLOBAL); }
//----Chuong trinh chinh--- void main()
61
{
int is=0; khoi_tao();
LCD_init();//Khởi tạo LCD
Printf(LCD_putchar,"DO KHOANG CACH"); LCD_putcmd(0xC0);
Printf(LCD_putchar,"Dang khoi tao..."); delay_ms(800);
LCD_putcmd(0xC0); Printf(LCD_putchar,"Vui long Scan... "); while(TRUE)
{
has_echo = 0; // Xác lập lại echo trig(); // Trigger
while (has_echo == 0) {} // Chờ đến khi nhật hết echo if(dist!=-1) { convert_bcd(); lcd_putcmd(0x80); printf(lcd_putchar,"K>Cach = %4.2f",dist); lcd_putchar(" cm "); } if(k1==0) { while(k1==0) LCD_putcmd(0xC0);
Printf(LCD_putchar," Da Scan xong ! "); delay_ms(800); scan = dist; LCD_putcmd(0xC0); Printf(LCD_putchar,"C_cao vat: 0 cm "); } if(k2==0) { while(k2==0) LCD_putcmd(0xC0); Printf(LCD_putchar,"C_cao vat:%4.2f",scan-dist); lcd_putchar("cm "); is=0; } if(k3==0) { while(k3==0) if(is==0||is==1) is=2; else is=1; } if(is==1) { LCD_putcmd(0xC0);
62
Printf(LCD_putchar,"Dag do chieu cao"); } if(is==2) { LCD_putcmd(0xC0); Printf(LCD_putchar,"C_cao vat:%4.2f",scan-dist); lcd_putchar("cm "); } } } //end main--- //----Chuong trinh chuyen doi ma bcd LCD---- void convert_bcd()
{
kc = (int16)dist;
high1 = (kc%1000)/100; high=(kc%100)/10;
low=kc%10; //Chia lấy dư hàng đơn vị low = low + 0x30;
high = high + 0x30; high1 = high1 + 0x30; }