【发布时间】: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 引脚定义正确。