你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

主发送I2C发送完数据后没有接收到应答信号

[复制链接]
watercici 提问时间:2018-3-26 15:09 /
我用STM32F103做主I2C,用PCF8563做从I2C,用模拟I2C进行的通信,但是主给从发送了数据之后,接收的到都是NACK信号,为什么接收不到ACK呢?代码如下
#include "stm32f10x.h"
#include "stm32f10x_i2c.h"
#include "stm32f10x_gpio.h"
#include "i2c_mgr.h"
#include "stm32f10x_it.h"
#include "rtc_mgr.h"
#include "timer_mgr.h"



void I2C_GPIO_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
        I2C_InitTypeDef I2C_InitStructure;
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
        //------------RTC_SDA->PB_11\RTC_SCL->PB_10----------------------------------------
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;//¿ªÂ©Êä³ö
       
        GPIO_Init(GPIOB,&GPIO_InitStructure);
        GPIO_SetBits(GPIOB,GPIO_Pin_11|GPIO_Pin_10);

}



void I2C_START(void)
{
                SDA_OUT();
                SCL_H();
                SDA_H();
                delay_us(5);
                SDA_L();
                delay_us(5);
}
void I2C_Send_Byte(u8 txd)  
{                          
    u8 t;     
    SDA_OUT();        

    for(t=0;t<8;t++)  
    {     
                                                SCL_L();
                                                delay_us(1);
            if((txd&0x80)>>7)  
                                                {
                                                                SDA_H();  
                                                                SCL_H();  
                                                                delay_us(5);
                                                                txd<<=1;
                                                }                                                       
            else  
                                                {
                                                        SDA_L();   
                                                        SCL_H();  
                                                        delay_us(5);
                                                        txd<<=1;       
                                                }                                                       
                                }       
                                        SCL_L();
                                 
                                                     
}
void I2C_STOP(void)
{
        SDA_OUT();
        SCL_L();
        delay_us(5);
        SDA_L();
        delay_us(5);
        SCL_H();
        delay_us(5);
        SDA_H();
        delay_us(5);
}


u8 I2C_Wait_ACK(void)
{
        u8 waitcnt = 0;
        u8 slaveack = 0;
       
        SCL_L();
        SDA_IN();
  //delay_us(5);
        SCL_H();
  delay_us(5);       
        if(READ_SDA())
        {
                SCL_L();
                return 1;
        }
         SCL_L();
        delay_us(5);

  return 0;
}
void I2C_ACK(void)
{
        SCL_L();
  SDA_OUT();
        SDA_L();
  delay_us(5);
        SCL_H();
        delay_us(5);
        SCL_L();
}

void I2C_NACK(void)
{
        SCL_L();
        SDA_OUT();
        SDA_H();
        delay_us(5);
        SCL_H();
        delay_us(5);
        SCL_L();
}



u8 I2C_Read_Byte(unsigned char ack)  
{  
    unsigned char i,receive=0;  
    SDA_IN();
    for(i=0;i<8;i++ )  
    {  

                                SCL_H();
                          delay_us(5);
        receive<<=1;
                       
        if(READ_SDA())receive++;     
        delay_us(5);
        SCL_L();   
        delay_us(5);                        
    }                     
    if (!ack)  
        I2C_NACK();
    else  
        I2C_ACK();     
    return receive;  
}  
void I2C_Write(u8 WriteAddr,u8 Dat)
{
                I2C_START();  
    I2C_Send_Byte(PCF8563_ADDR_W);
    I2C_Wait_ACK();  
    I2C_Send_Byte(WriteAddr);  
    I2C_Wait_ACK();  
    I2C_Send_Byte(Dat);
          I2C_Wait_ACK();
    I2C_STOP();  
}
u8 I2C_Read(u8 ReadAddr)
{
        u8 ReData,t=0;  
    I2C_START( );  
    I2C_Send_Byte(PCF8563_ADDR_W);
    I2C_Wait_ACK();  
    I2C_Send_Byte(ReadAddr);
    I2C_Wait_ACK();  
    I2C_START();  
    I2C_Send_Byte(PCF8563_ADDR_R);      
    I2C_Wait_ACK();  
    ReData = I2C_Read_Byte(0);  
    I2C_STOP();  
    return ReData;   
}

收藏 评论34 发布时间:2018-3-26 15:09

举报

34个回答
wenyangzeng 回答时间:2018-3-26 17:30:58
楼主在发送函数 I2C_Send_Byte()中的变量txd一会儿右移:
(txd&0x80>>7)
一会儿左移:
txd<<=1;
貌似无法得到正确的应答信号。

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

casc12 回答时间:2018-5-19 17:25:00
wenyangzeng 发表于 2018-3-26 17:30
楼主在发送函数 I2C_Send_Byte()中的变量txd一会儿右移:
(txd&0x80>>7)
一会儿左移:

for(t=0;t<8;t++)
    {              
        IIC_SDA=(txd&0x80)>>7;
        txd<<=1;           
                delay_us(2);   
                IIC_SCL=1;
                delay_us(2);
                IIC_SCL=0;       
                delay_us(2);
    }
(txd&0x80)>>7是为了取txd的最高位, txd<<=1; 是将下一位数据移位到最高位,就可以(txd&0x80)>>7取走最高位
废鱼 回答时间:2018-3-27 11:36:05
/*  
* 函数名: static void I2C_Stop(void)
* 描述  : 终止信号
* 输入  : 无
* 输出  : 无
* 说明  :  
*/  
static void I2C_Stop(void)  
{  
    SCL_L;  
    I2C_delay();  
    SDA_L;  
    I2C_delay();  
    SCL_H;  
    I2C_delay();  
    SDA_H;  
    I2C_delay();  
}  
清/ts囸図 回答时间:2018-3-26 19:22:08
是哪一步收不到应答呢
watercici 回答时间:2018-3-27 08:31:08
清/ts囸図 发表于 2018-3-26 19:22
是哪一步收不到应答呢

每一步都收不到应答,我在想是不是从设备没有收到我给的数据
清/ts囸図 回答时间:2018-3-27 08:49:25
watercici 发表于 2018-3-27 08:31
每一步都收不到应答,我在想是不是从设备没有收到我给的数据

用示波器看看引脚的波形,
I2C时序对不对
I2C从设备地址对不对

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

七哥 回答时间:2018-3-27 09:13:41
主程序在哪里?可能不是模拟I2C时序问题。
贴个工程上来。

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

watercici 回答时间:2018-3-27 09:23:53
本帖最后由 watercici 于 2018-3-27 09:29 编辑
清/ts囸図 发表于 2018-3-27 08:49
用示波器看看引脚的波形,
I2C时序对不对
I2C从设备地址对不对

我是用逻辑分析仪抓的,时序和地址发的没有问题
图片1.jpg
watercici 回答时间:2018-3-27 09:34:07
toofree 发表于 2018-3-27 09:13
主程序在哪里?可能不是模拟I2C时序问题。
贴个工程上来。

不好意思,工程不方便贴,我这个程序还没有调试到主循环中,只是main函数中的初始化,我觉得其他模块应该不影响它,我的从设备是PCF8563,我觉得它是不是没有收到数据啊
废鱼 回答时间:2018-3-27 09:36:33
楼主看一下8563的硬件地址是否正确。

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

七哥 回答时间:2018-3-27 09:38:17
watercici 发表于 2018-3-27 09:23
我是用逻辑分析仪抓的,时序和地址发的没有问题

知道第一个字节发送的时候没收到ACK意味着什么吗?
就是说,在这个地址就没找到有I2C设备。如果确定你的8563地址没错,那看看前面一个干扰脉冲怎么回事。
watercici 回答时间:2018-3-27 09:48:08
toofree 发表于 2018-3-27 09:38
知道第一个字节发送的时候没收到ACK意味着什么吗?
就是说,在这个地址就没找到有I2C设备。如果确定你的85 ...

那个干扰脉冲有影响吗?因为我在初始化IO口后,IO口的电平都是拉低的,然后我在初始化中加了一句“        GPIO_SetBits(GPIOB,GPIO_Pin_11|GPIO_Pin_10);”之后,就会有前面的那个低脉冲了
watercici 回答时间:2018-3-27 09:52:07
安 发表于 2018-3-27 09:36
楼主看一下8563的硬件地址是否正确。

硬件地址没有问题,其“从地址 读 0A3H;写 0A2H”,手册上说的
废鱼 回答时间:2018-3-27 10:24:24
watercici 回答时间:2018-3-27 10:37:29
安 发表于 2018-3-27 10:24
楼主可以参考一下:
http://blog.csdn.net/xiayufeng520/article/details/46292755

我看了一下您的程序,我先问一下,您的程序中没有对SDA方向进行控制吗,当等ACK的时候SDA的方向不应该是输入吗
废鱼 回答时间:2018-3-27 10:51:31
这个是我找的例程,我以前用过是可以用的。103下面使用,配置的是输出。
123下一页

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版