[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 }
转载于:https://www.cnblogs.com/zjutlitao/p/3704072.html
[51单片机] EEPROM 24c02 [I2C代码封装-保存实现流水灯]相关推荐
- 基于51单片机的51单片机的LED彩灯霓虹灯控制器(心形流水灯)设计
基于51单片机的51单片机的LED彩灯霓虹灯控制器(心形流水灯)设计 必看!!视频讲解 基于51单片机的LED彩灯霓虹灯心形流水灯设计 这里写目录标题 1 开发环境 2 功能说明介绍 3 仿真图 4 ...
- 【51单片机入门】点亮多个LED流水灯
[51单片机&入门]点亮多个LED流水灯 实验环境 功能实现 PCB原理图 代码 要点 仿真 代码 实验环境 Keil C51 Proteus 8.9 功能实现 LED流水灯依次从右向左亮起, ...
- 51单片机基础——串口通信发送字符ab控制流水灯
/* 当串口调试助手发送a时执行5ms流水灯功能, 当串口调试助手发送b时执行50ms流水灯功能 */#include <reg52.h> #include<intrins.h> ...
- 51单片机运用数组和if条件语句完成流水灯和蜂鸣器同步
文章目录 前言 一.蜂鸣器 二.使用步骤 1.引入库 2.读入数据 总结 一.蜂鸣器 #include "reg52.h"sbit FM=P2^5; main(){ FM=1 // ...
- 51单片机 定时器0中断实现1秒LED流水灯
使用定时器0中断实现LED1秒的流水灯 #include <reg52.h> typedef unsigned int u16; typedef unsigned char u8; u8 ...
- 中移4G模块-ML302-OpenCpu开发-51单片机串口转I2C
B站:https://space.bilibili.com/309103931 中移4G模块-ML302专栏:https://blog.csdn.net/qq_33259323/category_10 ...
- GC9A01-TFT屏幕驱动(整理有stm32/51单片机/arduino等驱动代码)
GC9A01-TFT屏幕驱动 & 整理有stm32/51单片机/arduino等驱动代码 前言 关于GC9A01 stm32驱动 引脚接线 代码移植 文件复制 端口修改 显示函数 中文汉字数组 ...
- ST7735-TFT屏幕驱动(整理有stm32/51单片机/arduino等驱动代码)
ST7735-TFT屏幕驱动 & 整理有stm32/51单片机/arduino等驱动代码 前言 关于ST7735 stm32驱动 引脚接线 代码移植 文件复制 端口修改 显示函数 中文汉字数组 ...
- 【单片机】C52单片机上用两个以上按键实现流水灯控制
[单片机]C52单片机上用两个以上按键实现流水灯控制 一.proteus电路图设计 二.程序控制代码 三.结果测试用例 本文主要介绍在C52单片机中断中,如何使用两个以上的外部按键实现流水灯控制! 在 ...
最新文章
- How Does Maven Work
- 数据绑定控件之DataList
- knockout的使用
- 大型网站架构 - 1.架构的演变过程
- 共享内存简介及docker容器的shm设置与修改
- Java 打印目录结构
- 组内分享slide 【about 3D】
- 【Computer Organization笔记15】清华计组大作业布置:奋战二十天,做台计算机!
- tensorflow之数据集
- 电商系统商品库的基本功能设计与实现
- 华为认证Datacom和Routing Switching方向的优势
- 奇点云数据中台技术汇(九)| 如何建设数据安全体系?
- ajax怎么传递list类型参数到后端,ajax传递给后台数组参数方式
- 红外真空离心浓缩仪ZLNS-II
- php完美导出word,php导出生成word的方法
- mysql performance tuning_Performance Tuning MySQL
- Elasticsearch教程---高亮搜索(十二)
- 北大青鸟 ASP.NET(C#) 视频 全32集
- 第一阶冲刺段结束后,对于其他组作品的建议
- Chrome浏览器开发新截图工具,安全浏览器截图方法
热门文章
- [Everyday Mathematics]20150103
- 使用 AppleScript 在 Chrome 中查看当前 Safari 打开的网页
- CSS分别设置Input样式(按input类型)
- 消息 245,级别 16,状态 1,第 1 行 在将 varchar 值 '2,8' 转换成数据类型 int 时失败。...
- JavaScript设计模式之发布-订阅模式(观察者模式)-Part1
- Node.js express 入门示例1
- 企业shell面试题:获取51CTO博客列表按时间倒序排序
- Boke宝贝 - 免费提供图片存储空间、计数器、留言板
- xUtils网络超时设置configCurrentHttpCacheExpiry和SoTimeout和connectionTimeout的区别
- KMP(字符串匹配)算法 O(m+n)