PDA

View Full Version : giao tiếp I2C pic6f877 o chay? help!


dung h
21-07-2009, 01:16 AM
mình đang tìm hiểu về giao tiếp i2c! mình viết chương trình gửi dữ liệu từ 1 mater là pic 16f877a xuống 1 slave nhưng mô phỏng o thấy gì hết????
code mater:
#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use Delay(Clock=4000000)

#define SLAVE_ADDRESS 0x10
#use i2c(master, sda=PIN_C4, scl=PIN_C3)

void write_I2C(int8 a)
{
i2c_start();
i2c_write(SLAVE_ADDRESS);
i2c_write(a);
i2c_stop();
}

void main()
{
int8 value;

value = 0;
while(true){
write_I2C(value);
output_b(value);
value++;
delay_ms(100);
}
}

cho con slave:
#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#use delay(Clock=4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10)

int8 value;

#INT_SSP
void i2c_isr()
{
int8 state;
int8 address;
state = i2c_isr_state();
if(state == 0)
address = i2c_read();
else if(state < 0x80)
value = i2c_read();
}

void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);

set_tris_b(0x00);
while(true){
output_b(value);
}
}

mình chửa hiểu lám 1 số lệnh trong ccs mong mọi người giúp:
state=i2c_isr_state() ; // trả về giá trị 8bit thông báo trang thái của i2c phảy o? hay gì
// mong giải thich cụ thể hơn
và giá trị state nhận được có y nghĩa như thế nào?
vd : state==0?????
state>0???
state<0x80???? // tại sao lại so sánh với 0x80??
state>0x80???
các thông số đó liên quan đến truyền ,nhận và bít ACK như thế nào?
khi nào mình biết mình nhận đủ 1 byte?
còn cả lệnh i2c_pull(); nữa???
mới học đọc các bài trên diễn đàn nhưng vẫn chưa ngộ ra!!!!mong được giúp đỡ!
thanks!

rien
22-07-2009, 11:40 AM
#if defined __PCH__
#byte SSPSTAT = 0xFC7
#byte SSPBUF = 0xFC9
#elif defined __PCM__
#byte SSPSTAT = 0x94
#byte SSPBUF = 0x13
#endif

#bit DA_BIT = SSPSTAT.5
#bit RW_BIT = SSPBUF.0

#inline
int8 my_i2c_isr_state(void)
{
static int8 i2c_state = 0x03;
int8 retval;

if(!DA_BIT) // If address byte was received
{
i2c_state = 0; // Then clear state.

if(RW_BIT) // If it is a Read address
bit_set(i2c_state, 7); // Then set bit 7 of state, i.e. i2c_state = 0x80
}

retval = i2c_state;

i2c_state++;

return(retval);
}


Đây là hàm i2c_isr_state() mình lấy từ diễn đàn ccscinfo. Bạn đọc nó thì sẽ hiểu rõ biến state: khi nào state = 1, 2, ....

Ta so sánh giá với 0x80. Theo mình là vì 0x80 = 128 = 256/2. Vì state có độ lớn 1 byte. Do đó vùng giá trị của nó được chia đôi. 1/2byte giá trị là dành cho i2c_write() và 1/2byte giá trị là dành cho i2c_read().

dung h
23-07-2009, 01:39 AM
cảm ơn bạn nhưng mình đọc nó nhưng chưa hiểu lắm,mình dùng ccs thôi
bạn có thể làm rõ cho mình vấn đề này dc o! thanks

rien
23-07-2009, 09:39 AM
cảm ơn bạn nhưng mình đọc nó nhưng chưa hiểu lắm,mình dùng ccs thôi
bạn có thể làm rõ cho mình vấn đề này dc o! thanks
Đoạn code trên viết bằng ccs đó. Đơn giản đoạn code trên có ý như thế này:

1) Nếu địa chỉ được nhận thì nhảy vào lệnh if và gán biến i2c_state =0.

2) Nếu bit RW = 1 thì nhảy vào lệnh if và set bit thứ 7 của i2c_state, tức là i2c_state = 0x80.

3) Sau đó hàm trả về giá trị của i2c_state. Sau đó tăng giá trị của i2c_state thêm 1.

Nếu lần truyền tiếp theo chỉ truyền dữ liệu thì sẽ không nhảy vào lệnh if nào hết. Chỉ thực hiện bước thứ 3 thôi.