没买板子之前,用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. 网页js生成当前年月日 星期

    只需将下面代码插入需要显示日期的地方即可 <div style="color: brown; font-size: 10px;">今天是: <script lan ...

  2. 不规则三角网(TIN)(转)

    来自:http://blog.csdn.net/kikitamoon/article/details/8217641 Ⅰ 数字高程模型(DEM) 地球表面高低起伏,呈现一种连续变化的曲面,这种曲面无法 ...

  3. DHCP 服务器

    简介: DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)是一个局域网的网络协议,使用UDP协议工作,主要用途:给内部网络或网络服务供应商自动分配 I ...

  4. IP地址子网掩码、主机数、子网掩码及主机段的算法

    http://wenku.baidu.com/view/2aa76cc6aa00b52acfc7ca6f.html很容易理解.

  5. ASP怎样获得代码中第一张图片地址

    '把pattern 又修改了下 'code要检测的代码 'http://www.knowsky.com/asp.asp 'leixing html 或者ubb 'nopic 代码没有图片时默认值 fu ...

  6. 【自用】爬虫配置XML时拼接URL中文转Unicode问题(例如北京转成%u5317%u4EAC)

    <var-def name="regionUnicode"> <while condition="true" index="s&qu ...

  7. 取A表数据,关联B表任意一条数据

     表A=================== AID, AName 1 jack 2 mary 3 lily 表B================== BID, AID, BName 1 1 aaa ...

  8. [jquery]基础篇--this与$this区别

    参考: http://www.cnblogs.com/hannover/p/4109779.html 1.JQuery this和$(this)的区别 相信很多刚接触JQuery的人,很多都会对$(t ...

  9. C++ 书籍

    C++ 书籍 一.<深度探索C++对象模型/Inside the C++ Object Model> 二.

  10. 为UITextView添加与UITextField一样的边框——UITextField默认边框颜色、宽度、圆角

    我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3789052.html,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体验 ...