您当前的位置: 首页 > 

鱼香ROS

暂无认证

  • 0浏览

    0关注

    498博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

IIC通讯笔记及硬件bug调试方法

鱼香ROS 发布时间:2018-01-23 02:00:57 ,浏览量:0

一二百行代码产生的错误,不知不觉的改到了现在,不得不说,硬件的bug确实比软件难改,会让人怀疑是硬件问题还是软件问题。为了改AT24C02的错误,花了半小时复习了下,主要内容在下面。现在先说以下这次bug造成的原因,以及以后大家在学习51单片机中遇到错误该怎们办。 这次bug的形成原因是细节上的错误。 第一个比较明显的:就是终止信号的时候 应该是SCL在高电平的时候收到一个SDA的上升沿,这个时候为终止。这里错写为SCL为低电平的时候,SDA出现上升沿了。 第二个错误:这个改出来的时候我想死的心都有了。。。。,

#ifndef uint define uint unsigned int endif

这个没问题吧,再看下面

#ifndef uchar define ucahr unsigned int endif

如果不仔细看你绝对发现不了,这样的好错误

然后现在讲51中遇到错误该怎们办(个人学习见解,能力有限,如有错误,还请指出) 首先先不要怀疑硬件问题(我们用的别人做好的板子,硬件一般是过关的) 用别人的代码进行测试(如果行得通,那就是你代码的问题了,这个时候就要好好检查了) 才用硬件调试 这个应该是调试寄存器,难度可能有点大 使用串口进行调试(我用的就是这个方式,也是我目前推荐的对于我们萌萌哒硬件的同学,51调试器暂时还没入手尝试下,串口怎么用呢!简单的说就是打印变量。我这里已经做了下封装,等下把相关代码传到群里。由于时间仓促,写的有可能也有点bug,如有发现还请指出)

最后呢希望大家继续努力,路漫漫其修远兮,上下而求索!

SDA 数据总线 SCL 时钟总线 只有当SCL上的电平为低电平时SDA上的数据才能够变化,也就是说当SCL(时钟总线)上为高电平时SDA(数据总线) 上的数据必须保持稳定。 起始信号和终止信号由通信主机掌控,产生起始信号后通讯总线就处于被占用状态,知道出现终止信号产生,总线就处于空闲状态。 接收到字节后接收器将SCL(时钟总线)拉低,让主机处于等待状态,接受完一个字节后就释放SCL(时钟总线)让数据继续发送 两个一个进行寻地址,一个进行传送数据 关于中间的不应答情况,暂且不要考虑 操作时序 第一步发送一个起始信号,然后发送7位寻址1位方向位(1代表R receiver 接受数据,0代表t 就是发送数据) 从机应答,主机发送数据,从机应答,主机再次发送数据,从机应答或者不应答,这个时候主机进行停止。 我们逐一分析 起始信号:当SCL为高电平的时候,SDA上出现一个下降沿 SDA 1 SCL 1 SDA 0 //出现下降沿 SCL 0 //将SCL置为0 ,表示占用总线

终止信号:当SCL为高电平的时候,SDA上出现一个上升沿 SDA 0 SCL 1 SDA 1 //出现一个上升沿 //结束后,SCL为高电平总线空闲

应答:SCL为高的时候等待SDA发生下降沿跳变,此跳变由从机发出(更准确的来说是,再经过一个时钟周期,再从SDK读入一个数据) SDA 1 SCL 1 等待SDA 0

非应答:SCL为高的时候等待SDA发生上升沿跳变,此跳变由从机发出(更准确的来说是,再经过一个时钟周期,再从SDK读入一个数据)

注意读数据过程 先写入 开始 地址 开始 地址 读取

AT24C02代码处 .#include “i2c.h” .#include “usart.h”

/********************************************************************* * 函数名 : Delay10us() * 函数功能 : 延时10us * 输入 : 无 * 输出 : 无 *********************************************************************/

void Delay10us() { unsigned char a,b; for(b=1;b>0;b–) for(a=2;a>0;a–);

} /********************************************************************* * 函数名 : I2cStart() * 函数功能 : 起始信号:在SCL时钟信号在高电平期间SDA信号产生一个下降沿 * 输入 : 无 * 输出 : 无 * 备注 : 起始之后SDA和SCL都为0 *********************************************************************/

void I2cStart() { SDA=1; Delay10us(); SCL=1; Delay10us();//建立时间是SDA保持时间>4.7us SDA=0; Delay10us();//保持时间是>4us SCL=0; Delay10us(); } /********************************************************************* * 函数名 : I2cStop() * 函数功能 : 终止信号:在SCL时钟信号高电平期间SDA信号产生一个上升沿 * 输入 : 无 * 输出 : 无 * 备注 : 结束之后保持SDA和SCL都为1;表示总线空闲 *********************************************************************/

void I2cStop() { SDA=0; Delay10us(); SCL=1; Delay10us();//建立时间大于4.7us SDA=1; Delay10us(); } /********************************************************************* * 函数名 : I2cSendByte(unsigned char dat) * 函数功能 : 通过I2C发送一个字节。在SCL时钟信号高电平期间,保持发送信号SDA保持稳定 * 输入 : num * 输出 : 0或1。发送成功返回1,发送失败返回0 * 备注 : 发送完一个字节SCL=0,SDA=1 *********************************************************************/

unsigned char I2cSendByte(unsigned char dat) { unsigned char a=0,b=0;//最大255,一个机器周期为1us,最大延时255us。 for(a=0;a>7; //起始信号之后SCL=0,所以可以直接改变SDA信号 dat=dat200) //如果超过2000us没有应答发送失败,或者为非应答,表示接收结束 { SCL=0; Delay10us(); return 0; } } SCL=0; Delay10us(); return 1; } /********************************************************************* * 函数名 : I2cReadByte() * 函数功能 : 使用I2c读取一个字节 * 输入 : 无 * 输出 : dat * 备注 : 接收完一个字节SCL=0,SDA=1. *********************************************************************/

unsigned char I2cReadByte() { unsigned char a=0,dat=0; SDA=1; //起始和发送一个字节之后SCL都是0 Delay10us(); for(a=0;a

关注
打赏
1666092100
查看更多评论
立即登录/注册

微信扫码登录

0.0566s