OpenEdv-开源电子网

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

求教模拟I2C发数据,最后一位为1时波形异常

[复制链接]

7

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
71
金钱
71
注册时间
2016-8-18
在线时间
28 小时
发表于 2017-4-5 13:00:16 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 Alvanbai 于 2017-4-5 13:02 编辑

各位前辈好,请教一下。我用的模拟I2C,发送一个字节8bit的数据,发现只要最后一位数据为1,SDA就异常。最后一位为0的话是正常的,请教一下可能的原因,谢谢。

图中分别发送的是0xFE和0xFF黄线是SDA,红线是SDL。经过测试,发现规律只要是最后一位数据为1,波形就拉不下去。

0xFE

0xFE



0xFF

0xFF



驱动代码参考了这位前辈,感谢。http://www.openedv.com/posts/list/61112.htm
I2C.C
[mw_shl_code=c,true]/**
  ******************************************************************************
  * @file      IIC.c
  * @brief     simulation function
  * @CPU       STM32F10x
  * @compiler  Keil uVision V4.74
  * @author    Alex.fang(china shenzhen)
  * @copyright GPL
  * @version   V1.0.0
  * @date      02-Sept-2015
  ******************************************************************************
  * @attention
  */  
     

  
GPIO_InitTypeDef  GPIO_InitStructure;   
   
   

void IIC_Init(void)  
{                          
        RCC_APB2PeriphClockCmd(IIC_RCC_APB2Periph_GPIOx, ENABLE);   
        GPIO_InitStructure.GPIO_Pin = IIC_SDA_GPIO_Pin | IIC_SCL_GPIO_Pin;  
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出  //推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(IIC_GPIOx, &GPIO_InitStructure);  
        GPIO_SetBits(IIC_GPIOx,IIC_SDA_GPIO_Pin | IIC_SCL_GPIO_Pin);  //PB10,PB11 输出高   
}  
  

void SDA_OUT(void)   
{   
        GPIO_StructInit(&GPIO_InitStructure);   
        GPIO_InitStructure.GPIO_Pin   = IIC_SDA_GPIO_Pin;   
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出  //推挽输出   //推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
        GPIO_Init(IIC_GPIOx, &GPIO_InitStructure);   
}   
  

void SDA_IN(void)   
{   
        GPIO_StructInit(&GPIO_InitStructure);   
        GPIO_InitStructure.GPIO_Pin   = IIC_SDA_GPIO_Pin;   
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     
        GPIO_Init(IIC_GPIOx, &GPIO_InitStructure);   
}   
  
  
unsigned char SDA_READ(void)  
{  
        return GPIO_ReadInputDataBit(IIC_GPIOx, IIC_SDA_GPIO_Pin);  
}  
  

void IIC_SDA_1(void)  
{  
        GPIO_SetBits(IIC_GPIOx, IIC_SDA_GPIO_Pin);  
}  
  
  
void IIC_SDA_0(void)  
{  
        GPIO_ResetBits(IIC_GPIOx, IIC_SDA_GPIO_Pin);  
}  
  

void IIC_SCL_1(void)  
{  
        GPIO_SetBits(IIC_GPIOx, IIC_SCL_GPIO_Pin);  
}  
  

void IIC_SCL_0(void)  
{  
        GPIO_ResetBits(IIC_GPIOx, IIC_SCL_GPIO_Pin);   
}  
  
  
  
void IIC_Start(void)  
{  
    SDA_OUT();     //sda output   
    IIC_SDA_1();            
    IIC_SCL_1();  
    delay_us(4);  
    IIC_SDA_0();   //START:when CLK is high,DATA change form high to low   
    delay_us(4);  
    IIC_SCL_0();   //hold scl line, prepare to transmit data   
}      
  

void IIC_Stop(void)  
{  
    SDA_OUT();    //sda output mode   
    IIC_SCL_0();  
    IIC_SDA_0();  //STOP:when CLK is high DATA change form low to high   
    delay_us(4);  
    IIC_SCL_1();   
    IIC_SDA_1();  //indicate transmit over   
    delay_us(4);                              
}  
  

unsigned char IIC_Wait_Ack(void)  
{  
    unsigned char ucErrTime = 0;  
    SDA_IN();      //set as input mode   
    IIC_SDA_1();  
    delay_us(1);        
    IIC_SCL_1();  
    delay_us(1);      
    while(SDA_READ())  
    {  
        ucErrTime++;  
        if(ucErrTime > 250)  
        {  
            IIC_Stop();  
            return 1;  
        }  
    }  
    IIC_SCL_0(); //release scl line   
    return 0;   
}   
  
  
void IIC_Ack(void)  
{  
    IIC_SCL_0();  
    SDA_OUT();  
    IIC_SDA_0();  
    delay_us(2);  
    IIC_SCL_1();  
    delay_us(2);  
    IIC_SCL_0();  
}  
  
  
void IIC_NAck(void)  
{  
    IIC_SCL_0();  
    SDA_OUT();  
    IIC_SDA_1();  
    delay_us(2);  
    IIC_SCL_1();  
    delay_us(2);  
    IIC_SCL_0();  
}                                          
  
  
  
void IIC_Send_Byte(unsigned char txd)  
{                          
        unsigned char i;     
        SDA_OUT();         
        IIC_SCL_0();//push down scl  to start transmit data   
        for(i = 0; i < 8; ++i)  
        {               
        if(txd & 0x80)  
        {  
                IIC_SDA_1();  
        }  
        else  
        {  
                IIC_SDA_0();  
        }  
        txd <<= 1;        
        delay_us(2);     
        IIC_SCL_1();  
        delay_us(2);   
        IIC_SCL_0();      
        delay_us(2);  
        }   
}      
  
   
unsigned char IIC_Read_Byte(unsigned char ack)  
{  
        unsigned char i, res = 0;  
        SDA_IN();               //SDA input mode   
        for(i = 0; i < 8; ++i ){  
                IIC_SCL_0();   
                delay_us(2);  
                IIC_SCL_1();  
                res <<= 1;  
                if(SDA_READ()){  
                        res++;   
                }        
                delay_us(1);   
        }                    
        if (!ack){  
                IIC_NAck();//make NACK   
        }  
        else {  
                IIC_Ack(); //make ACK   
        }  
        return res;  
}  [/mw_shl_code]

I2C.H
[mw_shl_code=c,true]#define IIC_SDA_GPIO_Pin           GPIO_Pin_12
#define IIC_SCL_GPIO_Pin           GPIO_Pin_15
#define IIC_GPIOx                  GPIOB
#define IIC_RCC_APB2Periph_GPIOx   RCC_AHBPeriph_GPIOB



void IIC_Init(void);
  
void SDA_OUT(void);   
  
void SDA_IN(void);  
  
unsigned char SDA_READ(void);
  
void IIC_SDA_1(void);
  
void IIC_SDA_0(void);
  
void IIC_SCL_1(void);
  
void IIC_SCL_0(void);
  
void IIC_Start(void);      

void IIC_Stop(void);
  
unsigned char IIC_Wait_Ack(void);  

void IIC_Ack(void);

void IIC_NAck(void);
  
void IIC_Send_Byte(unsigned char txd);      

unsigned char IIC_Read_Byte(unsigned char ack);


#endif[/mw_shl_code]


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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2017-4-5 19:10:17 | 显示全部楼层
回复

使用道具 举报

2

主题

64

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
349
金钱
349
注册时间
2017-3-20
在线时间
86 小时
发表于 2017-4-5 23:44:49 | 显示全部楼层
试试吧IO口配置成开漏输出。
回复

使用道具 举报

7

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
71
金钱
71
注册时间
2016-8-18
在线时间
28 小时
 楼主| 发表于 2017-4-6 13:28:34 | 显示全部楼层
不存在的时间 发表于 2017-4-5 23:44
试试吧IO口配置成开漏输出。

谢谢,试过改变IO口mode了,不起作用。当前就是开漏输出。
回复

使用道具 举报

33

主题

197

帖子

0

精华

高级会员

Rank: 4

积分
587
金钱
587
注册时间
2015-1-9
在线时间
80 小时
发表于 2017-4-6 13:33:37 | 显示全部楼层
延时加大一些试试。
另外考虑一下硬件问题,有没有可能管脚坏了。
君子性非异也,善假于物也
不知常,妄作,凶
纵浪大化中,不喜亦不惧,应尽便须尽,无复独多虑
路漫漫其修远兮,吾将上下而求索
菩萨畏因,凡夫畏果
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-8-22 09:17

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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