BME3308 嵌入式计算机系统与实验 MSP430部分

25 年 7 月 27 日 星期日
3245 字
17 分钟

MSP430系列处理器由于在开发调试过程中往往使用软硬联调而非51单片机的keil+proteus软件仿真, 因此很多程序例子可能有硬件特异性

本文主要使用的设备为MSP430F6638实验箱

架构概述

alt text 430的架构显然就要比51单片机要先进和复杂很多:

  • Unified Clock System: 其作为主要的时钟信号, 但其还可以输出频率不同的子时钟, 以实现不同元件不同功率, 达到更加节能的效果
  • 128/256kb flash, 16kb ram: 显然比51单片机的片内空间宽裕不少
  • I/O口: 总共有4*8=32个可以触发外部中断
  • RTC_B: 实时时钟, 可以产生时分秒等实际计时, 不需要再用定时器和时钟信号来模拟

CPU

alt text 前四个为特殊寄存器: R0/PC, R1/SP即类似于51的PC和SP, 而R2/SR类似于PSW, R3/CG2是一种常数生成器, 其可以以更快的速度产生例如0, 1, FF等常用常数

其余就是通用寄存器

Memory

alt text

与51单片机最大的区别在于统一编址

封装技术:

  • IP双列直插式封装 DIP(DualIn-line Package)是指采用双列直插形式封装的集成电路芯片,绝大多数中小规模集成电路(IC)均采用这种封装形式,其引脚数一般不超过100个。
  • BGA(Ball Grid Array)球形触点阵列,表面贴装型封装之一。在印刷基板的背面按阵列方式制作出球形凸点用以代替引脚,在印刷基板的正面装配LSI 芯片,然后用模压树脂或灌封方法进行密封。也称为凸点阵列载体(PAC)
  • QFP(Quad Flat Package)  四侧引脚扁平封装。表面贴装型封装之一,引脚从四个侧面引出呈海鸥翼(L)型。基材有陶瓷、金属和塑料三种。
  • SOT封装(Small Outline Transistor)是一种用于小功率器件的表面安装封装形式。SOT封装非常适合于晶体管、电压调整器、二极管等小型的半导体器件。

基础输入输出

GPIO

通用输入输出接口(General Purpose Input Output)是MSP430最主要的I/O接口, 总共有9个, 除了P7有6个管脚以外, 其余的都有8个管脚, 即总共70个管脚. 且其中的P1~P4支持外部中断, 即共有32个外部中断管脚

GPIO的寄存器

一般寄存器用PxXX表示, 例如P1IN表示P1的输入寄存器, 总长8个bit. 端口的作用就是通过这些寄存器实现的, 比如说你想输出

  • 输入寄存器(PxIN): 这部分寄存器反应了对应接口所接收到的信号, 每位0代表接收信号为低电平, 1代表接收信号为高电平, 这部分寄存器是只读的

  • 输出寄存器(PxOUT): 输出芯片传递的信号, 0代表低电平1代表高电平. MSP的接口还支持配置上拉/下拉电阻使能(即默认为高电平/低电平), 防止引脚悬空

  • 方向寄存器(PxDIR):

    确定接口的实际接收方向, 0为input, 1为output

  • 上拉/下拉使能(PxREN):

    (仅在输入状态下有效)确认是否启用上拉/下拉电阻, 如果启用, 会根据PxOUT的值判断上拉/下拉状态

    PxDIRPxRENPxOUT效果
    00/正常输入模式
    010输入, 下拉(无输入时为低电平)
    011输入, 上拉(无输入时为高电平)
    1//正常输出模式
  • 输出驱动加强(PxDS):

    输出驱动加强, 默认关闭, 开启后副作用为电磁干扰和功耗增强

  • Port功能选择(PxSEL):

    选择是IO还是由外设决定, 0为IO模式, 1为由外设决定

    当选择为由外设决定时, 中断功能失效

  • 中断设置:

    • PxIFG: 中断标志位, 当其置1的时候就说明这个端口满足的终端条件正在尝试触发中断
    • PxIES: 中断方式选择, 0说明是拉高时触发中断, 1说明是拉低时触发中断(注意在改变这个寄存器(拉高拉低)时这个行为本身就可能触发中断)
    • PxIE: 中断使能位, 0代表关闭1代表打开

代码实例

c
#include <msp430f6638.h>
void main(void)
{
  WDTCTL = WDTPW + WDTHOLD; // 关闭看门狗
  P4DIR |= BIT5; // 将P4中第五个引脚设置为输出方向(BIT5即0b00010000)
  P4REN |= BIT0; // 启用P4.0的上/下拉电阻模式
  P4OUT |= BIT0; // 与上一行配合, 将P4OUT1置一, 实际作用为设置为上拉模式, 即无输入时默认为高电平
  // 这里 |= 是位或计算, 目的是在对特定位进行改动的同时, 不会改变其他位已有的状态
  while (1)
  {
    if (P4IN & BIT0)  // 当P4IN第0位为高电平时为true, 即按钮未被按下时
    	P4OUT |= BIT5; // 将P4.5输出寄存器设置为高电平
    else
     P4OUT &= ~BIT5; // 将P4.5
  }
}

段式LCD

回忆在51单片机里用过的多段数码管显示, 其原理是有两组引脚, 一组是控制每位哪段亮的管脚, 另一组控制具体亮的是哪一位, 这样的主要问题一是管脚复用率低下, 二是实际上每次只有一个LED灯是亮的, 虽然高频状态下理论上对人眼没区别, 但一闪一闪的底层机制还是没变.

相对而言MSP430的段式LCD比51的要先进一点, 当然也要复杂很多, 首先整体架构是这个LCD本身就有一个存储阵列, 然后外接的引脚会向这些存储阵列写入高低电平, 而某一段亮与否则与其对应的寄存器与外接的COM引脚的电压差有关.

alt text

我们可以看见LCD的显示存储是16个八位寄存器, 在这个图中, 仅一个COM端被启用, 此时每个寄存器只有两位可以获取与COM的电压差, 而每位会有一个对应控制的LCD段, 例如, 向09Ch中写入0x10, 则第三位的h段亮起, g段熄灭, 以此类推.

为了提高利用率, 还有启用两个COM, 四个COM的模式, 在4COM模式下, 每一排八位寄存器就可以控制一位LCD数字, 即可以控制16位LCD七段管

alt text

(为什么不是a~h按顺序啊)

代码示例

c
void LCDSEG_SetDigit(int pos, int value) // 让第pos位显示value值
{
  uint8_t num2seg[16] = {...} // 假设这里是标准的数字与7段管的对照表
  // 例如num2seg[7]=0b00000111, 即只有abc三个管的位为1, 也就是数字7
  if(pos < 0 || pos > 6)
    return;

  uint8_t temp, mem;
  if(value < 0 || value > 16)
    temp = 0x00;
  else
    temp = num2seg[value];
  // 这个就是一个映射, 我们之前说了显示寄存器里不是0位对应a, 1位对应b这样, 因此要映射一下
  // 这里其实就是把例如0b00000111映射成了0b11100000
  const static uint8_t map[7] ={ BIT7, BIT6, BIT5, BIT0, BIT1, BIT3, BIT2 };
  // LCDMEM其实就是一个数组, 对应LCD里的显示存储, 改变它就是改变LCD里寄存器的值
  mem = LCDMEM[pos]; // 获取目标位的当前字符
  mem &= 0x10; // 清空控制数字段的位(保留小数点(h段, 对应第五位))
  int i;
  for(i=0;i<7;++i)
  {
    if(temp & (1 << i))
      mem |= map[i]; // 完成上述的那个转换
  }
  LCDMEM[pos] = mem; // 把新值传递给寄存器
}

低功耗模式与中断

低功耗模式

MSP430的核心优势区间就是其极低的功耗, 其每个模块都可以在CPU休眠状态下独立运行, 其总共有4级的低功耗模式, 通过配置SR(Status Register)中的值来控制.

时钟

如同之前我们提到过MSP430有多套时钟系统, 分别为M(main)CLK主系统时钟, SM(sub-main)CLK子系统时钟, A(auxiliary)CLK(辅助时钟), 当处在不同的功耗模式下, 部分时钟会进入休眠:

  • MCLK: 为CPU和系统提供时钟信号, 频率可调, 但一般较高
  • SMCLK: 为需要高速时钟信号的外设(ADC等)提供信号
  • ACLK: 功率很低的低频率时钟, 为LCD等低速时钟下运行的定时器提供信号

SR(status register)

类似于51单片机里的PSW, 其包含了:

  • 算术逻辑标志位:
    • V (Overflow flag - 溢出标志): 表示有符号数运算是否发生溢出
    • N (Negative flag - 负数标志): 表示运算结果是否为负
    • Z (Zero flag - 零标志): 表示运算结果是否为零
    • C (Carry flag - 进位标志): 表示无符号数运算是否产生进位,或在减法运算中是否发生借位
  • 中断控制: GIE (General Interrupt Enable - 全局中断使能): 当 GIE 位置位时,CPU 可以响应可屏蔽中断。如果 GIE 位清零,则所有可屏蔽中断都将被禁止。在中断服务程序执行期间,GIE 位通常会被 硬件自动清零,以防止中断嵌套(除非在中断服务程序中显式地重新使能),并在中断返回(RETI 指令)时恢复。
  • 低功耗控制位: 包括SCG1, SCG0, OSCOFF, CPUOFF, 效果如下(硬件0表示关闭, 1表示开启)
    SCG1SCG0OSCOFFCPUOFF功率模式CPU/MCLKACLKSMCLK
    0000正常状态111
    0001LPM0011/0
    0101LPM1011/0
    1001LPM2010
    1101LPM3010
    1111LPM4000

中断

MSP430的中断整体和51单片机的中断相似性比较高, 都是在满足中断使能且触发中断条件的情况下, 主程序暂停, 并跳转到中断向量处开始处理中断.

简单的中断流程: 触发中断 -> 主程序完成当前指令 -> 程序指针(PC)进栈 -> SR进栈 -> 当多个中断同时触发时选取优先级最高的中断 -> 再单中断情况下重置中断标志, 如果多终端看程序 -> 除了SCG0以外的所有SR位均被清空 -> 程序指针改为指向中断向量对应的地址中的内容, 开始中断服务程序 -> ... -> 完成中断服务程序, 存在栈上的SR弹出, 存在栈上的PC弹出, 恢复执行主程序

中断的优先级(部分): 系统重置(开门狗, 重启电源等) > Timer TB0 > Timer TA0 > Timer TA1 > I/O P1 > I/O P2 > Timer TA2 > Timer TA3 > Timer TA4

定时器

看门狗

类似于51单片机的看门狗, 作为看门狗使用时, 需要主程序每隔一定时间向其发送一个"喂狗"信号(16位, 其中高八位必须是0x5a**), 否则当看门狗溢出时, 会使程序复位(发出PUC信号). 合理配置的看门狗可以有效解决绝大部分的软件跑飞的问题, 防止卡死.

看门狗的主要行为由看门狗寄存器决定

名字功能
15~8WDTPW69h/5ah看门狗口令, 写入配置时必须为0x5a, 读取时必须是0x69, 否则会触发PUC复位
7WDTHOLD0/1设为1时看门狗停止工作
6~5WDTSSEL00~11时钟源选择
4WDTTMSEL0/10时为看门狗模式, 1时为普通计时器模式
3WDTCNTCL0/1设为1时看门狗计数器清零(喂狗)
2~0WDTIS000~111时间间隔(与时钟源一起决定定时长短)

代码实例

c
int main(void) {
    WDTCTL = WDTPW | WDTSSEL__ACLK | WDTIS_4; // 看门狗模式,ACLK,约1s溢出
    P4DIR |= BIT5 | BIT6 | BIT7;    // P4.5、P4.6、P4.7设为输出(接LED)
    P4OUT |= BIT5 | BIT6 | BIT7;
    __delay_cycles(500000); // 延时100ms,使用系统时钟
    P4OUT &= ~BIT5;
    P4OUT &= ~BIT6;
    P4OUT &= ~BIT7;
    while(1) {
        P4OUT ^= BIT5;    // LED闪烁
        __delay_cycles(50000); // 延时50ms,使用系统时钟
        // 喂狗,防止复位
        WDTCTL = WDTPW | WDTCNTCL | WDTSSEL__ACLK | WDTIS_4;
        // 如果不喂狗,系统会在约1秒后自动复位,LED会重新开始闪烁
    }
}

主要就解释一下第一行和最后一行:

  • WDTPW 是就是看门狗高八位口令, WDTSSEL__ACLK 就是把时钟源设置为 ACLK, 配合 WDTIS_4 大约1s溢出一次
  • 而最后一行多出来的 WDTCNTCL 就是

定时器

普通的MSP430定时器有16位, 且有4种工作模式可选, 也可以选择不同的时钟源作为时钟信号.

工作模式

由控制寄存器里的MC位决定:

MC值模式描述
00Stop计时器停止
01Up计时器从0计到TAxCCR0寄存器所存储的值
10Continuous计时器从0计到0xFFFF
11Up/Down从0计到TAxCCR0对应值再倒数回0

其实没写完, 但我不想写了(逃)

MSP430F6638实验箱的使用

  • 右下角S1S5按键分别于与P4.0P4.4连接
  • 右下角LED1~LED5指示灯分别于P4.5, P4.6, P4.7, P5.7, P8.0连接
  • MSP430与段式LCD的连接:
    • COM03连接COM03
    • P9.7P9.0连接S0S7, P8.7P8.4连接S8S11, P8.4~P8.6有复用关系, 所以不用段式LCD时可以把跳线帽拔掉.