【问题标题】:Data from PIC to PIC via I2C. It works in proteus but not in real life. Why?通过 I2C 从 PIC 到 PIC 的数据。它在 proteus 中有效,但在现实生活中无效。为什么?
【发布时间】:2016-08-20 20:46:37
【问题描述】:

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

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

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

slave 将接收到这个字节,将其存储在 ram 或 rom(包括两个程序)中,并将被 master 读取。

这在 Proteus 8 中运行良好,但在现实生活中却不行。

我在三个尝试中得到了三个不同的结果,使用相同的十六进制文件。

1.PROTEUS 8:运行良好,完美。

2.PROTEUS 7:它不起作用但它不会挂起

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

我的编译器是 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){     }}

【问题讨论】:

  • 检查上拉电阻。
  • 在这种情况下,通常是 Pullup 的问题。另外,如果在同一设备上共享其他外设,我建议确保您的 I2C 引脚定义正确。

标签: pic i2c


【解决方案1】:
#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,它工作正常。

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

谢谢大家。

【讨论】:

    猜你喜欢
    • 2010-10-30
    • 2014-05-19
    • 2022-12-23
    • 1970-01-01
    • 2019-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-07
    相关资源
    最近更新 更多