OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4983|回复: 2

软件iic读取at24c02数据异常

[复制链接]

1

主题

2

帖子

0

精华

新手入门

积分
7
金钱
7
注册时间
2021-7-30
在线时间
1 小时
发表于 2022-6-6 17:22:26 | 显示全部楼层 |阅读模式
5金钱
用的软件iic,一开始写完,向24c02指定地址写入一个数据,再读回来是正常的,我以为iic是正常了,但后面又测试了下,发现连续调用iic读取地址时,会经常收不到应答,导致读到的数据异常,实在找不出问题,求大神帮忙看看吧。排除硬件问题,用原子哥的程序是正常的,硬件是mini板。主程序通过串口发送EEPROM_Read的返回值,可以看到一个规律的返回值。四个一组循环发: 04 04 02 04 01 04 02 04 01 04 02 04 01 04 02 04 (04代表正常完成一次iic通讯,02代表在第二次应答就挂掉了,收不到应答),通讯成功收到的值是正常的。隔一次就应答不成功,发送数据测试过连续发没问题,但读老是无应答,而且还是有规律的。

u8 Device_Add_Write = 0xA0;
u8 Device_Add_Read = 0xA1;

void IIC_Init(){
        GPIO_InitTypeDef GPIO_Initure;
        __HAL_RCC_GPIOC_CLK_ENABLE();
       
        GPIO_Initure.Pin = GPIO_PIN_11|GPIO_PIN_12;   
        GPIO_Initure.Mode = GPIO_MODE_OUTPUT_OD;
        GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH;
        GPIO_Initure.Pull = GPIO_NOPULL  ;
        HAL_GPIO_Init(GPIOC,&GPIO_Initure);
       
        HAL_GPIO_WritePin(GPIOC,GPIO_PIN_11,GPIO_PIN_SET);
        HAL_GPIO_WritePin(GPIOC,GPIO_PIN_12,GPIO_PIN_SET);
}

void IIC_Start(){
        SDA_OUT();
        SCL = 1;
        SDA = 1;
        delay_us(5);
        SDA = 0;
        delay_us(4);
        SCL = 0;
}

void IIC_Stop(){
        SDA_OUT();
        SCL = 0;
        SDA = 0;
        delay_us(4);
        SCL = 1;
        SDA = 1;
        delay_us(4);
}
u8 IIC_WaitAck(){
        u16 ucErrTime=0;       
        SDA_OUT();
        SDA=1;delay_us(1);       
        SDA_IN();      //SDAéèÖÃÎaêäèë            
        SCL=1;delay_us(1);         
        while(READ_SDA)
        {
                ucErrTime++;
                if(ucErrTime>500)
                {
                        IIC_Stop();
                        return 1;
                }
        }
        SCL=0;//ê±Öóêä3ö0           
        return 0;  
}

void IIC_Ack(){
        SDA_OUT();
        SCL = 0;
        SDA = 0;
        delay_us(2);
        SCL = 1;
        delay_us(2);
        SCL = 0;
        SDA = 1;
}       
       
void IIC_NoAck(){
        SDA_OUT();
        SCL = 0;
        SDA = 1;
        delay_us(2);
        SCL = 1;
        SDA = 1;
        delay_us(2);
        SCL = 0;
}       
       
u8 IIC_RecieveData(){
        unsigned char IIC_Rec=0;
  u8 i;
        SDA_IN();
        SCL = 0;
        for(i=0;i<8;i++){
        delay_us(2);
        SCL = 1;
        IIC_Rec = IIC_Rec << 1;
        if(PCin(11))
        IIC_Rec++;               
        delay_us(2);
        SCL = 0;
        }       
        return IIC_Rec;
}       

void IIC_SendData(u8 Data){
        u8 i;
        SDA_OUT();
        SCL = 0;
//        SDA = 0;
        for(i=0;i<8;i++){
                SDA = (Data&0x80) >> 7;
                Data = Data << 1;
                delay_us(2);
                SCL = 1;
                delay_us(2);
                SCL = 0;
                delay_us(2);
        }
}

void EEPROM_Write(u8 Word_Add ,u8 Data){
        IIC_Start();
        IIC_SendData(Device_Add_Write);
        IIC_WaitAck();
        IIC_SendData(Word_Add);
        IIC_WaitAck();
        IIC_SendData(Data);
        IIC_WaitAck();
        IIC_Stop();
        delay_ms(10);       
}

u8 EEPROM_Read(u8 Word_Add){
        IIC_Start();
        IIC_SendData(Device_Add_Write);
        if(IIC_WaitAck()){
                return 1;
        }

        IIC_SendData(Word_Add);
        if(IIC_WaitAck()){
                return 2;
        }

        IIC_Start();
        IIC_SendData(Device_Add_Read);
        if(IIC_WaitAck()){
                return 3;
        }
        buf = IIC_RecieveData();
        IIC_Ack();
        IIC_Stop();
        delay_ms(2);
        return 4;
        }




u8 EEPROM_Check(){
         EEPROM_Write(255,0x55);
         EEPROM_Read(255);
         if(buf == 0x55)
                 return 1;
         else
                 return 0;
}

void EEPROM_WriteLenByte(u8 Word_Add ,u32 Data ,u8 Len){
        u8 t ;
        for(t=0;t<Len;t++){
                EEPROM_Write(Word_Add+t,Data&0xff);
                Data = Data>>8;
        }
}


int main(void)
{
    HAL_Init();                                                    
    Stm32_Clock_Init(RCC_PLL_MUL9);                          
          delay_init(72);
                LED_Init();
                KEY_Init();
                Uart_Init(115200);
                IIC_Init();
    if(EEPROM_Check()){
                        LED0 = 0;
                        LED1 = 0;
                }
                else{
                        LED0 =0;
                        LED1 =1;
                }
                EEPROM_WriteLenByte(10,0x12345678,4);
//                EEPROM_Read(11);
                if(buff[1]== 0x56)
                        LED0 = 1;
                        while(1)
        {                
                buff[0]=EEPROM_Read(10);
                delay_ms(1000);
                buff[1]=EEPROM_Read(11);
                delay_ms(1000);
                buff[2]=EEPROM_Read(13);
                delay_ms(1000);
                buff[3]=EEPROM_Read(12);
                delay_ms(1000);
                HAL_UART_Transmit(&UART1_Handler,(u8*)&buff[0],1,0xFFFF);
                HAL_UART_Transmit(&UART1_Handler,(u8*)&buff[1],1,0xFFFF);
                HAL_UART_Transmit(&UART1_Handler,(u8*)&buff[2],1,0xFFFF);
                HAL_UART_Transmit(&UART1_Handler,(u8*)&buff[3],1,0xFFFF);
                delay_ms(1000);

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

369

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4241
金钱
4241
注册时间
2020-7-24
在线时间
714 小时
发表于 2022-6-7 10:22:26 | 显示全部楼层
回复

使用道具 举报

3

主题

62

帖子

0

精华

高级会员

Rank: 4

积分
964
金钱
964
注册时间
2019-7-8
在线时间
145 小时
发表于 2022-6-7 10:48:16 | 显示全部楼层
用逻辑分析仪看一下时序,分析一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-27 02:07

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表