通过 I2C 从 PIC 到 PIC 的数据。它在 proteus 中有效,但在现实生活中无效。为什么?

Data from PIC to PIC via I2C. It works in proteus but not in real life. Why?

你好,我在尝试通过 I2C 将数据从 pic18f4550 发送到 pic16f818 时遇到了一些问题...

这个项目使用了一个 4x4kbd 和一个 lcd 库,但这部分在现实生活中也能正常工作。

当您按下“1”时,主芯片将向地址为 0xA0 的从 IC 发送一个字节,

从机接收到这个字节,存入ram或rom(均包含程序),由主机读取。

这在 Proteus 8 中工作正常,但在现实生活中却不行。

我用同一个 HEX 文件尝试了 3 次,得到了三种不同的结果。

1.PROTEUS 8:很好用,完美。

2.PROTEUS 7: 不行但不挂

3.REAL 寿命:芯片挂起并且不会 运行 任何其他指令,直到我重置它。

我的编译器是PCW 4.106。

You can download all the project files from here. [proteus simulation + ccs source code]

有人可以帮我解决这个问题吗?自从我尝试制作这个项目以来已经有很长时间了 运行 并且是一场噩梦。

是什么导致两个微控制器之间无法通信?

为什么芯片挂了?

感谢您的关注。

这是我的主密码:

#include <18f4550.h>
#fuses INTRC_IO,NOPROTECT,NOMCLR,NOWDT
#use delay(clock= 4000000)         
#use i2c(Master,fast,sda=PIN_E0,scl=PIN_E1) 
#define LCD_DATA_PORT getenv("SFR:PORTB")
#byte portd=0xf83
#include <lcd18.c>
#include <jkbd4x4d.c>
#include <i2c.c>         
void SEND_I2C(direccion, posicion, dato){

   i2c_start();            // Comienzo comunicación
   i2c_write(direccion);   // Dirección del esclavo en el bus I2C
   i2c_write(posicion);    // Posición donde se guardara el dato transmitido
   i2c_write(dato);        // Dato a transmitir
   i2c_stop();             // Fin comunicación
   delay_ms(50);
 }
 byte READ_I2C (byte direccion, byte posicion) {
byte dato;
   i2c_start();            // Comienzo de la comunicación
   i2c_write(direccion);   // Dirección del esclavo en el bus I2C
   i2c_write(posicion);    // Posición de donde se leerá el dato en el esclavo
   i2c_start();            // Reinicio
   i2c_write(direccion+1); // Dirección del esclavo en modo lectura
   dato=i2c_read(0);       // Lectura del dato
   i2c_stop();             // Fin comunicación
   delay_ms(50);           // Espera finalización del envio
   return dato;
}

void main() {
 char k;  
  lcd_init(); 
  kbd_init(); 
  port_b_pullups(TRUE);  
 lcd_putc("\fPress '1' for \r\nI2C test"); 
 while (TRUE) {
k=  getkey();
if(k=='x'){}else{                                      // Detecting the  key
printf(lcd_putc,"\f%c",k);                             // Print the  key
delay_ms(200);                                         // An anti-re-pressing delay
if(k=='1'){                                            // key 1 detected     
printf(lcd_putc,"\fSent AA to 00");                    // some info
SEND_I2C(0xA0, 0x00, 0xAA);                           // send i2c(chip Address, eeprom address, data)
delay_ms(100);                                         // Giving ages to slave to work
printf(lcd_putc,"\nRead %x",READ_I2C(0xA0, 0x00));  // read i2c (chip Address, eeprom address)

}  }  }} 

这是我的奴隶代码

#include <16F818.h>
#device adc=10
#fuses INTRC_IO,NOWDT,NOPROTECT,NOLVP,NOMCLR

#use delay(clock=4000000) 

#use i2c(slave, fast, sda=PIN_B1, scl=PIN_B4, address=0xA0,FORCE_HW)


byte fstate;       //I2C bus state
byte posicion;     //Memory buffer index
byte buffer[0x10]; //Ram address   
#INT_SSP
void ssp_interupt (){

   int incoming;                     //Everithing the master sends is gonna be placed here 
   fstate = i2c_isr_state();         //get I2C bus state 
   if(fstate == 0x80) {              // If master asks for data      
   i2c_write(buffer[posicion]);      // the slave will write the asked data to the I2C bus 
   } 
   else {                            //If the master sends data 
      incoming = i2c_read();         //we read it
  if (fState == 1) {                 //if the information is about the position
         posicion = incoming;        //We save it as a position
      }
      else if (fState == 2) {        //The info is a data
      buffer[posicion]=incoming;     // We save the data in the right position
    }  }  }

void main (){ 
   fState = 0; 
   enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);
  while(true){     }}
#include <18f4550.h>
#fuses INTRC_IO,NOPROTECT,NOMCLR,NOWDT

#use delay(clock=4000000) 

看来我的 18f4550 坏了,或者 18f4550 的保险丝配置不正确,因为它不能在稳定的时钟速度下工作。

微处理器以某种方式工作到 #use 延迟时钟的 1/4。

我用max 232和pc做了一个测试程序。 我在 vb.net 中构建了一个软件,通过将数据发送到只对接收到的字节进行回显的图片来扫描所有波特率速度。

因此 vb.net 扫描器可以检测到何时发回了正确的数据。

通过这种方式,我发现芯片(或波特率发生器)正在工作到线路中稳定的波特率的四分之一:

#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

我尝试过多种振荡器配置,但从未正常工作。

然后我将代码修改为 18f448,它工作正常。

如果有人需要,我会上传所有提到的软件。

感谢大家。