![]()  | 
		
			
  | 	
	
 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ử 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.  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
			
			
		
	 | 
| 		
			
			 | 
		#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  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
			
			
		
	 | 
| 		
			
			 | 
		#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.  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
			
			
		
	 | 
| 		
			
			 | 
		#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  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
			
			
		
	 | 
| 		
			
			 | 
		#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);
}
 | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
			
			
		
	 | 
| 		
			
			 | 
		#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ỉ?  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
			
			
		
	 | 
![]()  | 
	
	
| Ðiều Chỉnh | |
| Xếp Bài | |
		
  | 
	
		
  |