BÀI 12: I2C VỚI STM32F1.
- Một số khái niệm về lý thuyết.
- Có thể lập trình là Master hay Slave.
- Đối với Master: tạo ra xung clock và tạo ra tín hiệu start, stop.
- Đối với Slave : lập trình được địa chỉ của thiết bị I2C, chế độ kiểm tra bit stop.
- Số địa chỉ được sinh ra cũng như được kiểm tra là 7 bit hoặc 10 bit.
- Hỗ trợ 2 chuẩn tốc độ là 100khz và 400 Khz.
- Có bộ lọc nhiễu Analog.
- Tích hợp mode DMA.
- Có các cờ báo trạng thái : nhận, truyền, kết thúc chuyển đổi, báo lỗi…
- Có các ngắt như: ngắt buffer truyền, nhận; ngắt sự kiện, ngắt báo lỗi.
- Cấu hình sử dụng thư viện chuẩn.
- Chương trình con cấu hình I2C.
- Chương trình con write data xuống PCF8574 thông qua I2C.
- Chương trình con khởi động LCD thông qua I2C.
- Chương trình ghi thông số cài đặt lên LCD16x2.
- Chương trình con ghi data lên LCD16x2.
- Chương trình thực thi trong main.
- Một vài thanh ghi quan trọng.
- I2C_CR1 – I2C control register 1.
- ACK : cho phép nhận hoặc không nhận tín hiệu ACK return từ thiết bị được truyền.
- STOP : sinh ra tín hiệu stop kết thúc quá trình giao tiếp.
- START : sinh ra tín hiệu start để bắt đầu quá trình giao tiếp.
- PE: peripheral enable - bit này được bật lên bằng 1 khi quá trình giao tiếp I2C đang được thực hiện và kết thúc khi có tín hiện end communication.
- I2C_CR1 – I2C control register 1.
- ITBUFEN : cho phép hoặc không cho phép xảy ra ngắt khi có data trong truyền/nhận.
- ITEVTEN : cho phép ngắt khi xảy ra các sự kiện sau trên các bit sau: SB, ADDR, ADD10, STOPF, BTF , TxE, RxE.
- ITERREN : cho phép hoặc không cho phép xảy ra ngắt khi có lỗi xảy ra.
- FREQ[5:0] : bộ chia clock tần số được tính từ nhánh clock hệ thống chia cho bộ I2C.
- I2C_OAR1 – I2C own address register 1.
- ADDMODE : cài đặt số bit địa chỉ của slave là 7 hay 10 bit.
- ADD[9:8] : chỉ sử dụng khi mode địa chỉ là 10 bit.
- ADD[7:1] : bit địa chỉ của thiết bị slave.
- ADD0 : chỉ sử dụng khi mode địa chỉ là 10 bit.
- I2C_DR – I2C data register.
- I2C_SR1 – I2C status register 1.
- TIME OUT: báo hết thời gian đợi quá trình truyền nhận data.
- PECERR: chấp nhận lỗi PCE và phản hồi lại quá trình tín hiệu lỗi.
- OVR : báo quá trình overrun/ underrun.
- AF: báo tín hiệu ACK bị lỗi hay không.
- TxE : báo buffer truyền có trống hay không.
- RxE : báo buffer nhận có trống hay không.
- STOPF : cờ báo có kiểm tra quá trình stop hay không.
- BTF: báo truyền byte dữ liệu đã xong hay chưa.
- ADDR: báo địa chỉ đã được gửi(mode master) hay không tương thích (mode slave).
- SB: Có sử dụng bit start hay không.
- I2C_CCR – I2C clock control register.
- F/S : sử dụng mode Fast(400khz) hay slow(100Khz).
- DUTY: chỉ sử dụng cho mode fast với 2 chế độ .
- CCR[11:0] : thanh ghi chứa clock control cho bộ , công thức chia tham khảo thêm trong reference manual.
- Bài tập.
- Ghi kí tự "GIAO TIEP I2C" lên LCD 16X2 thông qua mạch chuyển giao tiếp LCD(dùng IC PCF8574) sử dụng I2C2 với thông số như sau: địa chỉ 7 bit, clock 100000, mode FM, duty cycle/2.
- Đọc ghi data lên IC nhớ 24LC04B/SN(EEPROM) 4kbit (cần có phần cứng bên ngoài để giao tiếp). IC này sử dụng giao thức I2C.
I2C – Inter- Intergrated Circuit là chuẩn truyền thông 2 dây gồm 1 dây Clock và 1 dây Data dùng chung cho quá trình truyền nhận được phát minh bởi Philips. Chuẩn I2C cũng trở nên thông dụng với nhiều module, IC sử dụng như :IC nhớ(24LCxxx), cảm biến góc nghiêng(MPU6050), module giao tiếp LCD(dùng IC PCF8574), IC thời gian thực(DS1307), IC chuyển đổi tín hiệu số, tương tự… So với UART tốc độ của I2C có vẻ nhỉnh hơn 1 chút, ở mức thông thường là 100Khz. Ở mode còn lại thì tốc độ cao hơn. Khi giao tiếp I2C với 1 IC nào đó cần chú ý : địa chỉ của Ic đó để giao tiếp, giao tiếp với tốc độ bao nhiêu, bao nhiêu bit.
STM32F103C8T6 có 2 bộ chuyển đổi I2C với tốc độ tối đa lên đến 400Kh ở mode Fm và 100khz ở mode sm. Các bộ I2C còn được hỗ trợ chức năng DMA giúp đẩy nhanh tốc độ giao tiếp với ngoại vi. Một số tính năng được tóm tắt như sau:
Quá trình truyền data tùy thuộc vào mode cấu hình của I2C là master hoặc là slave, ở chế độ 10 bit địa chỉ hay 7 bit địa chỉ, truyền theo cách 1 hay cách 2. Dưới đây là ví dụ về cấu hình I2C ở mode master, truyền 7 bit địa chỉ và truyền theo cách 1:
Tóm tắt quá trình truyền như sau: Đầu tiên bộ I2C sẽ tạo ra tín hiệu start -> kiểm tra EV5 – tương ứng code sẽ là kiểm tra có cài đặt mode master hay chưa(BUSY, MSL, SB ) -> nếu có, gửi địa chỉ và hướng truyền -> kiểm tra EV8 – tương ứng kiểm tra đã cài đặt mode master hay chưa(BUSY, MSL, ADDR, TXE, TRA) -> nếu có gửi data đến thiết bị slave với địa chỉ truyền ở trên -> kiểm tra EV8_2 – tương ứng code là kiểm tra data đã truyền xong chưa(TRA, BUSY, MSL, TXE, BTF) - > đợi truyền xong, bộ I2C sẽ tạo ra tín hiệu kết thúc.
Trên đây là tóm lược ý theo hiểu biết của mình, quá trình truyền, nhận các bạn có thể tham khảo trong reference manual, mục I2C – function description.
Vd: ghi kí tự "GIAO TIEP I2C" lên LCD 16X2 thông qua mạch chuyển giao tiếp LCD(dùng IC PCF8574) sử dụng I2C2 với thông số như sau: địa chỉ 7 bit, clock 100000, mode FM, duty cycle/2. Đây là ví dụ minh họa rõ nhất để thấy được giao thức giao tiếp I2C.
Sơ đồ kết nối :
Lưu ý: Địa chỉ I2C slave của IC PCF8574 là 0x7A. Quá trình giao tiếp với LCD16x2 qua IC PCF8574 cũng gần giống như sử dụng các chân VĐK điều khiển trực tiếp LCD16x2 bao gồm ghi thông số cài đặt và ghi data.
Lưu ý: Địa chỉ I2C slave của IC PCF8574 là 0x7A. Quá trình giao tiếp với LCD16x2 qua IC PCF8574 cũng gần giống như sử dụng các chân VĐK điều khiển trực tiếp LCD16x2 bao gồm ghi thông số cài đặt và ghi data.
Thanh ghi này gồm 8 bit, chứa data của quá trình truyền hoặc nhận.
Thanh ghi này chứa các cờ báo trạng thái của quá trình giao tiếp I2C:
Thanh ghi này gồm 8 bit, chứa data của quá trình truyền hoặc nhận.
Thanh ghi này chứa các cờ báo trạng thái của quá trình giao tiếp I2C:
Link tải chương trình bài tập 1
This comment has been removed by the author.
ReplyDeleteanh có tài liệu về canbus với smt32f1 không ạ
ReplyDeleteÝ bạn có phải là giao tiếp CAN hay không. Nếu là giao tiếp CAN trong STM32 thì chỉ có example của nhà sản xuất ST trong file thư viên mà bạn tải về thôi. Còn về lý thuyết bạn có thể tìm trên mạng thôi.
Deletecám ơn bạn, bài viết rất hay mình xin phép chia sẻ bài viết này đến người khác ạ.
ReplyDeleteOk bạn. Phiền bạn để rõ nguồn của bài viết nếu đăng lại ở trang khác. Cám ơn bạn đã quan tâm.
DeleteAnh cho em hỏi tại sao khi khởi động LCD phải gửi lcd_Control_Write(0x33) và lcd_Control_Write(0x32) thế ạ. Mấy lệnh còn lại trong lcd_init() thì em hiểu, chỉ có 2 lệnh này là không hiểu, mong anh giải thích cho em với
ReplyDeleteChào bạn! . Code này được viết theo sơ đồ khối của nhà sản xuất. Trong sơ đồ khối yêu cầu gửi 2 chuỗi kí tự xuống LCD để hoàn thành việc init LCD(với mode 4 dây data từ D4->D7, cờ Break flag). Mình có đính kèm link ở dưới(chú ý trang 47 - Figure 26 4-Bit Interface). bạn có thể tìm kiếm trên mạng và tìm hiểu thêm:
Deletehttps://drive.google.com/file/d/16MweTWDAd2tGfupPo80Pmk_n0V-OcLVM/view?usp=sharing
cám ơn anh rất nhiều, em đã hiểu vấn đề rồi
DeleteSao tôi làm như hướng dẫn lcd vẫn không hiển thị gì, tôi viết một hàm scan address i2c thì vẫn nhận được địa chỉ của pcf8574 là 0x27 chứng tỏ vi điều khiển đã bắt tay với pcf8574. Làm ơn giải thích cho tôi được không?
ReplyDeletebạn thử kiểm tra lại phần cứng xem đã đủ chưa nhé!! code thì mình đã test và chạy đươc rồi.Còn nếu chưa được thì bạn liên lạc vs mình nhé. Xin lỗi vì mình trả lời khá muộn.
DeleteA cho e hỏi ý nghĩa con số 12000 ở hàm Delay_ms được không ạ?
ReplyDeleteĐây là hàm delay tương đối nên sẽ độ chính xác là không cao. Con số 12000 là số lần lặp lại của vòng lặp while(chương trình sẽ dừng ở trong vòng lặp while khoảng 1ms với số tương ứng là 12000 - đây là ý kiến cá nhân của người viết, bạn có thể thay đổi số này). Cám ơn bạn đã quan tâm.
Deletecho mình hỏi phát khi chạy thử debug trên keic sau khi khởi tạo bit START thì giá trị EV5(CR1_SB) mình không thấy nó nhảy sang giá trị set (=1). cái này do lỗi phần cứng hay do debug của keic nó vậy.Giải thích chỗ này cho mình với
ReplyDeletechào bạn, mình cũng bị trường hợp này giống bạn và cũng chưa có hướng giải quyết. Bạn đã tìm ra hướng giải quyết chưa vậy ?
DeleteCho e hỏi muốn hiện ra lcd biểu tượng cục pin thì làm thế nào ạ
ReplyDeleteChào bạn, bạn có thể tham khảo thêm ở page này, mình có search và thấy cũng hay. Copy các mã code ở đây và ghi xuống lcd thao khảo thử nha bạn.
Deletehttps://www.circuitvalley.com/2012/02/lcd-custom-character-hd44780-16x2.html
Anh cho em hỏi thời gian timeout để chờ các sự kiện EV5, EV6, EV8 là bao nhiêu ạ? Và có thể xem ở đâu ạ? Trong Reference manual em tìm mà không thấy ạ (câu hỏi này dành cho trường hợp bị lỗi bus hoặc bus busy nếu không dùng timeout sẽ bị treo ạ)
ReplyDelete