目前总线上波形已经接近AT24C02数据手册上写和读的波形了,个人感觉读取应该是没有问题的,只是写入不能成功。调试期间有一将数据写入到了24C02且读了出来,另有一次是在板子重新上电时读出来,其余读出来都不对。
PCB图,中间图红星是去掉的电阻。
再不行就只能用模拟的方法了。
部分源代码
void I2C_HD_Init(void)
{
//MSSP状态寄存器(I2C模式)
SSPSTAT = 0x80; //压摆率控制位,使用100KHz标准速率,SMBus 选择位,不开启
SSPADD = 0x1D; //(Fosc/100000)/4 - 1; //100KHz总线频率 12MHz/100KHz/4-1 = 0x1D;
SSPCON1 = 0x28; //I2C 主模式,时钟 = FOSC/(4 * (SSPADD + 1)),同步串口使能位,开启
SSPCON2 = 0x00; //Clear Control Bits
DDRBbits.RB4 = 1; //开启SDA和SCL为输入
DDRBbits.RB6 = 1;
PIE1bits.SSPIE = 1;
}
//----------------------------------------I2C写入数据--------------------------------------------
void I2C_HD_Write(void)
{
SSPCON2bits.SEN = 1; // 1:在SDA 和SCL 引脚上发起启动条件。由硬件自动清零。
while ( SSPCON2bits.SEN ); //
SSPBUF = 0xAE; //AT24C02地址1010,A2-A0:111,写入 0.
while(SSPSTATbits.BF); // SSPBUF为空.
SSPCON2bits.ACKDT = 1;
SSPCON2bits.ACKEN = 1;
while(SSPCON2bits.ACKEN); // NotAckI2C1()
Delay_us(1);
SSPBUF = 0x0F; //地址.
while(SSPSTATbits.BF); // SSPBUF为空.
SSPCON2bits.ACKDT = 1;
SSPCON2bits.ACKEN = 1;
while(SSPCON2bits.ACKEN); // NotAckI2C1()
Delay_us(1);
SSPBUF = 0x7C; //数据124.
while(SSPSTATbits.BF); // SSPBUF为空.
while(SSPCON2bits.ACKSTAT) // 收到应答说明器件写操作成功,否则一直查询 。
{
SSPBUF = 0xAE; //AT24C02地址1010,A2-A0:111,写入 0.
while(SSPSTATbits.BF); // SSPBUF为空.
}
// Delay_us(1);
SSPCON2bits.ACKDT = 1;
SSPCON2bits.ACKEN = 1;
while(SSPCON2bits.ACKEN); // NotAckI2C1()
//Delay_us(1);
SSPCON2bits.PEN=1;
while(SSPCON2bits.PEN); //StopI2C2()
Delay_us(1);
}
//----------------------------------------I2C读取--------------------------------------------
void I2C_HD_Read(void)
{
SSPCON2bits.SEN = 1; // 1:在SDA 和SCL 引脚上发起启动条件。由硬件自动清零。
while ( SSPCON2bits.SEN ); //
SSPBUF = 0xAE; //AT24C02地址1010,A2-A0:111,寻址使用伪写 1.
while(SSPSTATbits.BF); // SSPBUF为空.
// Delay_us(1);
SSPCON2bits.ACKDT = 1;
SSPCON2bits.ACKEN = 1;
while(SSPCON2bits.ACKEN); // NotAckI2C1()
Delay_us(1);
SSPBUF = 0x0F; //地址.
while(SSPSTATbits.BF); // SSPBUF为空.
SSPCON2bits.ACKDT = 1;
SSPCON2bits.ACKEN = 1;
while(SSPCON2bits.ACKEN); // NotAckI2C1()
Delay_us(1);
SSPCON2bits.SEN = 1; // 1:在SDA 和SCL 引脚上发起启动条件。由硬件自动清零。
while ( SSPCON2bits.SEN ); //
SSPBUF = 0xAF; //AT24C02地址1010,A2-A0:111,读取 1.
while(SSPSTATbits.BF); // SSPBUF为空.
SSPCON2bits.ACKDT = 1;
SSPCON2bits.ACKEN = 1;
while(SSPCON2bits.ACKEN); // NotAckI2C1()
Delay_us(1);
SSPCON2bits.RCEN = 1; //使能接受。
while(!SSPSTATbits.BF); // SSPBUF为满.
SSPCON2bits.ACKDT = 0;
SSPCON2bits.ACKEN = 1;
while(SSPCON2bits.ACKEN); // AckI2C1()
// Delay_us(1);
SSPCON2bits.PEN=1;
while(SSPCON2bits.PEN); //StopI2C2()
Buff_Number = SSPBUF; //数据123.
}
void interrupt Isr(void)
{
if(TMR0IF == 1)
{
TMR0IF = 0;
LED = ~LED;
if(LED == 1)
{
I2C_HD_Write();
I2C_HD_Read();
Cont_Number = Buff_Number;
}
else
{
Cont_Number = 12345;
}
TMR0H = Timer0_RH;
TMR0L = Timer0_RL;
}
if(SSPIF == 1)
{
SSPIF = 0; //清中断。
}
}
复制代码
附件: 您需要 登录 才可以下载或查看,没有帐号?注册
最佳答案
lyl3257
查看完整内容
用不了那么复杂,给你一个PIC24 的程序参考 #include #define USE_AND_OR // To enable AND_OR mask setting for I2C. #include #define Fosc (16000000) #define Fcy (Fosc/2) //#define Fsck 400000 //400k #define Fsck 100000 //100k //#define I2C_BRG 79 #define I2C_BRG ((Fcy/2/Fsck)-1) #define uchar unsigned #define uint16 unsigned int void __delay32(unsigned long cycles); void DelayMS(unsigned ...
转载
|