PIC Vietnam

Go Back   PIC Vietnam > Microchip PIC > Các ngôn ngữ lập trình khác (CCS C, HT PIC,...)

Tài trợ cho PIC Vietnam
Trang chủ Đăng Kí Hỏi/Ðáp Thành Viên Lịch Bài Trong Ngày Vi điều khiển

Trả lời
 
Ðiều Chỉnh Xếp Bài
Old 20-06-2009, 04:18 PM   #1
rien
Đệ tử 1 túi
 
Tham gia ngày: Sep 2008
Bài gửi: 13
:
Smile 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)
{
   int16 result;
   int8 low, high;
   i2c_start();
   i2c_write(slave_addr+1);
   high= i2c_read(1);
   low= i2c_read(0);
   i2c_stop();
   result = make16(high, low);
   return result;
}
đoạn code write 2 byte của Master
Code:
void write_I2C_2byte(int8 byte1, int8 byte2, int8 slave_addr)
{
   i2c_start();
   i2c_write(slave_addr);
   i2c_write(byte1);
   i2c_write(byte2);   
   i2c_stop();
}
Đoạn code interrupt của Slave
Code:
#INT_SSP
void i2c_isr()
{
   int8 state;
   state = i2c_isr_state();
   if(state<0x80)
   {
      if (state == 1)
      byte1= I2C_read(1);
      if (state == 2)
      byte2= I2C_read(1);
   }
   
   if(state >= 0x80)
   {
      if (state == 0x80)
         I2C_write(high);
      if (state == 0x81)
         I2C_write(low);
   }
   clear_interrupt(INT_SSP);
}
Hàm i2c_isr_state(); sẽ trả về giá trị 0 khi Slave nhận được byte địa chỉ, trả về giá trị 1 khi nhận được byte thứ nhất, trả về giá trị 2 khi nhận được byte thứ 2,...

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ó.

thay đổi nội dung bởi: rien, 22-06-2009 lúc 05:21 PM.
rien vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 20-06-2009, 05:02 PM   #2
namqn
Trưởng lão PIC bang
 
Tham gia ngày: Feb 2006
Nơi Cư Ngụ: Tp. HCM, Việt Nam
Bài gửi: 3,025
:
Send a message via Yahoo to namqn
Trích:
Nguyên văn bởi rien View Post
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. ...
Giao thức I2C hỗ trợ truyền nhiều byte dữ liệu liên tiếp nếu không đổi chiều dữ liệu. Ngay cả khi có đổi chiều truyền dữ liệu, bạn cũng chỉ cần dùng điều kiện RESTART. Những thông tin về giao tiếp I2C đã được tôi trình bày cách đây khá lâu tại: http://namqn.byethost7.com/Commu.php (chú ý là tôi đã ghi rõ master đọc/ghi các byte dữ liệu giữa hai điều kiện START và STOP, khi trình bày về trình tự thực hiện các thao tác đọc/ghi dữ liệu).

Ở 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,
__________________
Biển học mênh mông, sức người có hạn.

Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau:
http://www.picvietnam.com/forum/showthread.php?t=1263
namqn vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 22-06-2009, 05:19 PM   #3
rien
Đệ tử 1 túi
 
Tham gia ngày: Sep 2008
Bài gửi: 13
:
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.
rien vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 21-07-2009, 01:21 AM   #4
nguyenhung1811
Đệ tử 3 túi
 
Tham gia ngày: Jul 2007
Bài gửi: 48
:
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.

thay đổi nội dung bởi: nguyenhung1811, 21-07-2009 lúc 01:30 AM.
nguyenhung1811 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 21-07-2009, 01:37 AM   #5
nguyenhung1811
Đệ tử 3 túi
 
Tham gia ngày: Jul 2007
Bài gửi: 48
:
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..
Hình Kèm Theo
File Type: jpg Capture.JPG (307.6 KB, 13 lần tải)
nguyenhung1811 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 22-07-2009, 04:01 PM   #6
hopeman
Đệ tử 6 túi
 
hopeman's Avatar
 
Tham gia ngày: Jul 2007
Bài gửi: 146
:
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.
__________________
mạch nạp - kit phát triển - linh kiện điện tử www.PNLabvn.com
hopeman vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 22-07-2009, 10:59 PM   #7
nguyenhung1811
Đệ tử 3 túi
 
Tham gia ngày: Jul 2007
Bài gửi: 48
:
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);
}
nguyenhung1811 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 23-07-2009, 02:04 AM   #8
nguyenhung1811
Đệ tử 3 túi
 
Tham gia ngày: Jul 2007
Bài gửi: 48
:
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.
nguyenhung1811 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 23-07-2009, 07:08 AM   #9
nguyenhung1811
Đệ tử 3 túi
 
Tham gia ngày: Jul 2007
Bài gửi: 48
:
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ế.
nguyenhung1811 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Trả lời


Quyền Sử Dụng Ở Diễn Ðàn
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is Mở
Smilies đang Mở
[IMG] đang Mở
HTML đang Tắt

Chuyển đến


Múi giờ GMT. Hiện tại là 09:14 AM.


Được sáng lập bởi Đoàn Hiệp
Powered by vBulletin®
Page copy protected against web site content infringement by Copyscape
Copyright © PIC Vietnam