微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 无线和射频 > TI无线射频设计 > 就到9月16日, 三款TI eStore最热销产品2折起, 库存有限, 立刻行动!

就到9月16日, 三款TI eStore最热销产品2折起, 库存有限, 立刻行动!

时间:12-22 整理:3721RD 点击:


 优惠期间: 9/1 ~ 9/16, 心动不如赶快行动 !




 
获奖无数的CC2541 SensorTag 开发套件
CC2541DK-SENSOR

首款蓝牙智能开发套件,专注于无线传感器应用,也是唯一面向智能手机应用开发人员的开发套件,可用作各种智能手机附件的参考设计和开发平台。

查看技术文档 / 查看視頻
原价:$25促销价:$12.5 [ 优惠码: promrxv6 ]
基于 CC430 的 GHz 以下频谱分析仪
MSP-SA430-SUB1GHZ

是一款基于 CC430 的参考设计,它提供了操作简便且价格实惠的工具,可在低于1 GHz 频谱范围内快速启动射频开发。

查看技术文档 / 查看視頻
原价:$249促销价:$50 [ 优惠码: promwe5x ]
Chronos:无线手表开发工具
EZ430-CHRONOS-433 

既是运动手表,又是基于 CC430 高度集成的无线开发系统。它可用作手表系统的参考平台、个人局域网的个人显示器或远程数据收集的无线传感器节点。

查看技术文档 / 查看視頻
原价:$58促销价:$29 [ 优惠码: promus56 ]
 
  更多新上线 50 款 DSP, MSP430, Sitara, 无线连接开发工具,抢先购买
★ 订购小帖示:

  请点“立即购买”,“从 TI 购买”进入 eStore 购物车,点“马上结算”按步骤申请,订单摘要中记得输入优惠码并提交订单,以享有此次折扣优惠。如果碰到不能自动进入采购车的情况,请在导航栏中点击工具 → Internet 选项 → 常规设置中清空历史浏览记录
  您订购的货物将在 7-10 个工作日后送达。若遇海关查验或者缺货,会有延长。
  以上订单总额不包含进口增值税或者关税。您在收到货物时,可能会被要求支付相关税费,合计金额大致为订单金额的 25%。

希望可以有更多的产品加入到促销

ti的网站打不开啊

最近网站好像又打不开了!

【晒心得】+ TI EZ430-CHRONOS-433 无线手表代码解析

作者EEWORLD网友 azhiking

开个帖子,共同学习EZ430。使用了一下EZ430-CHRONOS ,感觉挺酷的

 !不过也遇到这样那样的问题,看到坛子上不少大神都遇到了,所以我不是最幸运的,哈哈。所以先研究研究代码,想随后重新定制一下功能。因为很多配件要么压根没有,要么很贵,就像心律测试的,没有433MHz的,而且好几十美刀,消费不起啊。直接把这些个
功能去了,以后改成别的用途!看得到,用不到,闹心!

以前没有接触过MSP430,所以估计有很多不妥当的地方,欢迎各位拍拍砖(别砸死我就行了

 )。另外也希望大家多多支持,增加点学习的信心,多点动力



代码分析,我想按照代码的执行路径,一步一步解析,有其他的引用,通过注释或者在后面的跟贴中解析。

EZ430-CHEONOS的相关文档也上传上来了,方便大家下载。

代码下载地址:http://www.ti.com/lit/sw/slac341c/slac341c.zip
比较大,里面还包含PC端驱动和软件,所以就不上传了。下面分析的代码就是这里安装包里面的代码。采用默认路径安装,则
代码的存放位置为:
C:\Program Files\Texas Instruments\eZ430-Chronos\Software Projects\Chronos Watch\eZ430-Chronos v1.1 - white PCB\CCS\Sports Watch
我收到的是白色PCB的版本,所以选择代码时选择V1.1 - white PCB。不知道有没有朋友收到黑色PCB的版本,相信那个版本还是使用
没有缩水的VTI的传感器。

啰嗦了这么多,下面开始代码分析。(一天写一点

复制内容到剪贴板

  1. // *************************************************************************************************
  2. // @fn          main
  3. // @brief       Main routine
  4. // @param       none
  5. // @return      none
  6. // *************************************************************************************************
  7. int main(void)
  8. {
  9.     // Init MCU
  10. //初始化MCU,里面做的工作主要有配置MCU电源时钟,使能IO中断,复位关闭无线发射,初始化加速度传感器、LCD、按键、定时器、压力传感器
  11.     init_application();
  12.     // Assign initial value to global variables
  13. //初始化全局变量: 初始化菜单,复位各标志位,读取校正因子,复位时钟、日期、闹钟、蜂鸣器、跑表、高度计、加速度、协议栈、温度、电池电压等
  14. //如果你不想每次复位后手表都显示4:30,可以将初始化的初值改称你希望的值

     ,包括日期。

  15.     init_global_variables();
  16.     // Branch to welcome screen
  17. //测试模式,持续按住*和up键进入测试模式,按其他键退出。测试模式显示LCD上所有的字段,关闭看门狗。
  18.     test_mode();
  19.     // Main control loop: wait in low power mode until some event needs to be processed
  20. //主循环:无事件触发的时候,进入LPM3模式
  21.     while (1)
  22.     {
  23.         // When idle go to LPM3
  24. //系统空闲进入LPM3模式
  25.         idle_loop();
  26.         // Process wake-up events
  27. //处理唤醒事件
  28. //button结构体中标志位包括手表上的五个按键——长按或短按标志位,这个结构体定义在ports.h中
  29. // Set of button flags

  30. typedef union
  31. {
  32.     struct
  33.     {
  34.         // Manual button events
  35.         u16 star : 1;           // Short STAR button press
  36.         u16 num : 1;            // Short NUM button press
  37.         u16 up : 1;             // Short UP button press
  38.         u16 down : 1;           // Short DOWN button press
  39.         u16 backlight : 1;      // Short BACKLIGHT button press
  40.         u16 star_long : 1;      // Long STAR button press
  41.         u16 num_long : 1;       // Long NUM button press
  42.         u16 star_not_long : 1;  // Between short and long STAR button press
  43.         u16 num_not_long : 1;   // Between short and long NUM button press
  44.     } flag;
  45.     u16 all_flags;              // Shortcut to all display flags (for reset)
  46. } s_button_flags;

//sys结构体中标志位表包括系统中的标志位,结构体定义在project.h中

复制内容到剪贴板

  1. // Set of system flags
  2. typedef union
  3. {
  4.     struct
  5.     {
  6.         u16 idle_timeout : 1;             // Timeout after inactivity
  7.         u16 idle_timeout_enabled : 1;     // When in set mode, timeout after a given period
  8.         u16 lock_buttons : 1;             // Lock buttons
  9.         u16 mask_buzzer : 1;              // Do not output buzz for next button event
  10.         u16 up_down_repeat_enabled : 1;   // While in set_value(), create virtual UP/DOWN button
  11.                                           // events
  12.         u16 low_battery : 1;              // 1 = Battery is low
  13.         u16 use_metric_units : 1;         // 1 = Use metric units, 0 = use English units
  14.         u16 delay_over : 1;               // 1 = Timer delay over
  15.     } flag;
  16.     u16 all_flags;                        // Shortcut to all system flags (for reset)
  17. } s_system_flags;

if (button.all_flags || sys.all_flags)
            wakeup_event();

        // Process actions requested by logic modules
//处理逻辑模块触发事件
        if (request.all_flags)
            process_requests();

        // Before going to LPM3, update display
//有任何事件触发,更新显示
        if (display.all_flags)
            display_update();
    }
}


上一贴子中Button和sys描述有误,都是联合体,由于帖子审核后不能编辑,只能在这里重新说明一下了。

说道这里,顺便提一下位域的概念。
我们看到联合体中定义了flag的结构体,每个成员后都有一个“:”加上一个数字1。如紫色标注部分。

复制内容到剪贴板

  1. typedef union
  2. {
  3.     struct
  4.     {
  5.         // Manual button events
  6.         u16 star : 1;           // Short STAR button press
  7.         u16 num : 1;            // Short NUM button press
  8.         u16 up : 1;             // Short UP button press
  9.         u16 down : 1;           // Short DOWN button press
  10.         u16 backlight : 1;      // Short BACKLIGHT button press
  11.         u16 star_long : 1;      // Long STAR button press
  12.         u16 num_long : 1;       // Long NUM button press
  13.         u16 star_not_long : 1;  // Between short and long STAR button press
  14.         u16 num_not_long : 1;   // Between short and long NUM button press
  15.     } flag;
  16.     u16 all_flags;              // Shortcut to all display flags (for reset)
  17. } s_button_flags;

至于原因和作用(以前也没有注意过,
从来么有用过MSP430,一看才发现头文件中很多都是这样定义的),参考了一下度娘,下面摘录了部分内容
/*以下内容摘自"度娘"*/
    有些信息在存储时,并不需要占用一个完整的字节,而只需占几个或一个二进制位。例如在存放一个开关量时,只有0
和1两种状态,用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。
所谓“位域”是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按
域名进行操作。   这样就可以把几个不同的对象用一个字节的二进制位域来表示。
    位域的定义和位域变量的说明位域定义与结构定义相仿,其形式为:           
    struct   位域结构名           
    {   位域列表   };         
    其中位域列表的形式为:   类型说明符   位域名:位域长度

带有'位域'的结构体并不是按照每个域对齐的,而是将一些位域成员'捆绑'在一起做对齐的。
1. 一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。
2. 由于位域不允许跨两个字节,因此位域的长度不能大于一个字节的长度,也就是说不能超过8位二进位。
3. 位域可以无位域名,这时它只用来作填充或调整位置。无名的位域是不能使用的。
/*摘录部分结束*/

    flag中定义了9个U16类型的成员,9个成员所占位域空间之和9bit>8bit(1byte),所以占2个字节的空间
    这样一来,这个联合体只占2个字节的空间,节省了很多存储空间。
    联合体中成员的英文注释已经比较明了啦,这里就不再翻译啦。

下面开始解析函数init_application();

复制内容到剪贴板

  1. // *************************************************************************************************
  2. // @fn          init_application
  3. // @brief       Initialize the microcontroller.
  4. // @param       none
  5. // @return      none
  6. // *************************************************************************************************
  7. void init_application(void)
  8. {
  9.     volatile unsigned char *ptr;
  10.     // ---------------------------------------------------------------------
  11.     // Enable watchdog
  12. //使能看门狗
  13.     // Watchdog triggers after 16 seconds when not cleared
  14. //16s位清除看门狗触发复位操作
  15. #ifdef USE_WATCHDOG
  16. //通过WDTCTL寄存器,看门狗模块可以配置为看门狗功能或者内部定时器功能。WDTCTL是一个16位的带密码保护的可读写寄存器,
  17. //读写操作必须使用字指令,写操作必须在高位字节包含写密码,0x5A。这里宏WDRPW定义为写密码0x5A00。
  18. //WDTIS为时钟间隔选择,一共有8种时钟间隔可供选择。
  19. //WDTSSEL为时钟源选择:SMCLK、ACLK、VLOCLK、X_CLK
  20. //WDRHOLD为1时停止看门狗定时器
  21.     WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK;
  22. #else
  23.     WDTCTL = WDTPW + WDTHOLD;
  24. #endif
  25.     // ---------------------------------------------------------------------
  26.     // Configure PMM
  27. //提升核心供电电压
  28.     SetVCore(3);
  29.     // Set global high power request enable
  30. //0xA5为电源管理模块寄存器写操作密码
  31. //开启PMM的高能量消耗允许
  32.     PMMCTL0_H = 0xA5;
  33.     PMMCTL0_L |= PMMHPMRE;
  34. //写入除0x5A外设和数字,锁定PMM寄存器写操作
  35.     PMMCTL0_H = 0x00;
  36.     //UCS包括5个时钟源

  37.    //XT1CLK:低频/高频晶振,可以用低频32768Hz手表晶振、标准晶振、陶瓷振荡器、或范围4MHz-32MHz的外部时钟源。

接上篇

参考电路

统一时钟系统模块包含5个时钟源:

XT1CLK:低频/高频晶振,可以用低频32768Hz手表晶振、标准晶振、陶瓷振荡器、或范围4MHz-32MHz的外部时钟源。

VLOCLK:内部非常低功率、低频率的12KHz典型频率的晶振

REFOCLK:内部的、修正过的、低频32768Hz典型频率振荡器,可以作为FLL的基准时钟。

DCOCLK:内部数控振荡器,可以用FLL稳定。

XT2CLK:可选择的高频振荡器,可以用标准晶振、陶瓷振荡器、或范围4MHz-40MHz的外部时钟源。

从统一时钟系统模块有3个有效的时钟信号:

ACLK:辅助时钟。ACLK可软件选择来自XT1CLK、REFOCLK、VLOCLK、DCOCLK、DCOCLKdiv和XT2CLK(如果有)的信号。DCOCLKdiv是在FLL模块作用下分频为1、2、4、6、8、16或32的DCOCLK频率。ACLK可软件选择为个人外设模块的信号。ACLK/n是ACLK被分为1,2,4,6,8,16,32,并且可以用一个引脚外部输出。

MCLK:系统主时钟。MCLK可软件选择来自XT1CLK、REFOCLK、VLOCLK、DCOCLK、DCOCLKdiv和XT2CLK(如果有)的信号。MCLK可分频为1,2,4,6,8,16或32。MCLK主要用于CPU与系统.

SMCLK:子系统时钟。SMCLK可软件选择来自XT1CLK、REFOCLK、VLOCLK、DCOCLK、DCOCLKdiv和XT2CLK(如果有)的信号。SMCLK可分频为1,2,4,6,8,16或32。SMCLK可软件选择为个人外设模块。


参考MSP430F6137的datasheet和EZ430的原理图,可以看到其使用的是P5.0和P5.1作为外部晶振的输入输出,所以有
P5SEL |= 0x03;              // Select XIN, XOUT on P5.0 and P5.1
接下来配置CPU时钟为12MHz

// ---------------------------------------------------------------------
    // Enable 32kHz ACLK
    P5SEL |= 0x03;              // Select XIN, XOUT on P5.0 and P5.1
    UCSCTL6 &= ~XT1OFF;         // XT1 On, Highest drive strength
    UCSCTL6 |= XCAP_3;          // Internal load cap

    UCSCTL3 = SELA__XT1CLK;     // Select XT1 as FLL reference
    UCSCTL4 = SELA__XT1CLK | SELS__DCOCLKdiv | SELM__DCOCLKdiv;

    // ---------------------------------------------------------------------
    // Configure CPU clock for 12MHz
    _BIS_SR(SCG0);              // Disable the FLL control loop
    UCSCTL0 = 0x0000;           // Set lowest possible DCOx, MODx
    UCSCTL1 = DCORSEL_5;        // Select suitable range
    UCSCTL2 = FLLD_1 + 0x16E;   // Set DCO Multiplier
    _BIC_SR(SCG0);              // Enable the FLL control loop

    // Worst-case settling time for the DCO when the DCO range bits have been
    // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
    // UG for optimization.
    // 32 x 32 x 12 MHz / 32,768 Hz = 375000 = MCLK cycles for DCO to settle
    __delay_cycles(375000);

    // Loop until XT1 & DCO stabilizes, use do-while to insure that
    // body is executed at least once
    do
    {
        UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);
        SFRIFG1 &= ~OFIFG;      // Clear fault flags
    }
    while ((SFRIFG1 & OFIFG));

    // -----------------------------------------

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top