[DemoCode下载] 新唐M051 IIC使用程序

[复制链接]
 楼主| huangcunxiake 发表于 2017-4-24 15:57 | 显示全部楼层 |阅读模式
  1. #include "SmartM_M0.h"
  2. #define DEBUGMSG printf
  3. #define EEPROM_SLA              0xA0
  4. #define EEPROM_WR               0x00
  5. #define EEPROM_RD               0x01   
  6. #define I2C_CLOCK               13   
  7. #define PAGE_SIZE               8
  8. /*****************************************
  9. *函数名称:Timed_Write_Cycle
  10. *输    入:无
  11. *输    出:无
  12. *功    能:同步的写周期
  13. ******************************************/
  14. void Timed_Write_Cycle(void)                  
  15. {
  16.     while (I2STATUS != 0x18)
  17.     {
  18.         //启动
  19.         I2CON |= STA;                          
  20.         I2CON |= SI;
  21.         while ((I2CON & SI) != SI);
  22.         I2CON &= ((~STA) & (~SI));   
  23.   //设备地址
  24.         I2DAT = EEPROM_SLA | EEPROM_WR;
  25.         I2CON |= SI;
  26.         while ((I2CON & SI) != SI);
  27.     }        
  28.     if (I2STATUS != 0x18)                       //检查应答
  29.     {
  30.      DEBUGMSG("Not ACK returned!");
  31. }      
  32.     //停止
  33.     I2CON |= STO;
  34.     I2CON |= SI;
  35.     while (I2CON & STO);
  36. }
  37. /*****************************************
  38. *函数名称:I2CInit
  39. *输    入:无
  40. *输    出:无
  41. *功    能:I2C初始化
  42. ******************************************/
  43. VOID I2CInit(VOID)
  44. {
  45.     P3_PMD &= ~(Px4_PMD | Px5_PMD);
  46. P3_PMD |= (Px4_OD | Px5_OD);                //使能I2C0引脚
  47.     P3_MFP &= ~(P34_T0_I2CSDA | P35_T1_I2CSCL);
  48. P3_MFP |= (I2CSDA | I2CSCL);        //选择P3.4,P3.5作为I2C0功能引脚      
  49. APBCLK |= I2C0_CLKEN;                       //使能I2C0时钟
  50.     I2CLK = I2C_CLOCK;                                            
  51. I2CON |= ENSI;                              //使能I2C
  52. }
  53. /*****************************************
  54. *函数名称:AT24C0XWrite
  55. *输    入:unAddr   写地址
  56.           pucData  写数据
  57.     unLength 写长度
  58. *输    出:TRUE/FALSE
  59. *功    能:AT24C0X写数据
  60. ******************************************/
  61. BOOL AT24C0XWrite(UINT32 unAddr,UINT8 *pucData,UINT32 unLength)
  62. {
  63.     UINT32 i;
  64.     I2CON |= STA;              //启动
  65.     I2CON |= SI;                  
  66.     while ((I2CON & SI) != SI);        
  67.     I2CON &= ((~STA)&(~SI));            
  68.     if (I2STATUS != 0x08)            
  69.     {
  70.         DEBUGMSG("I2CStart fail,I2STATUS %02X\r\n",I2STATUS);
  71.   return FALSE;
  72.     }  
  73.     //进入读写控制操作
  74.     I2DAT = EEPROM_SLA | EEPROM_WR;
  75.     I2CON |= SI;
  76.     while ((I2CON & SI) != SI);
  77.     if (I2STATUS != 0x18)              
  78.     {
  79.      DEBUGMSG("I2C write control fail\r\n");        
  80.      return FALSE;
  81.     }
  82.     //写地址
  83.     I2DAT = unAddr;
  84.     I2CON |= SI;
  85.     while ((I2CON & SI) != SI);
  86.     if (I2STATUS != 0x28)              
  87.     {
  88.         DEBUGMSG("I2C write addr fail\r\n");
  89.      return FALSE;
  90.     }
  91. //写数据
  92. for(i=0; i<unLength; i++)
  93. {
  94.      I2DAT = *(pucData+i);
  95.      I2CON |= SI;
  96.      while ((I2CON & SI) != SI);
  97.      if (I2STATUS != 0x28)              
  98.      {
  99.          DEBUGMSG("I2C write data fail\r\n");
  100.       return FALSE;
  101.      }
  102. }
  103.     //停止
  104.     I2CON |= STO;
  105.     I2CON |= SI;
  106.     while (I2CON & STO);         
  107. //DEBUGMSG("I2C stop ok\r\n");
  108.     Timed_Write_Cycle();                                      
  109. return TRUE;            
  110. }
  111. /*****************************************
  112. *函数名称:AT24C0XRead
  113. *输    入:unAddr   读地址
  114.           pucData  读数据
  115.     unLength 读长度
  116. *输    出:TRUE/FALSE
  117. *功    能:AT24C0X读数据
  118. ******************************************/
  119. BOOL AT24C0XRead(UINT32 unAddr,UINT8 *pucData,UINT32 unLength)
  120. {
  121. UINT32 i;
  122.     I2CON |= STA;                 //启动
  123.     I2CON |= SI;                     
  124.     while ((I2CON & SI) != SI);         
  125.     I2CON &= ((~STA)&(~SI));            
  126.     if (I2STATUS != 0x08)            
  127.     {
  128.         DEBUGMSG("I2CStart fail,I2STATUS %02X\r\n",I2STATUS);  
  129.   return FALSE;
  130.     }
  131. //进入读写控制操作  
  132.     I2DAT = EEPROM_SLA | EEPROM_WR;
  133.     I2CON |= SI;
  134.     while ((I2CON & SI) != SI);
  135.     if (I2STATUS != 0x18)              
  136.     {
  137.      DEBUGMSG("I2C write control fail\r\n");      
  138.      return FALSE;
  139.     }
  140. //写入读地址
  141.     I2DAT = unAddr;
  142.     I2CON |= SI;
  143.     while ((I2CON & SI) != SI);
  144.     if (I2STATUS != 0x28)              
  145.     {
  146.         DEBUGMSG("I2C write addr fail\r\n");
  147.      return FALSE;
  148.     }  
  149.     // 重新启动
  150.     I2CON |= STA;         
  151.     I2CON |= SI;                                
  152.     while ((I2CON & SI) != SI);                 
  153.     I2CON &= ((~STA)&(~SI));   
  154.     if (I2STATUS != 0x10)                       
  155.     {
  156.         DEBUGMSG("I2C repeated start fail\r\n");
  157.   return FALSE;
  158.     }
  159.     //进入读操作  
  160.     I2DAT = EEPROM_SLA | EEPROM_RD;
  161.     I2CON |= SI;
  162.     while ((I2CON & SI) != SI);   
  163.     if (I2STATUS != 0x40)              
  164.     {
  165.         DEBUGMSG("I2C write control fail\r\n");
  166.         while (1);
  167.     }
  168. //读取数据
  169. I2CON |= AA;
  170. for(i=0; i<unLength; i++)
  171. {
  172.      I2CON |= SI;
  173.      while ((I2CON & SI) != SI);
  174.      if (I2STATUS != 0x50)              
  175.      {
  176.          DEBUGMSG("I2C read fail\r\n");
  177.          return FALSE;
  178.      }
  179.   *(pucData+i) = I2DAT;
  180. }
  181.     //发送NACK到AT24C02,执行断开连接操作
  182.     I2CON &= (~AA);
  183.     I2CON |= SI;
  184.     while ((I2CON & SI) != SI);
  185.    //停止
  186.     I2CON |= STO;
  187.     I2CON |= SI;
  188.     while (I2CON & STO);                     
  189. DEBUGMSG("I2C read ok\r\n");
  190. return TRUE;
  191. }
  192. VOID AT24C02ContinousWrite(UINT32 unAddr,UINT8 *pucData,UINT32 unLength)
  193. {
  194.     UINT32 i,m,n;
  195. UINT32 unCurWirteCount=0;
  196. //if(unLength <= 32)
  197. m = PAGE_SIZE-(unAddr % PAGE_SIZE);   //与当前每页32个字节已剩下多少个字节
  198. if(unLength <= m)
  199. {
  200.     AT24C0XWrite(unAddr,pucData,unLength);
  201. }
  202. else
  203. {
  204.     AT24C0XWrite(unAddr,pucData,m);
  205.     unLength -=m;
  206.     unCurWirteCount+=m;
  207.     m = unLength/PAGE_SIZE;
  208.     n = unLength%PAGE_SIZE;
  209.     for(i=0; i<m; i++)
  210.     {
  211.         AT24C0XWrite(unAddr+unCurWirteCount,pucData+unCurWirteCount,PAGE_SIZE);
  212.      unCurWirteCount += PAGE_SIZE;
  213.     }
  214.     AT24C0XWrite(unAddr+unCurWirteCount,pucData+unCurWirteCount,n);   
  215. }   
  216. }
  217. /*****************************************
  218. *函数名称:main
  219. *输    入:无
  220. *输    出:无
  221. *功    能:函数主体
  222. ******************************************/
  223. INT32 main(VOID)
  224. {
  225.   UINT8 i,buf[32];
  226.      Un_Lock_Reg();        //ISP下载时保护FLASH存储器
  227.   PWRCON |= XTL12M_EN;      //默认时钟源为外部晶振
  228.   while((CLKSTATUS & XTL12M_STB) == 0);   //等待12MHz时钟稳定  
  229.   CLKSEL0 = (CLKSEL0 & (~HCLK)) | HCLK_12M; //设置外部晶振为系统时钟
  230.   UartInit(12000000,9600);     //波特率设置为9600bps
  231.   I2CInit();
  232.   DEBUGMSG("I2C Test\r\n");
  233. //  while(1)
  234. //  {
  235.      for(i=0; i<sizeof(buf); i++)   //初始化写缓冲区
  236.     {
  237.         buf[i]=0x55;
  238.     }
  239.        DEBUGMSG("\r\nAT24C0XWrite Test\r\n");
  240.     AT24C0XWrite(0,buf,sizeof(buf));  //执行写操作
  241.     Delayms(500);
  242.     //==================================================
  243.        DEBUGMSG("AT24C0XRead Test\r\n");
  244.      for(i=0; i<sizeof(buf); i++)   //初始化读缓冲区
  245.     {
  246.         buf[i]=0x00;
  247.     }
  248.     AT24C0XRead(0,buf,sizeof(buf));    //执行读操作
  249.     for(i=0; i<10; i++)
  250.     {
  251.      DEBUGMSG("%02X ",buf[i]);     //打印读取的数值   
  252.     }
  253.     Delayms(500);
  254. //  }
  255. while(1);
  256. }


gejigeji521 发表于 2017-4-24 16:49 | 显示全部楼层
   DEBUGMSG("Not ACK returned!");
这个消息打印用的是串口0还是串口1?
稳稳の幸福 发表于 2017-4-24 17:15 | 显示全部楼层
这种应该先来个流程图,然后上程序,看的更明白。
xixi2017 发表于 2017-4-24 21:20 | 显示全部楼层
这个I2C驱动外部存储器的例子写的老练。
wahahaheihei 发表于 2017-4-25 16:38 | 显示全部楼层
封装的很好啊,比原版的看着给力。
xixi2017 发表于 2017-4-25 21:13 | 显示全部楼层
有时候通过位的逻辑操作将检测变的非常容易。
643757107 发表于 2017-4-26 09:45 | 显示全部楼层
对官方代码进行了二次封装。
xixi2017 发表于 2017-4-26 21:00 | 显示全部楼层
        while ((I2CON & SI) != SI);
        I2CON &= ((~STA) & (~SI));  
另外一个贴说的关键点啊。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

222

主题

3700

帖子

11

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

222

主题

3700

帖子

11

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