
CÁC VÍ DỤ LẬP TRÌNH RASPBERRY PI PICO WIRELESS VỚI MICROPYTHON
Xem thêm...
Time: 17:32 12/10/2023 | Cao Văn Vinh
---------------------------------
Xin chào các bạn, hôm nay mình sẽ hướng dẫn sửa lỗi OLED SSD1306 giao tiếp với PIC không lên. Lỗi này mình gặp phải khi đang thực hiện đồ án môn vi xử lý.
Trước tiên, mình sẽ hướng dẫn các bạn giao tiếp OLED SSD1306 với PIC trước. Có rất nhiều video trên mạng, hay các bài viết hướng dẫn cách giao tiếp này với phương thức I2C hay SPI. Ở trong project này, mình dùng PIC16F877A giao tiếp với I2C. Đầu tiên mình sẽ trình bày thông số kỹ thuật một chút 2 loại vi điều khiển này.
Đầu tiên là OLED, ở đây mình dùng loại SSD1306 OLED 128X64 0.96 inch - I2C. Màn hình OLED SSD1306 với kích thước 0.96 inch, cho khả năng hiển thị hình ảnh tốt với khung hình 128x64 pixel. Ngoài ra, màn hình còn tương thích với hầu hết các vi điều khiển hiện nay thông qua giao tiếp I2C. Màn hình sử dụng driver SSD1306 cùng thiết kế nhỏ gọn sẽ giúp bạn phát triển các sản phẩm DIY hoặc các ứng dụng khác một cách nhanh chóng.
Sơ đồ chân:
• VCC: 3.3~5 VDC
• GND: Ground
• SCL: Serial Clock
• SDA: Serial Data.
Tiếp theo, mình sử dụng PIC16F877A.
PIC16F877A là một Vi điều khiển PIC 40 chân và được sử dụng hầu hết trong các dự án và ứng dụng nhúng. Nó có năm cổng bắt đầu từ cổng A đến cổng E. Nó có ba bộ định thời trong đó có 2 bộ định thời 8 bit và 1 bộ định thời là 16 Bit. Nó hỗ trợ nhiều giao thức giao tiếp như giao thức nối tiếp, giao thức song song, giao thức I2C. PIC16F877A hỗ trợ cả ngắt chân phần cứng và ngắt bộ định thời. Bạn có thể tham khảo thêm tại các trang web khác. Ở bài viết này mình chỉ tập trung vào hướng dẫn giao tiếp và các fix lỗi không hiển thị trên OLED (I2C).
Đầu tiên, mình sử dụng thư viện SSD1306OLED.C . Các bạn có thể tải thư viện về ở đây:
Đây là thư viện gốc của nhà sản xuất.
Tiếp theo để giao tiếp I2C, cụ thể ở đây mình dùng PIC16F877A, các bạn khai báo như sau:
#include<16f877a.h>
#INCLUDE <"ĐƯỜNG DẪN THƯ VIỆN SSD1306OLED.C">
Lệnh này dùng sau khi khai báo thư viện:
#use I2C(MASTER, I2C1, FAST = 400000, stream = SSD1306_STREAM)
Trong chương trình chính, bạn khai báo:
SSD1306_Init(SSD1306_SWITCHCAPVCC, SSD1306_I2C_ADDRESS);
Sau đó, xác định toạ độ với lệnh:
SSD1306_GotoXY(x,y);
Trong đó: x là cột, y là hàng hiển thị.
Để hiển thị chữ lên oled, bạn sử dụng lệnh:
SSD1306_Putc("CAO VAN VINH 21161386");
Lúc này OLED sẽ hiển thị CAO VAN VINH 21161386 lên hàng và cột tương ứng. Trong trường hợp bạn muốn hiển thị giá trị của một bến lên OLED, bạn có thể sử dụng lệnh sau:
PRINTF(SSD1306_Putc,"%lu cm ",ketqua);
Lúc này, giá trị của biến ketqua sẽ được xuất ra, ví dụ ketqua=20; thì OLED sẽ hiển thị: 20 cm.
%lu là giá trị tương ứng vào biến, ở đây mình ketqua của mình dùng kiểu unsigned int16 nên mình dùng %lu. Trong trường hợp bạn sử dụng biến với kiểu giá trị khác thì có thể tham khảo như dưới đây:
// %u -> unsigned int8
// %ld -> signed int16, signed int32
// %lu -> unsigned int16, unsigned int32
// %03u -> lay 3 chu so, bien thuoc kieu unsigned int8
Tiếp theo, là kết nối phần cứng, ở đây các bạn như sau: VCC -> 3.3V - 5V GND -> GND SCL -> Nối vào chân SCL của PIC, ở đây mình mắc vào RC3 với pic 16f877a SDA -> Nối vào chân SCL của PIC, ở đây mình mắc vào RC4 với pic 16f877a Tới bước này, các bạn có thể giao tiếp và hiển thị lên OLED được rồi. Tuy nhiên, chúng ta sẽ nói về một số lỗi có thể mắc phải. Đầu tiên là phần cứng, ở PIC mình có đọc tài liệu bên nước ngoài, người ta sẽ sử dụng thêm 2 điện trở mắc vào nguồn như hình thì OLED mới thực sự được bật. Rất nhiều bạn không dùng trở kéo lên như vậy thì OLED không thể được bật. Điện trở ở đây mình khuyên dùng là loại 4k7 hoặc 10K nhé.
Tiếp theo là lỗi về phần mềm, rất nhiều bạn đã gặp khó khăn ở đây. Đó là khi mắc đúng như vậy rồi như OLED vẫn không lên. Lý do bởi vì là do địa chỉ được khai báo trong thư viện nhé.
Các bạn vào thư viện và thấy một dòng bên dưới
Ở đây, địa chỉ giao tiếp I2C là 0x78. Tuy nhiên, các bạn chú ý rằng, đây là khi bạn sử dụng loại SSD1306 có 7 chân (có cả chân D0,D1,RES,…) thì mới giao tiếp được. Còn nếu bạn sử dụng loại 4 chân như mình, thì hãy đổi địa chỉ giao tiếp thành 0x78 nhé. Tới đây, các bạn có thể giao tiếp thành công rồi nha!!! Chúc các bạn thành công!
Dưới đây là đoạn code mẫu in ra dòng "Hello World":
#include <16f877a.h>
#fuses hs
#use delay(clock=4M)
#use I2C(MASTER, I2C1, FAST = 400000, stream = SSD1306_STREAM)
#INCLUDE <"ĐƯỜNG DẪN THƯ VIỆN SSD1306OLED.C">
unsigned int16 i=0;
void main()
{
SSD1306_Init(SSD1306_SWITCHCAPVCC, SSD1306_I2C_ADDRESS);
SSD1306_ClearDisplay();
SSD1306_GotoXY(1,1);
//!SSD1306_StartScrollDiagRight(0x00, 0x07);
SSD1306_Putc("Hello World");
delay_ms(1000);
while(true)
{
//Ở đây nếu các bạn muốn hiển thị giá trị nhiều lần thì đưa vào while(true) nhé!
}
}