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 微控制器的使用方法。
超级会员免费看
48

被折叠的 条评论
为什么被折叠?



