[51单片机] EEPROM 24c02 [I2C代码封装-保存实现流水灯]

这里把EEPROM 24c02封装起来,今后可以直接调用,其连线方式为:SDA-P2.1;SCL-P2.0;WP-VCC

>_<:i2c.c


  1 /*-----------------------------------------------
2 名称:IIC协议
3 内容:函数是采用软件延时的方法产生SCL脉冲,固对高晶振频率要作 一定的修改....(本例是1us机器
4 周期,即晶振频率要小于12MHZ)
5 ------------------------------------------------*/
6 #include "i2c.h"
7 #define _Nop() _nop_() //定义空指令
8 bit ack; //应答标志位
9 sbit SDA=P2^1;
10 sbit SCL=P2^0;
11 /*------------------------------------------------
12 uS延时函数,含有输入参数 unsigned char t,无返回值
13 unsigned char 是定义无符号字符变量,其值的范围是
14 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
15 长度如下 T=tx2+5 uS
16 ------------------------------------------------*/
17 void DelayUs2x(unsigned char t)
18 {
19 while(--t);
20 }
21 /*------------------------------------------------
22 mS延时函数,含有输入参数 unsigned char t,无返回值
23 unsigned char 是定义无符号字符变量,其值的范围是
24 0~255 这里使用晶振12M,精确延时请使用汇编
25 ------------------------------------------------*/
26 void DelayMs(unsigned char t)
27 {
28 while(t--)
29 {
30 //大致延时1mS
31 DelayUs2x(245);
32 DelayUs2x(245);
33 }
34 }
35 /*------------------------------------------------
36 启动总线
37 ------------------------------------------------*/
38 void Start_I2c()
39 {
40 SDA=1; //发送起始条件的数据信号
41 _Nop();
42 SCL=1;
43 _Nop(); //起始条件建立时间大于4.7us,延时
44 _Nop();
45 _Nop();
46 _Nop();
47 _Nop();
48 SDA=0; //发送起始信号
49 _Nop(); //起始条件锁定时间大于4μ
50 _Nop();
51 _Nop();
52 _Nop();
53 _Nop();
54 SCL=0; //钳住I2C总线,准备发送或接收数据
55 _Nop();
56 _Nop();
57 }
58 /*------------------------------------------------
59 结束总线
60 ------------------------------------------------*/
61 void Stop_I2c()
62 {
63 SDA=0; //发送结束条件的数据信号
64 _Nop(); //发送结束条件的时钟信号
65 SCL=1; //结束条件建立时间大于4μ
66 _Nop();
67 _Nop();
68 _Nop();
69 _Nop();
70 _Nop();
71 SDA=1; //发送I2C总线结束信号
72 _Nop();
73 _Nop();
74 _Nop();
75 _Nop();
76 }
77 /*----------------------------------------------------------------
78 字节数据传送函数
79 函数原型: void SendByte(unsigned char c);
80 功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
81 此状态位进行操作.(不应答或非应答都使ack=0 假)
82 发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
83 ------------------------------------------------------------------*/
84 void SendByte(unsigned char c)
85 {
86 unsigned char BitCnt;
87 for(BitCnt=0;BitCnt<8;BitCnt++) //要传送的数据长度为8位
88 {
89 if((c<<BitCnt)&0x80)SDA=1; //判断发送位
90 else SDA=0;
91 _Nop();
92 SCL=1; //置时钟线为高,通知被控器开始接收数据位
93 _Nop();
94 _Nop(); //保证时钟高电平周期大于4μ
95 _Nop();
96 _Nop();
97 _Nop();
98 SCL=0;
99 }
100 _Nop();
101 _Nop();
102 SDA=1; //8位发送完后释放数据线,准备接收应答位
103 _Nop();
104 _Nop();
105 SCL=1;
106 _Nop();
107 _Nop();
108 _Nop();
109 if(SDA==1)ack=0;
110 else ack=1; //判断是否接收到应答信号
111 SCL=0;
112 _Nop();
113 _Nop();
114 }
115 /*----------------------------------------------------------------
116 字节数据传送函数
117 函数原型: unsigned char RcvByte();
118 功能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),
119 发完后请用应答函数。
120 ------------------------------------------------------------------*/
121 unsigned char RcvByte()
122 {
123 unsigned char retc;
124 unsigned char BitCnt;
125
126 retc=0;
127 SDA=1; //置数据线为输入方式
128 for(BitCnt=0;BitCnt<8;BitCnt++)
129 {
130 _Nop();
131 SCL=0; //置时钟线为低,准备接收数据位
132 _Nop();
133 _Nop(); //时钟低电平周期大于4.7us
134 _Nop();
135 _Nop();
136 _Nop();
137 SCL=1; //置时钟线为高使数据线上数据有效
138 _Nop();
139 _Nop();
140 retc=retc<<1;
141 if(SDA==1)retc=retc+1; //读数据位,接收的数据位放入retc中
142 _Nop();
143 _Nop();
144 }
145 SCL=0;
146 _Nop();
147 _Nop();
148 return(retc);
149 }
150 /*----------------------------------------------------------------
151 应答子函数
152 原型: void Ack_I2c(void);
153 ----------------------------------------------------------------*/
154 void Ack_I2c(void)
155 {
156 SDA=0;
157 _Nop();
158 _Nop();
159 _Nop();
160 SCL=1;
161 _Nop();
162 _Nop(); //时钟低电平周期大于4μ
163 _Nop();
164 _Nop();
165 _Nop();
166 SCL=0; //清时钟线,钳住I2C总线以便继续接收
167 _Nop();
168 _Nop();
169 }
170 /*----------------------------------------------------------------
171 非应答子函数
172 原型: void NoAck_I2c(void);
173 ----------------------------------------------------------------*/
174 void NoAck_I2c(void)
175 {
176 SDA=1;
177 _Nop();
178 _Nop();
179 _Nop();
180 SCL=1;
181 _Nop();
182 _Nop(); //时钟低电平周期大于4μ
183 _Nop();
184 _Nop();
185 _Nop();
186 SCL=0; //清时钟线,钳住I2C总线以便继续接收
187 _Nop();
188 _Nop();
189 }
190 /*----------------------------------------------------------------
191 向无子地址器件发送字节数据函数
192 函数原型: bit ISendByte(unsigned char sla,ucahr c);
193 功能: 从启动总线到发送地址,数据,结束总线的全过程,从器件地址sla.
194 如果返回1表示操作成功,否则操作有误。
195 注意: 使用前必须已结束总线。
196 ----------------------------------------------------------------*/
197 /*bit ISendByte(unsigned char sla,unsigned char c)
198 {
199 Start_I2c(); //启动总线
200 SendByte(sla); //发送器件地址
201 if(ack==0)return(0);
202 SendByte(c); //发送数据
203 if(ack==0)return(0);
204 Stop_I2c(); //结束总线
205 return(1);
206 }
207 */
208 /*----------------------------------------------------------------
209 向有子地址器件发送多字节数据函数
210 函数原型: bit ISendStr(unsigned char sla,unsigned char suba,ucahr *s,unsigned char no);
211 功能: 从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件
212 地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。
213 如果返回1表示操作成功,否则操作有误。
214 注意: 使用前必须已结束总线。
215 ----------------------------------------------------------------*/
216 bit ISendStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no)
217 {
218 unsigned char i;
219 for(i=0;i<no;i++)
220 {
221 Start_I2c(); //启动总线
222 SendByte(sla); //发送器件地址
223 if(ack==0)return(0);
224 SendByte(suba); //发送器件子地址
225 if(ack==0)return(0);
226
227 SendByte(*s); //发送数据
228
229 if(ack==0)return(0);
230 Stop_I2c(); //结束总线
231 DelayMs(2); //必须延时等待芯片内部自动处理数据完毕
232 s++;
233 suba++;
234 }
235 return(1);
236 }
237
238 /*----------------------------------------------------------------
239 向无子地址器件读字节数据函数
240 函数原型: bit IRcvByte(unsigned char sla,ucahr *c);
241 功能: 从启动总线到发送地址,读数据,结束总线的全过程,从器件地
242 址sla,返回值在c.
243 如果返回1表示操作成功,否则操作有误。
244 注意: 使用前必须已结束总线。
245 ----------------------------------------------------------------*/
246 /*bit IRcvByte(unsigned char sla,unsigned char *c)
247 {
248 Start_I2c(); //启动总线
249 SendByte(sla+1); //发送器件地址
250 if(ack==0)return(0);
251 *c=RcvByte(); //读取数据
252 NoAck_I2c(); //发送非就答位
253 Stop_I2c(); //结束总线
254 return(1);
255 }
256 */
257 /*----------------------------------------------------------------
258 向有子地址器件读取多字节数据函数
259 函数原型: bit ISendStr(unsigned char sla,unsigned char suba,ucahr *s,unsigned char no);
260 功能: 从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件
261 地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。
262 如果返回1表示操作成功,否则操作有误。
263 注意: 使用前必须已结束总线。
264 ----------------------------------------------------------------*/
265 bit IRcvStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no)
266 {
267 unsigned char i;
268
269 Start_I2c(); //启动总线
270 SendByte(sla); //发送器件地址
271 if(ack==0)return(0);
272 SendByte(suba); //发送器件子地址
273 if(ack==0)return(0);
274
275 Start_I2c();
276 SendByte(sla+1);
277 if(ack==0)return(0);
278
279 for(i=0;i<no-1;i++)
280 {
281 *s=RcvByte(); //发送数据
282 Ack_I2c(); //发送就答位
283 s++;
284 }
285 *s=RcvByte();
286 NoAck_I2c(); //发送非应位
287 Stop_I2c(); //结束总线
288 return(1);
289 }

>_<:i2c.h


 1 /*-----------------------------------------------
2 名称:IIC协议 头文件
3 ------------------------------------------------*/
4 #ifndef __I2C_H__
5 #define __I2C_H__
6 #include <reg52.h> //头文件的包含
7 #include <intrins.h>
8 #define _Nop() _nop_() //定义空指令
9 /*-----------------------------------------------
10 uS延时函数,含有输入参数 unsigned char t,无返回值
11 unsigned char 是定义无符号字符变量,其值的范围是
12 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
13 长度如下 T=tx2+5 uS
14 ------------------------------------------------*/
15 void DelayUs2x(unsigned char t);
16 /*------------------------------------------------
17 mS延时函数,含有输入参数 unsigned char t,无返回值
18 unsigned char 是定义无符号字符变量,其值的范围是
19 0~255 这里使用晶振12M,精确延时请使用汇编
20 ------------------------------------------------*/
21 void DelayMs(unsigned char t);
22 /*------------------------------------------------
23 启动总线
24 ------------------------------------------------*/
25 void Start_I2c();
26 /*------------------------------------------------
27 结束总线
28 ------------------------------------------------*/
29 void Stop_I2c();
30 /*----------------------------------------------------------------
31 字节数据传送函数
32 函数原型: void SendByte(unsigned char c);
33 功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
34 此状态位进行操作.(不应答或非应答都使ack=0 假)
35 发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
36 ------------------------------------------------------------------*/
37 void SendByte(unsigned char c);
38 /*----------------------------------------------------------------
39 字节数据传送函数
40 函数原型: unsigned char RcvByte();
41 功能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),
42 发完后请用应答函数。
43 ------------------------------------------------------------------*/
44 unsigned char RcvByte();
45 /*----------------------------------------------------------------
46 应答子函数
47 原型: void Ack_I2c(void);
48 ----------------------------------------------------------------*/
49 void Ack_I2c(void);
50 /*----------------------------------------------------------------
51 非应答子函数
52 原型: void NoAck_I2c(void);
53 ----------------------------------------------------------------*/
54 void NoAck_I2c(void);
55 /*----------------------------------------------------------------
56 向无子地址器件发送字节数据函数
57 函数原型: bit ISendByte(unsigned char sla,ucahr c);
58 功能: 从启动总线到发送地址,数据,结束总线的全过程,从器件地址sla.
59 如果返回1表示操作成功,否则操作有误。
60 注意: 使用前必须已结束总线。
61 ----------------------------------------------------------------*/
62 bit ISendByte(unsigned char sla,unsigned char c);
63
64 /*----------------------------------------------------------------
65 向有子地址器件发送多字节数据函数
66 函数原型: bit ISendStr(unsigned char sla,unsigned char suba,ucahr *s,unsigned char no);
67 功能: 从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件
68 地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。
69 如果返回1表示操作成功,否则操作有误。
70 注意: 使用前必须已结束总线。
71 ----------------------------------------------------------------*/
72 bit ISendStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no);
73 /*----------------------------------------------------------------
74 向无子地址器件读字节数据函数
75 函数原型: bit IRcvByte(unsigned char sla,ucahr *c);
76 功能: 从启动总线到发送地址,读数据,结束总线的全过程,从器件地
77 址sla,返回值在c.
78 如果返回1表示操作成功,否则操作有误。
79 注意: 使用前必须已结束总线。
80 ----------------------------------------------------------------*/
81 bit IRcvByte(unsigned char sla,unsigned char *c);
82 /*----------------------------------------------------------------
83 向有子地址器件读取多字节数据函数
84 函数原型: bit ISendStr(unsigned char sla,unsigned char suba,ucahr *s,unsigned char no);
85 功能: 从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件
86 地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。
87 如果返回1表示操作成功,否则操作有误。
88 注意: 使用前必须已结束总线。
89 ----------------------------------------------------------------*/
90 bit IRcvStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no);
91 #endif

>_<:下面是main函数中如何调用封装好的函数来实现流水灯的效果的:
>_<:流水灯8个的连线这里用的是P1


 1 /*-----------------------------------------------
2 名称:IIC协议 24c02存储花样灯程序
3 内容:将表格内容写入24c02,然后批量删除这些数据,
4 并从24c02中读取数据并显示
5 ------------------------------------------------*/
6 #include <reg52.h>
7 #include "i2c.h"
8 /*------------------------------------------------
9 花样灯表格
10 ------------------------------------------------*/
11 unsigned char dat[]={0x7f,0xbf,0xdf,0xef,
12 0xf7,0xfb,0xfd,0xfe,
13 0xff,0xff,0x00,0x00,
14 0x55,0x55,0xaa,0xaa
15 };//ram允许情况可以无限添加
16 /*------------------------------------------------
17 主函数
18 ------------------------------------------------*/
19 main()
20 {
21 //bit flag;
22 unsigned char i;
23 ISendStr(0xae,80,dat,16); //写入24c02
24 DelayMs(1); //写入后必须延时等待24c02内部
25 //烧录数据处理完毕方可继续其他操作
26 for(i=0;i<16;i++) //清除数据
27 dat[i]=0;
28 IRcvStr(0xae,80,dat,16); //从24c02读出数据
29 while(1)
30 {
31 for(i=0;i<16;i++) //查表
32 {
33 DelayMs(200);
34 P1=dat[i];
35 }
36 }
37 }

[51单片机] EEPROM 24c02 [I2C代码封装-保存实现流水灯],布布扣,bubuko.com

时间: 2024-10-09 20:49:06

[51单片机] EEPROM 24c02 [I2C代码封装-保存实现流水灯]的相关文章

[51单片机] EEPROM 24c02 + 数码管 + 中断 [统计开机次数]

>_<:24c02的SCL连P2.0;SDA连P2.1;WP接GND;P0接8位数码管的8针;P2.2连段码;P2.3连位码; >_<:delay.c 1 #include "delay.h" 2 /*------------------------------------------------ 3 uS延时函数,含有输入参数 unsigned char t,无返回值 4 unsigned char 是定义无符号字符变量,其值的范围是 5 0~255 这里使用

单片机(simple chip microcomputer)概论、51单片机、MCS-51单片机、STM32、ARM

catalogue 1. 单片机概论 2. 51单片机 3. MCS-51单片机 4. QX-MINI51开发板(STC89C52芯片) 5. STM32单片机 6. stm32f103zet6开发板实验 1. 单片机概论 0x1: 仿真器 单片机应用系统的软硬件调试需要专门的开发工具,称为"单片机开发系统"或"仿真机".常用的开发方式是把开发系统(例如PC)中的CPU和RAM暂时出借给用户系统,利用开发系统对用户系统的软硬件进行调试(又称仿真),然后将调试好的程序

51单片机实现对24C02进行页写、顺序读取并显示验证

源:51单片机实现对24C02进行页写.顺序读取并显示验证 //************************************************************************************* //**程序名称:51单片机实现对24C02进行页写.顺序读取并显示验证 //**编写人:**** //**修改人:**** //**程序目的:熟悉I2C总线协议,实现51模拟I2C时序和24C02通信 //**功能描述:51单片机将8个字节数据写入24C02的一

[51单片机] HC-SR04超声波测距仪 基础代码

>_<:超声波测距仪模块: >_<:51单片机,11.0592MHz晶振,将采集数据发送到串口的基础例子: >_<:代码: 1 /***********************************************************************************************************/ 2 //HC-SR04 超声波测距模块 DEMO 程序 3 //晶振:11.0592 4 //接线:模块TRIG接 P1.2

[原创]基于51单片机的红外遥控课程设计

[注]: 一眨眼,大学接近尾声,具有找工作需要,所以把大学做的电子设计“劣作”放上来.希望考研失意,还能赶上“好工作”的春招班车.如果大伙有什么工作推荐也可以联系我哦,因为一年考研少接触了这方面,所以难免有些生疏.但请相信我!给我机会我会很认真学的! 邮箱:[email protected] 转载请注明出处呀! 基于51单片机的红外遥控课程设计 目录 第一章 设计简介... 3 第二章 系统方案... 3 一.设计方案对比... 3 二.方案设计... 4 第三章 硬件设计... 5 一.红外遥

51单片机程序和变量存储位置

一.概念理清 使用环境: keil2,生成的代码大小如下,data保存于内部RAM中,xdata保存于外部扩展SRAM中,code保存于FLASH中. 51单片机涉及的存储介质: RAM: 内部RAM,每种51单片机都应该有,共256字节.大小固定 SRAM:内存,掉电消失,外部扩展RAM,比内部RAM稍慢,作用一样,用于定义变量.大小要查单片机具体手册.最大0xFFFF FLASH:(保存程序代码,只能按扇区更改).大小要查单片机具体手册. EEPROM:(保存掉电保存的数据,flash中也可

51单片机课程设计:基于DS18B20的温度报警器

51单片机课程设计:基于DS18B20的温度报警器 本程序用于读取DS18B20温度,同时具备报警功能,工程分为3个文件,main.c.temp.c.temp.h,经本人修改部分代码,适用于吉林农业大学51开发板,其他朋友亦可移植到其他型号开发板.工程文件在文章最下方. 1.main.c文件 /*********************************说明****************************************** 本程序用于读取温度检测模块DS18B20数值,并

51单片机课程设计:基于MQ-3的酒精浓度报警器

51单片机课程设计:基于MQ-3的酒精浓度报警器 本程序用于将MQ-3上读取到的模拟信号转换为对应的数字信号,经51单片机处理后,在数码管显示,同时具有报警功能,当检测值高于预警值,蜂鸣器报警.除了可以检测MQ-3酒精浓度模块的AD值,也适用于MQ系列的其他模块,原理基本都相同,都是将读取到的AD值转换为数字信号,程序修改后,如果接线方法正确,可以在吉林农业大学51开发板上完美运行,相关工程文件见最下方附件. /*************************************说明***

Windows 通用应用尝试开发 “51单片机汇编”总结

一.前言 终于完成windows通用应用“51单片机汇编”,半年前开始玩WindowsPhone开发的第一个真正意义上的App(还很多缺点=_=).开发从1月中旬考完试到今天,期间实习了半个月,玩了几天,算起来基本弄了3个多星期吧.不多说,总结总结. 二.开发数据准备 应用中主要的数据是单片机的汇编指令,我主要用XML文件来储存数据,没有使用SQLLite数据库,数据格式如下图: xml文件的数据是我手输入的,所以这是比较烦的.(可能有更简洁的办法获取数据). 而xml文件每个每个节点对应实例,