2924|4

9795

帖子

24

TA的资源

版主

楼主
 

【TI首届低功耗设计大赛】之电子产品运行数据记录仪 [复制链接]

本帖最后由 littleshrimp 于 2014-12-29 08:31 编辑

【TI首届低功耗设计大赛】 之电子产品运行数据记录仪

在研发电子产品的过程中可能会遇到自己设计的产品运行不稳定,经过出现异常现象,查看代码又发现不了问题。这时候一搬会弄一台笔记本,把串口连接到新产品上,记录新产品运行时的日志。这种方法对测试环境有一定的局限性,比如强干扰的环境、空间受限的环境、室外环境等,如果需要长时间记录,笔记本还需要配备电源,在没无法提供电源接入的场合笔记本就无法胜任此工作。
       另外笔记本的测试成本过高,在多个产品同时测试时提供大量的笔记本也是不现实滴。
       本方案是利用MSP430FR5969优越性能,通过一条串口线接收新产品的日志数据,实时保存到FRAM中,虽然新产品测试时的日志文件很大,但通常我们更关心的是出故障时的一段数据,通过反复重写保留最新日志数据。MSP430FR5969不仅功耗低而且写入速度也非常快,所以可以使用一个小小的钮扣电池来提供电能。这样记录仪的体积会变的很小,非常适用一些空间受限的场合。
       今天一整天都在赶活动,快饿死了,废话不说,上代码:


  1. #include <stdint.h>
  2. #include <string.h>
  3. #include <msp430.h>
  4. #include "mcu_config.h"
  5. #include "hal_timer.h"
  6. #define FRAM_STORE_START_ADDRESS        0xD000                                  //数据存储起始地址
  7. #define OFFSET_LEN                      4                                       //offset自身的长度(字节)
  8. #define MAX_STORE_LEN                   10000                                   //最大存储深度
  9. #define BUFFER_LEN                      128
  10. uint32_t *FRAM_offset_write_ptr;                                                //写入偏移量的指针
  11. char *FRAM_str_write_ptr;                                                       //写入字符串的指针
  12. uint8_t str_counter = 0;                                                        //存储数据计数器

  13. uint8_t clear_frame_command[] = "clear fram";
  14. uint8_t print_frame_command[] = "print fram";
  15. uint8_t buf[BUFFER_LEN];
  16. uint8_t buf_index = 0;
  17. uint32_t fram_read_offset(void)
  18. {
  19.   uint32_t fram_store_address_offset;                                           //数据偏移地址,保留4个字节用来存储修改后的偏移地址
  20.   FRAM_offset_write_ptr = (uint32_t *)(FRAM_STORE_START_ADDRESS);               //初始化读取fram_store_address_offset 的地址            
  21.   fram_store_address_offset = *FRAM_offset_write_ptr;
  22.   if(fram_store_address_offset == 0xffffffff)                                   //第一次上电
  23.   {
  24.     fram_store_address_offset = OFFSET_LEN;
  25.   }
  26.   return fram_store_address_offset;
  27. }
  28. void fram_write_offset(uint32_t offset)
  29. {
  30.     FRAM_offset_write_ptr = (uint32_t *)(FRAM_STORE_START_ADDRESS);             //初始化读取fram_store_address_offset 的地址            
  31.     *FRAM_offset_write_ptr = offset;
  32. }
  33. void fram_write_byte(uint8_t c)
  34. {
  35.   uint32_t offset = fram_read_offset();
  36.   FRAM_str_write_ptr = (char *)(FRAM_STORE_START_ADDRESS + offset );            //初始化数据存储地址  
  37.   *FRAM_str_write_ptr++ = c;                                                    //将数据写入FRAM
  38.   if(offset++ > MAX_STORE_LEN)
  39.   {
  40.      offset = OFFSET_LEN;                                                       //从零开始记录
  41.   }                                                                             //更新指针偏移
  42.   fram_write_offset(offset);
  43. }
  44. void fram_write_n_byte(uint8_t *buf,uint16_t len)
  45. {
  46.    uint16_t i;
  47.    for(i=0;i<len;i++)
  48.    {
  49.      fram_write_byte(buf[i]);
  50.    }
  51. }
  52. void fram_write_char(char c)
  53. {
  54.    fram_write_byte((uint8_t)c);
  55. }
  56. void fram_write_str(char * str)
  57. {
  58.   uint16_t len = strlen(str);
  59.   uint32_t offset = fram_read_offset();
  60.   FRAM_str_write_ptr = (char *)(FRAM_STORE_START_ADDRESS + offset );            //初始化数据存储地址  
  61.   while(*str)
  62.   {
  63.     *FRAM_str_write_ptr++ = *str++;                                             //将数据写入FRAM
  64.   }
  65.   offset += len;                                                                //更新指针偏移
  66.   fram_write_offset(offset);
  67. }
  68. void uart_init(void)
  69. {
  70.   // Configure GPIO
  71.   P1OUT &= ~BIT0;                           // Clear P1.0 output latch
  72.   P1DIR |= BIT0;                            // For LED on P1.0
  73.   P2SEL1 |= BIT0 | BIT1;                    // USCI_A0 UART operation
  74.   P2SEL0 &= ~(BIT0 | BIT1);
  75.   // Configure USCI_A0 for UART mode
  76.   UCA0CTLW0 = UCSWRST;                      // Put eUSCI in reset
  77.   UCA0CTL1 |= UCSSEL__SMCLK;                // CLK = SMCLK
  78.   UCA0BR0 = 8;                              // 1000000/115200 = 8.68
  79.   UCA0MCTLW = 0xD600;                       // 1000000/115200 - INT(1000000/115200)=0.68
  80.                                             // UCBRSx value = 0xD6 (See UG)
  81.   UCA0BR1 = 0;
  82.   UCA0CTL1 &= ~UCSWRST;                     // release from reset
  83.   UCA0IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt
  84. }
  85. void uart_tx_byte(uint8_t b)
  86. {   
  87.     while(!(UCA0IFG & UCTXIFG));
  88.     UCA0TXBUF = b;                     // Load data onto buffer
  89. }
  90. void uart_tx_n_bytes(uint8_t *buf,uint16_t len)
  91. {
  92.    uint16_t i;
  93.    for(i=0;i<len;i++)
  94.    {
  95.       uart_tx_byte(buf[i]);
  96.    }
  97. }
  98. void uart_tx_str(char * str)
  99. {
  100.     while(*str)
  101.     {
  102.       uart_tx_byte(*str++);
  103.     }
  104. }
  105. void fram_clear(void)
  106. {
  107.     uint32_t i;
  108.     uint32_t offset = fram_read_offset();
  109.     //FRAM_str_write_ptr = (char *)(FRAM_STORE_START_ADDRESS);            //初始化数据存储地址
  110.     for(i=0;i<MAX_STORE_LEN;i++)
  111.     {  
  112.         if(i%128 == 0)
  113.         {
  114.           FRAM_str_write_ptr = (char *)(FRAM_STORE_START_ADDRESS + i);            //初始化数据存储地址
  115.         }
  116.         *FRAM_str_write_ptr++ = 0xff;   
  117.     }
  118.     uart_tx_str("done");
  119.     //将数据写入FRAM
  120. }
  121. void print_all_str(void)
  122. {
  123.   uint32_t i;
  124.   uint32_t len = fram_read_offset();                                            //获得存储的数据长度
  125.   uint8_t * start_ptr = (uint8_t *)(FRAM_STORE_START_ADDRESS + OFFSET_LEN);     
  126.   for(i=0;i<len;i++)
  127.   {
  128.       uart_tx_byte(*start_ptr++);
  129.   }
  130. }
  131. uint8_t compare(uint8_t * a,uint8_t *b,uint8_t len)
  132. {
  133.     uint8_t i;
  134.     for(i=0;i< len;i++)
  135.     {
  136.         if(a[i] != b[i])
  137.         {
  138.            return 0;                                                
  139.         }
  140.     }
  141.     return 1;
  142. }
  143. int main(void)
  144. {
  145.   uint16_t i;
  146.   WDTCTL = WDTPW | WDTHOLD;                 // Stop watchdog

  147.   // Configure GPIO
  148.   PJOUT &= ~BIT0;                           // Clear P1.0 output latch
  149.   PJDIR |= BIT0;                            // For LED on P1.0
  150.   PM5CTL0 &= ~LOCKLPM5;
  151.   __delay_cycles(65500);
  152. //  fram_write("hello eeworld!\n");
  153. //  fram_write("msp430fr5969!\n");
  154.   uart_init();
  155.   print_all_str();

  156.   while(1)
  157.   {
  158.       __bis_SR_register(LPM0_bits | GIE);     // Enter LPM0, interrupts enabled
  159.       if(compare(buf,clear_frame_command,strlen(clear_frame_command)))
  160.       {
  161.            fram_clear();
  162.            buf_index = 0;
  163.       }
  164.       else if(compare(buf,print_frame_command,strlen(print_frame_command)))
  165.       {
  166.            print_all_str();
  167.            buf_index = 0;
  168.       }
  169.       else
  170.       {
  171.           fram_write_n_byte(buf,buf_index);
  172.           buf_index = 0;
  173.       }
  174.    
  175.   }
  176. }
  177. #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
  178. #pragma vector=USCI_A0_VECTOR
  179. __interrupt void USCI_A0_ISR(void)
  180. #elif defined(__GNUC__)
  181. void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void)
  182. #else
  183. #error Compiler not supported!
  184. #endif
  185. {
  186.   switch(__even_in_range(UCA0IV,USCI_UART_UCTXCPTIFG))
  187.   {
  188.     case USCI_NONE: break;
  189.     case USCI_UART_UCRXIFG:
  190.       buf[buf_index] = UCA0RXBUF;
  191.       UCA0TXBUF = buf[buf_index];
  192.       if(buf[buf_index] == '\n')
  193.       {
  194.           __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0 on reti
  195.       }
  196.       buf_index++;
  197.       break;
  198.     case USCI_UART_UCTXIFG: break;
  199.     case USCI_UART_UCSTTIFG: break;
  200.     case USCI_UART_UCTXCPTIFG: break;
  201.   }
  202. }
复制代码

视频讲解


最新回复

好的,感谢!   详情 回复 发表于 2020-11-7 14:43

赞赏

1

查看全部赞赏

 
点赞 关注
个人签名虾扯蛋,蛋扯虾,虾扯蛋扯虾

回复
举报

667

帖子

3

TA的资源

版主

沙发
 
用SD卡不是更好?
 
 

回复

4

帖子

0

TA的资源

一粒金砂(中级)

板凳
 

#include "mcu_config.h"

#include "hal_timer.h"

请问这两个头文件哪里可以下载呢?

点评

原来的工程找不到了,这是其它地方搜到的,你可以参考一下。    详情 回复 发表于 2020-10-27 11:37
 
 
 

回复

9795

帖子

24

TA的资源

版主

4
 
asd1005823780 发表于 2020-10-26 22:37 #include "mcu_config.h" #include "hal_timer.h" 请问这两个头文件哪里可以下载呢? ...

原来的工程找不到了,这是其它地方搜到的,你可以参考一下。

mcu_config.h (4.82 KB, 下载次数: 8)



hal_timer.h (1.62 KB, 下载次数: 5)

hal_timer.c (5.78 KB, 下载次数: 4)

 

 
个人签名虾扯蛋,蛋扯虾,虾扯蛋扯虾
 
 

回复

4

帖子

0

TA的资源

一粒金砂(中级)

5
 
littleshrimp 发表于 2020-10-27 11:37 原来的工程找不到了,这是其它地方搜到的,你可以参考一下。  

好的,感谢!

 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
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
快速回复 返回顶部 返回列表