![]() |
|
Tài trợ cho PIC Vietnam |
||||||||
| Giao tiếp USB, CAN, I2C, SPI, USART... Những giao tiếp được tích hợp trên PIC |
![]() |
|
|
Ðiều Chỉnh | Xếp Bài |
|
|
#1 |
|
Đệ tử 4 túi
Tham gia ngày: May 2009
Bài gửi: 74
: |
giao tiếp I2C pic6f877 o chay? help!
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: Code:
#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);
}
}
Code:
#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);
}
}
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! |
|
|
|
|
|
#2 |
|
Đệ tử 1 túi
Tham gia ngày: Sep 2008
Bài gửi: 13
: |
Code:
#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);
}
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(). |
|
|
|
|
|
#3 |
|
Đệ tử 4 túi
Tham gia ngày: May 2009
Bài gửi: 74
: |
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 |
|
|
|
|
|
#4 | |
|
Đệ tử 1 túi
Tham gia ngày: Sep 2008
Bài gửi: 13
: |
Trích:
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. |
|
|
|
|
![]() |
|
|