[STC单片机] 关于对STC官网控制24C04页写入程序的疑问

[复制链接]
2905|7
 楼主| jxw82284134 发表于 2014-4-13 15:59 | 显示全部楼层 |阅读模式
最近在做毕业设计,用到24c02存储数据。看到STC官网的程序,有点不理解。写完一页不是得有应答吗?为什么程序里没有。难道只写一页不用应答?
  1. /**************************************
  2. ;WWW.**.COM
  3. ;Mobile:13922805190
  4. ;0755-82948412
  5. AT24C04测试程序
  6. 主芯片  : STC12C5A60S2 (1T)
  7. 工作频率: 12.000MHz
  8. **************************************/

  9. #include "REG51.H"
  10. #include "INTRINS.H"

  11. typedef unsigned char BYTE;
  12. typedef unsigned short WORD;

  13. sbit SCL = P3^4;                //AT24C04的时钟
  14. sbit SDA = P3^5;                //AT24C04的数据

  15. BYTE BUF[16];                   //数据缓存区

  16. BYTE code TESTDATA[] =
  17. {
  18.     0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,
  19.     0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF
  20. };

  21. void Delay5us();
  22. void Delay5ms();
  23. void AT24C04_Start();
  24. void AT24C04_Stop();
  25. void AT24C04_SendACK(bit ack);
  26. bit AT24C04_RecvACK();
  27. void AT24C04_SendByte(BYTE dat);
  28. BYTE AT24C04_RecvByte();
  29. void AT24C04_ReadPage();
  30. void AT24C04_WritePage();

  31. void main()
  32. {
  33.     AT24C04_WritePage();
  34.     Delay5ms();
  35.     AT24C04_ReadPage();

  36.     while (1);

  37. }

  38. /**************************************
  39. 向AT24C04写1页(16字节)数据
  40. 将TESTDATA开始的16个测试数据写如设备的00~0F地址中
  41. **************************************/
  42. void AT24C04_WritePage()
  43. {
  44.     BYTE i;

  45.     AT24C04_Start();            //起始信号
  46.     AT24C04_SendByte(0xa0);     //发送设备地址+写信号
  47.     AT24C04_SendByte(0x00);     //发送存储单元地址
  48.     for (i=0; i<16; i++)
  49.     {
  50.         AT24C04_SendByte(TESTDATA[i]);
  51.     }
  52.     AT24C04_Stop();             //停止信号
  53. }

  54. /**************************************
  55. 从AT24C04读取1页(16字节)数据
  56. 将设备的00~0F地址中的数据读出存放在DATA区的BUF中
  57. **************************************/
  58. void AT24C04_ReadPage()
  59. {
  60.     BYTE i;

  61.     AT24C04_Start();            //起始信号
  62.     AT24C04_SendByte(0xa0);     //发送设备地址+写信号
  63.     AT24C04_SendByte(0x00);     //发送存储单元地址
  64.     AT24C04_Start();            //起始信号
  65.     AT24C04_SendByte(0xa1);     //发送设备地址+读信号
  66.     for (i=0; i<16; i++)
  67.     {
  68.         BUF[i] = AT24C04_RecvByte();
  69.         if (i == 15)
  70.         {
  71.             AT24C04_SendACK(1); //最后一个数据需要会NAK
  72.         }
  73.         else
  74.         {
  75.             AT24C04_SendACK(0); //回应ACK
  76.         }
  77.     }
  78.     AT24C04_Stop();             //停止信号
  79. }

  80. /**************************************
  81. 延时5微秒(STC12C5A60S2@12M)
  82. 不同的工作环境,需要调整此函数
  83. 此延时函数是使用1T的指令周期进行计算,与传统的12T的MCU不同
  84. **************************************/
  85. void Delay5us()
  86. {
  87.     BYTE n = 4;

  88.     while (n--)
  89.     {
  90.         _nop_();
  91.         _nop_();
  92.     }
  93. }

  94. /**************************************
  95. 延时5毫秒(STC12C5A60S2@12M)
  96. 不同的工作环境,需要调整此函数
  97. 此延时函数是使用1T的指令周期进行计算,与传统的12T的MCU不同
  98. **************************************/
  99. void Delay5ms()
  100. {
  101.     WORD n = 2500;

  102.     while (n--)
  103.     {
  104.         _nop_();
  105.         _nop_();
  106.         _nop_();
  107.         _nop_();
  108.         _nop_();
  109.     }
  110. }

  111. /**************************************
  112. 起始信号
  113. **************************************/
  114. void AT24C04_Start()
  115. {
  116.     SDA = 1;                    //拉高数据线
  117.     SCL = 1;                    //拉高时钟线
  118.     Delay5us();                 //延时
  119.     SDA = 0;                    //产生下降沿
  120.     Delay5us();                 //延时
  121.     SCL = 0;                    //拉低时钟线
  122. }

  123. /**************************************
  124. 停止信号
  125. **************************************/
  126. void AT24C04_Stop()
  127. {
  128.     SDA = 0;                    //拉低数据线
  129.     SCL = 1;                    //拉高时钟线
  130.     Delay5us();                 //延时
  131.     SDA = 1;                    //产生上升沿
  132.     Delay5us();                 //延时
  133. }

  134. /**************************************
  135. 发送应答信号
  136. 入口参数:ack (0:ACK 1:NAK)
  137. **************************************/
  138. void AT24C04_SendACK(bit ack)
  139. {
  140.     SDA = ack;                  //写应答信号
  141.     SCL = 1;                    //拉高时钟线
  142.     Delay5us();                 //延时
  143.     SCL = 0;                    //拉低时钟线
  144.     Delay5us();                 //延时
  145. }

  146. /**************************************
  147. 接收应答信号
  148. **************************************/
  149. bit AT24C04_RecvACK()
  150. {
  151.     SCL = 1;                    //拉高时钟线
  152.     Delay5us();                 //延时
  153.     CY = SDA;                   //读应答信号
  154.     SCL = 0;                    //拉低时钟线
  155.     Delay5us();                 //延时

  156.     return CY;
  157. }

  158. /**************************************
  159. 向IIC总线发送一个字节数据
  160. **************************************/
  161. void AT24C04_SendByte(BYTE dat)
  162. {
  163.     BYTE i;

  164.     for (i=0; i<8; i++)         //8位计数器
  165.     {
  166.         dat <<= 1;              //移出数据的最高位
  167.         SDA = CY;               //送数据口
  168.         SCL = 1;                //拉高时钟线
  169.         Delay5us();             //延时
  170.         SCL = 0;                //拉低时钟线
  171.         Delay5us();             //延时
  172.     }
  173.     AT24C04_RecvACK();
  174. }

  175. /**************************************
  176. 从IIC总线接收一个字节数据
  177. **************************************/
  178. BYTE AT24C04_RecvByte()
  179. {
  180.     BYTE i;
  181.     BYTE dat = 0;

  182.     SDA = 1;                    //使能内部上拉,准备读取数据
  183.     for (i=0; i<8; i++)         //8位计数器
  184.     {
  185.         dat <<= 1;
  186.         SCL = 1;                //拉高时钟线
  187.         Delay5us();             //延时
  188.         dat |= SDA;             //读数据
  189.         SCL = 0;                //拉低时钟线
  190.         Delay5us();             //延时
  191.     }

  192.     return dat;
  193. }
ayb_ice 发表于 2014-4-13 16:32 | 显示全部楼层
每个字节都要应答,

应该有的,看仔细了
 楼主| jxw82284134 发表于 2014-4-13 17:15 | 显示全部楼层
ayb_ice 发表于 2014-4-13 16:32
每个字节都要应答,

应该有的,看仔细了

void AT24C04_WritePage()这个函数里面没有见应答函数啊
ayb_ice 发表于 2014-4-14 08:01 | 显示全部楼层
jxw82284134 发表于 2014-4-13 17:15
void AT24C04_WritePage()这个函数里面没有见应答函数啊

都说了要仔细
 楼主| jxw82284134 发表于 2014-4-14 10:29 | 显示全部楼层
ayb_ice 发表于 2014-4-14 08:01
都说了要仔细

我知道了,void AT24C04_SendByte(BYTE dat)里面发送完一个8位的字节后有一个  AT24C04_RecvACK();这个就是应答信号。直接包含在写字节函数里了。我说怎么没见。跟郭天祥的程序不是一个思路
ayb_ice 发表于 2014-4-14 10:32 | 显示全部楼层
jxw82284134 发表于 2014-4-14 10:29
我知道了,void AT24C04_SendByte(BYTE dat)里面发送完一个8位的字节后有一个  AT24C04_RecvACK();这个就 ...

终于仔细了一回,

因为每个字节都要应答,这个写法才是正道,
 楼主| jxw82284134 发表于 2014-4-14 10:43 | 显示全部楼层
ayb_ice 发表于 2014-4-14 10:32
终于仔细了一回,

因为每个字节都要应答,这个写法才是正道,

确实,还是得借鉴写工程的思路
coody 发表于 2014-4-14 11:05 | 显示全部楼层
做技术要仔细
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

79

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部