3892|3

23

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

写过S3C2440对AT24C08读写的朋友的朋友看一下这个问题 [复制链接]

最近由于想写一个基于Linux的AT24C08驱动程序,所要就先写了一下裸机的驱动,主要完成S3C2440通过IIC总线对AT24C08进行读、写操作,其中写有两种方式:1)指定地址写;2)页写;   而读有三种方式:1)读当前地址;2)读指定地址;3)页读方式。搞了差不多一个星期了,一直还没有成功,都完全按其时序来书写程序的。由于本人没用仿真器,所以不知道这个程序错在什么地方。如果各位朋友有做过与我一样的程序,请送一个给小弟试试,看看是什么原因。
email:   sw_2006.1230@163.com
看了开发板(Mini2440)提供的例子,感觉是在什么地方抄的,在网上找到的都是与开发板提供的一样的例子,没有一个其它的,也不知道最初版本是谁写的,不知道是我理解错还是什么原因,我感觉里面有一个重大的错误在于rGPECON的设置上。因为IIC的SDA,SCL分别为GPE15与GPE14,而例程在进行GPIO口的初始化时为 rGPECON |= 0xA00000;  这不是把GPE14,GPE15设置为IIC端口,同时,GPE14,GPE15端口没有上端口上拉电阻,而例子中把rGEPUP 初始化为 rGPEUP |= 0xC000; 在2440中rGPEUP的有效位只为14位,这样初始有用吗?

下面是本人的代码,请给予指正。

  1. /************************************************
  2. *说明:本程序是S3C2440 IIC总线的一个简单的驱动程序
  3. *     由于本程序比较简单,所以,在此不再进行说明,
  4. *     有不懂的读者请自行阅读相关文档。
  5. *
  6. *     AT24C08 的地址格式为: 1 0 1 0 A2 P1 P0 W/R
  7. *     A2为设备地址位、P1,P0为片内页寻址  LSB=0 写
  8. *     LSB=1 读
  9. *
  10. *CPU          :S3C2440
  11. *编译环境     :ADS1.2
  12. *开发板       :MINI2440
  13. *作者         :舒稳
  14. *部门         : 长沙理工大学
  15. *               计算机与通信工程学院
  16. *               计算机07级04班
  17. *最后修改时间 :开发中
  18. ************************************************/

  19. #ifndef _MY_IIC_C_
  20. #define _MY_IIC_C_

  21. #include "../include/2440addr.h"
  22. #include "../include/2440lib.h"
  23. #include "../include/def.h"
  24. #include "../include/My_IIC.h"


  25. static int seave_gpecon;
  26. /*用于保存GPECON的当前值,为恢复GPECON做准备*/


  27. U8 write_buffer[16];
  28. /*写缓冲区*/

  29. U8 read_buffer[16];
  30. /*读缓冲区*/

  31. /*初始化GPIO*/
  32. void
  33. _init_gpio(void)
  34. {
  35.         seave_gpecon = rGPECON;
  36.        
  37.         rGPECON = 0xA0000000;  
  38. }

  39. /*恢复GPIO口*/
  40. void
  41. _resume_gpio(void)
  42. {
  43.         rGPECON = seave_gpecon;
  44. }

  45. /*初始化IIC总线*/
  46. void
  47. _init_iic(void)
  48. {
  49.     /*
  50.     *IIC应答使能有效、IICCLK = FPCLK/16、
  51.     *清除挂取条件、 TXCLK = IICCLK/16
  52.     */
  53.     rIICCON = (1 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
  54.     rIICSTAT = 0x10;
  55.     rIICADD = 0x10;
  56.     rIICLC = (1<<2)|(1);
  57. }

  58. /*
  59. *写一个字节到指地址单元
  60. *@device_address:从机地址
  61. *@word_address:要写入的单元地址
  62. *@data:要写入的数据
  63. */
  64. /*通过测试*/
  65. void
  66. _byte_write(U8 device_address, U8 word_address, U8 data)
  67. {
  68.         rIICCON = (1 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
  69.         rIICSTAT = (rIICSTAT & 0x0) | (0x1 << 7) | (0x1 << 6);
  70.         rIICDS  = device_address;
  71.         rIICSTAT = 0xF0;
  72.         while((rIICSTAT & 0x01) == 1);
  73.        
  74.         rIICDS = word_address;
  75.         while((rIICSTAT & 0x01) == 1);
  76.        
  77.         rIICDS = data;
  78.         while((rIICSTAT & 0x01) == 1);

  79.         rIICSTAT = 0xD0;
  80.         rIICCON = (1 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
  81. }


  82. /*
  83. *以页写的方式写入AT24C08中
  84. *@device_address:从机地址
  85. *@word_start_address:要写入的首地址
  86. *@buffer_start_address:要写入的数据的缓冲区首地址
  87. */
  88. /*通过测试*/
  89. void _page_write(U8 device_address, U8 word_start_address,U8 *buffer_start_address)
  90. {
  91.         unsigned int i;
  92.        
  93.         rIICCON = (1 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
  94.         rIICSTAT = (rIICSTAT & 0x0) | (0x1 << 7) | (0x1 << 6);
  95.         rIICDS  = device_address;
  96.         rIICSTAT = 0xF0;
  97.         while((rIICSTAT & 0x01) == 1);
  98.        
  99.         rIICDS = word_start_address;
  100.         while((rIICSTAT & 0x01) == 1);
  101.        
  102.         for(i = 0; i < 15; i ++){
  103.                 rIICDS = *(buffer_start_address + i);
  104.                 while((rIICSTAT & 0x01) == 1);
  105.         }
  106.        
  107.         rIICDS = *(buffer_start_address + i);
  108.         while((rIICSTAT & 0x01) == 1);
  109.        
  110.         rIICSTAT = 0xD0;
  111.         rIICCON = (1 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
  112. }


  113. /*
  114. *读当前地址单元的内容
  115. *@device_address:从机地址
  116. *返回值:读取到的字节
  117. */
  118. /*通过测试*/
  119. U8
  120. _current_address_read(U8 device_address)
  121. {
  122.         U8 data;

  123.         rIICCON = (1 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
  124.         rIICSTAT = (rIICSTAT &0x0) | (0x1 << 7) | (0 << 6);
  125.         rIICDS  = device_address;
  126.         rIICSTAT = 0xB0;
  127.         while((rIICSTAT & 0x01) == 1);

  128.    rIICCON = (0 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
  129.    data = rIICDS;
  130.    
  131.         rIICSTAT = 0x90;
  132.        
  133.   rIICCON = (1 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
  134.   
  135.         return data;
  136. }




  137. /*
  138. *读指定单元地址的内容
  139. *@device_address:从机地址
  140. *@word_address:指定的要读取的地址单元
  141. *返回值:读取到的字节
  142. */
  143. /*有误,需要修改*/
  144. U8
  145. _random_address_read(U8 device_address, U8 word_address)
  146. {
  147.     U8 data;
  148.    
  149.     rIICCON = (1 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
  150.         rIICSTAT = (rIICSTAT & 0x0) | (0x1 << 7) | (0x1 << 6);
  151.         rIICDS  = device_address & 0xFE;
  152.         rIICSTAT = 0xF0;
  153.         while((rIICSTAT & 0x01) == 1);
  154.        
  155.         rIICDS = word_address;
  156.         while((rIICSTAT & 0x01) == 1);
  157.        
  158.        
  159.         rIICSTAT = (rIICSTAT & 0x0) | (0x1 << 7) | (0 << 6);
  160.         rIICDS  = device_address;
  161.         rIICSTAT = 0xB0;
  162.         while((rIICSTAT & 0x01) == 1);
  163.        
  164.     rIICCON = (0 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
  165.     data = rIICDS;
  166.    
  167.        

  168.          rIICSTAT = 0x90;

  169.     rIICCON = (1 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
  170.   
  171.     return data;
  172. }


  173. /*
  174. *以页读的方式进行读取
  175. *@device_address:从机地址
  176. *@word_address:起始地址
  177. *@buffer_start_address:读取缓冲区首地址
  178. */
  179. /*有误,需修改*/
  180. void
  181. _sequential_address_read(U8 device_address,U8 word_address,U8 *buffer_start_address)
  182. {
  183.         unsigned i;
  184.        
  185.        
  186.         rIICCON = (1 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
  187.         rIICSTAT = (rIICSTAT & 0x0) | (0x1 << 7) | (0x1 << 6);
  188.         rIICDS  = device_address & 0xFE;
  189.         rIICSTAT = 0xF0;
  190.   while((rIICSTAT & 0x01) == 1);
  191.   
  192.         rIICDS = word_address;
  193.         while((rIICSTAT & 0x01) == 1);
  194.        
  195.         rIICSTAT = (rIICSTAT & 0x0) | (0x1 << 7) | (0 << 6);
  196.         rIICDS  = device_address;
  197.         rIICSTAT = 0x90;
  198.         while((rIICSTAT & 0x01) == 1);
  199.    
  200.         for(i = 0; i < 15; i ++){
  201.                 *(buffer_start_address + i) = rIICDS;
  202.                 _delay_time(3);
  203.         }

  204.    rIICCON = (0 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
  205.         *(buffer_start_address + i) = rIICDS;

  206.         rIICSTAT = 0x90;
  207.         rIICCON = (1 << 7) | ( 0 << 6) | (0 << 5) | (0xF);
  208. }


  209. /*
  210. *进行一小段延时
  211. *@delay_time:要进行的延时
  212. */
  213. void
  214. _delay_time(unsigned int delay_time)
  215. {
  216.         while(delay_time --);
  217. }


  218. /*测试程序*/
  219. void
  220. _test_iic(void)
  221. {
  222.         char i;
  223.        
  224.         /*实始化读 写缓冲区*/
  225.         for( i = 0; i < 16; i ++){
  226.                 *(write_buffer + i) = i * 2;
  227.                 *(read_buffer + i )= 0;
  228.                 }
  229.        
  230.         /*下面为测试按页写测试*/
  231.        
  232.         _page_write(DEVICE_ADDRESS_WRITE,0,write_buffer);
  233.         _delay_time(500);
  234.        
  235.          for(i = 0; i < 16; i ++){
  236.       Uart_Printf("%d     %d     %d\n",i + 1,_random_address_read(DEVICE_ADDRESS_READ,i),_current_address_read(DEVICE_ADDRESS_READ));
  237.       _delay_time(500);
  238.    
  239.       }
  240.        
  241.        
  242.        
  243.         for(i = 0; i < 16; i ++){
  244.           _byte_write(DEVICE_ADDRESS_WRITE, i,i * 3);
  245.          _delay_time(500);
  246.          
  247.          }
  248.        
  249.          for(i = 0; i < 16; i ++){
  250.       Uart_Printf("%d     %d     %d\n",i + 1,_random_address_read(DEVICE_ADDRESS_READ,i),_current_address_read(DEVICE_ADDRESS_READ));
  251.       _delay_time(500);
  252.    
  253.       }
  254.       
  255.         /*下面为测试按页读*/
  256.         _sequential_address_read(DEVICE_ADDRESS_READ,0,read_buffer);
  257.         _delay_time(500);
  258.        
  259.        
  260.         for(i = 0; i < 16; i ++)
  261.                 Uart_Printf("%d  %d\n",i + 1,*(read_buffer + i));
  262.        
  263.        
  264.        
  265.         Uart_Printf("\n");
  266. }


  267. #endif



  268. /************************************************
  269. ||
  270. ||
  271. ||
  272. ||            END My_IIC.c
  273. ||
  274. ||
  275. ||
  276. ************************************************/
复制代码

最新回复

多半是优化掉了,把定义加上volatile试试.  详情 回复 发表于 2010-5-29 22:37
点赞 关注

回复
举报

2

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
没仿真器,调试起来的确会有点麻烦,不过楼主你可以用LED来辨识程序运行流程,在关键分支的地方,显示一个LED。就知道他完整的流程了。判断问题所在。用IO的高低也可以的。
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
楼上的方法不错,就算没有LED拿几个IO做状态机也好啊。
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(初级)

4
 
多半是优化掉了,把定义加上volatile试试.
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
直播报名最后1周:艾迈斯欧司朗 OSP 开放协议,从氛围灯动态照明到传感器交互融合
直播时间:4月22日(周二)10:00
直播奖励:京东卡、蓝牙温湿度计、定制水杯

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网 5

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表