找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2737|回复: 5
收起左侧

单片机IIC接口存储器AT24C04的读写和显示程序(详细注释)

[复制链接]
划船须划水 发表于 2019-5-12 22:03 | 显示全部楼层 |阅读模式
通过仿真实现对存储器AT24C04读写操作,通过数码管或LED灯状态来显示

原理图

原理图


原理图



实验结果图

实验结果图

实验结果图

实验部分代码结构:
//24C04.c
  1. //-----------------------------------------------------------------
  2. //  名称: AT24C04读/写驱动程序
  3. //-----------------------------------------------------------------
  4. #define INT8U  unsigned char
  5. #define INT16U unsigned int
  6. #include <reg51.h>
  7. #include <intrins.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. sbit SCL = P1^0;                                        //串行时钟线
  11. sbit SDA = P1^1;                                        //串行数据线
  12. #include "I2C.h"                                        //IIC总线通用宏及函数
  13. //-----------------------------------------------------------------
  14. //AT24C04所调用的外部相关函数
  15. extern void Show_HEX(INT8U dat);         //16进制格式显示字节
  16. extern void PutStr(INT8U *s);                //串口输出字符串
  17. extern void delay_ms(INT16U);                //延时函数
  18. extern INT16U r;                                        //换行控制变量
  19. //-----------------------------------------------------------------
  20. // 向任意指定的地址写入一字节数据
  21. // 器件地址码字节格式 (其中E2,E1为片选位,A8为块地址位)
  22. // 位: B7 B6 B5 B4 B3 B2 B1 B0
  23. // 值:  1  0  1  0 E2 E1 A8 RW
  24. //-----------------------------------------------------------------
  25. void Random_Write(INT8U Dev_Addr,INT16U mem_addr,INT8U dat)
  26. {

  27. }

  28. //-----------------------------------------------------------------
  29. // 从任意地址读取一字节数据
  30. //-----------------------------------------------------------------
  31. INT8U Random_Read(INT8U Dev_Addr,INT16U mem_addr)
  32. {

  33. }

  34. //-----------------------------------------------------------------
  35. // 从指定地址开始连续顺序读取N节数据
  36. //-----------------------------------------------------------------
  37. void Sequential_Read(INT8U Dev_Addr,INT16U mem_addr,INT16U N)
  38. {

  39. }
复制代码
//IC.h

  1. //-----------------------------------------------------------------
  2. // 名称: IIC总线通用宏及函数
  3. //-----------------------------------------------------------------
  4. #define NOP4()        { _nop_();_nop_();_nop_();_nop_(); }
  5. //总线启动        -------------------------------------------------------
  6. #define IIC_Start()                \
  7. { SDA = 1; NOP4(); SCL = 1; NOP4(); SDA = 0; NOP4(); SCL = 0; }
  8. //总线停止        -------------------------------------------------------
  9. #define IIC_Stop()                \
  10. { SDA = 0; NOP4(); SCL = 1; NOP4(); SDA = 1; NOP4(); }
  11. //-----------------------------------------------------------------
  12. //以下3个有关应答的宏定义均生成第9个时钟脉冲,读取应答或发送应答/非应答
  13. //1.主机读从机应答        -----------------------------------------------
  14. //(SDA = 1设为输入,准备读取应答位,要使用该位作出处理时引用F0)
  15. #define IIC_Rd_Ack()        \
  16. { SDA = 1; NOP4(); SCL = 1; NOP4(); F0 = !SDA; NOP4(); SCL = 0;        }
  17. //2.主机发送应答位        -----------------------------------------------
  18. #define IIC_Ack()                \
  19. { SDA = 0; NOP4(); SCL = 1; NOP4(); SCL = 0; NOP4(); SDA = 1;        }
  20. //3.主机发送非应答位        -------------------------------------------
  21. #define IIC_NAck()                \
  22. { SDA = 1; NOP4(); SCL = 1; NOP4(); SCL = 0; NOP4(); SDA = 0;        }
  23. //-----------------------------------------------------------------
  24. // 主机向IIC总线写一字节
  25. //-----------------------------------------------------------------
  26. bit IIC_WriteByte(INT8U dat)
  27. {

  28. }

  29. //-----------------------------------------------------------------
  30. // 主机从IIC总线读一字节
  31. //-----------------------------------------------------------------
  32. INT8U IIC_ReadByte()
  33. {

  34. }
复制代码
主程序main.c

  1. //-----------------------------------------------------------------
  2. //        名称: I2C接口存储器AT24C04读写与显示(4片)
  3. //-----------------------------------------------------------------
  4. //        说明: 按下K1-K4按键时,前两个分别向第1,2片AT24C04中写入400个随机字节
  5. //                  后2个按键分别写第3,4片AT24C04,先写入200个0x01,再写入200个0x02
  6. //                  写入后接着读取并显示.(400个字节的地址范围: 0x0000~0x018F)
  7. //
  8. //-----------------------------------------------------------------
  9. #define INT8U  unsigned char
  10. #define INT16U unsigned int
  11. #include <reg51.h>
  12. #include <intrins.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. sbit K1 = P3^3;                //四个操作按键定义
  16. sbit K2 = P3^4;
  17. sbit K3 = P3^5;
  18. sbit K4 = P3^6;
  19. INT16U r = 0;                //满20个字节换行控制变量
  20. //AT24C04相关函数
  21. extern void Random_Write(INT8U Dev_Addr,INT16U mem_addr,INT8U dat);
  22. extern INT8U Random_Read(INT8U Dev_Addr,INT16U mem_addr);
  23. extern void Sequential_Read(INT8U Dev_Addr,INT16U mem_addr,INT16U N);
  24. //-----------------------------------------------------------------
  25. // 延时函数
  26. //-----------------------------------------------------------------
  27. void delay_ms(INT16U x) {INT8U t; while(x--) for(t = 0; t<120; t++);}
  28. //-----------------------------------------------------------------
  29. // 向串口发送1字节
  30. //-----------------------------------------------------------------
  31. void PutChar(INT8U c) {        SBUF = c; while( TI == 0 ); TI = 0;}
  32. //-----------------------------------------------------------------
  33. // 向串口发送字符串
  34. //-----------------------------------------------------------------
  35. void PutStr(INT8U *s) { while(*s) PutChar(*s++); }
  36. //-----------------------------------------------------------------
  37. // sprintf对%2X格式支持不稳定,编译时有时可以输出正确结果,有时则不正常
  38. // sprintf(s,"%02X ",(INT8U)Random_Read(0xA0,i)); PutStr(s);
  39. // 故改用下面的函数实现十六进制形式显示所读取的字节
  40. //-----------------------------------------------------------------
  41. void Show_HEX(INT8U dat)
  42. {

  43. }

  44. //-----------------------------------------------------------------
  45. // 主程序
  46. //-----------------------------------------------------------------
  47. void main()
  48. {
  49.         INT16U i; char s[] = "NO.X\r\n";
  50.         INT8U n = 0, ChipNo = 0;
  51.         //串口配置
  52.         SCON = 0x40;        TMOD = 0x20;        PCON = 0;
  53.         TH1 = 0xFD;                TL0 = 0xFD;
  54.         TI = 0;                        TR1 = 1;
  55.         srand(30);                //随机种子
  56.         PutStr("\r\n>>> Press K1~K4, Write/Read No.1~4 AT24C04...\r\n ");
  57.         while(1)
  58.         {        if ((P3 & 0xF0) != 0xF0)                //P3端口高4位按键状态检测
  59.                 {



  60.                 } else { delay_ms(10); continue; }
  61.                 PutStr("\r\n\r\n>>> Write IIC, Waiting.........\r\n\r\n ");
  62.                 //提示当前读取的AT24C04芯片号1~4(由0~3加1得到)
  63.                 s[3] = ChipNo + '1'; PutStr(s);        
  64.                 switch (ChipNo)
  65.                 {        case 0: case 1:         //K1,K2分别向第1,2片写入400个随机字节



  66.                         case 2: case 3:         //K3,K4分别写第3,4片,写入200个0x01,0x02



  67.                 }
  68.                 PutStr("\r\n\r\n>>> Reading From IIC...........\r\n\r\n");
  69.                 r = 0;                                                        //满20个字节换行显示控制变量归0
  70.                 //从指定的AT24C04中读取400字节并发送串口显示,下面两种读取方法中,
  71.                 //随机寻址单字节读取共400字节将明显慢于顺序连续读取400字节









  72.         }
  73. }
复制代码
完整代码

IC.zip (2.71 KB, 下载次数: 26)
回复

使用道具 举报

刀刀见红 发表于 2019-5-13 04:44 | 显示全部楼层
       其实很简单,首先你要知道仿真与实际不一样!一开始你就拖家带口的将你要完成功能的代码都写进去,必死无疑!
       正确的方法了先做一个,调试24C04外设固定地址,很重要!因为仿真库内芯片外设地址还真不是一回事!
       一个一个将外设地址调对好,再就是设24C04存储器存储数据地址,设好后读写操作正常与否,再就是连读连写,多读多写,后面就是调试与按键配合
回复

使用道具 举报

 楼主| 划船须划水 发表于 2019-5-13 21:19 | 显示全部楼层
刀刀见红 发表于 2019-5-13 04:44
其实很简单,首先你要知道仿真与实际不一样!一开始你就拖家带口的将你要完成功能的代码都写进去, ...

大佬说的对。经验之谈
回复

使用道具 举报

liangker 发表于 2020-10-17 18:26 | 显示全部楼层
重入函数吗?你真的测试过吗
回复

使用道具 举报

kzghaohaohao 发表于 2020-10-20 10:06 | 显示全部楼层
大佬说的对
回复

使用道具 举报

长风007 发表于 2020-10-20 17:42 | 显示全部楼层
写一个固定地址,测试先。然后再读这个地址看是否有变化!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表