7453|4

9790

帖子

24

TA的资源

版主

楼主
 

【TI首届低功耗设计大赛】使用MSP430FR5969做的MAG3110磁力计测试 [复制链接]

好资料要分享,所有贴子里的资料不收费,不隐藏。


上来先抱怨一下,刚刚费了半天劲写的贴子,点击提交的时候只给了我这么一句话,剩下就什么也没有了,对,我写的东西也没有了。

最近用MSP430FR5969做了一个飞思卡尔地磁传感器的测试。
下面是MAG3110的官方介绍:


MAG3110是一款小型低功耗数字3-D磁传感器,具有较宽的动态范围,能够在外部磁场较高的PCB中工作。MAG3110
磁力计可以测量局部磁场的3个分量,这些分量就是地磁场与电路板中组件产生的磁场之和。
与 3轴加速度传感器结合使用时,可以获得独立于方向的精确罗盘方位信息。MAG3110采用标准I2C串行接口,能
够测量最高10高斯的局部磁场,输出数据 速率(ODR)高达80 Hz。这些输出数据速率对应的采样间隔从12 ms至数
秒不等。MAG3110采用塑料DFN封装,在-40°C至+85°C宽温度范围能够可靠工作。
特性


    最大采样率80 Hz
    400 kHz I2C接口
    工作温度-40°C至+85°C
    工作电压0.95至3.6V


因为考虑到以后做FR5969项目时的引脚灵活性,我使用了I/O口I模拟I2C,这样的好处是灵活,坏处是费电,占用cpu资源。
以前一直喜欢用硬件外设,430的用过一些单片机,I2C部分感觉硬件的代码看起来不是很爽,也比较难使用。
我在网上抄了一个软I2C的代码(太简单懒的写),然后做了一些修改,(这里的延时函数不准,因为和时钟频率有关不要拿来直接使用):

  1. /*******************************************************************************
  2. * Copyright (C), 2014, ?? ??. Co., Ltd.
  3. * FileName: soft_i2c.c
  4. * Author: littleshrimp
  5. * Version : 1.0
  6. * Date:  2014-10-3 13:16
  7. * Description:
  8. * Function List: //
  9. * 1. -------
  10. * History:
  11. * <author>   <time>                <version >  <desc>
  12. * littleshrimp      2014-10-3 13:16  1.0         build this moudle
  13. ******************************************************************************/

  14. /*******************************************************************************
  15. *  * INCLUDES
  16. *  */
  17. #include <msp430.h>
  18. #include "soft_i2c.h"
  19. /*******************************************************************************
  20. *  * MACROS
  21. *  */

  22. /*******************************************************************************
  23. *  * CONSTANTS
  24. *  */

  25. /*******************************************************************************
  26. *  * TYPEDEFS
  27. *  */

  28. /*******************************************************************************
  29. *  * GLOBAL VARIABLES
  30. *  */

  31. /*******************************************************************************
  32. *  * EXTERNAL VARIABLES
  33. *  */

  34. /*******************************************************************************
  35. *  * EXTERNAL FUNCTIONS
  36. *  */

  37. /*******************************************************************************
  38. *  * LOCAL VARIABLES
  39. *  */

  40. /*******************************************************************************
  41. *  * PROFILE CALLBACKS
  42. *  */

  43. /*******************************************************************************
  44. *  * LOCAL FUNCTIONS
  45. *  */

  46. /*******************************************************************************
  47. *  * PUBLIC FUNCTIONS
  48. *  */
  49. /*******************************************************************************
  50. * Function:      delay_ms
  51. * Description:   延时一毫秒
  52. * Calls:        
  53. * Input:         unsigned char time
  54. * Return:        void
  55. ******************************************************************************/
  56. void delay_ms(unsigned char time)
  57. {
  58.     while( time --)
  59.     {
  60.         __delay_cycles(60);
  61.     }
  62. }
  63. /*******************************************************************************
  64. * Function:      delay_us
  65. * Description:   延时一微秒
  66. * Calls:        
  67. * Return:        void
  68. ******************************************************************************/
  69. void delay_us()
  70. {
  71.     __delay_cycles(6);
  72. }
  73. /*******************************************************************************
  74. * Function:      start
  75. * Description:   起始位
  76. * Calls:        
  77. * Return:        void
  78. ******************************************************************************/
  79. void start()
  80. {
  81.     SET_SDA_OUT;
  82.     SDA_HIGH;
  83.     delay_us();
  84.     SCL_HIGH;
  85.     delay_us();
  86.     SDA_LOW;
  87.     delay_us();
  88.     SCL_LOW;
  89.     delay_us();
  90. }

  91. /*******************************************************************************
  92. * Function:      stop
  93. * Description:   停止位
  94. * Calls:        
  95. * Return:        void
  96. ******************************************************************************/
  97. void stop()
  98. {
  99.     SET_SDA_OUT;
  100.     SCL_LOW;
  101.     delay_us();
  102.     SDA_LOW;
  103.     delay_us();
  104.     SCL_HIGH;
  105.     delay_us();
  106.     SDA_HIGH;
  107.     delay_ms(10);
  108. }
  109. /*******************************************************************************
  110. * Function:      i2c_init
  111. * Description:   初始化I2C引脚
  112. * Calls:        
  113. * Return:        void
  114. ******************************************************************************/
  115. void i2c_init()
  116. {
  117.     I2C_DIR|=I2C_SCL;
  118.     I2C_DIR&=~I2C_SDA;
  119.     SCL_LOW;
  120.     stop();
  121. }
  122. /*******************************************************************************
  123. * Function:      ack
  124. * Description:   应答标志
  125. * Calls:        
  126. * Return:        void
  127. ******************************************************************************/
  128. void ack()
  129. {
  130.     SET_SDA_OUT;
  131.     SDA_LOW;
  132.     delay_us();
  133.     SCL_HIGH;
  134.     delay_us();
  135.     SCL_LOW;
  136.     delay_us();
  137.     SDA_HIGH;
  138. }
  139. /*******************************************************************************
  140. * Function:      noAck
  141. * Description:   NO ACK
  142. * Calls:        
  143. * Return:        void
  144. ******************************************************************************/
  145. void noAck()
  146. {
  147.     SET_SDA_OUT;
  148.     SDA_HIGH;
  149.     delay_us();
  150.     SCL_HIGH;
  151.     delay_us();
  152.     SCL_LOW;
  153.     delay_us();
  154. }
  155. /*******************************************************************************
  156. * Function:      read_ack
  157. * Description:   读ACK
  158. * Calls:        
  159. * Return:        unsigned char
  160. ******************************************************************************/
  161. unsigned char read_ack()
  162. {
  163.     unsigned char ack;
  164.     SCL_HIGH;
  165.     delay_us();
  166.     SET_SDA_IN;
  167.     delay_us();
  168.     ack=SDA_IN;
  169.     delay_us();
  170.     SCL_LOW;
  171.     delay_us();
  172.     return(ack);
  173. }
  174. /*******************************************************************************
  175. * Function:      write_byte
  176. * Description:   写一个字节
  177. * Calls:        
  178. * Input:         unsigned char input
  179. * Return:        void
  180. ******************************************************************************/
  181. void write_byte(unsigned char b)
  182. {
  183.     unsigned char t,t1;
  184.     SET_SDA_OUT;
  185.     for(t=8;t!=0;t--)
  186.     {
  187.         t1=b&0x80;
  188.         if(t1==0x80)
  189.             SDA_HIGH;
  190.         else
  191.             SDA_LOW;
  192.         delay_us();
  193.         SCL_HIGH;  
  194.         delay_us();
  195.         SCL_LOW;  
  196.         b=b<<1;
  197.     }
  198.     SDA_LOW;
  199. }
  200. /*******************************************************************************
  201. * Function:      read_byte
  202. * Description:   读一个字节
  203. * Calls:        
  204. * Return:        unsigned char
  205. ******************************************************************************/
  206. unsigned char read_byte()
  207. {
  208.     unsigned char t,t1,b=0;
  209.     SET_SDA_IN;
  210.     for(t = 8; t != 0; t--)
  211.     {
  212.         SCL_HIGH;  
  213.         delay_us();
  214.         b = b<<1;
  215.         SET_SDA_IN;
  216.         t1 = SDA_IN;
  217.         if(t1 == I2C_SDA)
  218.             b = b|0x01;
  219.         delay_us();
  220.         SCL_LOW;  
  221.         delay_us();
  222.     }
  223.     return(b);
  224. }
  225. /*******************************************************************************
  226. * Function:      i2c_read_n_byte
  227. * Description:   读N个字节
  228. * Calls:        
  229. * Input:         unsigned char deviceAddr//设备地址,8位格式
  230. * Input:         unsigned char dataAddr//寄存器地址
  231. * Input:         unsigned char * data//数据
  232. * Input:         unsigned char len//长度
  233. * Return:        unsigned char
  234. ******************************************************************************/
  235. unsigned char i2c_read_n_byte(unsigned char deviceAddr, unsigned char dataAddr, unsigned char

  236. *data,unsigned char len)
  237. {  
  238.     start();

  239.     write_byte(deviceAddr);//发设备地址,写
  240.     delay_us();
  241.     if(read_ack()==1)
  242.         return 0;

  243.     write_byte(dataAddr);//发寄存器地址
  244.     delay_us();
  245.     if(read_ack()==1)
  246.         return 0;

  247.     stop();
  248.     delay_us();

  249.     start();

  250.     write_byte(deviceAddr | 1);//发设备地址,读
  251.     delay_us();
  252.     if(read_ack() == 1)
  253.         return 0;

  254.     while(len != 1)
  255.     {
  256.         *data=read_byte();
  257.         ack();
  258.         data++;
  259.         len--;
  260.     }   

  261.     *data=read_byte();  //读入最后一个字节
  262.     noAck();

  263.     stop();
  264.     return 1;
  265. }


  266. /*******************************************************************************
  267. * Function:      i2c_write_n_byte
  268. * Description:   写N个字节
  269. * Calls:        
  270. * Input:         unsigned char deviceAddr//设备地址8位
  271. * Input:         unsigned char dataAddr//寄存器地址
  272. * Input:         unsigned char * data//数据
  273. * Input:         unsigned char len//长度
  274. * Return:        unsigned char
  275. ******************************************************************************/
  276. unsigned char i2c_write_n_byte(unsigned char deviceAddr, unsigned char dataAddr, unsigned char

  277. *data,unsigned char len)
  278. {
  279.     start();

  280.     write_byte(deviceAddr);            
  281.     delay_us();               
  282.     if(read_ack()==1)
  283.         return 0;

  284.     write_byte(dataAddr);
  285.     delay_us();
  286.     if(read_ack()==1)
  287.         return 0;

  288.     for(;len > 0;len--)
  289.     {
  290.         write_byte(*data);
  291.         delay_us();
  292.         if(read_ack()==1)
  293.             return 0;
  294.         data++;
  295.     }           

  296.     stop();
  297.     return 1;
  298. }
复制代码

I2C调通以后接着写MAG3110的代码,这个代码也是抄的,做了一些修改:

  1. /*******************************************************************************
  2. * Function:      mag3110_init
  3. * Description:   MAG3110初始化
  4. * Calls:        
  5. * Return:        void
  6. ******************************************************************************/
  7. void mag3110_init()
  8. {
  9.     uint8_t buf[1];
  10.     i2c_init();//初始化I2C
  11.     buf[0] = (BIT7|BIT6|BIT5|BIT0);
  12.     i2c_write_n_byte(SLV_ADDR,CTRL_REG1,buf,1); //配置寄存器CTRL_REG1
  13.     buf[0] = (BIT7|BIT4);
  14.     i2c_write_n_byte(SLV_ADDR,CTRL_REG2,buf,1); //配置寄存器CTRL_REG2
  15. }
复制代码






配置完寄存器先读一下MAG3110的WHO_AM_I寄存器,地址是0x08,看看通信能否成功,如果返回0xC4说明通信正常



  1.   i2c_read_n_byte(0x1c,WHO_AM_I,buf,1);//读WHO_AM_I
复制代码


确定通信正常后再读取寄存器DR_STATUS,等待数据准备完成后再读取相应通道的数据,下边是读取X通道的代码



  1. int read_x (void)
  2. {
  3.     while((read_1_byte(DR_STATUS)&DR_STATUS_XDR) != DR_STATUS_XDR)//等待数据准备完毕
  4.     {
  5.       delay_ms(10);
  6.     }
  7.     return read_2_byte(OUT_X_MSB);
  8. }
复制代码


能正确读取到数据以后,再次数据转换成字符串,通过串口发送给PC

  1.     sprintf(outBuf,"x:%d,y:%d,z:%d",x,y,z);
  2.     sleep(100);
  3.     uart_tx_string(outBuf);//输出到PC
复制代码

上边的sleep函数是使用定时器来实现的,和delay不同之处在于sleep延时期间CPU处于休眠状态,目的只有一个

,省电。
代码是TI触摸传感器库里的,基本没做什么修改,下边的延时函数的代码:


  1. /*******************************************************************************
  2. * Copyright (C), 2014, ?? Tech. Co., Ltd.
  3. * FileName: timer.c
  4. * Author: litleshrimp
  5. * Version : 1.0
  6. * Date:  2014-10-12 14:55
  7. * Description:
  8. * Function List: //
  9. * 1. -------
  10. * History:
  11. * <author>   <time>                <version >  <desc>
  12. * litleshrimp      2014-10-12 14:55  1.0         build this moudle
  13. ******************************************************************************/

  14. /*******************************************************************************
  15. *  * INCLUDES
  16. *  */

  17. #include "msp430.h"
  18. /*******************************************************************************
  19. *  * MACROS
  20. *  */

  21. /*******************************************************************************
  22. *  * CONSTANTS
  23. *  */

  24. /*******************************************************************************
  25. *  * TYPEDEFS
  26. *  */

  27. /*******************************************************************************
  28. *  * GLOBAL VARIABLES
  29. *  */

  30. /*******************************************************************************
  31. *  * EXTERNAL VARIABLES
  32. *  */

  33. /*******************************************************************************
  34. *  * EXTERNAL FUNCTIONS
  35. *  */

  36. /*******************************************************************************
  37. *  * LOCAL VARIABLES
  38. *  */

  39. /*******************************************************************************
  40. *  * PROFILE CALLBACKS
  41. *  */

  42. /*******************************************************************************
  43. *  * LOCAL FUNCTIONS
  44. *  */

  45. /*******************************************************************************
  46. *  * PUBLIC FUNCTIONS
  47. *  */
  48. // Sleep Function
  49. // Configures Timer A to run off ACLK, count in UP mode, places the CPU in LPM3
  50. // and enables the interrupt vector to jump to ISR upon timeout
  51. void sleep(unsigned int time)
  52. {
  53.     TA0CCR0 = time;
  54.     TA0CTL = TASSEL__ACLK + MC__UP + TACLR;
  55.     TA0CCTL0 &= ~CCIFG;
  56.     TA0CCTL0 = CCIE;
  57.     __bis_SR_register(LPM3_bits+GIE);
  58.     __no_operation();

  59. }
  60. /******************************************************************************/
  61. // Timer0_A0 Interrupt Service  Routine: Disables the timer and exists LPM3
  62. /******************************************************************************/
  63. #pragma vector=TIMER0_A0_VECTOR
  64. __interrupt void ISR_Timer0_A0(void)
  65. {
  66.   TA0CTL &= ~(MC_1);
  67.   TA0CCTL0 &= ~(CCIE);
  68.   __bic_SR_register_on_exit(LPM3_bits+GIE);
  69. }
复制代码

串口发送程序是我通过MSP430FR5969的官方例程修改来的,因为没用到接收,也就没实现接收部分,代码里有一处问题,一直没抽出时间去解决,就是串口发送完判断后如果判断数据发送完再后马上发送下一条数据就会出问题,后来我在里边加了一个延时临时解决了:

  1. /*******************************************************************************
  2. * Copyright (C), 2014, ?? Tech. Co., Ltd.
  3. * FileName: uart.c
  4. * Author: littleshrimp
  5. * Version : 1.0
  6. * Date:  2014-10-12 14:52
  7. * Description:
  8. * Function List: //
  9. * 1. -------
  10. * History:
  11. * <author>   <time>                <version >  <desc>
  12. * littleshrimp      2014-10-12 14:52  1.0         build this moudle
  13. ******************************************************************************/

  14. /*******************************************************************************
  15. *  * INCLUDES
  16. *  */

  17. #include "msp430.h"
  18. #include "uart.h"
  19. /*******************************************************************************
  20. *  * MACROS
  21. *  */

  22. /*******************************************************************************
  23. *  * CONSTANTS
  24. *  */

  25. /*******************************************************************************
  26. *  * TYPEDEFS
  27. *  */

  28. /*******************************************************************************
  29. *  * GLOBAL VARIABLES
  30. *  */

  31. /*******************************************************************************
  32. *  * EXTERNAL VARIABLES
  33. *  */

  34. /*******************************************************************************
  35. *  * EXTERNAL FUNCTIONS
  36. *  */

  37. /*******************************************************************************
  38. *  * LOCAL VARIABLES
  39. *  */

  40. /*******************************************************************************
  41. *  * PROFILE CALLBACKS
  42. *  */

  43. /*******************************************************************************
  44. *  * LOCAL FUNCTIONS
  45. *  */

  46. /*******************************************************************************
  47. *  * PUBLIC FUNCTIONS
  48. *  */

  49. /*******************************************************************************
  50. * Function:      uart_init
  51. * Description:   串口初始化
  52. * Calls:        
  53. * Input:         void
  54. * Return:        void
  55. ******************************************************************************/
  56. void uart_init(void)
  57. {
  58.   P2SEL1 |= BIT0 | BIT1;                    // USCI_A0 UART operation
  59.   P2SEL0 &= ~(BIT0 | BIT1);

  60.   // Disable the GPIO power-on default high-impedance mode to activate
  61.   // previously configured port settings
  62.   PM5CTL0 &= ~LOCKLPM5;

  63.   // Configure USCI_A0 for UART mode
  64.   UCA0CTLW0 = UCSWRST;                      // Put eUSCI in reset
  65.   UCA0CTL1 |= UCSSEL__SMCLK;                // CLK = SMCLK
  66.   UCA0BR0 = 8;                              // 1000000/115200 = 8.68
  67.   UCA0MCTLW = 0xD600;                       // 1000000/115200 - INT(1000000/115200)=0.68
  68.                                             // UCBRSx value = 0xD6 (See UG)
  69.   UCA0BR1 = 0;
  70.   UCA0CTL1 &= ~UCSWRST;                     // release from reset
  71.   //把接收中断去掉
  72. //  UCA0IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt

  73. }

  74. /*******************************************************************************
  75. * Function:      uart_tx_byte
  76. * Description:   串口发送一个字节
  77. * Calls:        
  78. * Input:         uint8_t data//要发送的数据
  79. * Return:        void
  80. ******************************************************************************/
  81. void uart_tx_byte(uint8_t data)
  82. {
  83.     while(!(UCA0IFG & UCTXIFG));
  84.     UCA0TXBUF = data;                     // Load data onto buffer
  85.     __delay_cycles(200);//有一个问题没解决,就是UCA0TXBUF数据为空后的判断,试过一些方法没成功,不得

  86. 已在这个地方加了一个延时。
  87. }

  88. /*******************************************************************************
  89. * Function:      uart_tx_string
  90. * Description:   串口发送一个字符串
  91. * Calls:        
  92. * Input:         char * str//字符串数据
  93. * Return:        void
  94. ******************************************************************************/
  95. void uart_tx_string(char *str)
  96. {
  97.   while(*str)
  98.   {
  99.     uart_tx_byte(*str);
  100.     str++;
  101.   }
  102. }
复制代码

代码写好后下到单片机里,打开串口助后就会看到数据被发送到电脑。
下边是引脚连接关系图

实物连接图:


下边是简单录制的视频(背景很吵杂,容易伤到耳朵,建议把电脑静音观看)

最后附上源代码:
ti.mcu.msp430.msp430fr5969.code.freescale.sensor.mag3110.code @19.msp430fr5969 i.rar (746.72 KB, 下载次数: 154)

这是第一步,后续再放上带图形界面的程序。

最新回复

验证需要姓名,,我是刚才问你MAG3110的那位  详情 回复 发表于 2017-10-31 15:40
 
点赞 关注
个人签名虾扯蛋,蛋扯虾,虾扯蛋扯虾

回复
举报

2万

帖子

74

TA的资源

管理员

沙发
 
辛苦楼主啦   开头提到的问题 我们再问问技术有没有办法  

建议边写帖子 边保存草稿
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身

点评

多谢提醒,才注意到有草稿按钮,平时都使用记事本备份,一旦出问题数据还有但是格式和图片需要重新配置。以后不怕了。  详情 回复 发表于 2014-10-12 21:12
 
个人签名

加油!在电子行业默默贡献自己的力量!:)

 

回复

9790

帖子

24

TA的资源

版主

板凳
 
soso 发表于 2014-10-12 19:33
辛苦楼主啦   开头提到的问题 我们再问问技术有没有办法  

建议边写帖子 边保存草稿

多谢提醒,才注意到有草稿按钮,平时都使用记事本备份,一旦出问题数据还有但是格式和图片需要重新配置。以后不怕了。
 
个人签名虾扯蛋,蛋扯虾,虾扯蛋扯虾
 
 

回复

4

帖子

0

TA的资源

一粒金砂(初级)

4
 
验证需要姓名,,我是刚才问你MAG3110的那位

点评

"猜不到"  详情 回复 发表于 2017-10-31 15:46
 
 
 

回复

9790

帖子

24

TA的资源

版主

5
 
zzh192126 发表于 2017-10-31 15:40
验证需要姓名,,我是刚才问你MAG3110的那位

"猜不到"
 
个人签名虾扯蛋,蛋扯虾,虾扯蛋扯虾
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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

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

北京市海淀区中关村大街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
快速回复 返回顶部 返回列表