MSP430的CPU结构
12个寄存器
状态寄存器R2
MSP430F14x内部结构
MSP430F14x的低功耗模式
复位
中断
引起非可屏蔽中断的三种情况
①配置为非可屏蔽中断模式
②振荡器失效
③对Flash错误访问
时钟
IO
①PxIN(输入寄存器)
②PxOUT(输出寄存器)
③PxDIR(方向寄存器):输出输入切换
④PxSEL(功能寄存器):输出输入数字、输出输入片内外设
P1、P2提供外部中断(16个):边沿(跳变)中断,P1IN、P2IN为中断使能
USART
定时器
看门狗
定时器A(16位)
定时器B
FLASH
ADC
ADC寄存器1
LED闪烁
#include <msp430x14x.h> //基础配置
#include "BoardConfig.h"
void main(void)
{
BoardConfig.h(0xb8); //基础配置
WDCTTL=WDTPW+WDTHOLD; //关闭看门狗
P3DIR |=BIT4; //P3第4位设置为输出位
for(;;) //死循环
{
unsigned int i;
P3OUT ^=BIT4; //LED闪烁
i=50000;
do(i--); //延时
while(i!=0);
}
设置定时器 MCLK、ACLR、SMCIK
#include <msp430x14x.h> //基础配置
#include "BoardConfig.h"
void main(void)
{
BoardConfig.h(0xb8); //基础配置
WDCTTL=WDTPW+WDTHOLD; //关闭看门狗
//DCO调至频率最大
DCOCTL=DCO0+DCO1+DCO2; //DCO最大
BCSCTL2=RSEL0+RSEL1+RSEL2; //RSEL最大
BCSCTL2 |=SELS; //子系统时钟为高频振荡控制
P5DIR |=0x70; //P5设置为输出位
P5SEL |=0x70; //P5内部模块使用
while(1)
{
}
}
系统时钟从默认DCO切换到高频晶体振荡器
#include <msp430x14x.h> //基础配置
#include "BoardConfig.h"
void main(void)
{
volatile unsigned int i;
BoardConfig.h(0xb8); //基础配置
WDCTTL=WDTPW+WDTHOLD; //关闭看门狗
P5DIR |=0x10; //P5.4输出
P5SEL |=0x10; //p5.4选择MCLK时钟
BCSCTL1 &= ~XT2OFF; //片内主系统输出(XT2OFF默认为1(关闭),0时为打开)
do
{
IFG1 &=~OFIFG; //清除振荡器失效标志位(IFG1振荡器失效标志位)
for(i = 0xFF;i>0;i--); //延时
}
while((IFG1 & OFIFG)); //判断振荡器失效标志位是否真正消除
BCSCTL2 |=SELM_2; //将主时钟切换为高频晶体振荡器
for(;;);
}
设置低功耗模式 & I0 端口寄存器设置
#include <msp430x14x.h>
#include "BoardConfig.h"
void main(void)
{
BoardConfig(0xb8);
BCSCTL1 |=DIVA_2; //基础时钟定时器1s/4分频
WDTCTL = WDT_ADLY_1000; //看门狗变为间隔定时器(间隔1000ms)(实际8s)
IE1 |=WDTIE; //打开看门狗中断
//设置寄存器
P1DIR = 0xFF; //设置为输出(0xFF输出;0x00输入)(读端口值temp=P1IN)
P1OUT = 0;
P2DIR = 0xFF;
P2OUT = 0;
P3DIR = 0xFF;
P3OUT = 0x30; //0x30第三位和第四位为1(可写成BIT3+BIT4)
P4DIR = 0xFF;
P4OUT = 0;
P5DIR = 0xFF;
P5OUT = 0;
P6DIR = 0xFF;
P6OUT = 0x80; //0x80第一位为1(可写成BIT1)
while(1)
{
uint i;
_BIS_SR(LPM3_bits + GIE); //进入低功耗模式3,同时打开通用中断
P3OUT &= ~BIT5; //P3.5输出
}
}
//看门狗定时器中断
#pragma vector=WDT_VECTOR
__interrupt void watchdog_timer (void)
{
_BIC_SR_IRQ(LPM3_bits); //从低功耗模式退出(从低功耗(随眠)模式中唤醒)
}
看门狗定时器、TimerA寄存器设置
中断
#pragma vetcor = 中断向量
__interrupt void 名称(void)
{
用户程序;
}
看门狗用作间隔定时器
例1
#include <msp430x14x.h>
#include "BoardConfig.h"
void main(void)
{
BoardConfig(0xb8);
WDTCTL = WDT_MDLY_32; //看门狗为定时器(间隔时间32ms)
IE1 |=WDTIE; //打开看门狗中断,使能中断
P3DIR |=BIT4; //P3.4输出
_BIS_SR(LPM0_bits + GIE); //低功耗模式+使能全局中断
}
//看门狗定时器中断
#pragma vector=WDT_VECTOR
__interrupt void watchdog_timer (void)
{
P3OUT ^=BIT4;
}
例2
#include <msp430x14x.h>
#include "BoardConfig.h"
void main(void)
{
BoardConfig(0xb8);
WDTCTL = WDT_ADLY_250; //看门狗为定时器(时钟源为ACLK,时间间隔为250ms)
IE1 |=WDTIE; //打开看门狗中断,使能中断
P3DIR |=BIT4; //P3.4输出
_BIS_SR(LPM0_bits + GIE); //低功耗模式+使能全局中断
}
//看门狗定时器中断
#pragma vector=WDT_VECTOR
__interrupt void watchdog_timer (void)
{
P3OUT ^=BIT4;
}
比较器A寄存器
#include <msp430x14x.h> //基础配置
#include "BoardConfig.h"
void main(void)
{
BoardConfig.h(0xb8); //基础配置
WDCTTL=WDTPW+WDTHOLD; //关闭看门狗
CACTL1 = CARSEL + CAREF1 + CAON; //参考电压输入负端
CACTL2 =P2CAO; //打开外部信号输入端CA0
P2DIR = 0x00; //P2输入
P2SEL |= BIT3;
P3OUT |=BIT5; //P3.5输出
P3DIR |=BIT5;
while(1)
{
if((CACTL2 | 0xfe)==0xff) //比较电压是否超过0.25Vcc
{
P3OUT &= ~BIT5;
CACTL1 &= 0xfe; //中断标志清除(CAIFG = 0)
}
else
{
P3OUT |= BIT5;
}
}
Flash读写
#include <msp430x14x.h>
#include "BoardConfig.h"
uchar value;
uchar DataBuffer[128];
void write_SegA (uchar value);
void copy_A2B(void);
void main(void)
{
BoardConfig(0xb8);
WDTCTL=WDTPW+WDTHOLD;
FCTL2=FWKEY + FSSEL0 + FN0; //设置Flash寄存器(FWKEY(A5)写入受密码保护;FSSEL0时钟选择(主系统时钟);FN分频选择(2分频))
Value = 0;
while(1)
{
write_SegA(value++); //在信息段中写数据
copy_A2B(); //将数据从信息段A复制到信息段B
_NOP(); //在此处设置断点
}
}
void write_SegA(uchar value)
{
uchar *Flash_ptr; //Flash的指针
uint i;
Flash_ptr = (uchar*) 0x1080; //0x1080是信息段A起始位置
FCTL1 = FWKEY + ERASE; //设置擦除位(ERASE 擦除一个独立端)
FCTL3 = FWKEY; //清除锁定位(清除Lock位)
*Flash_ptr = 0; //假写入(虚拟写入擦除Flash)
FCTL1= FWKEY + WRT; //写模式
for(i=0;i<128;i++) //128个字节写入
{
*Flash_ptr ++= value;
}
FCTL1 = FWKEY; //清除写模式
FCTL3 = FWKEY + LOCK; //恢复保护
}
void copy_A2B (void)
{
uchar *Flash_ptrA; //FlashA的指针
uchar *Flash_ptyB; //FlashB的指针
uint i;
Flash_ptrA = (uchar *) 0x1080; //A端首地址
Flash_ptrB = (uchar *) 0x1000; //B端首地址
FCTL1 = FWKEY + ERASE; //设置擦除位(ERASE 擦除一个独立端)
FCTL3 = FWKEY; //清除锁定位(清除Lock位)
*Flash_ptrB = 0; //假写入(虚拟写入擦除FlashB)
FCTL1 = FWKEY + WRT; //设置写模式
for(i=0;i<128;i++)
{
DataBuffer[i] = *Flash_ptrA++;//从A中读出
*Flash_ptrB ++= DataBuffer[i];//再写入B
}
FCTL1 = FWKEY; //清除写模式
FCTL3 = FWKEY + LOCK; //恢复保护
}
异步通信寄存器设置
#include <msp430x14x.h> //基础配置
#include "BoardConfig.h"
void main(void)
{
BoardConfig.h(0xb8); //基础配置
WDCTTL=WDTPW+WDTHOLD; //关闭看门狗
P3SEL |= 0x03; //P3.4和P3.5输出
ME1 |=UTXE0 + URXE0; //设置USART触发中断(启用USART TXD/RXD)
UCTL0 |= CHAR; //8个字节
UTCYL0 |=SSEL0; //选择内部时钟源(ACLK)
//波特率调整参数
UBR00 = 0x03;
UBR10 = 0x00;
UMCTL0 = 0x4A;
UCTL0 &= ~SWRST; //复位端清除,相当于初始化
IE1 |= URXIE0; //使能接收中断
for(;;)
{
_BIS_SR(LPM3_bits + GIE); //进入低功耗,打开全局中断
while(!(IFG1 & UTXIFG0)); //保证发送区为空
TXBUF0 = RXBUF0; //发送
}
}
#pragma vector=UART0RX_VECTOR
__interrupt void usart0_rx (void)
{
_BIC_SR_IRQ(LPM3_bits); //唤醒中断
}
ADC12寄存器设置
#include <msp430x14x.h>
void main(void)
{
WDTCTL = WDTPW + WDTHOLD;
ADC12CTL0 = SHT0_2 + ADC12ON; //设置ADC控制寄存器(SHT0_2设置采样保持时钟(16时钟);ADC12ON打开ADC模块))
ADC12CTL1 = SHP; //SHP选择模式脉冲选择
ADC12IE = 0x01; //使能ADC中断
ADC12CTL0 |= ENC; //让ADC可以进行转换
P6SEL |= 0X01; //P6.0选择ADC输入
P3DIR |=BIT4; //p3.4输出
for(;;)
{
ADC12CTL0 |=ADC12SC; //启动转换
_BIS_SR(CPUOFF + GIE); //进入低功耗模式,开启全局中断
}
}
#pragma vector=ADC_VECTOR
__interrupt void ADC12_ISR (void)
{
if(ADC12MEMO < 0x7FF) //判断寄存器是否小于1/2供电电压
P3OUT &= ~BIT4;
else
P3OUT |= BIT4;
_BIC_SR_IRQ(CPUOFF); //激活CPU
}
定时器A
连续计数模式
#include <msp430x14x.h>
void main(void)
{
WDTCTL = WDTPW + WDTHOLD;
P3DIR |= BIT4; //P3.4输出
CCTL0 = CCIE; //使能CCR0中断
CCR0 = 50000; //比较周期
TACTL = TASSEL_2 + MC_2; //配置定时器寄存器2(子系统时钟+连续记数MC_2)
_BIS_SR(LPM_bits + GIE); //进入低功耗模式,打开全局中断
}
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
P3OUT ^=BIT4;
CCR0 += 50000;
}
增计数模式
#include <msp430x14x.h>
void main(void)
{
WDTCTL = WDTPW + WDTHOLD;
P3DIR |= BIT4; //P3.4输出
CCTL0 = CCIE; //使能CCR0中断
CCR0 = 20000; //比较周期
TACTL = TASSEL_2 + MC_1; //配置定时器寄存器2(子系统时钟+增记数模式MC_1)
_BIS_SR(LPM_bits + GIE); //进入低功耗模式,打开全局中断
}
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
P3OUT ^=BIT4;
}