![]() |
I2C truyền và nhận nhiều byte dữ liệu.
Chào các bạn,
Mình có đọc các bài viết về I2c Trên diễn đàn nhưng đa số chỉ truyền nhận 1 byte, hoặc truyền nhiều byte nhưng phải start và stop nhiều lần. Sau khi mày mò, mình đã truyền được nhiều byte. Dưới đây là đoạn code đọc 2 byte của Master Code:
int16 read_I2C_2byte( int8 slave_addr) Code:
void write_I2C_2byte(int8 byte1, int8 byte2, int8 slave_addr) Code:
#INT_SSP Hàm i2c_isr_state(); sẽ trả về giá trị 0x80 khi Slave truyền byte thứ nhất, trả về giá trị 0x81 khi Slave truyền byte thứ hai,... Các đoạn code trên có thể được điều chỉnh để truyền hoặc nhận tối đa 127 byte chỉ với 1 lần Start và 1 lần Stop. Đây là những gì mình đọc, suy nghĩ và kiểm chứng trên mạch thật. Mong các bạn đóng góp ý kiến để hoàn thiện nó. |
Trích:
Ở picvietnam, tôi chỉ có các tutorial cho dsPIC, nhưng tutorial 4 về giao tiếp UART và I2C cho dsPIC (link ở đây: http://www.picvietnam.com/forum/showthread.php?t=623) cũng đã minh họa việc ghi liên tiếp 8 byte dữ liệu ra vi mạch thời gian thực DS1307 thông qua giao tiếp I2C. Rất tiếc đến giờ bạn mới tự mày mò ra được. Thân, |
Anh hiểu sai ý em rồi.
Đúng là I2C hỗ trợ truyền nhiều byte. Đúng là trên diễn đàn đã có bài viết về truyền nhiều byte bằng I2C. Nhưng những bài viết đó không dùng những hàm có sẵn của CCSC. Đa số các bài viết dùng CCSC trên diễn đàn chỉ truyền 1 byte dữ liệu. Rất mong sự đóng góp của các bạn. |
chuong trinh minh viet co j sai ko ha cac ban? sao minh viet mai ma` no' chi thuc hien duoc 1 lan ghi, sau cau lenh i2c_stop() thi no' khong the doc ghi duoc nua?
----------------------------------------------------------------------------------- #include <16f877a.h> #include <def_16f877a.h> #device *=16 ADC=8 #FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT #use delay(clock=20000000) #use I2C(master,sda=PIN_C4,scl=PIN_C3) // dung i2c = phan cung #include <lcd_lib_4bit.c> // Thu vien ham cho LCD void write(int8 value, int8 add) { i2c_start(); i2c_write(0xD0); i2c_write(add); i2c_write(value); i2c_stop(); delay_us(3); } int8 read(int8 add) { int8 value_re; i2c_start(); i2c_write(0xD0); i2c_write(add); i2c_start(); i2c_write(0xD1); value_re = i2c_read(); i2c_stop(); delay_us(3); return(value_re); } void khoitao(){ i2c_start(); i2c_write(0xD0); //den dia chi ds1307. i2c_write(0x00); //den dia chi thanh ghi 00H. i2c_write(0x00); //s i2c_write(0x00); //m i2c_write(0x52); //h i2c_write(0x02); //day i2c_write(0x03); //date i2c_write(0x04); //mth i2c_write(0x05); //y i2c_write(0x10); //tao xung vuong 1Hz. i2c_stop(); delay_us(3); } int h,m,s,day,date,month,year,con; void main() { int value; set_tris_b(0x00); write(0x90,0x07);// o day tao xung 1hz delay_ms(2000); // write(0x00,0x07);// ket thuc qua trinh tao xung. nhung mo phong thi no khong the tat chan SWQ duoc????? } ----------------------------------------------------------------------------- o tren, minh chi ghi duoc giu lieu duoc 1 lan, sau cau lenh i2c_stop() thi minh khong the dung cac ham write() va read() duoc, co' phai do chuong trinh dich bi loi hay sao? minh dung CCS 4.057. |
1 Attachment(s)
so do mach cua minh.
con nua khi khai bao #use i2c(master, sda=pin_c4,scl=pin_c3) thi no ghi duoc, con khai bao #use i2c(master, sda=pin_c4,scl=pin_c3,force_hw) thì nó khong chạy duoc, minh dung pic 16f877a.. |
Bạn Hùng thân mến, tôi khuyến cáo bạn nên để 1 vòng lặp while(1) { ... } trong chương trình chính (main) vì nếu không khi chạy hết chương trình con trỏ sẽ tự động nhảy tiếp xuống dưới và thực hiện một cái gì đó lung tung.
|
minh da thu chen vong lap while(1) cho no dung yen tai cho nhung van vay. Cho minh hỏi chương trình con đọc và ghi 1 byte dữ liệu của mình như vậy đã đúng chưa?.
void write(int8 value, int8 add) { i2c_start();// tao đk start i2c_write(0xD0);// dia chi cua DS1307 i2c_write(add); // dia chi ô nhớ cần ghi i2c_write(value); // dữ liệu cần ghi i2c_stop(); // kết thúc ghi dữ liệu } int8 read(int8 add) { int8 value_re; i2c_start();// tao đk start i2c_write(0xD0);dia chi cua DS1307 r/w =0 ghi du lieu i2c_write(add); dia chi ô nhớ cần ghi i2c_start(); restart i2c_write(0xD1);dia chi cua DS1307 r/w =1 đọc dữ liệu value_re = i2c_read(); i2c_stop(); return(value_re); } |
mày mò mãi, tìm trên mấy cái diễn đàn cuối cùng cũng mìnn cũng viết được. ở 2 đoạn chương trinh con đọc và ghi dữ liệu cần thêm điều kiên DS1307 đã sẵn sàng bằng cách chèn thêm đoạn code sau
int1 ready_DS1307(void) { int1 ack; i2c_start(); ack = i2c_write(0xD0); i2c_stop(); delay_us(5); return !ack; } và trước mỗi ct con ta thêm vầo câu lệnh while(!ready_DS1307()) {;} là được ví dụ ở đoạn ct con ghi dữ liệu: void write(int8 value, int8 add) { while(!ready_DS1307()) {;} i2c_start(); i2c_write(0xD0); i2c_write(add); i2c_write(value); i2c_stop(); } với đoạn code như trên thì mình đã đọc và ghi dữ liệu cho con ds1307 được rồi. Tuy nhiên đoạn ct ready_DS1307() la mình copy trên diễn đàn nên mình vẫn ko hiểu lắm. Ai hiểu đoạn code trên làm ơn giải thích giùm mình với. |
mình nhầm rồi. Chỉ có ghi đựoc thôi, còn đọc dữ liệu từ con ds1307 ra vẫn chưa được. Các bạn giup mình với. Mình nghĩ mấy hàm trong CCS sẽ đơn giản nhưng nó lại rắc rối đến thế.
|
Múi giờ GMT. Hiện tại là 04:17 PM. |
Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam