没买板子之前,用protues画过电路图,实现了通过i2c总线向EEPROM中写入和读出数据。

今天,在自己买的板子上面写关于i2c总线的程序,有个地方忘了延时,调程序的时候很蛋疼。下面说说我对I2c总线的理解

i2c总线共有两根线,一根是时钟信号线,一根是数据线。这里我只实现了,指定EEPROM片内地址,并向其中写入一个字节。从EEPROM中指定地址读出一个字节。

写入过程

1.需要发一个启动信号

2.发送EEPROM设备地址

3.发送EEPROM片内地址

4.发送你要写入的数据

5.发送结束信号

读出过程:

1.发送启动信号

2.发送设备地址(注意这里是伪写  和写入过程前两个步骤一样  注意仔细看EEPROM文档)

3.发送EEPROM片内地址

4.发送启动信号(读数据需要启动两次)

5.发送设备地址(这里和读过程不同的是r/w位  前面是低电平  这里是高电平)

6.读取数据

7.发送结束信号

6.发送结束信号

当然单片机向总线写数据完成后,要注意检测应答信号,读取数据后,单片机应向设备发送,非应答信号或者叫应答非信号。

 /*=================================================================================
功能:通过i2c总线向EEPROM中写入数据 并读回数据 验证I2C总线通信 实现记录开机次数
电路图:P2.0接SCL
P2.1接SDA
P1口接led发光二极管
P2.3接 数码管位选信号
P2.2接段选信号
P0口接数码管
注意理解设备发出的应答
和单片机发出的非应答或者叫应答非
两者使得通信完整 只不过方向不一样
====================================================================================*/
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define TIME_SET 50000 /* 一次定时时间 */ sbit scl = P2^;
sbit sda = P2^; bit ack; uchar code table[] = {
0x3F,0x06,0x5b,0x4f,0x66,0x6d,
0x7d,0x07,0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x00
}; //led亮的数字 sbit wela = P2^;//位选信号
sbit dula = P2^;//段选
uchar times; void start(); /* 开始信号 */
void stop(); /* 结束信号 */
void write(uchar byte); /* 向EEPROM中写入一个字节 */
void delay(uchar time_delay); /* 延时函数 */
void write_address(uchar byte, uchar address); /* 根据地址向EEPROM中写入数据 */
uchar read_address(uchar address); /* 从指定地址读出数据 */
void no_ack(); /* 发送一个非应答信号 */
void display(uchar num_display); /* 显示开机次数 */
void init(); void main()
{
init();
times = read_address(0x50);
times += ;
write_address(times, 0x50);
display(times);
while();
}
/*==========================
功能:发送启动信号
输入:无
输出:启动信号 SDA负跳变
============================*/
void start()
{
sda = ;
// _nop_(); /* ? */
scl = ;
delay();
sda = ;
delay();
scl = ; /* scl为什么要拉低 */
delay(); /* ? */
}
/*==========================
功能:发送结束信号
输入:无
输出:启动信号 SDA正跳变
============================*/
void stop()
{
sda = ;
_nop_();
scl = ;
delay();
sda = ;
delay();
}
/*==============================================
功能:延时函数 time_delay = 10 延时大约0.5MS
输入:延时时间
输出:延时
================================================*/
void delay(uchar time_delay)
{
uchar i,j;
for(i = time_delay; i > ; i--)
for(j = time_delay; j > ; j --)
{}
}
/*=====================================
功能:向数据线上写一个字节 先写高位
输入:待写字节
输出:写到数据总线上
=======================================*/
void write(uchar byte)
{
uchar i = ; for(; i < ; i ++)
{
if((byte << i) & 0x80)
sda=;
else
sda = ;
delay(); /* 为啥要延时 */
scl = ;
delay();
scl = ;
}
delay(); sda = ;
delay();
scl = ;
delay();
if(sda == )
ack = ;
else
ack = ; scl = ;
} /*=========================================
功能:向指定地址写入一个字节数据
输入:address写入地址,byte写入字节数据
输出:无
===========================================*/
void write_address(uchar byte, uchar address)
{
start();
delay();
write(0xae); /* 写入设备地址 */
delay();
write(address);
delay();
write(byte); delay(); stop();
delay(); /* 延时很重要!!??? */
}
/*==========================
功能:从指定地址读出数据
输入:数据地址
输出:指定地址的数据
============================*/
uchar read_address(uchar address)
{
uchar i;
uchar result = ;
start(); write(0xae); /* 写入设备地址 */ write(address); start(); /* 第二次设置开始信号 */ write(0xaf); sda = ; for(i = ; i < ; i ++) /* 读出数据 */
{
scl = ;
delay();
scl = ;
delay();
result <<= ; /* result <<= 1? */
if(sda == )
result = result + ; delay();
}
scl = ; /* 为啥要拉低 */
delay(); no_ack(); /* 发送非应答信号 */ stop();
return result;
}
/*=======================
功能:初始化变量
输入:无
输出:初始化后的变量
========================*/
void init()
{
ack = ;
scl = ;
sda = ; times = ;
EA = ;
ET0 = ;
TH0 = ( - TIME_SET) / ;
TL0 = ( - TIME_SET) % ;
TR0 = ;
}
/*==========================
功能:发送一个非应答信号
输入:无
输出:非应答信号
============================*/
void no_ack()
{
sda = ;
delay();
scl = ;
delay();
scl= ;
delay();
}
/*======================
功能:定时器中断函数
输入:定时器0中断
输出:刷新数码管显示
========================*/
void timer0() interrupt
{
TH0 = ( - TIME_SET) / ;
TL0 = ( - TIME_SET) % ;
display(times);
}
/*==========================
功能:数码管显示开机次数
输入:开机次数
输出:数码管显示开机次数
============================*/
void display(uchar num_display)
{
uchar ge,shi;//个位和十位 ge = num_display % ;
shi = num_display / ;
//消影
P0 = 0xff;
wela = ;
wela = ;
P0 = ;
dula = ;
dula = ; //显示十位数字
P0 = 0xfe;
wela = ;
wela = ;
P0 = table[shi];
dula = ;
dula = ;
delay(); //消影
P0 = 0xff;
wela = ;
wela = ;
P0 = ;
dula = ;
dula = ; //显示个位数字
P0 = 0xfd;
wela = ;
wela = ;
P0 = table[ge];
dula = ;
dula = ;
delay();
}

通过I2C总线向EEPROM中写入数据,记录开机次数的更多相关文章

  1. 向post请求中写入数据,最终保存在了HttpWebRequest.Params中

    一.向post请求中写入数据,最终保存在了HttpWebRequest.Params中: 1)如果存入的是IDictionary类型的字符串变量,如:“username=administrator”, ...

  2. PHP连接sqlserver的两种方法,向sqlserver2000中写入数据,中文乱码

    项目环境是php5.3.28 项目用的ThinkPHP3.2.3  已经mysql5.5数据库,要和另一个项目对接,需要连接sqlsever2000数据库进行一些操作. 第一种用php自带扩展连接数据 ...

  3. 【转】从QDataStream向QByteArray中写入数据时的注意点(QT)

    最近发现从QDataStream向QByteArray中写入数据常常是写不进去的,通过查看QT的源码: QDataStream &operator>>(QDataStream &a ...

  4. POI往word模板中写入数据

    转: POI往word模板中写入数据 2018年03月24日 16:00:22 乄阿斗同學 阅读数:2977  版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn ...

  5. Verilog利用$fdisplay命令往文件中写入数据

    最近在做的事情是,用FPGA生成一些满足特定分布的序列.因此为了验证我生成的序列是否拥有预期的性质,我需要将生成的数据提取出来并且放到MATLAB中做数据分析. 但是网上的程序很乱,表示看不懂==其实 ...

  6. 复制excel表,往excel表中写入数据

    import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import jav ...

  7. POI向Excel中写入数据及追加数据

    import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFRow; import ...

  8. 计算机二级-C语言-程序填空题-190117记录-对文件的处理,复制两个文件,往新文件中写入数据。

    //给定程序的功能是,调用函数fun将指定源文件中的内容赋值到指定目标文件中,复制成功时函数返回1,失败时返回0,把复制的内容输出到终端屏幕.主函数中源文件名放在变量sfname中,目标文件名放在变量 ...

  9. lua向文件中写入数据,进行记录

    function readfile(path) local file = io.open(path, "r") if file then local content = file: ...

随机推荐

  1. React Editor 应用编辑器(1) - 拖拽功能剖析

    这是可视化编辑器 Gaea-Editor 的第一篇连载分析文章,希望我能在有限的篇幅讲清楚制作这个网页编辑器的动机,以及可能带来的美好使用前景(画大饼).它会具有如下几个特征: 运行在网页 文档流布局 ...

  2. 对于 NSLayoutConstraint 不执行动画的处理:

    在开发中  我们有时候需要改变某个空间的约束条件 也就是更改NSLayoutConstraint的值  (比如说我想在键盘顶部增加一个工具栏 让工具栏随着键盘的位置变化而变化  有一个动画效果)但是发 ...

  3. 计算机程序和C++语言简介

    C++程序设计 第一章 计算机程序和C++语言简介 1.计算机是一台能够存储并处理数据的电子设备,包含硬件和软件两部分. 2.计算机硬件由: 1)中央处理单元(Central Processing U ...

  4. C语言枚举

    应该是 各种语言都支持枚举的. 所以这个 之前在我们java案例里面就出现过的季节代码再次出现了. 枚举帮我们起到一个变量值,在某一范围内的限定,用来避免一些非法值的键入. 值得注意的是,这里面的枚举 ...

  5. WebSocket实时异步通信

    WebSocket实时异步通信 [一]WebSocket简介 WebSocket是HTML5推出一个协议规范,用来B/S模式中服务器端和客户端之间进行实时异步通信. 众所周知,传统的HTTP协议中,服 ...

  6. VSPackge插件系列:简单文本编辑器的实现

    相比其它开发环境,VS的好用就不用多说了,尽管VS很人性化,但是针对具体的我们想实现的功能时,会力不从心,也许会有很多现成的插件,但是作为一名程序员,我还是喜欢自己去写一些东西,因为这样能随心所欲的想 ...

  7. Eclipse中的TreeViewer类和ListViewer类

    TreeViewer和TableViewer在使用上还是有很多相似之处.TreeViewer中冶有TableViewer中的过滤器和排序器.具体使用看TableViewer中的使用. 和Table有J ...

  8. 解决了jQuery插件未能导入到项目之中

    Loading jQuery plugins from third-party scripts <script src="js/jquery.js" type="t ...

  9. ###《High-level event recognition in unconstrained videos》

    Author: Yu-Gang Jiang, Shih-Fu Chang 事件检测的目标就是自动识别给定视频序列中的感兴趣事件.进行视频事件检测通常很困难,特别是在网络中非限制的视频.在非限制情况下, ...

  10. iOS开发——手机号,密码,邮箱,身份证号,中文判断

    目前这些方面的判断主要是用了正则表达式 手机号的判断,目前主要是长度.均是数字,支持的号段由于第三方通讯比如京东通讯,小米通讯等支持的号段挺多, 有171,170,135,147等等,所以号段限制简单 ...