msp430硬件II2C

msp430系列硬件I2C操作24LC128程序


说明:24lc128为美信公司EEPROM存储器,存取空间为128kbit。具体的通信规则可以看其器件手册。 

***************************************************************************************/ 

运行代码  复制代码
  1.  
  2. /*******************************************************************************  
  3. 包含头文件  
  4. *******************************************************************************/  
  5. #include <msp430x54x.h>  
  6. /*******************************************************************************  
  7. 全局变量的定义  
  8. *******************************************************************************/  
  9. unsigned char RXData;  
  10. unsigned char count;  
  11. /*******************************************************************************  
  12. 函数定义  
  13. *******************************************************************************/  
  14. void IIC_init(void);                         // 初始化设置  
  15. void EEPROM_Write(unsigned char high_Address,unsigned char low_Address,unsigned char Word);  
  16.                                              // 字节写设置  
  17. void EEPROM_radom(unsigned char high_Address,unsigned char low_Address);  
  18.                                              // 随机读设置  
  19. void EEPROM_read();                          // 连续读设置  
  20. /*************************************************************************  
  21. ** 函数名称:  
  22. ** 工作环境:    
  23. ** 作者:      
  24. ** 生成日期:  
  25. ** 功能:STOP信号和START信号之间延时 5MS  
  26. ** 相关文件:  
  27. ** 修改日志:  
  28. *************************************************************************/  
  29. void Delay()  
  30. {  
  31.   for(unsigned char i=0;i<0xff;i++);  
  32.   for(unsigned char i=0;i<0xff;i++);  
  33.   for(unsigned char i=0;i<0xff;i++);  
  34.   for(unsigned char i=0;i<0xff;i++);  
  35.   for(unsigned char i=0;i<0xff;i++);  
  36. }  
  37.  
  38. /*************************************************************************  
  39. ** 函数名称:  
  40. ** 工作环境:  
  41. ** 作者:      
  42. ** 生成日期:  
  43. ** 相关文件:  
  44. ** 修改日志:  
  45. *************************************************************************/  
  46. void main(void)  
  47. {  
  48.    
  49.   WDTCTL = WDTPW + WDTHOLD;                 // 关闭看门狗  
  50.   for(unsigned char i=0;i<0xff;i++);  
  51.   IIC_init();                               // 初始化IIC  
  52.   EEPROM_Write(0x01,0x00,0x10);             // 字节写  
  53.   Delay();                                  // 延时  
  54.   EEPROM_radom(0x01,0x00);                  // 随机读  
  55.   EEPROM_read();                            // 立即读  
  56.   LPM0;  
  57. }  
  58. /*************************************************************************  
  59. ** 函数名称:  
  60. ** 工作环境:  
  61. ** 作者:      
  62. ** 生成日期:  
  63. ** 功能:初始化I2C接口  
  64.         传输方式设置,主从设置,波特率设置  
  65. ** 相关文件:  
  66. ** 修改日志:  
  67. *************************************************************************/  
  68. void IIC_init(void)  
  69. {  
  70.   P10SEL |= BIT1 + BIT2;  
  71.   P10REN |= BIT1 + BIT2;  
  72.   UCB3CTL1 |= UCSWRST;                      // 置位UCSWRST  
  73.   UCB3CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C 主机, 同步 模式  
  74.   UCB3CTL1 |= UCSSEL_2;                     // SMCLK  
  75.   UCB3BR0 = 12;                             // fSCL = SMCLK/12 = ~100kHz  
  76.   UCB3BR1 = 0;  
  77.   UCB3I2CSA = 0x50;                         // 从机地址0x50  
  78.   UCB3CTL1 &= ~UCSWRST;                     // 清除UCSWRST  
  79.   UCB3IE |= UCRXIE;                         // 使能接收中断  
  80.   _EINT();  
  81. }  
  82.  
  83. /*************************************************************************  
  84. ** 函数名称:  
  85. ** 工作环境:  
  86. ** 作者:      
  87. ** 生成日期:  
  88. ** 功能:向相关的存储单元写入数据  
  89. ** 相关文件:  
  90. ** 修改日志:  
  91. *************************************************************************/  
  92. void EEPROM_Write(unsigned char high_Address,unsigned char low_Address,unsigned char Word)  
  93. {  
  94.   while (UCB3CTL1 & UCTXSTP);               // 确定总线空闲  
  95.   UCB3CTL1 |= UCTXSTT + UCTR;               // 发送起始位,确定为发送模式  
  96.   UCB3TXBUF = high_Address;                 // 发送高位地址  
  97.   while((UCB3IFG & UCTXIFG)==0);            // 判断是否发送完毕  
  98.   UCB3TXBUF = low_Address;                  // 发送低位地址  
  99.   while((UCB3IFG & UCTXIFG)==0);            // 判断是否发送完毕  
  100.   UCB3TXBUF = Word;                         // 发送数据  
  101.   while((UCB3IFG & UCTXIFG)==0);            // 判断是否发送完毕  
  102.   UCB3CTL1 |= UCTXSTP;                      // 发送停止位  
  103.   while((UCB3CTL1 & UCTXSTP)==1);           // 判断停止位是否发送完毕  
  104. }  
  105.   
  106. /*************************************************************************  
  107. ** 函数名称:字节读函数  
  108. ** 工作环境:  
  109. ** 作者:      
  110. ** 生成日期:  
  111. ** 功能:     连续读发送设置  
  112. ** 相关文件:  
  113. ** 修改日志:  
  114. *************************************************************************/  
  115. void EEPROM_read()  
  116. {  
  117.   UCB3CTL1 &= ~UCTR;                       // 确定为读  
  118.   while (UCB3CTL1 & UCTXSTP);              // 总线是否空闲  
  119.   UCB3CTL1 |= UCTXSTT;                     // 发送开始位  
  120. }  
  121.   
  122. /*************************************************************************  
  123. ** 函数名称:字节写函数  
  124. ** 工作环境:  
  125. ** 作者:      
  126. ** 生成日期:  
  127. ** 功能:     随机读发送设置  
  128. ** 相关文件:  
  129. ** 修改日志:  
  130. *************************************************************************/  
  131. void EEPROM_radom(unsigned char high_Address,unsigned char low_Address)  
  132. {  
  133.   while (UCB3CTL1 & UCTXSTP);               // Ensure stop condition got sent  
  134.   UCB3CTL1 |= UCTXSTT + UCTR;               // 发送起始位,确定为写  
  135.   UCB3TXBUF = high_Address;                 // 发送地址位高位  
  136.   while((UCB3IFG & UCTXIFG)==0);            // 判断是否发送完毕  
  137.   UCB3TXBUF = low_Address;                  // 发送地址位低位  
  138.   while((UCB3IFG & UCTXIFG)==0);            // 判断是否发送完毕  
  139.   UCB3CTL1 &= ~UCTR;                        // 确定为接收  
  140.   while (UCB3CTL1 & UCTXSTP);               // 判断总线是否被释放  
  141.   UCB3CTL1 |=UCTXSTT;                       // 重新发送起始位  
  142.   while((UCB3CTL1 & UCTXSTT)==1);           // 判断起始位是否发送成功  
  143.   for(unsigned char i=0x0;i<0x2f;i++);      // 延时确定数据已经被发送出去  
  144.   UCB3CTL1 |=UCTXSTP + UCTXNACK;            // 发送停止位和NACK位  
  145. }  
  146.   
  147. /*************************************************************************  
  148. ** 函数名称:接收中断函数  
  149. ** 工作环境:  
  150. ** 作者:      
  151. ** 生成日期:  
  152. ** 功能:    存取接收的数据  
  153. ** 相关文件:  
  154. ** 修改日志:  
  155. *************************************************************************/  
  156. #pragma vector = USCI_B3_VECTOR  
  157. __interrupt void USCIAB3_ISR(void)  
  158. {  
  159.   if(UCB3IFG  & UCRXIFG)                     // 接收中断  
  160.   {  
  161.    count++;  
  162.    RXData = UCB3RXBUF;  
  163.   }  
  164. }  


分享: 
程序在开始调试的时候,一直都调不通。数据总是只能发送一次,程序复位后,数据就发不出去了,找了好长时间都找不出来。最后找来示波器,发现数据发送一次后,没有发送停止位,程序停止后,SCL依然为低电平,没有变为高。(复位也不可以)可是将SCL断开后在插上,发现SCL就变成高电平,就可以在发送数据了。当程序发送了停止位后,这种情况就没有了,复位后就可以重新发送数据了。 
在对器件进行字节写后,立马进行读操作时,一定要加上足够长的延时,所以在程序中会有5ms的长延时。如果写停止后,立即进行读操作,可能读不到数据。不通的芯片,加的延时可能不通,但延时最好能足够长。 
呵呵,一点小小的心得。希望对大家有点用。有错误的地方,希望可以一起交流。
此贴最后由DC在2009-2-5 2:06:05编辑过 ]
微控网感谢您的参与
2
  • 头像
  • 级别
    谢谢xixi风,问一下硬件I2C在430哪几个系列里有的啊,,我手头上F413和F1481的好像都没有这个硬件I2C的。。 
    还有程序里面有点问题想问一下: 
    1.  while((UCB3CTL1 & UCTXSTT)==1);           // 判断起始位是否发送成功 
      for(unsigned char i=0x0;i<0x2f;i++);      // 延时确定数据已经被发送出去 
      UCB3CTL1 |=UCTXSTP + UCTXNACK;            // 发送停止位和NACK位 
    这里的延时是为了留出时间让数据从接收中断中读完吗 
    2.void EEPROM_read() 

      UCB3CTL1 &= ~UCTR;                       // 确定为读 
      while (UCB3CTL1 & UCTXSTP);              // 总线是否空闲 
      UCB3CTL1 |= UCTXSTT;                     // 发送开始位 

    这个函数怎么只发了起始位,没有结束位和ACK的? 
    3.void EEPROM_Write(unsigned char high_Address,unsigned char low_Address,unsigned char Word) 

      while (UCB3CTL1 & UCTXSTP);               // 确定总线空闲 
      UCB3CTL1 |= UCTXSTT + UCTR;               // 发送起始位,确定为发送模式 
      UCB3TXBUF = high_Address;                 // 发送高位地址 
      while((UCB3IFG & UCTXIFG)==0);            // 判断是否发送完毕 
      UCB3TXBUF = low_Address;                  // 发送低位地址 
      while((UCB3IFG & UCTXIFG)==0);            // 判断是否发送完毕 
      UCB3TXBUF = Word;                         // 发送数据 
      while((UCB3IFG & UCTXIFG)==0);            // 判断是否发送完毕 
      UCB3CTL1 |= UCTXSTP;                      // 发送停止位 
      while((UCB3CTL1 & UCTXSTP)==1);           // 判断停止位是否发送完毕 

    每次发送完数据不需要接收ACK的吗,,还是硬件自动接收处理的
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值