Giả sử chúng ta cần cho Động cơ chạy tới trong 2s, dừng 1s rùi chạy ngược trong 1s chẳng hạn. Chương trình sau giúp chúng ta thực hiện công việc trên: Mã:
#include<16F877A> #fuses NOWDT,PUT,HS,NOPROTECT #use delay(clock=10000000) main() { output_high(PIN_B0); output_low(PIN_B1); delay_ms(2000); output_low(PIN_B0); delay_ms(1000); output_high(PIN_B1); output_high(PIN_B0); delay_ms(1000); } Giải thích từng dòng nhe. Mã:
#include<16F877A> Khai báo con PIC bạn sử dụng, file này chương trình viết sẵn nhằm khai báo các bit, thanh ghi quan trọng trong con pic này.Các bạn có thể vào thư mục cài đặt C:\Program Files\PICC\Devices\16F877A.h để xem nó khai báo được những gì trong đó! Mã:
#fuses NOWDT,PUT,HS,NOPROTECT Thiết lập các config Mã:
#use delay(clock=10000000) Khai báo tần số xung clk cấp vào (nó bằng tần số con thạch anh bạn xài) Mã:
output_high(PIN_B0); output_low(PIN_B1); Mỗi port của PIC có 1 thanh ghi Tris 8 bit. Mỗi bit của thanh ghi này tuơng ứng với trạng thái của một pin trong port đó. 1 là input, 0 là output... Trước khi đọc hay xuất dữ liệu lên port phải tác động lên Tris trước. Tuy nhiêN CCSC cung cấp hai hàm output_high() và output_low() cho phép xuất riêng rẽ từng pin của PIC. lệnh này tác động trực tiếp lên thanh ghi tris, bạn không cần thay đổi tris. Tuy nhiên khi cần inport hoặc outport toàn bộ các bit, có 1 cách khác là fast i_o, mình sẽ đề cập sau.
Ngược lại, CCSC cung cấp lệnh input_pin() để đọc 1 giá trị từ chân VĐK giả sử mạch của mình thiết kế chân B0 là ON-OFF, B1 là dirrection thì hai lệnh trên đã set cho Động cơ chạy tới. Mã:
delay_ms(1000); Tạo trễ 1000 ms=1s; Khá đơn giản phải không nào? Tuy nhiên để sử dụng toàn bộ 1 port của VĐK PIC cho cùng 1 chức năng thì sao nhỉ, ví dụ dàn sensor dò đường 8 led chẳng hạn. Không lẽ ngồi input_pin() nguyên 1 dọc dài à? Rất thiếu chính xác và ... cực như con mực. Tại sao không gán một tên gợi nhớ cho 1 port rùi gọi tên ấy ra. Cách này mình sẽ trình bày trong kỳ tiếp theo, mong bà con ủng hộ... Net cùi bắp quá, bực cả mình. Sư bố thằng nào đi cắt cáp bán ve chai...Đang post thì disconnect...Grrr... Rùi, xả xong stress rùi, típ tục giới thiệu về Pic C nhá. Đây là câu trả lời cho việc xuất nhập Port bằng khai báo fast_io. Bài toán là vầy, giả sử bạn có port d là dàn sensor dò đường 8 led, port b là 8 động cơ chẳng hạn. Bạn muốn nếu hai bit trung tâm sáng thì bật hai đc bánh xe chạy tới, nếu sáng hết thì tới vạch ngang dừng lại, còn nếu tối thui hết thì là lạc đường, lùi lại. Nói chung là tạm thời đơn giản hóa vậy thui, còn dò đường thật thì phức tạp hơn h ơn nhìu. Mã:
#include<16F877A> #fuses NOWDT,PUT,HS,NOPROTECT #use delay(clock=10000000) #use fast_io(d) #use fast_io(b) #byte portb=0x06 #byte portd=0x08 [code]#bit B0=0x06.0 [/code] //On-off bánh 1 #bit B1=0x06.1 //Chiều bánh 1 #bit B2=0x06.2 //On-off bánh 2 #bit B3=0x06.3 //chiều bánh 2 main() { int i; set_tris_d(0xFF); set_tris_b(0); while(true) { i=portd;
//Đọc port D vào
if (i==0x18) {B0=1; B1=0; B2=1; B3=0; } else if (i==0) {B0=1; B1=1; B2=1; B3=1; } else if (i==0xff) {B0=0; B1=0; B2=0; B3=0; } else continue;
// 00011000
//00000000
//11111111
} } Mã:
#byte portb=0x06 #byte portd=0x08 Khai báo địa chỉ port b và port d. Nêế không có khai báo này portb và portd sẽ không được define Mã:
#bit B0=0x06.0 ... Khai báo chân Port B.0, bạn có thể đặt nó bằng cái tên khác, nếu thích, nhưng quan trọng là địa chỉ bit phải đúng thui. Mã:
set_tris_d(0xFF); set_tris_b(0); Tất cả các chân của portB là output, muốn set tất cả các chân là input thì trong ngoặc là FF,.... Trong HELP hướng dẫn lệnh này như sau: "These functions allow the I/O port direction (TRI-State) registers to be set. This must be
used with FAST_IO and when I/O ports are accessed as memory such as when a #BYTE directive is used to access an I/O port. Using the default standard I/O the built in functions set the I/O direction automatically." Rõ ràng khi set byte làm I/O nếu ta thêm khai báo: Mã:
#use fast_io(b) thì CCSC chỉ dùng 1 lệnh cho việc xuất nhập port, nếu không nó sẽ mất khoảng 3-4 lệnh gì đó. Đặc biệt nên nhớ nếu dùng fast_io thì phải set tris trước khi xuất ra biến gợi nhớ mà mình define trước đó. Nếu không dữ liệu sẽ nằm hoài trong buffer của port mà không có xuất ra đâu đấy... Vậy là phần I/O + delay tạm ổn. Các bạn có thể thử viết chương trình xuất led chạy trái phải, led 7 đoạn hay điều khiển xuất nhập dữ liệu từ các port chẳng hạn. Một ví dụ thực tế nhất liên quan tới Robocon là viết chương trình nhận phím nhấn từ bàn phím điều khiển và thực hiện các tác vụ tương ứng. VD,bấm phím 1 thì chạy tới, 2 chạy lùi, v.v... Bạn naà viết đc cái gì hay hay thì post lên cho mọi người bàn luận nghen. Sao có mình tui độc diễn cái topic này hoài thế???