基于蓝桥杯的单片机模块练习——IIC驱动的注释及修改

本文探讨了在单片机IIC通信中,延迟时间参数对数据传输稳定性的影响。作者在蓝桥杯比赛中遇到PCF8591和AT24C02读取问题,通过调整DELAY_TIME的值解决了不稳定性。发现延迟时间过长或过短都会导致读取错误,适中的延迟确保了数据正确传输。
摘要由CSDN通过智能技术生成

基于蓝桥杯的单片机模块练习——IIC驱动的注释及修改

iic.c

/*
  程序说明: IIC总线驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台 8051,12MHz
  日    期: 2011-8-9
*/
#include "iic.h"
//=====================================================
//总结:IIC_SendByte(unsigned char byt)函数不要忘记释放SDA = 1;
//      IIC_SendAck(bit ackbit)函数不要忘记释放SDA = 1;
//====================================================
void IIC_Delay(unsigned char i)
{
    do{_nop_();}
    while(i--);        
}
//总线启动条件
void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 0;//在SCL高电平期间,SDA由高变低
    IIC_Delay(DELAY_TIME);
    SCL = 0;	
}

//总线停止条件
void IIC_Stop(void)
{
    SDA = 0;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 1;//在SCL高电平期间,SDA由低变高
    IIC_Delay(DELAY_TIME);
}

//发送应答
void IIC_SendAck(bit ackbit)
{
    SCL = 0;
    SDA = ackbit;  					// 0:应答,1:非应答
    IIC_Delay(DELAY_TIME);
    SCL = 1;
    IIC_Delay(DELAY_TIME);//第9个时钟周期
    SCL = 0; 
    SDA = 1;//释放sda
    IIC_Delay(DELAY_TIME);
}

//等待应答
bit IIC_WaitAck(void)
{
    bit ackbit;
	
    SCL  = 1;
    IIC_Delay(DELAY_TIME);
    ackbit = SDA;
    SCL = 0;
    IIC_Delay(DELAY_TIME);
    return ackbit;
}

//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
    unsigned char i;

    for(i=0; i<8; i++)
    {
        SCL  = 0;
        IIC_Delay(DELAY_TIME);
        if(byt & 0x80) SDA  = 1;//数据位是高电平
        else SDA  = 0;//数据位是低电平
        IIC_Delay(DELAY_TIME);
        SCL = 1;//SCL高电平期间,SDA的数据要保持稳定
        byt <<= 1;//发送的数据左移,准备发送下一位
        IIC_Delay(DELAY_TIME);//等待SDA的数据被读取
    }
    SCL  = 0;  
    //***********需要自己添加的两行**************
		SDA = 1;//释放SDA
	  IIC_Delay(DELAY_TIME);
	 //***********需要自己添加的两行**************
	
}

//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
    unsigned char i, da;

    for(i=0; i<8; i++)
    {   
    	SCL = 1;
	IIC_Delay(DELAY_TIME);//在SCL高电平期间,读取SDA的数据
	da <<= 1;
	if(SDA) da |= 1;
	SCL = 0;
	IIC_Delay(DELAY_TIME);
    }
      
    return da;    
}

iic.h

#ifndef _IIC_H
#define _IIC_H
#include "SystemInit.h"
#include "intrins.h"

#define DELAY_TIME 5

#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

//总线引脚定义
sbit SDA = P2^1;  /* 数据线 */
sbit SCL = P2^0;  /* 时钟线 */
void IIC_Start(void); 
void IIC_Stop(void);  
bit IIC_WaitAck(void);  
void IIC_SendAck(bit ackbit); 
void IIC_SendByte(unsigned char byt); 
unsigned char IIC_RecByte(void); 

#endif

注意:在第九届决赛的代码编写中我发现一个问题:读取PCF8591的电压显示在数码管上的数值不稳定,一直在跳变。(AT24C02的读取也是有问题的)经过不断地尝试,我发现把#define DELAY_TIME 5中的5改成小一点的数3,就可以解决问题。
但是,同样不能把它改的太小,如果改成2又会出现读取错误。
但是我想不明白其中的缘由。

转载:

在这里插入图片描述

原文链接:https://blog.csdn.net/KelvinFlying/article/details/46674339

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ღ 金龍戲水 ღ

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值