一二百行代码产生的错误,不知不觉的改到了现在,不得不说,硬件的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
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?