OpenEdv-开源电子网

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

STM32模拟I2C为什么接收不到应答信号?

[复制链接]

4

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2013-10-16
在线时间
0 小时
发表于 2014-1-7 14:18:16 | 显示全部楼层 |阅读模式
STM32模拟I2C与ad5161通讯,为什么接收不到应答信号?
/* 
 * 函数名:void I2C_GPIO_Config(void)
 * 描述 : I2C管脚初始化
 * 输入  :无
 * 输出 : 无
 */

void I2C_GPIO_Config(void)//void I2C_GPIO_Init(void)
{
 
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB ,ENABLE);


// PB6-I2C1_SCL、PB7-I2C1_SDA 
//初始化SCL管脚
GPIO_InitStructure.GPIO_Pin =  SCL_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;//PP;  
GPIO_Init(SCL_PORT, &GPIO_InitStructure);

//初始化SDA管脚
GPIO_InitStructure.GPIO_Pin =  SDA_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;//;
GPIO_Init(SDA_PORT, &GPIO_InitStructure);

SCL_H;
SDA_H;
}


/* 
 * 函数名: void I2C_delay(void)
 * 描述 : 短暂延时
 * 输入 : 无
 * 输出 : 无
 * 说明 : 内部定义的i可以优化速度,经测试最低到5还能写入
 */
 
static void I2C_delay(void)   //
{   
    u16 i=2000; 
    while(i) 
    { 
        i--; 
    } 
}

static void I2C_delay1(void)   //
{   
    u16 i=500; 
    while(i) 
    { 
        i--; 
    } 
}

void I2C_Delay(vu32 nCount)
{
  for(; nCount != 0; nCount--);
}
/* 
 * 函数名: bool I2C_Start(void)
 * 描述 : 起始信号
 * 输入 : 无
 * 输出 : TRUE : 成功
                     FALSE : 失败
 * 说明 : IIC起始信号定义为当SCL为高电平(HIGH)时,SDA线从高到低的跳变
 */
 
bool I2C_Start(void)
{
 
SDA_OUT(); //sda线输出
    SDA_H;
    I2C_delay();
    SCL_H;
    I2C_delay();

    SDA_L;
    I2C_delay();

    SCL_L; //钳住I2C总线,准备发送或接收数据,避免在SCL为高电平期间,再次发出起始信号或者停止信号
    //I2C_delay();

return TRUE;
}

/* 
 * 函数名: static void I2C_Stop(void)
 * 描述 : 终止信号
 * 输入 : 无
 * 输出 : 无
 * 说明 :IIC停止信号定义为当SCL为高电平(HIGH)时,SDA线从低到高的跳变  
 */
 
void I2C_Stop(void)
{

SDA_OUT(); //sda线输出

    SCL_L;
SDA_L;
    I2C_delay();
    SCL_H;
    I2C_delay();
    SDA_H;
    I2C_delay();

}

/* 
 * 函数名: static void I2C_Ack(void)
 * 描述 :产生应答信号 ,主机从从机读取数据后,向从机发出应答信号
 * 输入 : 无
 * 输出 : 无
 * 说明 : 主机在接收到从机的数据后,向从机返回一个应答信号,
 继续通信,在SCL为高电平器件,SDA一直保持低电平表示应答
 */

static void  I2C_Ack(void)
{   

    SCL_L;

SDA_OUT();

//    I2C_delay();
    SDA_L;
    I2C_delay();
    SCL_H;
    I2C_delay();
    SCL_L; //SCL再输出低电平,保证在SCL为高电平期间,SDA始终保持高电平,表示应答信号
    //I2C_delay();
}

/* 
 * 函数名: void I2C_NoAck(void)
 * 描述 : 不产生应答信号,主机接收到从机的数据后,不发出应答信号 
 * 输入 : 无
 * 输出 : 无
 * 说明 : 
 */
 
static void I2C_NoAck(void)
{
   
    SCL_L;

SDA_OUT();

    SDA_H;
    I2C_delay();
    SCL_H;
    I2C_delay();
    SCL_L;    //SCL再次输出低电平,保证SCL为高时,SDA一直为高
    //I2C_delay();

}

/* 
 * 函数名: bool I2C_WaitAck(void)
 * 描述 : 等待应答信号
 * 输入 : 无
 * 输出 : TRUE : 有应答
                     FALSE : 无应答
 * 说明 : IIC通信时,接收到数据,从机(Slave)会发出ACK信号,
 一般是一个低电平 信号出现在SDA线上,若主机检测到,则认为此次通信成功
 */

static bool I2C_WaitAck(void)   
    u16 ucErrTime=0;

SDA_IN();

SDA_H;  //释放总线
I2C_delay1();

SCL_H;
    I2C_delay1();
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>500)
{
I2C_Stop();
       return FALSE;
}
}
    SCL_L;
//    I2C_delay();

    return TRUE;  
}

/* 
 * 函数名: static void I2C_SendByte(u8 SendByte) 
 * 描述 : 发送一个字节
 * 输入 : SendByte : 字节数据
 * 输出 : 无
 * 说明 : 数据从高位到低位
 */

static void I2C_SendByte(u8 SendByte) 
{
    u8 i;
SDA_OUT();

SCL_L; //拉低时钟开始数据传输
    for(i=0;i<8;i++) 
    {
        if((SendByte<<i)&0x80)
{
            SDA_H;
}  
        else
            SDA_L;   
        I2C_delay();

SCL_H;
        I2C_delay();

SCL_L;
        I2C_delay();

}
}

/* 
 * 函数名: static u8 I2C_ReceiveByte(void) 
 * 描述 : 读取一个字节
 * 输入 : 无 
 * 输出 : 字节数据
 * 说明 : ReceiveByte : 数据从高位到低位
 */

u8 I2C_ReceiveByte(u8 ack)  
    u8 i,ReceiveByte=0;
SDA_IN();
    
// SDA_H;
// I2C_delay();

    for(i=0;i<8;i++)
    {
        SCL_L;
        I2C_delay();

        SCL_H;

ReceiveByte<<=1;
//        I2C_delay();

        if(READ_SDA)
            ReceiveByte++;
        I2C_delay();
    }
if(!ack)
I2C_NoAck(); //不回应
else
I2C_Ack(); //回应
    return ReceiveByte;
}

/*
* 函数名: Delay(vu32 nCount)
 * 描述 : 延时函数 
 * 输入 : 
 * 输出 :
 * 说明 : 
*/
void Delay_ms(vu32 nCount)
{
  for(; nCount != 0; nCount--);
}


/* 
 * 函数名: bool I2C_WriteByte(u8 DeviceAddress, u16 cmd, u8 SendByte)
 * 描述 : 写入1字节数据  
 * 输入 : DeviceAddress : 器件地址
  cmd:控制命令
SendByte : 要写入数据
                     
 * 输出 : TRUE : 成功
                     FALSE : 失败
 * 说明 : 
 */

bool I2C_WriteByte(u8 DeviceAddress, u16 cmd, u8 SendByte)
{

    I2C_Start();

I2C_SendByte(DeviceAddress);//写入器件地址

    I2C_WaitAck();   


    I2C_SendByte(cmd);   //写入控制命令
  
    I2C_WaitAck();   

 
    I2C_SendByte(SendByte);  //写入数据



    I2C_WaitAck(); 

    I2C_Stop(); 
    return TRUE;
}


/* 
 * 函数名: bool I2C_ReadByte(u8* pBuffer,   u8 length,     u16 ReadAddress,  u8 DeviceAddress)
 * 描述 : 读出1串数据
 * 输入 : pBuffer : 要读取数据缓冲区指针
           length : 待读取长度  
                     DeviceAddress : 器件地址
 * 输出 : TRUE : 成功
                     FALSE : 失败
 * 说明 : 跨页写入1串数据
 */

u8 I2C_ReadByte(u8 DeviceAddress)
{   
u8 pBuffer=0xFE;

I2C_Start();
    I2C_SendByte(DeviceAddress);//设置器件地址 0x59
  I2C_WaitAck();

    I2C_delay();
    
pBuffer=I2C_ReceiveByte(0);  //接收数据无应答位

    I2C_Stop();
    return pBuffer;
}

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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-1-7 15:02:02 | 显示全部楼层
回复 支持 反对

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2014-1-7 16:13:49 | 显示全部楼层
回复【楼主位】小悦怡然:
---------------------------------
好好看IIC通讯协议去
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

17

主题

470

帖子

1

精华

高级会员

Rank: 4

积分
718
金钱
718
注册时间
2013-11-23
在线时间
0 小时
发表于 2014-1-7 20:42:38 | 显示全部楼层
IIC器件读数据不是你这么写的吧,即使读一个字节函数,一般也是先写地址-应答-写控制字-应答-停止-再起始-(写读的地址)-(应答)-写数据,只少你最后一个函数有问题,IIC时序模拟部分没看出什么问题
回复 支持 反对

使用道具 举报

4

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2013-10-16
在线时间
0 小时
 楼主| 发表于 2014-1-8 13:46:52 | 显示全部楼层
回复【4楼】hechao3225:
---------------------------------
程序没有错,是硬件问题,换了块ad5161就好了。谢谢你的回答。
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-11 11:32

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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