stm8L10x模拟IIC读取数据怎么老是0xff 求大侠路见不平!!!

2019-07-19 20:47发布

本帖最后由 哔哩吧啦 于 2017-6-30 11:23 编辑

这个是IIC.c文件
#include "bsp_i2c.h"

void I2C_Config(void)
{
//    GPIO_Init(GPIO_I2C, I2C_SDA, GPIO_Mode_Out_OD_HiZ_Fast);  //高速推挽输出高电平
//    GPIO_Init(GPIO_I2C, I2C_SCL, GPIO_Mode_Out_PP_High_Fast);  //高速推挽输出高电平
//   
    GPIO_Init(GPIO_I2C, I2C_SDA, GPIO_Mode_Out_OD_HiZ_Fast);  //高速开漏输出高电平
    GPIO_Init(GPIO_I2C, I2C_SCL, GPIO_Mode_Out_OD_HiZ_Fast);  //高速开漏输出高电平


}

//产生起始信号
void I2C_Start(void)
{   
    I2C_SDA_H;
    I2C_SCL_H;
    delay_us(5);
    I2C_SDA_L;
    delay_us(5);
    I2C_SCL_L;
}

//产生停止信号
void I2C_Stop(void)
{
   I2C_SCL_L;
   I2C_SDA_L;
   I2C_SCL_H;
   delay_us(5);
   I2C_SDA_H;
   delay_us(5);
}

//主机产生应答信号ACK
void I2C_Ack(void)
{
   I2C_SCL_L;
   I2C_SDA_L;
   delay_us(5);
   I2C_SCL_H;
   delay_us(5);
   I2C_SCL_L;
}

//主机不产生应答信号NACK
void I2C_NAck(void)
{
   I2C_SCL_L;
   I2C_SDA_H;
   delay_us(5);
   I2C_SCL_H;
   delay_us(5);
   I2C_SCL_L;
}
//等待从机应答信号
//返回值:1 接收应答失败
//                  0 接收应答成功
u8 I2C_Wait_Ack(void)
{
    u8 tempTime=0;


    I2C_SDA_H;
    delay_us(5);
    I2C_SCL_H;
    delay_us(5);

    while(GPIO_ReadInputDataBit(GPIO_I2C,I2C_SDA))
    {
        tempTime++;
        if(tempTime>250)
        {
            I2C_Stop();
            return 1;
        }         
    }

    I2C_SCL_L;
    return 0;
}
//I2C 发送一个字节
void I2C_Send_Byte(u8 txd)
{
    u8 i=0;

    I2C_SDA_OUT;
    I2C_SCL_L;//拉低时钟开始数据传输

    for(i=0;i<8;i++)
    {
        if((txd&0x80)>0) //0x80  1000 0000
            I2C_SDA_H;
        else
            I2C_SDA_L;

        txd<<=1;
        //delay_us(5);
        I2C_SCL_H;
        delay_us(5); //发送数据//兼容  TM1650
        I2C_SCL_L;
        delay_us(5);
    }
}

//I2C 读取一个字节

u8 I2C_Read_Byte(u8 ack)
{
   u8 mask,receive;

   //I2C_SDA_IN;     此处屏蔽过
   I2C_SDA_H;   //加多的
   for(mask=0x80; mask!=0; mask>>=1)
   {
        delay_us(5);
        //delay_us(2);
        I2C_SCL_H;
        if(GPIO_ReadInputDataBit(GPIO_I2C,I2C_SDA) == 0)
        {
           receive &= ~mask;
        }
        else
        {
             receive |= mask;
        }

        delay_us(5);
        I2C_SCL_L;
        //delay_us(1);
               
   }

    if(ack==0)
        I2C_NAck();
    else
        I2C_Ack();

    return receive;
}

设备读取一个字节的函数

u8 AT24Cxx_ReadOneByte(u16 addr)
{
    u8 temp=0;

    I2C_Start();


    I2C_Send_Byte(AT24Cxx_Address);
    while( I2C_Wait_Ack());

    I2C_Send_Byte(addr>>8);        //发送数据地址高位
    while( I2C_Wait_Ack());

    I2C_Send_Byte(addr%256);//双字节是数据地址低位               
    while( I2C_Wait_Ack());                                            //单字节是数据地址低位


    I2C_Start();
    I2C_Send_Byte(0xa3);
    while( I2C_Wait_Ack());

    temp=I2C_Read_Byte(0); //  0   代表 NACK
    I2C_Stop();

    return temp;        
}

主函数

u16 p = 0;

int main(void)
{
  CLK_MasterPrescalerConfig(CLK_MasterPrescaler_HSIDiv1);
  USART_Config();
  I2C_Config();
  p = AT24Cxx_ReadOneByte(0x6004);
  USART_Send_Btye(p);
  while(1)
  {

  }               

}


想了几天了  楞是没想出来  求助


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
3条回答
哔哩吧啦
1楼-- · 2019-07-19 23:12
问题解决,字节仔细研究了下硬件资料发现那个温湿度在测量时需要时间,所以加上合适的延时就解决了。
哔哩吧啦
2楼-- · 2019-07-20 04:40
 精彩回答 2  元偷偷看……
正点原子
3楼-- · 2019-07-20 08:14
 精彩回答 2  元偷偷看……

一周热门 更多>