13、MSP430 微控制器简单示例与应用

MSP430 微控制器简单示例与应用

1. MSP430G2553 比较器模块示例

在使用 MSP430G2553 微控制器时,当 CAPDx 位等于 0(默认值),对应的数字缓冲器启用;若要禁用缓冲器,需将相应位设置为 1,例如 CAPD7 对应 CA7,CAPD6 对应 CA6 等。

1.1 达到参考电压示例

此示例将比较电位器上的电压与 Comparator_A+ 模块的参考电压。我们会将模块设置为比较电位器电压与 VCAREF,且 VCAREF 设为 0.5 x Vcc,假设使用线性电位器,参考电压大致在电位器中间位置达到。

为实现此设置,需配置 Compare_A+ 模块的 CACTL1 和 CACTL2 寄存器,具体设置如下:

CACTL1 寄存器设置
| 位名称 | 位 | 用途 |
| ---- | ---- | ---- |
| CAEX | 位 7 | Comparator_A+ 交换。0 为正常操作,1 为交换输入并反转输出 |
| CARSEL | 位 6 | CAEX = 0 时,0 表示 VCAREF 应用于 + 端子,1 表示应用于 - 端子 |
| CAREFx | 位 5 - 4 | 参考电压 VCAREF 选择。00 不使用内部参考,01 参考 = 0.25 x Vcc,10 参考 = 0.50 x Vcc,11 使用二极管参考 |
| CAON | 位 3 | 开关整个比较器模块。0 关闭,1 开启 |
| CAIES | 位 2 | Comparator_A+ 中断边缘选择,此例不使用,设置无关紧要 |
| CAIE | 位 1 | Comparator_A+ 模块中断使能。0 禁用,1 启用 |
| CAIFG | 位 0 | Comparator_A+ 模块中断标志,此例设置无关紧要 |

CACTL2 寄存器设置
| 位名称 | 位 | 用途 |
| ---- | ---- | ---- |
| CASHORT | 位 7 | 短接 + 端子和 - 端子输入。0 不短接,1 短接 |
| P2CA4:P2CA0 | 位 6 和位 2 | 输入选择,根据 CACTL1.CAEX 值确定输入端子 |
| P2CA3 - P2CA1 | 位 5 - 3 | 输入选择,根据 CACTL1.CAEX 值确定输入端子 |
| CAF | 位 1 | 输出滤波器开关。0 不滤波,1 滤波 |
| CAOUT | 位 0 | 比较结果输出。0 表示 - 端子比 + 端子更正,1 表示 + 端子更正 |

1.2 硬件

此示例复用为电位器实验构建的屏蔽罩,无需其他硬件。

1.3 Energia 固件

该固件使用 Energia - 1.8.7E21 编写和测试,无需特殊库,示例代码如下:

//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
//MSP430
//Chapter 3.6.1. - Hit the reference
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
void setup()                      //(1) set-up routine
{
  pinMode(P1_6, OUTPUT);          //(2) configure Pin 6 as digital output -> LED
  CACTL2 = 0b00000100;            //(3) set the config2 for Compare Module
  CACTL1 = 0b01101000;            //(4) set the config1 for Compare Module
}
//----------------------------------------------------------------------------------
void loop()                       //(5) main software loop
{
  if((CACTL2 & 0x01) == 0)        //(6) if CA0 <= Vcaref - blink slowly
  {
    digitalWrite(P1_6, HIGH);     //(7) switch the LED on
    delay(500);                   //(8) wait 0,5 sec
    digitalWrite(P1_6, LOW);      //(9) swtich the LED off
    delay(500);                   //(10) wait 0,5 sec
  }
  else
  {
    digitalWrite(P1_6, HIGH);     //(11) switch the LED on
    delay(100);                   //(12) wait 0,1 sec
    digitalWrite(P1_6, LOW);      //(13) swtich the LED off
    delay(100);                   //(14) wait 0,1 sec
  }
}
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------

代码解释:
- setup 函数:首先将 P1.6 配置为数字输出,然后设置 CACTL2 和 CACTL1 寄存器,先设置 CACTL2 再设置 CACTL1 是因为设置 CACTL1 会开启比较器模块。
- loop 函数:通过判断 CACTL2 & 0x01 的结果,若为 0 表示 CA0 电压小于 VCAREF,LED 慢闪;否则 LED 快闪。

1.4 CCS 固件

该固件使用 CCS Version: 10.1.1.00004 编写和测试,示例代码如下:

//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
#include <msp430.h>                         //(1) include msp430 constants & declarations
void delay_ms(unsigned int iv_delay_ms);    //(2) definition of the delay routine
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
int main(void)                              //(3) main function starts here
{
    WDTCTL = WDTPW | WDTHOLD;               //(4) Stop watchdog timer
    P1DIR = 0b01000000;                     //(5) Set P1.6 to I/O output
    //         bbbbbbbb
    //         76543210
    CACTL2 = 0b00000100;                    //(6) set the config2 for Compare Module
    //         bbbbbbbb
    //         76543210
    CACTL1 = 0b01101000;                    //(7) set the config1 for Compare Module
    //--------------------------------------------------------------------------
    for(;;)                                 //(8) endless loop
    {
        if((CACTL2 & 0x01) == 0)            //(9) if CA0 <= Vcaref - blink slowly
        {
            P1OUT = 0b01000000;             //(10) switch on the LED on P1.0 (pin #2)
            delay_ms(500);                  //(11) wait 0,5 sec
            P1OUT = 0b00000000;             //(12) switch off the LED on P1.0 (pin #2)
            delay_ms(500);                  //(13) wait 0,5 sec
        } //if
        else                                //(14) if CA0 > Vcaref - blink fast
        {
            P1OUT = 0b01000000;             //(15) switch on the LED on P1.0 (pin #2)
            delay_ms(100);                  //(16) wait 0,1 sec
            P1OUT = 0b00000000;             //(17) switch off the LED on P1.0 (pin #2)
            delay_ms(100);                  //(18) wait 0,1 sec
        } //else
    } //for
}
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
void delay_ms(unsigned int iv_delay_ms)     //(19) delay routine
{
    while(iv_delay_ms--) __delay_cycles(1000);
}
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------

代码解释:
- 首先包含 msp430 库,定义延迟函数。
- main 函数中,停止看门狗定时器,将 P1.6 设置为输出,配置 CACTL2 和 CACTL1 寄存器。
- 进入无限循环,根据比较结果控制 LED 慢闪或快闪。

2. MSP430F2001 / MSP430F2012 示例

MSP430F2001 是 MSP430 系列中较简单的成员,由于 Energia IDE 不支持 MSP430F2001,需使用更复杂的 CCS IDE。以下是一些简单示例:

示例 对应外设 简短描述
闪烁的心形 GPIO 简单电路,可作为礼物
交通灯 GPIO 简单的两路交通灯,无行人灯
游戏方块 2 GPIO 类似之前的游戏方块示例
游戏方块 3 GPIO / ADC10 用于演示的游戏方块
温度测量 GPIO / ADC10 使用模拟温度传感器测量客厅温度

需注意,MSP430F2001 相比 MSP430G2553 端口更少(10 个而非 16 个),闪存内存显著减少(1kB 而非 16kB)。在部分示例中会使用微控制器的 ADC 模块,因 MSP430F2001 无 ADC 模块,后续会使用 MSP430F2012。

2.1 闪烁的心形示例

这是一个简单项目,通过连接到 P1 的多个 LED 闪烁形成心形,若使用低功耗 LED,可用 CR2032 电池(3.0V)供电。

硬件 :硬件包括 LED、几个电阻和微控制器,如 MSP430F2001、MSP430F2002 或 MSP430F2012。LED 连接方式为:LED1 由 P1.0 驱动,LED12 由 P1.6 驱动,其余 LED 成对连接,如 LED2 和 LED3 连接到 P1.1 等。

CCS 固件

//----------------------------------------------------------------------------------
#include <msp430.h>                             //(1) MSP430 library
void wait001(unsigned long int i_wt);           //(2) predefinition of wait routine
//----------------------------------------------------------------------------------
int main(void)                                  //(3) start of main function
{
    unsigned long int wait_time = 25000;        //(4) definition of wait time value
    WDTCTL = WDTPW | WDTHOLD;                   //(5) stop watchdog timer
    P1DIR = 0xFF;                               //(6) set P1.0 - P1.7 to output
    for(;;)                                     //(7) start of endless loop
    {
        P1OUT = 0x01;                           //(8.1-1) send 0b0000 0001 to output
        wait001(wait_time);                     //(8.1-2) wait predefined time
        P1OUT = 0x03;                           //(8.2-1) send 0b0000 0011 to output
        wait001(wait_time);                     //(8.2-2) wait predefined time
        P1OUT = 0x07;                           //(8.3-1) send 0b0000 0111 to output
        wait001(wait_time);                     //(8.3-2) wait predefined time
        P1OUT = 0x0F;                           //(8.4-1) send 0b0000 1111 to output
        wait001(wait_time);                     //(8.4-2) wait predefined time
        P1OUT = 0x1F;                           //(8.5-1) send 0b0001 1111 to output
        wait001(wait_time);                     //(8.5-2) wait predefined time
        P1OUT = 0x3F;                           //(8.6-1) send 0b0011 1111 to output
        wait001(wait_time);                     //(8.6-2) wait predefined time
        P1OUT = 0x7F;                           //(8.7-1) send 0b0111 1111 to output
        wait001(wait_time);                     //(8.7-2) wait predefined time
        P1OUT = 0xFF;                           //(8.8-1) send 0b1111 1111 to output
        wait001(wait_time);                     //(8.8-2) wait predefined time
        P1OUT = 0x00;                           //(8.9-1) send 0b0000 0000 to output
        wait001(wait_time);                     //(8.9-2) wait predefined time
    }
}
//----------------------------------------------------------------------------------
void wait001(unsigned long int i_wt)            //(9) wait function
{
   volatile unsigned int i;
   i = i_wt;
   do i--;
   while(i != 0);
}
//----------------------------------------------------------------------------------

代码解释:
- 包含 MSP430 库,定义等待函数。
- main 函数中,停止看门狗定时器,将 P1.0 - P1.7 设置为输出,进入无限循环,按顺序控制 LED 闪烁。

2.2 交通灯示例

交通灯示例从硬件和软件角度都较简单,设计一个简单的“Y”型交叉路口的单向交通灯,有两种模式:
- 主动模式:正常交通控制。
- 被动模式:仅黄色灯闪烁,无交通控制。

硬件 :硬件包括微控制器和多个 LED,一路交通灯的 LED 连接到 P1.0(黄色)、P1.1(绿色)、P1.2(红色),另一路连接到 P1.3(黄色)、P1.4(绿色)、P1.5(红色)。P2.6 连接按钮用于切换模式,P1.6 连接一个 LED 用于指示模式切换。还添加了 LDO 提供 3.3V 电压。

CCS 固件

//----------------------------------------------------------------------------------
#include <msp430.h>                             //(1) MSP430 library
// P1.0 = L1-Yellow
// P1.1 = L1-Green
// P1.2 = L1-Red
// P1.3 = L2-Yellow
// P1.4 = L2-Green
// P1.5 = L2-Red
// P1.6 = board LED - signalization of change from operation to yellow-flash
// P2.6 = button (connected to GND)
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
void wait001(unsigned long int i_wt);           //(2) predefinition of wait routine
void m_loop();                                  //(3) predefinition of m_loop routine
void i_loop();                                  //(4) predefinition of i_loop routine
void post_i_loop();                             //(5) predefinition of post_i_loop routine
unsigned int butt_act;                          //(6) declaration of “button-variable”
//----------------------------------------------------------------------------------
void main(void)                                 //(7) start of main function
{
    WDTCTL = WDTPW | WDTHOLD;                   //(8) stop watchdog timer
    P1DIR = 0xFF;                               //(9) set P1.0 - P1.7 as outputs
    P2DIR = 0x00;                               //(10) set P2.x as inputs
    P2REN = 0x40;                               //(11-1) enable pull-up resistor for P2.6
    P2OUT = 0xFF;                               //(11-2) enable pull-up resistor for P2.6
    P1OUT = 0x00;                               //(12) all LEDs off
    for(;;)                                     //(13) start of endless loop
    {
        P1OUT &= 0b10111111;                    //(14) transition LED off
        m_loop();                               //(15) execute main working loop - traffic light work
        P1OUT &= 0b10111111;                    //(16) transition LED off
        i_loop();                               //(17) execute idle loop - yellow light is flashing
        post_i_loop();                          //(18) execute transition
    }
}
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
void post_i_loop()                              //(19) transition phase
{
    unsigned int i;                             //(20) help variable definition
// post “off” phase:
//       just wait a while to void switch to the i_loop by pressing the button too long
    i = 3;                                      //(21) 3x repeat the loop
    do {                                        //(22) inner loop
        i--;                                    //(23) decrease the help variable
        P1OUT |= 0b00001001;                    //(24) L1 & L2-Yellow on
        wait001(30000);                         //(25) wait a while
        P1OUT &= 0b11110110;                    //(26) L1 & L2-Yellow off
        wait001(30000);                         //(27) wait a while
       }
    while(i != 0);                              //(28) end of the inner loop
}
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
void i_loop()                                   //(29) Idle loop - yellow blink
{
    unsigned int i;                             //(30) help variable definition
// first phase - keep the red on main road on first
    P1OUT &= 0b11011111;        //L2-Red off
    i = 5;
    do {
        i--;
        P1OUT |= 0b00001000;        //L2-Yellow on
        wait001(30000);
        P1OUT &= 0b11110111;        //L2-Yellow off
        wait001(30000);
       }
    while(i != 0);
// second / main phase - keep just the yellow lights flashing
    P1OUT = 0x00;                   //switch everything off
    butt_act = 0;                   // default - button is not active
    for(;;) {
        P1OUT |= 0b00001001;        //L1-Yellow on & L2-Yellow on
        wait001(30000);
        P1OUT = 0x00;               //switch all lights off
        wait001(30000);
        if (butt_act == 1) return;
    }
}
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
void m_loop()
{
    butt_act = 0;                   // default - button is not active
    P1OUT = 0x00;                   //switch all lights off
    for(;;) {
        P1OUT |= 0b00100100;        //L1-Red on & L2-Red on
        wait001(100000);
        if (butt_act == 1) return;
        P1OUT |= 0b00000001;        //L1-Yellow on
        wait001(100000);
        P1OUT &= 0b11111010;        //L1-Yellow off & L1-Red off
        P1OUT |= 0b00000010;        //L1-Green on
        wait001(400000);
        P1OUT &= 0b11111101;        //L1-Green off
        P1OUT |= 0b00000001;        //L1-Yellow on
        wait001(100000);
        P1OUT &= 0b11111110;        //L1-Yellow off
        P1OUT |= 0b00000100;        //L1-Red on
        wait001(100000);
        if (butt_act == 1) return;
        P1OUT |= 0b00001000;        //L2-Yellow on
        wait001(100000);
        P1OUT &= 0b11010111;        //L2-Yellow off & L2-Red off
        P1OUT |= 0b00010000;        //L2-Green on
        wait001(400000);
        P1OUT &= 0b11101111;        //L2-Green off
        P1OUT |= 0b00001000;        //L2-Yellow on
        wait001(100000);
        P1OUT &= 0b11110111;        //L2-Yellow off
    }
}
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
void wait001(unsigned long int i_wt)
{
    volatile unsigned long int i;
    i = i_wt;
    do {
        i--;
        if ((P2IN & 0x40) != 0x40)

代码解释:
- 包含 MSP430 库,定义多个函数和变量。
- main 函数中,停止看门狗定时器,设置 P1 为输出,P2 为输入,启用 P2.6 的上拉电阻,进入无限循环,依次执行主循环、空闲循环和过渡阶段。
- post_i_loop 函数用于过渡阶段,控制黄色灯闪烁几次。
- i_loop 函数实现空闲模式,黄色灯闪烁。
- m_loop 函数实现主动模式,按正常交通灯逻辑控制灯的亮灭。

通过以上示例,我们可以看到 MSP430 微控制器在不同应用场景下的使用方法,包括比较器模块的配置、LED 闪烁控制以及交通灯模式切换等。这些示例为进一步开发更复杂的应用提供了基础。

MSP430 微控制器简单示例与应用

3. 代码逻辑流程分析

为了更好地理解上述示例代码的执行流程,我们可以通过 mermaid 流程图来展示。

3.1 MSP430G2553 比较器模块示例流程
graph TD;
    A[开始] --> B[设置 P1.6 为输出];
    B --> C[设置 CACTL2 寄存器];
    C --> D[设置 CACTL1 寄存器,开启比较器模块];
    D --> E[进入主循环];
    E --> F{CA0 <= Vcaref?};
    F -- 是 --> G[LED 慢闪];
    F -- 否 --> H[LED 快闪];
    G --> E;
    H --> E;

这个流程图展示了 MSP430G2553 比较器模块示例的主要执行流程。首先进行初始化设置,包括引脚和寄存器的配置,然后进入主循环,在循环中根据比较结果控制 LED 的闪烁速度。

3.2 闪烁的心形示例流程
graph TD;
    A[开始] --> B[停止看门狗定时器];
    B --> C[设置 P1.0 - P1.7 为输出];
    C --> D[进入无限循环];
    D --> E[按顺序设置 P1OUT 控制 LED 闪烁];
    E --> D;

闪烁的心形示例流程较为简单,主要是进行初始化设置后,进入无限循环,在循环中按顺序控制 LED 闪烁。

3.3 交通灯示例流程
graph TD;
    A[开始] --> B[停止看门狗定时器];
    B --> C[设置 P1 为输出,P2 为输入,启用 P2.6 上拉电阻];
    C --> D[所有 LED 熄灭];
    D --> E[进入无限循环];
    E --> F[过渡 LED 熄灭];
    F --> G[执行主工作循环(主动模式)];
    G --> H[过渡 LED 熄灭];
    H --> I[执行空闲循环(被动模式)];
    I --> J[执行过渡阶段];
    J --> E;

交通灯示例的流程相对复杂,包含了初始化设置、主工作循环、空闲循环和过渡阶段。在无限循环中,依次执行这些阶段,实现交通灯的两种模式切换。

4. 总结与拓展

通过以上几个示例,我们深入了解了 MSP430 微控制器在不同场景下的应用,包括比较器模块的使用、简单的 LED 控制以及交通灯的模式切换。这些示例不仅展示了 MSP430 微控制器的基本功能,还为我们进一步开发更复杂的应用提供了思路。

4.1 总结
  • 硬件方面 :不同的示例使用了不同的硬件组合,如电位器、LED、按钮等,通过合理的连接和配置,可以实现各种功能。
  • 软件方面 :使用了 Energia 和 CCS 两种开发环境,编写了相应的固件代码。代码主要涉及引脚配置、寄存器设置、循环控制和条件判断等基本编程技巧。
4.2 拓展
  • 功能拓展 :可以在现有示例的基础上进行功能拓展。例如,在交通灯示例中,可以添加行人按钮,实现行人过街请求功能;在温度测量示例中,可以增加数据存储和显示功能,记录并显示不同时间的温度值。
  • 硬件拓展 :可以尝试使用更多的外设,如传感器、显示屏等,丰富应用的功能。例如,在闪烁的心形示例中,可以添加一个光敏传感器,根据环境光线强度自动调整 LED 的亮度。

总之,MSP430 微控制器具有丰富的功能和广泛的应用场景,通过不断学习和实践,我们可以开发出更加复杂和实用的应用程序。希望以上示例和分析能够帮助大家更好地掌握 MSP430 微控制器的使用方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值