名称:IIC协议 EEPROM24c02 通过串口通信存数读取数据

内容:此程序用于检測EEPROM性能,測试方法例如以下:写入24c02一个数据,然后在内存中改变这些数据。 掉电后主内存将失去这些信息,然后从24c02中调入这些数据。看是否与写入的同样。

电脑通过串口发送一个十六进制的数据到单片机,存储进24c02,要求断电重新启动后在数码管上显示上一次发送的数据。

(本例是1us机器周期,即晶振频率要小于12MHZ)

  1. #include <reg52.h> //头文件的包括
  2. #include <intrins.h>
  3.  
  4. #define _Nop() _nop_() //定义空指令
  5. #define DataPort P0
  6. sbit WEI=P2^7;
  7. sbit DUAN=P2^6;
  8. // 常,变量定义区
  9. unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
  10. 0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x00};// 显示段码值0~F,-,全空
  11. unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别相应相应的数码管点亮,即位码
  12.  
  13. unsigned char TempData[8];
  14.  
  15. sbit SDA=P2^1; //模拟I2C数据传送位
  16. sbit SCL=P2^0; //模拟I2C时钟控制位
  17.  
  18. bit ack; //应答标志位
  19.  
  20. unsigned char res;
  21. void DelayUs2x(unsigned char t);//函数声明
  22. void DelayMs(unsigned char t);
  23.  
  24. void Delay(unsigned int t)
  25. {
  26. while(t--);
  27. }
  28.  
  29. void InitUART(void)
  30. {
  31. SCON=0x50;
  32. TMOD|=0x20;
  33. TH1=0xFD;
  34. TR1=1;
  35. EA=1;
  36. }
  37.  
  38. void DelayUs2x(unsigned char t)
  39. {
  40. while(--t);
  41. }
  42.  
  43. void DelayMs(unsigned char t)
  44. {
  45.  
  46. while(t--)
  47. {
  48. //大致延时1mS
  49. DelayUs2x(245);
  50. DelayUs2x(245);
  51. }
  52. }
  53.  
  54. void Display(unsigned char FirstBit,unsigned char Num)
  55. {
  56. unsigned char i;
  57. for(i=0;i<Num;i++)
  58. {
  59. DataPort=0; //清空数据。防止有交替重影
  60. DUAN=1; //段锁存
  61. DUAN=0;
  62.  
  63. DataPort=dofly_WeiMa[i+FirstBit]; //取位码
  64. WEI=1; //位锁存
  65. WEI=0;
  66.  
  67. DataPort=TempData[i]; //取显示数据,段码
  68. DUAN=1; //段锁存
  69. DUAN=0;
  70.  
  71. Delay(200); // 扫描间隙延时。时间太长会闪烁,
  72. //太短会造成重影
  73.  
  74. }
  75. }
  76.  
  77. /*------------------------------------------------
  78. 启动总线
  79. ------------------------------------------------*/
  80. void Start_I2c()
  81. {
  82. SDA=1; //发送起始条件的数据信号
  83. _Nop();
  84. SCL=1;
  85. _Nop(); //起始条件建立时间大于4.7us,延时
  86. _Nop();
  87. _Nop();
  88. _Nop();
  89. _Nop();
  90. SDA=0; //发送起始信号
  91. _Nop(); //起始条件锁定时间大于4μ
  92. _Nop();
  93. _Nop();
  94. _Nop();
  95. _Nop();
  96. SCL=0; //钳住I2C总线。准备发送或接收数据
  97. _Nop();
  98. _Nop();
  99. }
  100. /*------------------------------------------------
  101. 结束总线
  102. ------------------------------------------------*/
  103. void Stop_I2c()
  104. {
  105. SDA=0; //发送结束条件的数据信号
  106. _Nop(); //发送结束条件的时钟信号
  107. SCL=1; //结束条件建立时间大于4μ
  108. _Nop();
  109. _Nop();
  110. _Nop();
  111. _Nop();
  112. _Nop();
  113. SDA=1; //发送I2C总线结束信号
  114. _Nop();
  115. _Nop();
  116. _Nop();
  117. _Nop();
  118. }
  119.  
  120. void SendByte(unsigned char c)
  121. {
  122. unsigned char BitCnt;
  123.  
  124. for(BitCnt=0;BitCnt<8;BitCnt++) //要传送的数据长度为8位
  125. {
  126. if((c<<BitCnt)&0x80)SDA=1; //推断发送位
  127. else SDA=0;
  128. _Nop();
  129. SCL=1; //置时钟线为高,通知被控器開始接收数据位
  130. _Nop();
  131. _Nop(); //保证时钟高电平周期大于4μ
  132. _Nop();
  133. _Nop();
  134. _Nop();
  135. SCL=0;
  136. }
  137.  
  138. _Nop();
  139. _Nop();
  140. SDA=1; //8位发送完后释放数据线。准备接收应答位
  141. _Nop();
  142. _Nop();
  143. SCL=1;
  144. _Nop();
  145. _Nop();
  146. _Nop();
  147. if(SDA==1)ack=0;
  148. else ack=1; //推断是否接收到应答信号
  149. SCL=0;
  150. _Nop();
  151. _Nop();
  152. }
  153.  
  154. unsigned char RcvByte()
  155. {
  156. unsigned char retc;
  157. unsigned char BitCnt;
  158.  
  159. retc=0;
  160. SDA=1; //置数据线为输入方式
  161. for(BitCnt=0;BitCnt<8;BitCnt++)
  162. {
  163. _Nop();
  164. SCL=0; //置时钟线为低,准备接收数据位
  165. _Nop();
  166. _Nop(); //时钟低电平周期大于4.7us
  167. _Nop();
  168. _Nop();
  169. _Nop();
  170. SCL=1; //置时钟线为高使数据线上数据有效
  171. _Nop();
  172. _Nop();
  173. retc=retc<<1;
  174. if(SDA==1)retc=retc+1; //读数据位,接收的数据位放入retc中
  175. _Nop();
  176. _Nop();
  177. }
  178. SCL=0;
  179. _Nop();
  180. _Nop();
  181. return(retc);
  182. }
  183.  
  184. /*----------------------------------------------------------------
  185. 应答子函数
  186. 原型: void Ack_I2c(void);
  187.  
  188. ----------------------------------------------------------------*/
  189. void Ack_I2c(void)
  190. {
  191.  
  192. SDA=0;
  193. _Nop();
  194. _Nop();
  195. _Nop();
  196. SCL=1;
  197. _Nop();
  198. _Nop(); //时钟低电平周期大于4μ
  199. _Nop();
  200. _Nop();
  201. _Nop();
  202. SCL=0; //清时钟线,钳住I2C总线以便继续接收
  203. _Nop();
  204. _Nop();
  205. }
  206. /*----------------------------------------------------------------
  207. 非应答子函数
  208. 原型: void NoAck_I2c(void);
  209.  
  210. ----------------------------------------------------------------*/
  211. void NoAck_I2c(void)
  212. {
  213.  
  214. SDA=1;
  215. _Nop();
  216. _Nop();
  217. _Nop();
  218. SCL=1;
  219. _Nop();
  220. _Nop(); //时钟低电平周期大于4μ
  221. _Nop();
  222. _Nop();
  223. _Nop();
  224. SCL=0; //清时钟线。钳住I2C总线以便继续接收
  225. _Nop();
  226. _Nop();
  227. }
  228.  
  229. /*----------------------------------------------------------------
  230. 向无子地址器件发送字节数据函数
  231. 函数原型: bit ISendByte(unsigned char sla,ucahr c);
  232. 功能: 从启动总线到发送地址。数据,结束总线的全过程,从器件地址sla.
  233. 假设返回1表示操作成功,否则操作有误。
  234. 注意: 使用前必须已结束总线。
  235.  
  236. ----------------------------------------------------------------*/
  237. /*bit ISendByte(unsigned char sla,unsigned char c)
  238. {
  239. Start_I2c(); //启动总线
  240. SendByte(sla); //发送器件地址
  241. if(ack==0)return(0);
  242. SendByte(c); //发送数据
  243. if(ack==0)return(0);
  244. Stop_I2c(); //结束总线
  245. return(1);
  246. }
  247. */
  248.  
  249. /*----------------------------------------------------------------
  250. 向有子地址器件发送多字节数据函数
  251. 函数原型: bit ISendStr(unsigned char sla,unsigned char suba,ucahr *s,unsigned char no);
  252. 功能: 从启动总线到发送地址。子地址,数据,结束总线的全过程,从器件
  253. 地址sla,子地址suba。发送内容是s指向的内容,发送no个字节。
  254. 假设返回1表示操作成功。否则操作有误。
  255. 注意: 使用前必须已结束总线。
  256. ----------------------------------------------------------------*/
  257. bit ISendStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no)
  258. {
  259. unsigned char i;
  260.  
  261. Start_I2c(); //启动总线
  262. SendByte(sla); //发送器件地址
  263. if(ack==0)return(0);
  264. SendByte(suba); //发送器件子地址
  265. if(ack==0)return(0);
  266.  
  267. for(i=0;i<no;i++)
  268. {
  269. SendByte(*s); //发送数据
  270. if(ack==0)return(0);
  271. s++;
  272. }
  273. Stop_I2c(); //结束总线
  274. return(1);
  275. }
  276.  
  277. /*----------------------------------------------------------------
  278. 向无子地址器件读字节数据函数
  279. 函数原型: bit IRcvByte(unsigned char sla,ucahr *c);
  280. 功能: 从启动总线到发送地址,读数据。结束总线的全过程,从器件地
  281. 址sla,返回值在c.
  282. 假设返回1表示操作成功,否则操作有误。
  283.  
  284. 注意: 使用前必须已结束总线。
  285. ----------------------------------------------------------------*/
  286. /*bit IRcvByte(unsigned char sla,unsigned char *c)
  287. {
  288. Start_I2c(); //启动总线
  289. SendByte(sla+1); //发送器件地址
  290. if(ack==0)return(0);
  291. *c=RcvByte(); //读取数据
  292. NoAck_I2c(); //发送非就答位
  293. Stop_I2c(); //结束总线
  294. return(1);
  295. }
  296.  
  297. */
  298. /*----------------------------------------------------------------
  299. 向有子地址器件读取多字节数据函数
  300. 函数原型: bit ISendStr(unsigned char sla,unsigned char suba,ucahr *s,unsigned char no);
  301. 功能: 从启动总线到发送地址。子地址,读数据,结束总线的全过程,从器件
  302. 地址sla。子地址suba,读出的内容放入s指向的存储区。读no个字节。
  303.  
  304. 假设返回1表示操作成功,否则操作有误。
  305.  
  306. 注意: 使用前必须已结束总线。
  307.  
  308. ----------------------------------------------------------------*/
  309. bit IRcvStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no)
  310. {
  311. unsigned char i;
  312.  
  313. Start_I2c(); //启动总线
  314. SendByte(sla); //发送器件地址
  315. if(ack==0)return(0);
  316. SendByte(suba); //发送器件子地址
  317. if(ack==0)return(0);
  318.  
  319. Start_I2c();
  320. SendByte(sla+1);
  321. if(ack==0)return(0);
  322.  
  323. for(i=0;i<no-1;i++)
  324. {
  325. *s=RcvByte(); //发送数据
  326. Ack_I2c(); //发送就答位
  327. s++;
  328. }
  329. *s=RcvByte();
  330. NoAck_I2c(); //发送非应位
  331. Stop_I2c(); //结束总线
  332. return(1);
  333. }
  334. /*------------------------------------------------
  335. 主函数
  336. ------------------------------------------------*/
  337. void main()
  338. {
  339. unsigned char doflye; // 定义暂时变量
  340. unsigned char i;
  341.  
  342. IRcvStr(0xae,4,&doflye,1); //调用存储数据
  343. TempData[0]=dofly_DuanMa[doflye/16];
  344. TempData[1]=dofly_DuanMa[doflye%16];
  345.  
  346. InitUART();
  347. ES=1;
  348.  
  349. while(1)
  350. {
  351. Display(0,2);
  352. doflye=res;
  353. ISendStr(0xae,4,&doflye,1); //写入24c02
  354.  
  355. }
  356. }
  357.  
  358. void UART_SER(void) interrupt 4
  359. {
  360. unsigned char Temp;
  361. // unsigned char i;
  362. if(RI)
  363. {
  364. RI=0;
  365. Temp=SBUF;
  366. res=Temp;
  367. TempData[0]=dofly_DuanMa[Temp/16];
  368. TempData[1]=dofly_DuanMa[Temp%16];
  369. }
  370. if(TI)
  371. TI=0;
  372. }

单片机: EEPROM和串口通信的更多相关文章

  1. labview与单片机串口通信

    labview与单片机串口通信   VISA是虚拟仪器软件体系结构的缩写(即Virtual Instruments Software Architecture),实质上是一个I/O口软件库及其规范的总 ...

  2. 51单片机GPIO口模拟串口通信

    51单片机GPIO口模拟串口通信 标签: bytetimer终端存储 2011-08-03 11:06 6387人阅读 评论(2) 收藏 举报 本文章已收录于:   分类: 深入C语言(20) 作者同 ...

  3. C语言dsPIC / PIC24 serial bootloader和C#语言bootloader PC端串口通信程序

    了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 新dsPIC/PIC2 ...

  4. C语言PIC18 serial bootloader和C#语言bootloader PC端串口通信程序

    了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 新PIC18 Boot ...

  5. C语言PIC16 serial bootloader和C#语言bootloader PC端串口通信程序

    了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 新PIC16 Boot ...

  6. STC12C5A60S2 双串口通信

    STC12C5A60S2单片机是一款功能比较强大的单片机,它拥有两个全双工串行通信接口,串口1的功能及操作与传统51单片机串行口相同:特殊的是STC12C5A60S2单片机内部有一个独立波特率发生器, ...

  7. 【C51】UART串口通信

    我们常需要单片机和其他模块进行通信,数据传输,常用的方式就是串口通信技术. 常用来 单片机<-->电脑,  单片机<-->单片机之间通信. 串行通信 versus 并行通信 并 ...

  8. Qt编写串口通信程序全程图文解说

    (说明:我们的编程环境是windows xp下,在Qt Creator中进行,假设在Linux下或直接用源代码编写,程序稍有不同,请自己修改.) 在Qt中并没有特定的串口控制类,如今大部分人使用的是第 ...

  9. Delphi 串口通信(1)

    利用 Delphi实现串口通信的常用的方法有 3种: 一是利用控件,如 MSCOMM控件和 SPCOMM控件: 二是使用 API函数: 三是调用其他串口通信程序.其中利用 API编写串口通信程序较为复 ...

随机推荐

  1. NAT配置

    静态NAT Router(config)#ip nat inside source static tcp 192.168.100.2 61.159.62.131   指定地址转换映射 Router(c ...

  2. FFMpeg在Windows下搭建开发环境【转】

    本文转载自:http://blog.csdn.net/wootengxjj/article/details/51758621 版权声明:本文为博主原创文章,未经博主允许不得转载. FFmpeg 是一个 ...

  3. [Swift]二进制、八进制、十进制、十六进制之间的转换

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  4. 38.Qt模型/视图结构

    1.模型/视图类 2.模型 3.视图 4.代理 1 模型/视图类 InterView框架提供了一些可以直接使用的模型类和视图类,如QStandardModel类,QDirModel类,QStringL ...

  5. 10. Regular Expression Matching[H]正则表达式匹配

    题目 Given an input string(s) and a pattern(p), implement regular expression matching with support for ...

  6. github结合TortoiseGit使用sshkey,无需每次输入账号和密码

    首先需要明确,github上支持三种方式进行项目的clone    https,ssh,subversion ssh的方式 git@github.com:用户名/版本库t.git            ...

  7. Python学习——爬虫篇

    requests 使用requests进行爬取                 下面是我编写的第一个爬虫的脚本                   import requests # 导入reques ...

  8. jsp指令和学习笔记集锦

    Jsp包含三个编译指令和七个动作指令.三个编译指令为:page.include.taglib. 七个动作指令为:jsp:forward.jsp:param.jsp:include.jsp:plugin ...

  9. UVa 11549 Open Credit System

    题意:给出n个数,找出两个整数a[i],a[j](i < j),使得a[i] - a[j]尽量大 从小到大枚举j,在这个过程中维护a[i]的最大值 maxai晚于ans更新, 可以看这个例子 1 ...

  10. 杭电 1114 Piggy-Bank【完全背包】

    解题思路,首先很容易想到方程f[v]=min(f[v],f[v-w[i]+p[i]),因为是要求当包装满的时候(因为题目中给出的是包的质量是一定的),包里面装的钱最少,所以将f[]初始化成一个很大的数 ...