第一章 绪论
1.1 单片机基础
全称:单片微型计算机(Single Chip MicroComputer)
它是把MPU、存储器、I/O口、定时器/计数器、中断系统、时钟电路、A/D-D/A等集成在一个芯片上构成的微型计算机系统。
单片机又称:单片微控制器、嵌入式微控制器
1.2 MSP430F663x片内资源
MSP430F663x 系列配置有一个高性能12 位ADC、比较器、两个USCI、USB2.0、硬件乘法器、DMA、四个16 位定时器、带有报警功能的RTC、LCD 驱动器和多达74 个I/O 。
1.3 进制转换
【注意】小数的进制转换
1.4 原码、反码、补码的书写
【注意】一般是8位补码,有时也有16位补码
1.5 位操作
P1OUT|=BIT1; //P1.1置1
P1OUT|=BIT0+BIT2+BIT6+BIT7; //P1.0、 P1.2、 P1.6、 P1.7置1
P1OUT&=~BIT7; //P1.7清0
P1OUT&=~(BIT1+BIT3); //P1.3、 P1.1清0
P1OUT^=BIT0; //P1.0取反
P1OUT^= BIT0+BIT2+BIT4+BIT6; //P1.0、 P1.2、 P1.4、 P1.6取反
MSP430的C编译器不支持位寻址,所以运算中尽量减少位操作。
第2章 硬件结构
2.1 MSP430 CPU 与 MSP430X CPU
MSP430 CPU是指MSP430F1xx系列采用的16 位CPU,数据总线宽度16位,地址总线宽度16位,寄存器16位。寻址空间216=64KB。
MSP430X CPU(简称CPUX)是指MSP430F2xx/4xx/5xx/6xx系列采用的CPU,数据总线宽度16位,地址总线宽度20位,寄存器20位。寻址空间220=1MB。CPUX的算术逻辑单元(ALU)也可以完成20位的计算。
CPUX向下兼容MSP430 CPU。
2.2 PC、SP、SR
PC:
取完指令后CPU根据该指令的字节数自动增量PC,因此20位的PC(R0)的值总是指向下一条要执行的指令。PC总是指向偶地址(bit0=0)。
SP:
20位的堆栈指针,始终指向偶地址
【作用】:保护现场和恢复现场。
先进后出
堆栈分两种:
(1)向上增长,栈底占用较低地址,栈顶占用较高地址:8051
(2)向下增长,栈底占用较高地址,栈顶占用较低地址:MSP430、AVR
(3)ARM支持两种增长方式的堆栈。
SR:
用作源或目标寄存器的16位状态寄存器(SR,也称为R2)只能用于通过字指令寻址的寄存器模式。 寻址模式的其余组合用于支持常数发生器。
SCG1:系统时钟发生器1该位可用于根据器件系列启用或禁用时钟系统中的功能; 例如,DCO偏置启用或禁用。
SCG0:系统时钟发生器0该位可用于根据器件系列启用或禁用时钟系统中的功能; 例如,FLL(频率锁定环)启用或禁用。
OSCOFF:关闭振荡器。 该位置1时,当LFXT1 CLK不用于MCLK或SMCLK时,它会关闭LFXT1晶体振荡器。
CPUOFF:CPU关闭。 该位置1时,将关闭CPU。
CPUOFF,OSCOFF,SCGO和SCG1位请求系统进入低功耗模式。
【例如】:关闭和打开锁频环(FLL)
__bis_SR_register(SCG0); // Disable the FLL control loop
UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx
UCSCTL1 = DCORSEL_3; // Set RSELx for DCO = 4.9 MHz
UCSCTL2 = FLLD_1 + 74; // Set DCO Multiplier for 2.45MHz
// (FLL_N + 1) * FLLRef = FdcoCLKDIV
// (74 + 1) * 32768 = 2.45MHz
// Set FLL Div = fDCOCLK/2
__bic_SR_register(SCG0); // Enable the FLL control loop
//其中__bis_SR_register()函数是将SR寄存器中的相应位置1
//__bic_SR_register()函数是将SR寄存器中的相应位置0
2.3 三种系统复位
2.4 复位状态
在BOR之后,初始设备条件是:
RST / NMI引脚配置为复位模式。
I / O引脚切换到输入模式。
状态寄存器(SR)复位。
看门狗定时器在看门狗模式下上电。
第3章 中断、时钟与低功耗
3.1 中断
3.1.1 各种中断向量
【注意】排序顺序为实验顺序,不代表优先级大小
中断向量的计算
3.1.2 中断优先级
不同中断源发出的中断请求重要程度不同,每个中断源对应一个优先级,称为中断优先级。
【作用】:多个中断同时发生时,决定哪个中断被响应。
【注意】:
中断优先级只有在多个中断同时到来时才起作用,在中断嵌套中是不考虑的
中断优先级固定不变,取决于模块在中断向量表中的排序
3.1.3 中断嵌套
CPU响应某一中断时,在开总中断的前提下若有其他中断发生,CPU将中断当前ISR,执行新的ISR。
MSP430默认关闭中断嵌套,即进入中断服务函数后,默认关闭总中断。如果想要开启中断嵌套需要用户使用软件开启总中断。
开启和关闭总中断例程中最常用的方式是
__bis_SR_register(GIE); // 开启总中断
__bic_SR_register(GIE); // 关闭总中断
//其中__bis_SR_register()函数是将SR寄存器中的相应位置1
//__bic_SR_register()函数是将SR寄存器中的相应位置0
3.1.4 中断服务函数
如果是多元中断,可能会在终端服务函数中查看是那种中断置位,即用if或switch语句判断中断标志位是否为1.例如:
// Timer_A1 Interrupt Vector (TAIV) handler
#pragma vector=TIMER0_A1_VECTOR
__interrupt void TIMER0_A1_ISR(void)
{
switch(__even_in_range(TA0IV,14))// __even_in_range()本征函数,用于多源中断的查询。
{
case 0: break; // No interrupt
case 2: break; // CCR1 not used
case 4: break; // CCR2 not used
case 6: break; // reserved
case 8: break; // reserved
case 10: break; // reserved
case 12: break; // reserved
case 14: P4OUT ^= BIT1; // TAIFG
break;
default: break;
}
}
3.2 UCS时钟系统
3.2.1 五种时钟源和三种时钟信号
【注】DCOCLKDIV时钟为DCOCLK分频得到
3.2.2 FLL——锁频环
计算公式:fDCOCLK ÷[D × (N + 1) ] = fFLLREFCLK ÷ n
【注释】:
D:FLLD,默认为2
N:FLLN,默认为31
n:FLLREFDIV, 默认为1
fFLLREFCLK :FLL的参考时钟,默认为XT1CLK(32768Hz)
所以fDCOCLK 默认为2097152Hz,fDCOCLKDIV默认为1048576Hz
3.2.3 UCS复位之后
由于复位的时候XT1CLK未稳定,所以ACLK和FLL的参考时钟会自动变为REFOCLK(注意这里是REFOCLK,和后边WDT看门狗模式下的时钟故障保护功能,自动变成VLOCLK相区别)
根据实验情况,如果在配置ACLK和FLL之前,XT1CLK未稳定,那么时钟频率会相对变低
//稳定XT1CLK和XT2CLK的程序
//1. 解锁XT1的引脚,这是f66xx设备独有的
while(BAKCTL & LOCKBAK)// Unlock XT1 pins
{
BAKCTL &= ~(LOCKBAK);
}
//2. 设置XT2的引脚
P7SEL |= BIT2 + BIT3; // Port select XT2
//3. 开启XT1, XT2
UCSCTL6 &= ~(XT1OFF + XT2OFF); // Set XT1, XT2 On
//4. 稳定XT1CLK、XT2CLK、DCOCLK
do
{
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags
SFRIFG1 &= ~OFIFG; // Clear fault flags
}while (SFRIFG1&OFIFG); // Test oscillator fault flag
//5. ACLK选择XT1CLK、SMCLK选择XT2CLK
UCSCTL4 |= SELA__XT1CLK + SELS__XT2CLK; // Select SMCLK, ACLK source
3.2.4 设置DCOCLK输出的频率范围
使用UCSCTL1寄存器中的DCORSEL位来设置范围
不用看UCSCTL0寄存器中的DCO和MOD位,单片机会自动设置
尽可能让输出的频率在DCORSEL控制的范围的中间位置
3.2.5 UCS模块失效安全操作
任何一种失效都会导致OFIFG(振荡器失效中断、非屏蔽)
受到OFIE使能位控制
振荡器关闭、打开但未正常工作时,对应振荡器失效位XT1 LFOFFG,XT1 HFOFFG, XT2OFFG置位;
振荡器失效位一旦置位必须用户软件清除;
若用户软件清除振荡器失效位后失效条件依然存在,振荡器失效位会自动置位。
振荡器失效事件不受GIE控制。
3.3 低功耗
最常用的开启低功耗的方式
__bis_SR_register(LPM3_bits);//开启低功耗模式3
__bic_SR_register(LPM3_bits);//关闭低功耗模式3
//也可以这样:
LPM3;//开启
LPM3_EXIT;//关闭
第四章 数字I/O模块
4.1 数字I/O模块寄存器设置
关于PxDIR,PxREN和PxOUT在正确I / O配置中的用法
对于P1,P2引脚而言,具有中断能力,利用PxIFG, PxIE,和PxIES 寄存器进行配置。
4.2 按键
4.2.1 关于上下拉
对于按键必须要有上下拉,因为要有默认的输入值,不能让输入值处于浮空状态
可以选择内部的上下拉和外部的上下拉
MSP430F6638具有内部上下拉,所以不一定必须使用外部上下拉
4.2.2 按键消抖
软件消抖:在首次检测到按键按下后,先执行一段延时子程序,然后再次确认按键是否按下,达到消抖目的。
硬件消抖:常用双稳态电路、单稳态电路和RC积分电路等方法。
4.3 额外的东西
对于在中断服务函数中手动清零中断标志位IFG,其实有一种更方便的方法老师没讲——PxIV,这个东西会在后边讲Timer_A中看到类似的寄存器——TAxIV
读/写这个寄存器都会使得正在等待处理的最高中断标志位清零
如果有多个中断同时到来,那么处理完最高中断后会从新开启一个中断。
第5章 看门狗WDT_A
5.1 看门狗概述
5.1.1 看门狗的作用
看门狗(Watchdog Timer-WDT)分硬件看门狗和软件看门狗,用于程序跑飞时的系统复位。
5.1.2 程序跑飞
程序跑飞不是一种硬件故障,但它会引起死机。
5.1.3 看门狗是什么
简单的说是一个定时器,从程序开始运行的时候就开始计数,当计数满的时候就会使程序复位。所以要在计满之前让看门狗定时器的数值清零,俗称喂狗。如果在计满之前看门狗没有收到喂狗信号,则认为程序已经跑飞。
5.1.4 看门狗的两种功能
分别是看门狗模式和间隔定时器模式
这两种模式使用不同的中断向量,但是都是单源中断(所以中断标志位WDTIFG可以自动清零)
看门狗模式的中断是系统中断
间隔定时器的中断是可屏蔽中断
看门狗和间隔定时器使用相同的中断标志位:WDTIFG
这两种模式不能同时使用
看门狗模式具有时钟故障保护功能,但是间隔定时器模式没有
5.2 看门狗的默认复位时间
WDTIS默认为4h,其时钟信号默认为SMCLK,而SMCLK的时钟源默认为DCOCLKDIV,DCOCLKDIV的频率默认为1048576Hz,所以时间间隔默认为
5.3 时钟故障保护
为保证WDT在看门狗模式下能工作,如果SMCLK或ACLK作为WDT_A时钟源发生故障,WDT将自己的时钟自动调整为VLOCLK(注意这里是VLOCLK,而不是REFOCLK )
WDT_A提供故障安全时钟功能,确保在看门狗模式下不能禁止WDT_A的时钟。 这意味着LPM可能会受到WDT_A时钟选择的影响。
当WDT_A模块用于间隔定时器模式时,WDT A中没有用于时钟源的故障安全功能。
5.4 低功耗模式下的操作
用程序的要求和使用的时钟类型决定了WDT_A的配置方式。 例如,如果用户想要使用LPM3,则WDT_A不应配置为看门狗模式,其时钟源最初来自DCO,XT1为高频模式,XT2为SMCLK或ACLK。 在这种情况下,SMCLK或ACLK将保持启用状态,从而增加LPM3的当前消耗。
5.5 关闭看门狗的方法
//1. 正确的方法
WDTCTL = (WDTPW + WDTHOLD);
WDTCTL = WDTPW | WDTHOLD;
//2. 错误的方法
WDTCTL |= (WDTPW + WDTHOLD);//错误
第6章 定时器Timer_A
6.1 各种寄存器(x代表数字,比如我们用的TA1,那么x=1)
6.1.1 TAxR——16位计数器
16位定时器/计数器寄存器TAxR随时钟信号的每个上升沿递增或递减(取决于工作模式)。 可以使用软件读取或写入TAxR。 另外,定时器在溢出时可以产生中断。
可以通过将TAxCTL寄存器中的TACLR位置1来清零TAxR。 将该位置1会复位TAxR,定时器时钟分频器逻辑和计数方向。 TACLR位自动复位,始终读为0。
6.1.2 TAxCTL——时钟控制
TASSEL——选择时钟
MC——设置计数模式
MC Mode 中文 Description
TACLR——清空TAxR
TAIE——中断使能
6.1.3 TAxCCTLn——Timer_Ax捕捉/比较控制寄存器n
捕获比较模块一共7个,n=(0~6)
CAP——设置捕获模式/比较模式
OUTMOD——设置输出方式(共8种)
第一种是电平输出,可以指定输入的电平(OUT位)
模式 2, 3, 6, and 7 对于 TAxCCR0 是没有用的因为 EQUx = EQU0.
CCIE——中断使能
【注意】:这个是捕获比较的中断使能,和上面的Timer_A的中断不同。
6.1.4 TAxCCRn——捕捉/比较寄存器n
放数的
6.1.5 TAxIV——中断寄存器
用于查询是哪个中断到来
其中包含的中断事件不包括TAxCCR0中断
6.2 中断
6.2.1TAxCCR0中断
TAxCCR0 CCIFG具有最高的Timer_A中断优先级,并具有专用中断向量(TIMER0_A0_VECTOR)。 当TAxCCR0中断请求被服务时,TAxCCR0 CCIFG自动复位。
这是一个单源中断
6.2.2 TAxIV中断
TAxCCRy CCIFG和TAIFG被优先化并组合以获得单个中断向量。(这表明其优先级可以被软件设置,这和所谓中断优先级是两个概念) 这话大错特错!!优先级不能设置,写错了!
TAxIV用于确定请求中断的标志。
禁用Timer_A中断不会影响TAxIV值。
TAxIV寄存器的任何访问,读取或写入都会自动重置最高的待处理中断标志。 如果设置了另一个中断标志,则在服务初始中断后立即产生另一个中断。(如果你们做过实验会发现后边的串口通信也有这个性质)
这是一个多源中断,但是不用手动清中断标志位
6.3 程序
6.3.1 TA0CCR0 中断
下面程序采用增计数模式,那么增加到TA0CCR0 就会产生TA0CCR0 中断,然后计数器自动清零,重新计数
【注意】:这是一个单源中断
#include void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT P4DIR |= BIT1; // P4.1 output TA0CCTL0 = CCIE; // 开启TA0CCR0 的中断 TA0CCR0 = 50000; TA0CTL = TASSEL__SMCLK + MC__UP + TACLR; // 时钟源选SMCLK,增计数模式,清零计数器 _BIS_SR(LPM0_bits + GIE); // Enter LPM0, enable interrupts _NOP(); // For debugger } // Timer_A0 ISR #pragma vector=TIMER0_A0_VECTOR __interrupt void TIMER0_A0_ISR(void) // 注意这个中断向量 { P4OUT } 6.3.2 TAxIV中断 下面程序,由于是连续计数模式,计数器会从0到FFFF重复计数,但是又未设置TA0CCRn的值,所以只在0FFFFh的时候才产生TAIFG这个中断,这个中断的查询在TAxIV=14的位置 【注意】:这是多源中断 #include void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT P4DIR |= BIT1; // P4.1 output TA0CTL = TASSEL__ACLK + MC__CONTINUOUS + TACLR + TAIE; // 时钟源为ACLK,连续计数模式,清空计数器,是能中断 __bis_SR_register(LPM3_bits + GIE); //【区分】:__bic_SR_register()这个函数是和上面的作用相反, //比如__bic_SR_register(LPM0_bits + GIE);是关闭低功耗并且关闭总中断 _NOP(); } #pragma vector=TIMER0_A1_VECTOR // 这个中断向量和上面的程序不一样 __interrupt void TIMER0_A1_ISR(void) { switch(__even_in_range(TA0IV,14))// __even_in_range()本征函数,用于多源中断的查询。 { case 0: break; // No interrupt case 2: break; // CCR1 not used case 4: break; // CCR2 not used case 6: break; // reserved case 8: break; // reserved case 10: break; // reserved case 12: break; // reserved case 14: P4OUT ^= BIT1; // TAIFG break; default: break; } } 第7章 模数转换器ADC12_A 7.1 概述 7.1.1 ADC12 这是一个12位的模拟量转换为数字量的内部外设 主要的过程为: 将模拟量通过某个单片机的引脚输入进去 ADC读取该引脚的电压值,并根据参考电压的大小,将其转化为12位的数字量的值 将这个12位的数字值保存到一个12位寄存器中 在ADC12的中断服务函数中读取这个寄存器的值,从而进行相应的操作 7.1.2 分辨率 用数字量的二进制位数来表示。如12位ADC的分辨率就是12位 用1个LSB使输出变化的程度表示,如12位ADC的分辨率为满刻度的1/212 7.1.3 量化间隔 满量程输入电压/(2n-1) 其中n为ADC的位数,这里为12 满量程输入电压一般为正参考电压,即VR+ 7.1.4 量化误差 是ADC的有限位数对模拟量进行量化而引起的误差,有两种计算方法: 绝对误差=量化间隔/2 相对误差=1/(2n+1) 这里的n还是12 7.1.5 关于参考电压的选取(REFMSTR的设置) 在REFCTL这个寄存器中有一个神奇的位叫做REFMSTR,可以通过它来设定由谁控制ADC12的参考电压。 当REFMSTR=1时,ADC12允许通过REFCTL寄存器控制参考系统,ADC寄存器组(ADC12REFON,ADC12REF2_5,ADC12TCOFF和ADC12REFOUT)内的原先的控制位就失去了作用,但是 ADC12SR和ADC12REFBURST仍由ADC12_A控制,因为它们非常特定于ADC12_A模块。 当REFMSTR=0时,ADC12的参考电压由它自己的寄存器组设置,就是上边提到的那些寄存器 7.1.6 转换的计算公式 其中4095的由来是212−1=4095 2^{12}-1=40952 12 −1=4095 当输入电压大于正参考电压时,寄存器的值为0x0fff,当输入电压小于负参考电压时,寄存器的值为0x0000 7.2 ADC12的采样 7.2.1 SHI 一次AD转换由采样输入信号SHI的上升沿触发 SHI的来源: 7.2.2 SAMPCON 采样控制信号SAMPCON控制采样周期和转换开始,当SAMPCON 为高时采样激活, SAMPCON 的下降沿触发模数转换。 ADC12SHP 定义了2种采样时序(方法): 扩展采样模式 SAMPCON的长度由SHI的时间控制。即,采样输入信号SHI直接作为采样控制信号SAMPCON,决定采样的起始时刻、采样周期和转换时刻 脉冲采样模式 脉冲采样模式下,采样输入信号SHI仅用于触发采样,采样周期由采样定时器(ADC12SHT0x和ADC12SHT1x设置)确定 7.3 各种寄存器 7.3.1 ADC12CTL0 ADC12SHT1x & ADC12SHT0x 用于设定采样的周期,其中 ADC12SHT1x配置ADC12MEM8 ~ADC12MEM15寄存器的采样周期 ADC12SHT0x配置ADC12MEM0 ~ADC12MEM7寄存器的采样周期 ADC12REF2_5V 内部参考电压的设置 ADC12REFON 内部参考电压开启/关闭 ADC12ON ADC12的开启/关闭 ADC12ENC ADC12_A的转换使能,这个位在配置寄存器之前应该置0,配置结束后置1 ADC12SC ADC12的转换开始,这个位在转换结束后会自动复位,所以在应用程序中转换结束后应该将这一位软件置1 7.3.2 ADC12CTL1 ADC12CSTARTADDx 转换地址选择,即ADC12MEMx的选择 ADC12SHSx SHI信号选择 ADC12SHP 采样模式选择(扩展采样和脉冲采样) ADC12SSELx ADC12CLK的选择 ADC12CONSEQx 模式选择,一般选择单通道单次转换,即00 7.3.3 ADC12MEMx 转换出来的值存放在这里,一般在终端服务函数中查看这个寄存器。当转换结果写入选定的ADC12MEMx, ADC12IFGx中对应标志位置位;当这个寄存器的值被读取之后,IFG自动复位。 强调一下:转换结果写入ADC12MEMx时对应的ADC12IFGx置位,若对应的ADC12IEx 和GIE 置位,将会产生中断请求。 7.3.4 ADC12MCTLx 这里的x是由ADC12CTL1寄存器中的ADC12CSTARTADDx位确定的 ADC12SREFx参考电压选择 ADC12INCHx模拟量输入通道选择 7.3.5 ADC12IE 中断使能寄存器,使能哪一位也是由ADC12CTL1寄存器中的ADC12CSTARTADDx位确定的 7.3.6 ADC12IV 这个寄存器可以查看是哪个中断标志位置位,具体的代码是: switch(__even_in_range(ADC12IV,34))// 注意这个内置函数,用于查看是哪个中断到来
上一篇:MSP430(F5529)学习笔记——UCS配置详解
下一篇:MSP430学习笔记——MSP430的系统时钟
推荐阅读
史海拾趣
从C++Builder转入wince开发, 准备用C++在wince5下开发, 在网上看了很多,还是不怎么清楚, 想问问,用C++在wince5下开发,用什么开发工具好, 用evc4?看了《EVC高级编程及其应用开发》说evc4 不支持wince5开发, 用vs2005?直接用vs2005里 ...… 查看全部问答∨ |
|
请问各路大仙,在开发wince中一般用的是什么3g模块啊? 在网上看到很多,都是关于驱动的问题,有没有什么型号的3g模块提供了驱动的啊? 最好是usb的3g网卡。 谢谢!!… 查看全部问答∨ |
我前几天在网上买了个开发板,好像是力天电子的,但是出现了个问题,很纠结,用H-JTAG可以在RAM中仿真,但是下不进去程序,不能在FLASH中仿真和下载程序,很郁闷,而且有时候可以下进去,有时候下不进去,我还重新安装了IAR和H-JTAG的驱动,都不可 ...… 查看全部问答∨ |
MSP-EXP430F5529评估板是我在一个网友处买来的,花了200多大洋,虽然没有论坛团购的便宜,但是也物所超值了。 一般不带字库的LCD屏显示汉字无疑是首先获得汉字的字模数据,然后根据字模在液晶上显示出来。 通常有两种方法,一种方法是把字模放在 ...… 查看全部问答∨ |
|