|
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 |
05-09-2008, 03:22 PM | #1 |
Đệ tử 1 túi
Tham gia ngày: Apr 2007
Bài gửi: 20
: |
hỏi về giao tiếp I2C
Chào các bạn!
Mình đang gặp khó khăn trong giao tiếp I2C. Bài toán của mình là giao tiếp giữa 2 con PIC 16F877A. Khi mình sử dụng thạch anh 4 Mhz thì nó chạy tốt. Nhưng khi thay con thạch anh 20 Mhz thì không còn chạy được nữa code master: Code:
#include <16F877A.H> #fuses XT,NOWDT,NOPROTECT,NOLVP #use Delay(Clock=20000000) #use i2c(master, sda=PIN_C4, scl=PIN_C3) void write_I2C(int8 value, int8 slave_addr) { i2c_start(); delay_ms(1); i2c_write(slave_addr); delay_ms(1); i2c_write(value); delay_ms(1); i2c_stop(); } int8 read_I2C(int8 slave_addr) { int8 value_re; i2c_start(); delay_ms(1); i2c_write(slave_addr + 1); delay_ms(1); value_re = i2c_read(0); delay_ms(1); i2c_stop(); return value_re; } void main() { int8 value_re=2; int8 i; const int8 N = 8; const int8 slave_addr = 0x10; set_tris_b(0x00); while(1){ write_I2C(1, slave_addr); delay_ms(500); value_re = read_I2C(slave_addr); output_b(value_re); delay_ms(500); write_I2C(0, slave_addr); delay_ms(500); value_re = read_I2C(slave_addr); output_b(value_re); delay_ms(500); } } code slave: Code:
#include <16F877A.H> #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay(Clock=20000000) #use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10) int8 value = 0x01; #INT_SSP void i2c_isr() { int8 state; state = i2c_isr_state(); if(state < 0x80 && state>0) value = i2c_read(); if(state == 0x80){ i2c_write(value); } } void main() { enable_interrupts(INT_SSP); enable_interrupts(GLOBAL); set_tris_b(0x00); while(1){ output_b(value); } } thay đổi nội dung bởi: namqn, 05-09-2008 lúc 04:31 PM. |
05-09-2008, 04:32 PM | #2 |
Trưởng lão PIC bang
|
Với thạch anh 20 MHz, bạn nên dùng HS thay vì XT cho cấu hình bộ dao động.
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 |
07-09-2008, 01:06 AM | #3 |
Đệ tử 1 túi
Tham gia ngày: Apr 2007
Bài gửi: 20
: |
Chào các bạn!
Mình muốn hỏi thêm các bạn một vấn đề nữa trong giao tiếp I2C. Bài toán của mình vẫn như trên (giao tiếp giữa 2 con PIC 16F877A). Cho hỏi hàm i2c_isr_state() khi nào trả giá trị về 1,2... 0x81,0x82...Mình mới chỉ thành công khi giao tiếp 1 lần truyền 1 byte, còn 2 byte thì không đúng, code truyền 2 byte: code master: Code:
#include <16F877A.H> #include <def_877a.h> #fuses HS,NOWDT,NOPROTECT,NOLVP #use Delay(Clock=20000000) #define use_portd_lcd TRUE #include <lcd.c> //#include <toanlcd.c> #use i2c(master, sda=PIN_C4, scl=PIN_C3) int8 value_re,value_re1,value_re2; void write_I2C(int8 value, int8 slave_addr) { i2c_start(); delay_ms(1); i2c_write(slave_addr); delay_ms(1); i2c_write(value); delay_ms(1); i2c_stop(); } void read_I2C(int8 slave_addr) { i2c_start(); delay_ms(1); i2c_write(slave_addr + 1); delay_ms(1); value_re1 = i2c_read(0); delay_ms(1); value_re2 = i2c_read(0); delay_ms(1); i2c_stop(); } void main() { int8 value_re=2; int8 i=10; const int8 N = 8; const int8 slave_addr = 0x10; set_tris_b(0x00); trisd=0; rd3=0; LCD_init(); delay_ms(200); lcd_send_byte(0,0x1); while(1){ read_I2C(slave_addr); lcd_send_byte(0,0x1); delay_ms(10); lcd_gotoxy(1,1); Printf(LCD_putc,"so1:%u\nso2:%u",value_re1,value_re2); delay_ms(400); } } //************************************************ code slave: #include <16F877A.H> #fuses HS,NOWDT,NOPROTECT,NOLVP #use delay(Clock=20000000) #use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10) int8 bang[]={3,4,5,6}; int8 value = 0x01,valueh=0,valuel=0; #INT_SSP void i2c_isr() { int8 state; state = i2c_isr_state(); if(state >= 0x80)i2c_write(bang[state - 0x80]); } void main() { enable_interrupts(INT_SSP); enable_interrupts(GLOBAL); set_tris_b(0x00); while(1); } Giúp mình nha! // mình vẫn chưa cho code vào trong khung được thay đổi nội dung bởi: namqn, 07-09-2008 lúc 02:35 AM. |
07-09-2008, 02:36 AM | #4 |
Trưởng lão PIC bang
|
__________________
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 |
08-09-2008, 10:32 AM | #5 |
Đệ tử 1 túi
Tham gia ngày: Apr 2007
Bài gửi: 20
: |
Chào các bạn!
Mình đã giải quyết được vấn đề trên. Mình gửi 4 số từ Master đến Slave và nhận lại về 4 số đó, cho hiển thị lên LCD. Ai có cách khác thì post lên cho mọi người cùng tham khảo nhé code master: Code:
#include <16F877A.H> #include <def_877a.h> #fuses HS,NOWDT,NOPROTECT,NOLVP #use Delay(Clock=20000000) #define use_portd_lcd TRUE #include <lcd.c> //#include <toanlcd.c> #use i2c(master, sda=PIN_C4, scl=PIN_C3) int8 value_re,value_re1=0,value_re2=0,value_re3=0,value_re4=0; void write_I2C(int8 value1,int8 value2,int8 value3,int8 value4,int8 slave_addr) { i2c_start(); i2c_write(slave_addr); i2c_write(value1); i2c_write(value2); i2c_write(value3); i2c_write(value4); i2c_start(); i2c_write(slave_addr); i2c_stop(); } void read_I2C() { i2c_start(); i2c_write(0x11); value_re1 = i2c_read(); value_re2 = i2c_read(); value_re3 = i2c_read(); value_re4 = i2c_read(); i2c_start(); i2c_write(0x11); i2c_stop(); } void main() { int8 value_re=2; int8 i=10; const int8 N = 8; const int8 slave_addr = 0x10; set_tris_b(0x00); trisd=0; rd3=0; LCD_init(); delay_ms(200); lcd_send_byte(0,0x1); while(1){ write_I2C(1,2,3,4,0x10); delay_ms(10); read_I2C(); lcd_send_byte(0,0x1); delay_ms(1); lcd_gotoxy(1,1); Printf(LCD_putc,"so1:%u so2:%u\nso3:%u so4:%u",value_re1,value_re2,value_re3,value_re4); delay_ms(500); write_I2C(5,6,7,8,0x10); delay_ms(10); read_I2C(); lcd_send_byte(0,0x1); delay_ms(1); lcd_gotoxy(1,1); Printf(LCD_putc,"so1:%u so2:%u\nso3:%u so4:%u",value_re1,value_re2,value_re3,value_re4); delay_ms(500); } } Code:
#include <16F877A.H> #fuses HS,NOWDT,NOPROTECT,NOLVP #use delay(Clock=20000000) #use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10) int8 bang[4]; int8 value = 0x01,valueh=0,valuel=0; int8 state; #INT_SSP void i2c_isr() { state = i2c_isr_state(); if(state >=0x80)i2c_write(bang[state-0x80]); else if(state>0)bang[state-1]=i2c_read(); } void main() { enable_interrupts(INT_SSP); enable_interrupts(GLOBAL); set_tris_b(0x00); while(1); } |
24-10-2009, 06:02 PM | #6 |
Nhập môn đệ tử
Tham gia ngày: Jul 2008
Bài gửi: 9
: |
...............
void main() { int8 value_re=2; int8 i=10; const int8 N = 8; const int8 slave_addr = 0x10; set_tris_b(0x00); trisd=0; rd3=0; ............... Các bạn cho mình hỏi trong chương trình của bạn toanck86: * Biến i, N dùng để làm gì? * rd3=0 có ý nghĩa gì vậy nhỉ? |
|
|