Ich verwende den Pic24fj128ga202-Mikrocontroller und das 24c256-EEPROM und die ISL1208-RTC, die über den I2c-Bus verbunden sind. Das Problem ist, dass ich die Daten in EEPROM und RTC lesen und schreiben kann, aber auf einigen anderen Boards (mit demselben Design) kann ich die Daten nicht über den i2c-Bus lesen oder schreiben. Ich habe meinen Code und meinen Schaltplan gepostet. Bitte spricht mich jemand an, was ist das Problem? Ich habe kein Oszilloskop, um das zu überprüfen.
#include <stdio.h>
#include "C:\Program Files\Microchip\xc16\v1.24\support\PIC24F\h\p24FJ128GA202.h"
#include "uart.h"
// calculate baud rate of I2C
#define Fosc 32000000
#define Fcy (Fosc/2)
#define Fsck 400000
#define I2C_BRG ((Fcy/2/Fsck)-1)
int main()
{
InitProcessor();
Delayms();
while(1)
{
I2c_Write(0xA0,1,'A');
Delayms(5000);
uart1tx(I2C_read(0xA0,1));
}
}
void InitProcessor(void)
{
// Oscillator 8mhz no pll
OSCCON = 0x0011;
CLKDIV = 0x0000;
// Configure Digital pins
ANSA = 0x0003;
ANSB = 0x0000;
// Assign IO values for Ports
PORTA = 0x0000;
TRISA = 0x001B;
TRISB = 0x468f; // 7 as receive and 8 as transmitter
//PORTB = 0x0000;
// Interrupt Bits
INTCON1 = 0x0000; // Disable Interrupts
INTCON2 = 0x0000;
// Init I2C
I2C2CONL = 0x8000;
I2C2CONH = 0x0000;
I2C2STAT = 0x0000;
I2C2BRG = I2C_BRG;
//I2C2BRG = 79;
Delayms(1000);
Init_rtc();
}
void Init_rtc()
{
I2c_Write(0xde, 0x07, 0x10);
I2c_Write(0xde, 0x06, 0x00);
Delayms(20);
}
void I2c_Write(unsigned char DeviceAddress,unsigned int Addr,unsigned char i2c_value)
{
unsigned char i2c_exit=1,i2c_write=0;
int I2creg = 0;
IFS3 &= ~0x0004;
I2C2CONL |= 0x0001;
I2cTimer = 0;
while(i2c_exit)
{
if(I2cTimer > 30){ // Exit routine
i2c_exit = 0;
}
if(IFS3& 0x0004)
{
IFS3 &= ~0x0004;
I2cTimer = 0;
if(i2c_write == 0)
{
I2C2TRN = (DeviceAddress & 0xfe);
if(DeviceAddress == 0xde)
i2c_write = 1;
}
else if(i2c_write == 1)
I2C2TRN = Addr >> 8;
else if(i2c_write == 2)
I2C2TRN = Addr & 0xFF;
else if(i2c_write == 3)
I2C2TRN = i2c_value;
else if(i2c_write == 4)
I2C2CONL |= 0x04;
else
{
i2c_write = 100;
i2c_exit = 0;
}
i2c_write++;
}
}
Delayms(5);
}
/* Function to Read and return a data through I2C */
unsigned char I2C_read(unsigned char DeviceAddress,unsigned int Addr)
{ unsigned char db, ReadState=0,I2CFlag;
ReadState = 0;
IFS3 &= ~0x0004; // Master I2C interrupt flag
I2CFlag = 1;
I2C2CONL |= 0x0001; // SEN = 1;
I2cTimer = 0;
while(I2CFlag){
if(I2cTimer > 30){ // Exit routine
I2CFlag = 0;
//ModemDiagnostics(64,1);
}
//uart1tx('r');
if(IFS3 & 0x0004)
{
I2cTimer = 0;
IFS3 &= ~0x0004;
if(ReadState == 0)
{
I2C2TRN = (DeviceAddress & 0xfe);
if(DeviceAddress == 0xde)
ReadState = 1;
}
else if(ReadState == 1)
I2C2TRN = Addr >> 8;
else if(ReadState == 2)
I2C2TRN = Addr & 0xff;
else if(ReadState == 3)I2C2CONL |= 0x0002;
else if(ReadState == 4)I2C2TRN = (DeviceAddress | 0x01);
else if(ReadState == 5){
I2C2CONL |= 0x0008; // RCEN = 1, Enable data receive
db = I2C2RCV;
}
else if(ReadState == 6){
db = I2C2RCV; // Read Data
I2C2CONL |= 0x0020; // ACKDT = 1, Set Acknowledge bit (No Acknowledge)
Delayms(5);
I2C2CONL |= 0x0010; // ACKEN = 1
}
else if(ReadState == 7)I2C2CONL |= 0x04; // PEN = 1, Stop enable bit forI2C
else{ReadState = 100; I2CFlag = 0;}
ReadState++;
}
}
if(db)
return db;
else
return 0;
}
Die Berechnung des maximalen Pull-Ups bei 400 kHz lautet:
= ; durch Umstellen erhalten wir:
= für Ihren Fall ergibt sich 30 pF.
Die Pin-Kapazitäten des EEPROM und des RTC liegen wahrscheinlich beide in der Größenordnung von 10 pF; Fügen Sie die Pin-Kapazität des PIC hinzu, und Sie nähern sich bereits 30 pF und setzen das Design auf eine haarige Kante (um den gebräuchlichen Begriff zu verwenden), wo es möglicherweise ordnungsgemäß funktioniert oder nicht, was genau das ist, was Sie erleben.
Es ist nicht schwierig, eine Streukapazität von 10 pF oder mehr zu erreichen, und dies würde die Anforderung für die maximale Pull-up-Größe verletzen, was zu beschädigten I2C-Daten führen würde.
Wenn Sie diese Teile durch 4,7 k ersetzen, dürfen Sie fast 64 pF Buskapazität haben, was das Problem sehr wahrscheinlich lösen wird.
Wie bereits erwähnt, wenn Sie die Busgeschwindigkeit reduzieren und sie ordnungsgemäß funktioniert, ist dies ein klarer Hinweis darauf, dass dies das Problem ist.
Da es in einem anderen Board wie gewünscht funktioniert, gehe ich davon aus, dass die Probleme von der Hardware herrühren (auch wenn eine schlechte Software es verschlimmern kann). Dafür sehe ich 2 Gründe:
Peter Schmidt