TODOPIC
Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: RuXBee en 26 de Septiembre de 2021, 16:12:23
-
If you have a HARDWARE design with AT24C32E and PCF8563T in the same I2C bus, you should know this.
In MPLAB with CCS Compiler, when you use I2C with this two devices, compiler enter in a error mode, because program blocked when I ask for an EEPROM register.
i2c_read(STREAM, ACK) has a parameter that you can choose if you want ACK Acknowledge or not.
The solution to this problem, is to avoid ACK control byte on i2c_read() routine.
If you apply this solution, you should know that you are exposed to lost bus data bytes.
Has anyone another valid solution?
Thanks!
-
You can give an example of how you create those two I2C ports/devices
-
I have used PIC24FJ256GA705.
Exactly, the probles occurs when you use I2C directives.
#include "24FJ256GA705.h"
#device ADC=12
#fuses PROTECT, FRC, BROWNOUT
#use delay(clock=8000000)
#use i2c(master,slow=100000,SDA=PIN_B9,SCL=PIN_B8)
#pin_select U2TX=PIN_C2
#pin_select U2RX=PIN_A13
#use rs232(baud=38400, xmit=PIN_C2, rcv=PIN_A13, errors, stream=NEXTION, UART2)
#pin_select SCK1OUT=PIN_B6
#pin_select SDI1=PIN_A14
#pin_select SDO1=PIN_B5
In my infinite loop I do a callback of the next routines:
uint8 e2prom_read(uint16 addres)
{
uint16 temp;
uint8 c, data;
i2c_start();
i2c_write(I2C_ADDRES_WRITE);
temp = addres >> 8;
c = temp;
i2c_write(c);
c = addres & 0xFF;
i2c_write(c);
i2c_start();
i2c_write(I2C_ADDRES_READ);
data = i2c_read(0); //No check ACK because cause problems with #use I2C
i2c_stop();
return data;
}
void rtc_i2c_read(rtc_type *time)
{
i2c_start();
i2c_write(cRTC_I2C_WRITE);
i2c_write(cRTC_TIME_ADDRES);
i2c_stop();
i2c_start();
i2c_write(cRTC_I2C_READ);
time->tm_sec = bcd2uint(i2c_read()&0x7f); //sec
time->tm_min = bcd2uint(i2c_read()&0x7f); //min
time->tm_hour = bcd2uint(i2c_read()&0x3f); //hr
time->tm_mday = bcd2uint(i2c_read()&0x3f); //day
time->tm_wday = bcd2uint(i2c_read()&0x7); //wday
time->tm_mon = bcd2uint(i2c_read()&0x1f); //month
time->tm_year = bcd2uint(i2c_read()); //year
i2c_stop();
}
When I use e2prom_read(addres) I have never use ACK acknowledge. If you use ACK, the program will blocked at first EEPROM read.
Also, you can use I2C software. But I don't like this solution because MCU is subjected to many tasks on my program.
-
What I would recommend is to use a logic analyzer, I have always had problems with the I2C bus or the SPI, and the way to determine what exactly is happening is to use the tool that I mention.
It is also using the disassembler to determine how the compiler is writing the code.
I don't use CCS the compiler, a long time ago I saw that I had those problems that it doesn't create the code properly and that is one of the reasons why I decided to go for another option to work professionally developing embedded systems.
Again, I recommend that you look at the disassembled code and see if the instructions are correct with what you write.