[原创] [TI首届低功耗设计大赛]+FR5969硬件IIC驱动MPL3115气压传感器

IC爬虫   2014-12-22 10:34 楼主
本实验的工作是使用MSP430FR5969的硬件IIC驱动飞思卡尔的MPL3115气压传感器,读取温度和海拔。IIC的使用的是直接寄存器的操作,没有使用TI的驱动库。IIC和MPL3115库源码:
scr.rar (4.15 KB)
(下载次数: 125, 2014-12-22 10:37 上传)
MSP430FR5969配置如下: 使用外部晶振 ACLK = 32768Hz, MCLK = SMCLK = BRCLK = 8MHz IIC使用的管脚为SDA->p1.6,SCL->p1.7 IIC从机地址为(7位)0x60 MP3115配置如下: 直接读海拔模式 采样速率为128 未开启中断模式 图1,逻辑分析仪抓取的IIC总线的起始的时序 QQ截图20141222100750.png 图2,是图1中的绿色标示部分的展开,配置MPL3115时序 QQ截图20141222101242.png 图3,配置MPL3115完成后,读取MPL3115相应寄存器的数据的时序 QQ截图20141222101658.png 图4,自己设计的MPL3115 PCB板 0s0-1307928572IMG_20141030_152049.jpg 图5,MPL3115焊接完成所示 0s0-1335569596IMG_20141222_093125.jpg 图6,将MPL3115模块插入NOKIA1202LaunchpadBOOS的IIC接口槽 0s0-875910404IMG_20141222_093215.jpg 图7,将MPL3115模块插入NOKIA1202LaunchpadBOOS的IIC接口槽 0s01195208890IMG_20141222_093249.jpg 图8,LCD显示海拔和温度(公司) 0s0-525119188IMG_20141222_093401.jpg 图9,LCD显示海拔和温度(公司) 0s0-601579230IMG_20141222_093428.jpg 图10,LCD显示海拔和温度(宿舍) 0s0957236518IMG_20141220_114214.jpg 本帖最后由 IC爬虫 于 2014-12-22 10:38 编辑

回复评论 (23)

  1. //******************************************************************************
  2. //  描述: I2C 驱动库
  3. //
  4. //               MSP430FR5969
  5. //             -----------------
  6. //            |              XIN|-
  7. //            |                 |  32KHz Crystal
  8. //            |             XOUT|-
  9. //         /|\|                 |
  10. //          | |                 |
  11. //          --|RTS  P1.6/UCB0SDA|
  12. //            |                 |   
  13. //            |                 |   
  14. //            |     P1.7/UCB0SCL|
  15. //            |                 |
  16. //  IC爬虫   QQ:1394024051
  17. //   
  18. //   Oct 2014
  19. //   Built with IAR Embedded Workbench V6.1
  20. //******************************************************************************
  21. #include "I2C.h"

  22. /*********************************************************
  23. *名称:I2C_Init
  24. *功能:I2C初始化
  25. *入口参数:SlaveAddr:从机的设备地址
  26. *出口参数:无
  27. *说明:设置为P1.6和P1.7为IIC通信端口,使用SMCLK(32.768khz)
  28.        作为串口的时钟,配置波特率为9600
  29. **********************************************************/
  30. void I2C_Init (uchar SlaveAddr)
  31. {
  32.   P1DIR |= BIT7;
  33.   P1OUT |= BIT7;
  34.   // 输出9个时钟 以恢复I2C总线状态
  35.   for( uchar i = 0 ; i < 9 ; i++ )
  36.   {
  37.     P1OUT |= BIT7;
  38.     __delay_cycles(8000);
  39.     P1OUT &= ~BIT7;
  40.     __delay_cycles(8000);
  41.   }
  42.    
  43.   P1SEL1 |= BIT6 | BIT7;                    // I2C pins                  
  44.   
  45.   PM5CTL0 &= ~LOCKLPM5;                     // 关闭上电端口默认输出高阻抗的功能,使能上电保持起始设置
  46.      
  47.   // Configure USCI_B0 for I2C mode
  48.   UCB0CTLW0 |= UCSWRST;                     // Software reset enabled
  49.   UCB0CTLW0 = UCMST + UCMODE_3 + UCSYNC ;   // I2C mode, 主模式, 同步
  50.   UCB0CTLW0 |= UCSSEL_2;                    // Use SMCLK, keep SW reset
  51.   //UCB0CTLW1 |= UCASTP_2;                  // 自动产生停止位在UCB0TBCNT之后
  52.   UCB0BRW = 0x0008;                         // fSCL = SMCLK/12 = ~100kHz
  53.                                             // 波特率 = SMCLK / 8
  54.   //UCB0TBCNT = 0x0005;                     // number of bytes to be received
  55.   UCB0I2CSA = SlaveAddr;                    // Slave address
  56.   UCB0CTLW0 &= ~UCSWRST;                    // Clear SW reset, resume operation
  57.   //UCB0IE |= UCRXIE | UCNACKIE | UCBCNTIE

  58. }
  59. /**********************************************************/
  60. //函数名称:void I2C_WriteInit
  61. //入口参数:无
  62. //出口参数:无
  63. //函数功能:I2C写数据初始化,发送模式,接收中断关闭,发送中断启用
  64. /**********************************************************/
  65. void I2C_WriteInit()
  66. {
  67.   UCB0CTLW0 |= UCTR;       // 写模式
  68.   UCB0IFG   &= ~UCTXIFG;   //清除发送完成标志位
  69.   UCB0IE    &= ~UCRXIE;    // disable Receive ready interrupt
  70.   UCB0IE    |=  UCTXIE;    // enable Transmit ready interrupt
  71.   UCB0CTLW0 |= UCTXSTT;    // 发送启动位和写控制字节
  72.   __delay_cycles(10);
  73. }
  74. /**********************************************************/
  75. //函数名称:void I2C_ReadInit
  76. //入口参数:无
  77. //出口参数:无
  78. //函数功能:I2C读数据初始化,接收模式,接收中断开启,发送中断关闭
  79. /**********************************************************/
  80. void I2C_ReadInit()
  81. {
  82.   UCB0CTL1  &= ~UCTR;      // UCTR=0 => Receive Mode (R/W bit = 1) 写模式  
  83.   UCB0IFG   &= ~UCRXIFG;   //清除发送完成标志位
  84.   UCB0IE    &= ~UCTXIE;    // disable Transmit ready interrupt
  85.   UCB0IE    |=  UCRXIE;     // enable Receive ready interrupt
  86.   UCB0CTL1  |= UCTXSTT;//开始条件产生,开始I2C通信
  87.   __delay_cycles(10);
  88. }
  89. /**********************************************************/
  90. //函数名称:unsigned char I2C_Write
  91. //入口参数:address->寄存器地址,data->要往寄存器地址中写入的数据
  92. //出口参数:返回IIC写是否成功的状态,1->发送失败,0->发送成功
  93. //函数功能:IIC发送data数据到设备的address这个寄存器中
  94. /**********************************************************/
  95. unsigned char I2C_Write(uchar address,uchar data)
  96. {
  97.   while( UCB0CTLW0 & UCTXSTP );
  98.   
  99.   I2C_WriteInit();              // 初始化IIC为发送模式
  100.   UCB0TXBUF = address;          // 发送字节地址
  101.   
  102.   while(!(UCB0IFG & UCTXIFG))  // 等待UCTXIFG=1 与UCTXSTT=0 同时变化 等待一个标志位即可
  103.   {
  104.     if( UCB0IFG & UCNACKIFG )  // 若无应答 UCNACKIFG=1
  105.     {
  106.       return 1;                //发送失败
  107.     }
  108.   }   
  109.   
  110.   UCB0TXBUF = data;            // 发送字节内容
  111.   while(!(UCB0IFG & UCTXIFG));// 等待UCTXIFG=1

  112.   UCB0CTLW0 |= UCTXSTP;
  113.   while(UCB0CTLW0 & UCTXSTP); // 等待发送完成
  114.   
  115.   return 0;                   //发送成功
  116. }
  117. /**********************************************************/
  118. //函数名称:unsigned char I2C_Read
  119. //入口参数:address->寄存器地址,*pword_value->把寄存器地址中读取的数据存入这个指针指向的变量
  120. //出口参数:返回IIC写是否成功的状态,1->读取失败,0->读取成功
  121. //函数功能:IIC接收设备的address这个寄存器中的数据
  122. /**********************************************************/
  123. unsigned char I2C_Read(uchar address,uchar *pword_value)
  124. {
  125.   I2C_WriteInit();              // 初始化IIC为发送模式
  126.   UCB0TXBUF = address;          // 发送字节地址
  127.   while(!(UCB0IFG & UCTXIFG))  // 等待UCTXIFG=1 与UCTXSTT=0 同时变化 等待一个标志位即可
  128.   {
  129.     if( UCB0IFG & UCNACKIFG )  // 若无应答 UCNACKIFG=1
  130.     {
  131.       return 1;                //发送失败
  132.     }
  133.   }
  134.   I2C_ReadInit();               //初始化IIC为接收模式
  135.   while(UCB0CTLW0 & UCTXSTT);  // 等待UCTXSTT=0
  136.                               
  137.   UCB0CTLW0 |= UCTXSTP;        // 先发送停止位

  138.   while(!(UCB0IFG & UCRXIFG)); // 读取字节内容
  139.   *pword_value = UCB0RXBUF;    // 读取BUF寄存器在发送停止位之后

  140.   while( UCB0CTLW0 & UCTXSTP );
  141.   
  142.   return 0;
  143. }

  144. #pragma vector = USCI_B0_VECTOR
  145. __interrupt void USCI_B0_ISR(void)
  146. {
  147.   switch(__even_in_range(UCB0IV,12))
  148.   {
  149.   case  0: break;                           // Vector  0: No interrupts
  150.   case  2: break;                           // Vector  2: ALIFG
  151.   case  4: break;                           // Vector  4: NACKIFG
  152.   case  6: break;                           // Vector  6: STTIFG
  153.   case  8: break;                           // Vector  8: STPIFG
  154.   case 10:                                  // Vector 10: RXIFG
  155.     /*
  156.         if(RX_byte)
  157.         {
  158.            RX_byte--;
  159.            P4OUT ^= BIT5;
  160.            I2CRecvBuffer[RX_byte] = UCB0RXBUF;       // Get RX data
  161.         }
  162.         else  
  163.         {
  164.           UCB0CTL1 |= UCTXSTP;       // I2C stop condition
  165.           _BIC_SR_IRQ(LPM3_bits);   // Exit LPM3
  166.         }  
  167.        break;
  168.   case 12:                                  // Vector 12: TXIFG
  169.      
  170.         if (TX_byte>0)                          // Check TX byte counter
  171.         {      
  172.             UCB0TXBUF =  *I2C_T_Buffer++;      // Load TX buffer
  173.             TX_byte--;
  174.         }
  175.    
  176.        else
  177.         {         
  178.             UCB0CTL1 |= UCTXSTP;                  // I2C stop condition
  179.             UCB0IFG &= ~UCTXIFG;                  // Clear USCI_B0 TX int flag         
  180.             _BIC_SR_IRQ(LPM3_bits);// Exit LPM3
  181.         }
  182.     break;*/
  183.    
  184.   default: break;
  185.   }
  186. }
  1. /*
  2. * This file contains some mpu6050 operation.
  3. * By IC爬虫 (1394024051@qq.com)
  4. * 2014-12-19 v1.0
  5. */
  6. #include "MPL3115.h"
  7. #include "I2C.h"
  8. /**********************************************************/
  9. //函数名称:void MPL3115Init
  10. //入口参数:无
  11. //出口参数:无
  12. //函数功能:MPL3115初始化
  13. /**********************************************************/
  14. void MPL3115_Init()
  15. {  
  16.   I2C_Init(MPL3115A2_ADDRESS);
  17.   I2C_Write(CTRL_REG1,0xB8);
  18.   I2C_Write(PT_DATA_CFG,0x07);
  19.   I2C_Write(CTRL_REG1,0xB9);
  20. }
  21. /**********************************************************/
  22. //函数名称:readAltitude
  23. //入口参数:无
  24. //出口参数:返回海拔
  25. //函数功能:读取MPL3115海拔
  26. /**********************************************************/
  27. float readAltitude()
  28. {
  29.   uchar statu;
  30.   unsigned char MSB=0,CSB=0,LSB=0;
  31.   I2C_Read(STATUS,&statu);
  32.   if(statu & 0x02)
  33.   {
  34.      I2C_Read(0x01,&MSB);
  35.      I2C_Read(0x02,&CSB);
  36.      I2C_Read(0x03,&LSB);
  37.      
  38.      float tempcsb = (LSB>>4)/16.0;

  39.      float altitude = (float)( (MSB << 8) | CSB) + tempcsb;

  40.      return(altitude);
  41.   }
  42.   return 0 ;
  43. }
  44. /**********************************************************/
  45. //函数名称:readTemp
  46. //入口参数:无
  47. //出口参数:返回温度
  48. //函数功能:读取MPL3115温度值
  49. /**********************************************************/
  50. float readTemp()
  51. {
  52.   uchar statu;
  53.   uchar T_MSB=0,T_LSB=0;
  54.   I2C_Read(STATUS,&statu);
  55.   if( statu & 0x02)
  56.   {
  57.      I2C_Read(0x04,&T_MSB);
  58.      I2C_Read(0x05,&T_LSB);

  59.      float temperature = (float)(T_MSB + (float)(T_LSB>>4)/16);

  60.      return(temperature);
  61.   }
  62.   return 0;
  63. }


点赞  2014-12-22 10:36
楼主,硬件和软件都不错,IIC写的中规中矩,思路清晰,赞一个
点赞  2014-12-22 10:46
赞!
点赞  2014-12-22 11:17
不错不错
继续坐看高手出招
So TM what......?
点赞  2014-12-22 13:49
引用: 传媒学子 发表于 2014-12-22 10:46
楼主,硬件和软件都不错,IIC写的中规中矩,思路清晰,赞一个
谢谢
点赞  2014-12-22 16:06
引用: ljj3166 发表于 2014-12-22 13:49
不错不错
继续坐看高手出招
谢谢斑竹大大
点赞  2014-12-22 16:07
好厉害!!!
点赞  2014-12-22 21:20
谢谢楼主分享
点赞  2015-3-23 10:03
还需要芯币才能下载?
点赞  2016-1-5 15:54
缺芯币啊。。。怎么才能弄到芯币。。想下载下来看看呢。
点赞  2016-1-5 15:56
引用: zhouqichishi 发表于 2016-1-5 15:56
缺芯币啊。。。怎么才能弄到芯币。。想下载下来看看呢。

你可以在论坛多多发帖,回帖,都是可以获得芯币的! 1.jpg
点赞  2016-1-5 16:37
代码运行中遇到了一点问题,调了两天才算大体解决,在这里和大家分享一下。
1月份开始学习I2C,手边的板子是MSP430FR5969lachpad。TI提供的是中断方式的I2C,不过一向觉得查询方式的用起来更容易理解一些,所以就开始参考各方资料。不知道为什么大家都喜欢用软件模拟的方式,不过我还是喜欢用硬件提供的I2C,感觉这样正式一点。找到的比较准确的代码就是楼主分享的代码,就此借鉴了一下。可惜的是还是遇到了一些问题,曾经一度想要放弃,不过幸好坚持了下来,终于找到了问题所在。为了感谢楼主的分享,也把自己的问题写出来,希望提供借鉴。
问题出在这段代码:
while(!(UCB0IFG & UCTXIFG))  // 等待UCTXIFG=1 与UCTXSTT=0 同时变化 等待一个标志位即可
  {
    if( UCB0IFG & UCNACKIFG )  // 若无应答 UCNACKIFG=1
    {
      return 1;                //发送失败
    }
  }   

我在写代码的时候觉得有无应答的判断并不重要,MSP430应该会自动进行有无ACK的判断,如果没有应答软件应该无法运行下去。所以将这一段省略为:
while(!(UCB0IFG & UCTXIFG)); //而且IAR 提供的库函数中也是这样写的,所以就没有多想。
当然结果肯定是不正常的,虽然软件能够正常运行,但是读出的数据总是0xFF。实际上数据既没有写进去,也没有读出来。
最后的分析是:在发送一个字节后一定要做一下判断if(UCB0IFG & UCNACKIFG),这样才能保证代码的正确运行。
点赞  2016-1-7 22:08
引用: 姜囡殁 发表于 2016-1-7 22:08
代码运行中遇到了一点问题,调了两天才算大体解决,在这里和大家分享一下。
1月份开始学习I2C,手边的板子 ...

挺好的经验分享
加油!在电子行业默默贡献自己的力量!:)
点赞  2016-1-8 09:14
                     
点赞  2016-3-18 22:14
有人用IO口模拟IIC与 mpl3115通信的程序吗?
点赞  2016-3-29 14:55
刚弄了个MPL3115 ,果断收藏!
点赞  2016-7-13 17:17
很棒,谢谢分享,正好有用,为什么不用TI的库来写呢?
点赞  2016-8-12 08:22
回复的时候字数总是不够,所以就没有积分,我的积分少得可怜,为啥论坛有这个规定呢?

字数得要超过多少才有积分的啊?这不是让我水多点嘛,我很能水的,别酱紫。。。。
点赞  2016-8-12 08:23
楼主,MPL3115你自己画的板子的原理图有么?
点赞  2016-8-21 16:19
12下一页
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复