MSP430经典例程讲解
- 格式:doc
- 大小:78.50 KB
- 文档页数:14
单片机与可编程器件图2a单片机与可编程器件图4图2c图2b单片机与可编程器件图5术及系统设计实例》、《MSP430系列单片机C语言程序设计与开发》等教材和参考资料所必须的实验设备,它既能适合科研开发,又能适合大面积实验教学、课程设计、毕业设计等方面的要求,为广大高校师生提供一个良好的实验开发环境。
同时也是广大的电子爱好者学习、开发MSP430系列单片机的良好平台。
该学习板集成了丰富的接口电路与模块,具体如下:● 2种输出电压5V和3.6V● 12键的行列键盘,3个独立按键●3种显示模式:LED、LCD(段码)、LCD(点阵)●3种通讯模式: 485、232、M_BUS●2种外围接口方式:SPI方式和 总线(串行EEPROM)模块方式● A/D转换接口(12位)● 外部FLASH DATA 模块●Timer_A比较/捕获模式接口学习板还把全部引脚用插座引出,并可通过DIP开关选择是否与外部电路相连,方便用户自己扩展模块与单片机相连。
学习板的平面布置如图5所示。
为了能更好地了解和掌握MSP430Flash系列单片机的特点、使用方法,能更好、更快地投入开发,针对学习板设计了丰富的实验项目,有基础的DEMO实验,更有复杂、精彩的综合实验,同时准备了大量的相关程序,以便用户调试。
◆GPS系统是利用卫星进行测时、测距的系统。
GPS的定位方式分为绝对定位和相对定位。
GPS相对定位用于大地测量。
目的是要测量被测量点相对于某一已知点的位置。
不是直接测量被测点在WGS-84地心坐标系的绝对位置。
而对于运动的目标瞬间位置和运动速度的测量是采用GPS绝对定位方式。
无论那一种方式,都是由GPS同时观测4颗以上的卫星,根据每颗卫星的位置和每颗卫星与被测点的伪距数值,建立伪距定位方程组,通过对方程组求解和进行误差校正运算,得到被测点在WGS-84地心坐标系的坐标,然后转换成‘新1954年北京坐标系’的坐标。
对于建立GPS移动目标跟踪系统的关键技术是将GPS发布的广播电文通过通信平台发送出去。
MSP430单片机入门例程MSP430单片机是一款低功耗、高性能的16位单片机,广泛应用于各种嵌入式系统。
下面是一个简单的MSP430单片机入门例程,可以让大家初步了解MSP430单片机的基本使用方法。
所需材料:1、MSP430单片机开发板2、MSP430单片机编译器3、MSP430单片机调试器4、电脑和相关软件步骤:1、安装MSP430单片机编译器首先需要安装MSP430单片机的编译器,该编译器可以将C语言代码编译成MSP430单片机可以执行的机器码。
在安装编译器时,需要选择与您的单片机型号匹配的编译器。
2、编写程序下面是一个简单的MSP430单片机程序,可以让LED灯闪烁:c本文include <msp430.h>int main(void)本文P1DIR |= 0x01; //设置P1.0为输出while(1){P1OUT ^= 0x01; //反转P1.0的状态,LED闪烁__delay_cycles(); //延时一段时间,控制闪烁频率}本文上述程序中,首先定义了P1DIR寄存器,将P1.0设置为输出。
然后进入一个无限循环,在循环中反转P1.0的状态,使LED闪烁。
使用__delay_cycles()函数实现延时,控制LED闪烁频率。
3、编译程序使用MSP430单片机编译器将程序编译成机器码,生成可执行文件。
在编译时,需要注意选择正确的编译器选项和单片机型号。
4、调试程序使用MSP430单片机调试器将可执行文件下载到单片机中,并使用调试器进行调试。
在调试时,可以观察单片机的输出口状态和LED灯的闪烁情况,确保程序正常运行。
随着嵌入式系统的发展,MSP430单片机作为一种低功耗、高性能的微控制器,在各种应用领域中得到了广泛的应用。
为了更好地理解和应用MSP430单片机,我在学习过程中积累了一些经验,现在分享给大家。
MSP430单片机是一种超低功耗的微控制器,由德州仪器(Texas Instruments)推出。
一、基础_实验【10个】1、入门试验:LED闪烁(1个)2、时钟实验:设置MCLK、ACLK、SMCLK(1个)3、低功耗实验:设置低功耗模式(1个)4、IO端口试验:IO端口寄存器设置(1个)5、定时器:看门狗定时器、TimerA寄存器设置(2个)6、比较器:比较器A寄存器(1个)7、Flash:flash读写(1个)8、异步通信:异步通信寄存器设置(1个)9、ADC:ADC12寄存器设置(1个)二、开发板模块简单程序【56个】1、LED流水灯实验(红、黄、绿)(1)LED1:检测开发板(2)LED2:普通IO控制闪烁(3)LED3:PWM信号控制闪烁2、蜂鸣器实验(1)蜂鸣器1:单频音(步进变音调)(2)蜂鸣器2:奏乐(祝你平安)3、数码管实验(1)数码管1(显示123456)(2)数码管2(动态显示0~F)(3)数码管3(流动光圈)(4)数码管4(来回光标)4、4×1独立按键实验(1)4×1键盘1:扫描数码管显示(2)4×1键盘2:中断数码管显示(3)4×1键盘3:控制LED(4)4×1键盘4:控制蜂鸣器5、4×4矩阵键盘实验(1)4×4键盘1:行列扫描数码管显示(2)4×4键盘2:行列扫描1602液晶显示(3)4×4键盘3:控制LED蜂鸣器6、1602液晶实验(1)1602液晶1:动态字符显示(2)1602液晶2:静态字符显示(3)1602液晶3:内部时钟显示7、3.3V-5V电平转换实验(1)电平转换1:输出5V方波(2)电平转换2:输出不同占空比的方波(3)电平转换3:MCLK,SMCLK,ACLK8、RS232接口实验(1)RS232接口1:MCU发送数据PC机显示(2)RS232接口2:按键控制MCU发送数据PC机显示(3)RS232接口3:PC机发送数据MCU液晶显示(4)RS232接口4:MCU回发接收到的PC机数据(5)RS232接口5:RS232控制蜂鸣器9、RS485接口实验(1)RS485接口1:发送程序(2)RS485接口2:接收程序10、USB接口实验(1)USB接口1:简单连接测试(2)USB接口2:USB接收数据(3)USB接口3:USB发送数据11、PS2接口实验(1)PS2接口1:PS2控制1602显示(2)PS2接口2:PS2控制数码管显示(3)PS2接口3:PS2控制LED和蜂鸣器12、12-Bit高精度温度传感器实验(1)温度传感器1:DS18B20在数码管显示(2)温度传感器2:DS18B20在液晶显示13、RTC实时时钟实验(1)实时时钟1:DS1302测试(2)实时时钟2:DS1302电子钟14、2k Bit EEPROM实验(1)EEPROM1:AT24C02测试(2)EEPROM2:读出数据通过串口在PC机显示15、12-Bit模数转换器(ADC)接口实验(1)模数转换器1:ADC在数码管显示(2)模数转换器2:ADC在1602液晶在显示(3)模数转换器3:ADC通过串口在PC机显示16、8-Bit数模转换器(DAC)实验(1)数模转换器1:DAC控制LED(2)数模转换器2:DAC输出电压,ADC采样转换并在液晶上显示17、12864液晶实验(与12864液晶配套)(1)12864液晶并口1:字符显示(2)12864液晶并口2:汉字显示(3)12864液晶并口3:图形显示(4)12864液晶并口4:综合演示(5)12864液晶串口5:字符显示(6)12864液晶串口6:汉字显示(7)12864液晶串口7:图形显示(8)12864液晶串口8:综合演示18、射频模块CC1000实验(1)射频模块1:发送数据(2)射频模块2:接收数据19、ucos移植注:17、18程序随模块赠送三、开发板综合程序【30】1、键盘综合实验(1)4×4键盘+蜂鸣器+LED+数码管显示(2)4×4键盘+蜂鸣器+LED+1602液晶显示(3)4×4键盘+蜂鸣器+LED+PC机显示(4)PS2键盘+UART+PC机显示(5)PS2键盘+USB+PC机显示2、接口综合实验(1)USB UART(2)UART USB(3)RS232 RS485(4)RS485 RS2323、温度时间综合实验(1)DS18B20 + DS1302 + 数码管(2)DS18B20 + DS1302 + USB(3)DS18B20 + DS1302 + UART(4)DS18B20 + DS1302 + 16024、AD DA综合实验(1)ADC + 1602(2)ADC + UART(3)ADC + USB(4)DAC + LED + KEY(5)DAC + UART(6)DAC + USB(7)ADC + UART + DS1302(8)ADC + DAC + 1602 + KEY(9)ADC + DAC + UART + KEY5、其他综合实验(1)AT24C02高级应用(搜索,擦除,读出全部)(2)DS1302高级应用(内部RAM存取数据)6、12864液晶综合实验(1)汉字库(2)图形库7、3.2寸TFT触摸屏实验(1)静态图片(2)动画/***************************************************程序功能:BoardConfig.h 头文件---------------------------------------------------***************************************************/ typedef unsigned char uchar;typedef unsigned int uint;//控制位的宏定义#define Ctrl_Out P3DIR |= BIT3 + BIT6 + BIT7;#define Ctrl_0 P3OUT &= ~(BIT3 + BIT6 + BIT7) #define SRCLK_1 P3OUT |= BIT7#define SRCLK_0 P3OUT &= ~BIT7#define SER_1 P3OUT |= BIT6#define SER_0 P3OUT &= ~BIT6#define RCLK_1 P3OUT |= BIT3#define RCLK_0 P3OUT &= ~BIT3//板上资源配置函数void BoardConfig(uchar cmd){uchar i;Ctrl_Out;Ctrl_0;for(i = 0; i < 8; i++){SRCLK_0;if(cmd & 0x80) SER_1;else SER_0;SRCLK_1;cmd <<= 1;}RCLK_1;_NOP();RCLK_0;}/***************************************************程序功能:控制8个LED闪烁,用于测试下载功能是否正常---------------------------------------------------测试说明:观察LED闪烁***************************************************/#include <msp430x14x.h>//#include "BoardConfig.h"/****************主函数****************/void main(void){WDTCTL = WDTPW + WDTHOLD; //关闭看门狗// BoardConfig(0xf0); //关闭数码管和电平转换,打开流水灯CCTL0 = CCIE; //使能CCR0中断CCR0 = 2047; //设定周期0.5STACTL = TASSEL_1 + ID_3 + MC_1; //定时器A的时钟源选择ACLK,增计数模式P6DIR = 0xff; //设置P6口方向为输出P6OUT = 0xff;_EINT(); //使能全局中断LPM3; //CPU进入LPM3模式}/*******************************************函数名称:Timer_A功能:定时器A的中断服务函数参数:无返回值:无********************************************/#pragma vector = TIMERA0_VECTOR__interrupt void Timer_A (void){P6OUT ^= 0xff; //P2口输出取反}/***********************************************程序功能:实现流水灯以三种流动方式和四种流动速度的不同组合而进行点亮"流动"------------------------------------------------测试说明:观察流水灯流动顺序和速度的变化************************************************//***********************************************程序功能:实现流水灯以三种流动方式和四种流动速度的不同组合而进行点亮"流动"------------------------------------------------测试说明:观察流水灯流动顺序和速度的变化************************************************/#include <msp430x14x.h>#include "BoardConfig.h"uint i = 0,j = 0,dir = 0;uint flag = 0,speed = 0; //flag--灯光流动方式,speed--灯光流动速度/****************主函数****************/void main(void){WDTCTL = WDTPW + WDTHOLD; //关闭看门狗// BoardConfig(0xf0);CCTL0 = CCIE; //使能CCR0中断CCR0 = 50000;TACTL = TASSEL_2 + ID_3 + MC_1; //定时器A的时钟源选择SMCLK,8分频增计数模式P6DIR = 0xff; //设置P2口方向为输出P6OUT = 0xff;_EINT(); //使能全局中断LPM0; //CPU进入LPM0模式}/*******************************************函数名称:Timer_A功能:定时器A的中断服务函数,在这里通过标志控制流水灯的流动方向和流动速度参数:无返回值:无********************************************/#pragma vector = TIMERA0_VECTOR__interrupt void Timer_A (void){if(flag == 0){P6OUT = ~(0x80>>(i++)); //灯的点亮顺序D8 -> D1}else if(flag == 1){P6OUT = ~(0x01<<(i++)); //灯的点亮顺序D1 -> D8}else{if(dir) //灯的点亮顺序D8 -> D1,D1 -> D8,循环绕圈{P6OUT = ~(0x80>>(i++));}else{P6OUT = ~(0x01<<(i++));}}if(i == 8){i = 0;dir = ~dir;}j++;if(j == 40){i = 0;j = 0;flag++;if(flag == 4) flag = 0;switch(speed){case 0:TACTL &=~ (ID0 + ID1);TACTL |= ID_3;break;case 1:TACTL &=~ (ID0 + ID1);TACTL |= ID_2;break;case 2:TACTL &=~ (ID0 + ID1);TACTL |= ID_1;break;case 3:TACTL &=~ (ID0 + ID1);TACTL |= ID_0;break;default:break;}if(flag != 3) speed++;if(speed == 4) speed = 0;}}/*******************************************************程序功能:用从P2.3和P2.4输出的PWM波形驱动LED闪烁P2.3口输出方波的占空比为75%P2.4口输出方波的占空比为25%-------------------------------------------------------测试说明:观察LED的亮灭的时间长短用来连2.3到6.1口看*******************************************************/#include <msp430x14x.h>//#include "BoardConfig.h"void main(void){WDTCTL = WDTPW + WDTHOLD; // 关狗//BoardConfig(0xb0); // 关闭数码管和电平转换,打开流水灯P2DIR = 0xff; // P2端口设置为输出P2OUT = 0xff; // 关闭其他LEDP2SEL |= BIT3 + BIT4; // P2.3和P2.4连接内部模块CCR0 = 4096-1; // PWM周期为1SCCTL1 = OUTMOD_7; // CCR1 reset/setCCR1 = 3072; // CCR1 PWM duty cycleCCTL2 = OUTMOD_7; // CCR2 reset/setCCR2 = 1024; // CCR2 PWM duty cycleTACTL = TASSEL_1 + ID_3 + MC_1; // ACLK/8, up mode_BIS_SR(LPM3_bits); // Enter LPM3}//****************************************************************************** // MSP-FET430P140 Demo - Basic Clock, Output Buffered SMCLK, ACLK and MCLK//// Description: Output buffered MCLK, SMCLK and ACLK.// ACLK = LFXT1 = 32768, MCLK = DCO Max, SMCLK = XT2// //* XTAL's REQUIRED - NOT INSTALLED ON FET *//// //* Min Vcc required varies with MCLK frequency - refer to datasheet *//内部已经连好了的//// MSP430F149// -----------------// /|\| XIN|-// | | | 32k// --|RST XOUT|-// | |// | XT2IN|-// | | XTAL (455k - 8Mhz)// |RST XT2OUT|-// | |// | P5.4|-->MCLK = DCO Max// | P5.5|-->SMCLK = XT2// | P5.6|-->ACLK = 32kHz//// M. Buccini// Texas Instruments Inc.// Feb 2005// Built with IAR Embedded Workbench Version: 3.21A//******************************************************************************#include <msp430x14x.h>#include "BoardConfig.h"void main(void){BoardConfig(0xb8);WDTCTL = WDTPW +WDTHOLD; // Stop Watchdog Timer DCOCTL = DCO0 + DCO1 + DCO2; // Max DCOBCSCTL1 = RSEL0 + RSEL1 + RSEL2; // XT2on, max RSELBCSCTL2 |= SELS; // SMCLK = XT2P5DIR |= 0x70; // P5.6,5,4 outputsP5SEL |= 0x70; // P5.6,5,5 optionswhile(1){}}//****************************************************************************** // MSP-FET430P140 Demo - Basic Clock, LPM3 Using WDT ISR, 32kHz ACLK//// Description: This program operates MSP430 normally in LPM3, pulsing P3.4// at 4 second intervals. WDT ISR used to wake-up system. All I/O configured// as low outputs to eliminate floating inputs. Current consumption does// increase when LED is powered on P3.4. Demo for measuring LPM3 current.// ACLK= LFXT1/4= 32768/4, MCLK= SMCLK= default DCO// //* External watch crystal on XIN XOUT is required for ACLK *////暗久才亮一下和亮暗和时钟没关系啊// MSP430F149// ---------------// /|\| XIN|-// | | | 32kHz// --|RST XOUT|-// | |// | P3.5|-->LED//// Dasheng// LiTian Electronic Inc.// Feb 2008// Built with IAR Embedded Workbench Version: 3.42A//******************************************************************************#include <msp430x14x.h>#include "BoardConfig.h"void main(void){BoardConfig(0xb8);//BCSCTL1 |= DIVA_2; // ACLK/4WDTCTL = WDT_ADL Y_1000; // WDT 1s/4 interval timerIE1 |= WDTIE; // Enable WDT interruptP1DIR = 0xFF; // All P1.x outputsP1OUT = 0; // All P1.x resetP2DIR = 0xFF; // All P2.x outputsP2OUT = 0; // All P2.x resetP3DIR = 0xFF; // All P3.x outputsP3OUT = 0x30; // All P3.x resetP4DIR = 0xFF; // All P4.x outputsP4OUT = 0; // All P4.x resetP5DIR = 0xFF; // All P5.x outputsP5OUT = 0; // All P5.x resetP6DIR = 0xFF; // All P6.x outputsP6OUT = 0x80; // All P6.x resetwhile(1){uint i;_BIS_SR(LPM3_bits + GIE); // Enter LPM3P3OUT &= ~BIT5; // Set P3.5 LED on亮for (i = 18000; i>0; i--); // DelayP3OUT |= BIT5; // Clear P3.5 LED off暗}}#pragma vector=WDT_VECTOR__interrupt void watchdog_timer (void){_BIC_SR_IRQ(LPM3_bits); // Clear LPM3 bits from 0(SR)}//******************************************************************************* // MSP-FET430P140 Demo - Software Toggle P3.4//// Description: Toggle P3.4 by xor'ing P3.4 inside of a software loop.// ACLK= n/a, MCLK= SMCLK= default DCO ~800k//// MSP430F149// -----------------// /|\| XIN|-// | | |// --|RST XOUT|-// | |// | P3.4|-->LED//// Dasheng// LiTian Electronic Inc.// Feb 2008// Built with IAR Embedded Workbench Version: 3.42A//******************************************************************************#include <msp430x14x.h>#include "BoardConfig.h"void main(void){BoardConfig(0xb8);WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timerP3DIR |= BIT4; // Set P3.4 to output directionfor (;;){volatile unsigned int i;P3OUT ^= BIT4; // Toggle P3.4 using exclusive-ORi = 50000; // Delaydo (i--);while (i != 0);}}//****************************************************************************** // MSP-FET430P140 Demo - WDT, Toggle P3.4, Interval Overflow ISR, DCO SMCLK//P3.4使用软件WDT中断时间。
本讲讲述串口功能与连接的实现。
大多数MSP430芯片都有硬件异步通讯功能,有一些器件有两个通讯端口,也有少数没有。
没有硬件串口的芯片可以实现软件(模拟)串口。
下面表格为430系列芯片串口的情况。
对于没有硬件串口的芯片也可以实现软件串口,这里先讲硬件串口,后讲软件串口,然后再讲串口的链路实现。
1.串口功能的实现(1)硬件串口 图1是MSP430系列芯片硬件串口的框图。
在该框图中,串口通讯由通讯速度的控制(数据位流的产生)、接收控制、发送控制等三部分构成。
波特率生成部分由时钟输入选择与分频、波特率发生器、调整器、波特率寄存器等组成。
串行通信时,接收与发送以什么样的速率将数据位收进或送出呢,这个速率就由波特率生成构件控制。
图2为其较为详细的结构。
整个模块的时钟源来自内部时钟或外部输入时钟,由SSEL1、SSEL0选择,以决定最终进入模块的时钟信号BRCLK的频率。
时钟信号BRCLK送入一个15位的分频器,通过一系列的硬件控制,最终输出移出与移进两移位寄存器使用的移位位时钟BITCLK信号。
那么这个信号(BITCLK)究竟是怎样产生的呢,从图的下半部分的一个波特率产生例子可以看出,是分频器在起作用。
当计数器减计数到“0”时,输出触发器翻转,送给BITCLK信号。
所以BITCLK信号周期的一半就是定时器(分频计数器)的定时时间。
接收控制部分与发送控制部分分别由两个移位寄存器构成。
接收时,当接收到一个完整数据,产生一个信号(URXIFG0=1),表示接收到完整数据,可以将此数据取走。
而在发送时,当一个数据正在发送过程中,UTXIFG0=1,此时,不能再发送数据,必须等当前数据发送完毕(UTXIFG0=0)时,方可继续发送。
串口接收一般采用中断方式,而发送数据则多采用主动方式。
在本刊的网站(www.eleworld.com)里给出了一段简单的完整通讯程序,实现的功能是将接收的数据原样送回。
(2)软件串口 而对于没有硬件串口的型号,如何实现异步串口功能呢?先分析异步串口的原理。
MSP430按键程序范例(附原理图)#i ncludevoid Init_Port(void){//将P1口所有的管脚在初始化的时候设置为输入方式 P1DIR = 0; //将P1口所有的管脚设置为一般I/O口P1SEL = 0;// 将P1.4 P1.5 P1.6 P1.7设置为输出方向P1DIR |= BIT4;P1DIR |= BIT5;P1DIR |= BIT6;P1DIR |= BIT7;//先输出低电平P1OUT = 0x00;// 将中断寄存器清零P1IE = 0;P1IES = 0;P1IFG = 0;//打开管脚的中断功能//对应的管脚由高到低电平跳变使相应的标志置位P1IE |= BIT0;P1IES |= BIT0;P1IE |= BIT1;P1IES |= BIT1;P1IE |= BIT2;P1IES |= BIT2;P1IE |= BIT3;P1IES |= BIT3;_EINT();//打开中断return;}void Delay(void){int i;for(i = 100;i--;i > 0) ;//延时一点时间}int KeyProcess(void){int nP10,nP11,nP12,nP13;int nRes = 0;//P1.4输出低电平P1OUT &= ~(BIT4);nP10 = P1IN & BIT0;if (nP10 == 0) nRes = 13; nP11 = P1IN & BIT1; if (nP11 == 0) nRes = 14; nP12 = P1IN & BIT2; if (nP12 == 0) nRes = 15; nP13 = P1IN & BIT3; if (nP13 == 0) nRes = 16; //P1.5输出低电平P1OUT &= ~(BIT4);nP10 = P1IN & BIT0;if (nP10 == 0) nRes = 9; nP11 = P1IN & BIT1; if (nP11 == 0) nRes = 10; nP12 = P1IN & BIT2; if (nP12 == 0) nRes = 11; nP13 = P1IN & BIT3; if (nP13 == 0) nRes = 12; //P1.6输出低电平P1OUT &= ~(BIT4);nP10 = P1IN & BIT0;if (nP10 == 0) nRes = 5; nP11 = P1IN & BIT1; if (nP11 == 0) nRes = 6; nP12 = P1IN & BIT2; if (nP12 == 0) nRes = 7; nP13 = P1IN & BIT3; if (nP13 == 0) nRes = 8; //P1.7输出低电平P1OUT &= ~(BIT4);nP10 = P1IN & BIT0;if (nP10 == 0) nRes = 1; nP11 = P1IN & BIT1;if (nP11 == 0) nRes = 2; nP12 = P1IN & BIT2;if (nP12 == 0) nRes = 3; nP13 = P1IN & BIT3;if (nP13 == 0) nRes = 4; P1OUT = 0x00;//恢复以前值。
msp430按键控制LED最基本程序按键篇经过一短时间的学习,下面,亲自动手编写一下程序吧。
程序的目的是:按下按键,控制LED的亮和灭。
短按键,则小灯亮1秒,然后灭; 长按键,小灯常亮。
首先,完成键盘的扫描程序。
第一点:如果是扫描,就要用到定时器。
我想设计定时器每隔IOms扫描一次按键。
定时器,我选用定时器A。
它的定时中断函数如下:函数名称:TimerA_ISR功能:定时器A 的中断服务函数参数:无返回值:无********************************************/ #pragma vector = TIMERAO_VECTOR __interrupt void TimerA_ISR(void) {GetKey() ;}上面这个定时中断函数的意思就是:每当定时时间到了以后,就调用GetKey() 函数一次。
GetKey() 函数就是扫描键盘按键的函数了。
在GetKey() 函数中,会根据按键类型(长按/ 短按)返回不同的数值。
根据返回的数值,做小灯亮法的操作。
那么,返回的这个值,我们需要保存在一个变量中,在这里定义一个变量ucharFlagLcd ; 来保存返回值。
这个变量在全局变量中定义,以保证它的作用域。
那么定时函数就变为#pragma vector = TIMERAO_VECTOR__interrupt void TimerA_ISR(void){FlagLcd =GetKey() ;}定时器中断的时间间隔,我在主函数中定义。
这样写:CCTLO = CCIE; // 使能CCR冲断CCRO = 4O; // 设定周期O.O1STACTL = TASSEL_1 + ID_3 + MC_1; //定时器A的时钟源选择ACLK增计数模式这样,定时器这块就算完工了。
那么,下面进行按键扫描程序。
按键的定义是这样的,根据我板子的按键原理图如下Pl +PlAPl 了这是一个矩阵键盘。
【MSP430入门例程】:ADC12模块作者:DC 微控技术论坛原创MSP430单片机入门基础例程若想了解MSP430单片机常用模块应用原理,请下载<<MSP430F常用模块应用原理>> /datasheet/msp430/msp430base/MSP430register_guide.pd f最近有网友向我们反映,建议我们建立一个模块专题用于讲述MSP430单片机的某模块的原理与应用的。
为此,我先以ADC12模块建立此贴。
贴子内容有待整理中...,如下是我整理的图文资料。
如果发现有错误请及时通知我更正。
下图是ADC12模块结构图在还有没讲述ADC12模块中组成之前,我想着重讲述ADC12的采样与转换这部分。
后面在再作其它部分讲述。
【采样与转换】ADC12完成对一个模拟信号模数转换过程由两部分组成:采样保持和转换.完成采样转换周期时间= 采样保持时间 +转换时间完成采样转换周期时间:ADC12完成对一个模拟信号模数转换所需要时间,这部分由采样保持时间和转换时间组成。
采样保持时间:由产生SAMPCON信号开始到结束所需时间,这期间ADC进行对模拟信号采样保持。
在脉冲采样模式时(SHP=1),采样时间: Tsample = 4 x ADC12CLK x N式中,Tsample为采样保持时间,ADC12CLK为ADC12内核时钟周期,N则由SHT1(SHT0)的4位二进制码决定。
采样保持时间与ADC12模块的等效输入电路有关。
从ADC12模块输入看A DC内部等效为一个电阻(2K)与一个电容(30pf)相串联.这个内部RC常数直接影响着最小的采样保持时间参数.所以,在采样转换中有一个最小采样保持时间值概念.这个最小采样保持时间值从上式中可以看出是由ADC12CLK时间周期决定(N=1时),也就是说ADC12CLK的最高频率;这个频率不能超出MSP430芯片手册中所指定的最高频率(最小采样保持时间值)。
第6章MSP430单片机及设计实例本章将介绍MSP430单片机及设计实例。
MSP430是德州仪器(TI)公司开发的一种低功耗、高性能的16位RISC微控制器。
它广泛应用于嵌入式系统和便携式设备中,具有较低的功耗和丰富的外设。
首先,我们将介绍MSP430的基本特性。
MSP430采用的是Harvard架构,具有16位数据总线和16位地址总线。
它具有多种工作模式,包括运行模式、空闲模式和休眠模式,可以根据实际需求选择合适的模式以实现最低功耗。
另外,MSP430具有丰富的外设。
它包括通用输入/输出引脚、定时器、串口通信接口、模数转换器等。
这些外设可以满足各种应用的需求,并且具有灵活的配置和控制能力。
接下来,我们将介绍几个MSP430的设计实例。
首先是LED闪烁实例。
我们可以利用MSP430的通用输入/输出引脚和计时器来实现LED的闪烁,实现简单的灯光效果。
其次是温度监测实例。
我们可以利用MSP430的模数转换器和温度传感器来实现温度的实时监测,根据温度变化来控制其他外设的工作状态。
最后是无线通信实例。
我们可以利用MSP430的串口通信接口和无线模块来实现与其他设备的无线通信,如蓝牙通信或Wi-Fi通信。
以上这些设计实例只是MSP430的一小部分应用案例,MSP430还可以应用于很多其他领域,如智能家居、工业自动化、医疗设备等。
它的低功耗和高性能使其成为许多嵌入式系统的理想选择。
总之,MSP430是一种功能强大、灵活性高的单片机,通过灵活配置和控制外设,可以实现各种应用需求。
在接下来的学习中,我们将更深入地了解MSP430的内部结构和编程实践,为设计更复杂的嵌入式系统奠定基础。
MSP4301.时钟控制:430三个时钟源:LFXT1CLK低频时钟源,XT2CLK,高频时钟源,DCOCLK数控RC 振荡器。
2.三种时钟源可提供三种时钟信号:1.ACLK辅助时钟:ACLK是LFXT1CLK信号经过1、2、4、8分频得到的。
ACLK可由软件选作外围器件的时钟信号。
2.MCLK系统主时钟:可由软件来设置来源于低频时钟源,高频,数控。
之后可再经过1、2、4、8分频得到。
MCLK主要用于CPU和系统。
3.SMCLK:可有软件选这高频时钟来源,用于高速外围设备。
其中P1.4/SMCLK, P2.0/ACLK, P5.5/SMCLK, P5.6/ACLK。
时钟信号输出,可由PnSEL|=0xXX,l来设置特殊功能端口。
4.三个振荡器的控制位:1.低频LFXT1:OscOff;2.高频XT2CLK:XT2OFF;3.DCO:SCG0;5.一、时钟模块主要由三个寄存器来进行控制。
1.DCOCTL DCO控制器高三位:DCO.2、DCO.1 DCO.0定义8种频率之一,相邻两位相差10%,第五位详细调整频率。
其中DCO为7时表示选择最高频率。
2.BCSCTL1基本时钟控制器1位数7(最高)---XT2OFF:控制XT2的开启与关闭,0:开启;1:关闭。
6---------XTS:控制LFXT1工作模式:0:低频工作模式32768HZ;1:高频工作模式(前提接了相应的高频晶振)。
5,4--------DIV.1、DIV.0:控制ACLK分频(ACLK时钟来源于LFXT1)0:不分;1: 2分;2: 4分;3:8分;3-------XT5V:此位设置为0;2,1,0-----Rsel.0~Rsel.2 :0~7:最低标频~最高标频。
3.BCSCTL27,6-------SELM.1,SELM.0:选择MCLK时钟源(系统主时钟)0,1:DCOCLK为时钟源2:XT2CLK为时钟源3:时钟源为LFXT1CLK5,4-------DIVM.0,DIVM.1 选择MCLK分频。
这只是我在学习TI公司生产的16位超的功耗单片机MSP430的随笔,希望能对其他朋友有所借鉴,不对之处还请多指教。
下面,开始430之旅。
讲解430的书现在也有很多了,不过大多数都是详细说明底层硬件结构的,看了不免有些空洞和枯燥,我认为了解一个MCU的操作首先要对其基础特性有所了解,然后再仔细研究各模块的功能。
1、首先你要知道msp430的存储器结构。
典型微处理器的结构有两种:冯 ? 诺依曼结构----程序存储器和数据存储器统一编码;哈佛结构----程序存储器和数据存储器。
MSP430系列单片机属于前者,而常用的mcs51系列属于后者。
0-0xf特殊功能寄存器;0x10-0x1ff外围模块寄存器;0x200-?根据不同型号地址从低向高扩展;0x1000-0x107f seg_b0x1080_0x10ff seg_a 供flash信息存储,剩下的从0xffff 开始向下扩展,根据不同容量,例如149为60KB,0xffff-0x11002、复位信号是MCU工作的起点,430的复位型号有两种:上电复位信号POR和上电清楚信号PUC。
POR信号只在上电和RST/NMI复位管脚被设置为复位功能,且低电平时系统复位。
而PUC信号是POR信号产生,以及其他如看门狗定时溢出、安全键值出现错误是产生。
但是,无论那种信号触发的复位,都会使MSP430在地址0xffff处读取复位中断向量,然后程序从中断向量所指的地址开始执行。
复位后的状态不写了,详见参考书,嘿嘿。
3、系统时钟是一个程序运行的指挥官,时序和中断也是整个程序的核心和中轴线。
430最多有三个振荡器:DCO内部振荡器;LFXT1外接低频振荡器,常见的32768HZ,不用外接负载电容;也可接高频450KHZ-8M,需接负载电容;XT2接高频450KHZ-8M,加外接电容。
430有三种时钟信号:MCLK系统主时钟,可分频1/2/4/8,供CPU使用,其他外围模块在有选择情况下也可使用;SMCLK系统子时钟,供外围模块使用,可选则不同振荡器产生的时钟信号;ACLK辅助时钟,只能由LFXT1产生,供外围模块。
一:基础实验功能:控制IO口实现流水灯的一次点亮并循环下去#include"msp430x14x.h"void delay(unsigned int a){unsigned int i,j;for(j=a;j>0;j--)for(i=80;i>0;i--);}void main(void){WDTCTL=WDTPW+WDTHOLD;P2DIR|=0XF0; //1111-0000 1表示输出,0表示输入P2OUT&=0X0F; //0000-1111 输出寄存器while(1){P2OUT|=BIT4;delay(800);P2OUT|=BIT5;delay(800);P2OUT|=BIT6;delay(800);P2OUT|=BIT7;delay(800);P2OUT&=0X0F;delay(800);}}二:IO口控制(IO口中断)实验功能:利用IO口中断实现按键中断,当按键按下时对应LED等亮#include<msp430x14x.h>#pragma vector=PORT2_VECTOR //声明中断源是IO口2 的中断__interrupt void port2(void);void main(void){WDTCTL=WDTPW+WDTHOLD;_EINT();P2DIR|=BIT4;P2DIR&=~BIT0;P2IE|=BIT0 ;P2IES|=BIT0 ;_BIS_SR(LPM3_bits + GIE); //开总中断并使CPU进入低功耗模式while(1);}__interrupt void port2(void){if((P2IN&BIT0)==BIT0)P2OUT&=~BIT4;elseP2OUT|=BIT4;}三:数码管实验功能:编程实现6个数码管依次显示1到6/******************************************************************** **********____ ____ ____ ____ ____ ____f| a |b | | | | | | | | | ||____| |____| |____| |____| |____| |____|e| g |c | | | | | | | | | ||____| |____| |____| |____| |____| |____|d LED6 | LED5 | LED4 | LED3 | LED2 | LED1| | | | | |P5.7 P5.6 P5.5 P5.4 P5.3 P5.2a--P4.0 b--P4.1 c--P4.2 d--P4.3 e--P4.4 f--P4.5 g--P4.6.--P4.7 段码1选通P5.2--P5.7 位码0导通// 跳线P14 P15 P5 P6 P7 P8********************************************************************* **********/#include"msp430x14x.h"#define uchar unsigned charunsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};unsigned char seg[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb};void display(uchar i,uchar j){P5OUT=seg[i];P4OUT=table[j];}void main(){WDTCTL=WDTPW+WDTHOLD;P5DIR|=(BIT2+BIT3+BIT4+BIT5+BIT6+BIT7);P4DIR|=(BIT0+BIT1+BIT2+BIT3+BIT4+BIT5+BIT6+BIT7);while(1){display(0,1);display(1,2);display(2,3);display(3,4);display(4,5);display(5,6);}}四:独立按键综合实验//*************************************************************** // 描述:// 有按键中断时,LED5,LED6,LED7,LED8亮与灭;//// 跳线:P9 P10 P17*************************************************************** #include <msp430x14x.h>#define led5_pout P2DIR|=BIT4 //通讯状态指示灯设置为输出口#define led5_high P2OUT|=BIT4 //通讯状态指示灯输出高点亮指示灯#define led5_low P2OUT&=~BIT4 //通讯状态指示灯输出低关闭指示灯#define led6_pout P2DIR|=BIT5 //通讯状态指示灯设置为输出口#define led6_high P2OUT|=BIT5 //通讯状态指示灯输出高点亮指示灯#define led6_low P2OUT&=~BIT5 //通讯状态指示灯输出低关闭指示灯#define led7_pout P2DIR|=BIT6 //通讯状态指示灯设置为输出口#define led7_high P2OUT|=BIT6 //通讯状态指示灯输出高点亮指示灯#define led7_low P2OUT&=~BIT6 //通讯状态指示灯输出低关闭指示灯#define led8_pout P2DIR|=BIT7 //通讯状态指示灯设置为输出口#define led8_high P2OUT|=BIT7 //通讯状态指示灯输出高点亮指示灯#define led8_low P2OUT&=~BIT7 //通讯状态指示灯输出低关闭指示灯unsigned char led5,led6,led7,led8,flag;void delay(unsigned int i){while(i--);}void IOinit(void){led5_pout;led6_pout;led7_pout;led8_pout;led5_low;led6_low;led7_low;led8_low;P2IE|=BIT0+BIT1+BIT2+BIT3;P2IES|=BIT0+BIT1+BIT2+BIT3;}void main(void){WDTCTL=WDTPW+WDTHOLD;IOinit();_EINT();while(1){switch(flag){case 1: if(led5%2)led5_high;else led5_low;flag=0;break;case 2: if(led6%2)led6_high; else led6_low;flag=0;break;case 3: if(led7%2)led7_high; else led7_low;flag=0;break;case 4: if(led8%2)led8_high; else led8_low;flag=0;break;default: break;}_BIS_SR(LPM3_bits+GIE);}}#pragma vector=PORT2_VECTOR__interrupt void port2 (void){delay(40000);//去抖;if((P2IFG&BIT0)==BIT0){led5++;flag=1;}if((P2IFG&BIT1)==BIT1){led6++;flag=2;}if((P2IFG&BIT2)==BIT2){led7++;flag=3;}if((P2IFG&BIT3)==BIT3){led8++;flag=4;}P2IFG=0;_BIC_SR_IRQ(LPM3_bits);}五:行列式键盘实验/**************************************************************** // P6.7 P6.6 P6.5 +3V// | | | |// P6.1------ /---- /----- /----R--|// | | | |// P6.2------ /---- /----- /----R--|// | | | |// P6.3------ /---- /----- /----R--|// | | | |// P6.4------ /---- /----- /----R--|// 跳线 P2 P3****************************************************************/ #include"msp430x14x.h"#include"key.h"void delay(unsigned int i){while(i--);}unsigned char key(void){unsigned char x=0XFF;P6DIR=0XE0;P6OUT=0X7F;// //扫描第一列 if((P6IN&0X02)==0X00)x=12; //x=0;elseif((P6IN&0X04)==0)x=11;//x=1;elseif((P6IN&0X08)==0)x=10;//x=2;elseif((P6IN&0X10)==0)x=9;else{P6OUT=0XBF;// //扫描第二列 if((P6IN&0X02)==0X00)x=8; //x=0;elseif((P6IN&0X04)==0)x=7;//x=1;elseif((P6IN&0X08)==0)x=6;//x=2;elseif((P6IN&0X10)==0)x=5;else{P6OUT=0XDF; //扫描第三列if((P6IN&0X02)==0X00)x=4; //x=0;elseif((P6IN&0X04)==0)x=3;//x=1;elseif((P6IN&0X08)==0)x=2;//x=2;elseif((P6IN&0X10)==0) x=1;}}return(x);}unsigned char get_key(void){unsigned char x,y;if((P6IN&0X1F)!=0X1F){delay(20);if((P6IN&0X1F)!=0X1F){x=key();if(x!=0xFF)y=x;}}return y;}六:看门狗程序//*************************************************************** *// MSP430F149// -----------------// /|\| XIN|-// | | |// --|RST XOUT|-// | |// | P1.1|-->LED//*************************************************************** *#include <msp430x14x.h>void main(void){WDTCTL = WDT_MDLY_0_064; // Set Watchdog Timer interval to ~30msIE1 |= WDTIE; // Enable WDT interruptP1DIR |= 0x02; // Set P1.1 to output direction_BIS_SR(LPM0_bits + GIE); // Enter LPM0 w/ interrupt}// Watchdog Timer interrupt service routine#pragma vector=WDT_VECTOR__interrupt void watchdog_timer(void){P1OUT ^= 0x02; // Toggle P1.1 using exclusive-OR}七:TimerA 定时/计数器//*************************************************************** *// MSP-FET430P140 Demo - Timer_A, Toggle P1.1/TA0, Up Mode, 32kHz ACLK //// Description: Toggle P1.1 using hardware TA0 output. Timer_A is configured// for up mode with CCR0 defining period, TA0 also output on P1.1. In this// example, CCR0 is loaded with 1000-1 and TA0 will toggle P1.1 at TACLK/1000.// Thus the output frequency on P1.1 will be the TACLK/2000. No CPU or software// resources required. Normal operating mode is LPM3.// As coded with TACLK = ACLK, P1.1 output frequency = 32768/2000 = 16.384Hz.// ACLK = TACLK = 32kHz, MCLK = default DCO ~800kHz// //* External watch crystal installed on XIN XOUT is required for ACLK *////// MSP430F149// -----------------// /|\| XIN|-// | | | 32kHz// --|RST XOUT|-// | |// | P1.1/TA0|--> ACLK/2000//// 跳线:J10 Timer_A P0//*************************************************************** *#include <msp430x14x.h>void main(void){WDTCTL = WDTPW + WDTHOLD; // Stop WDTP1DIR |= 0x02; // P1.1 output 选择P1.1为输出P1SEL |= 0x02; // P1.1 option select外围模块CCTL0 = OUTMOD_4; // CCR0 toggle mode 输出为反转模式 CCR0 = 1000-1;TACTL = TASSEL_1 + MC_1; // ACLK, upmode_BIS_SR(LPM3_bits); // Enter LPM3 w/interrupt}//#include//typedef unsigned char uchar;//typedef unsigned int uint;//uchar flag=0;//void main(void)//{// WDTCTL=WDTPW+WDTHOLD;// BCSCTL1 &= ~XT2OFF;// BCSCTL2 |=SELS+DIVS_3;// P3DIR |= BIT4;// TACTL=TASSEL_2+MC_2+TAIE;//_BIS_SR(LPW0_bits+GIE);//}//Timer_A3 Interrupt Vector( TATV) handler//#pragma vector=TIMERA1_VECTOR//__interrupt void Timer_A(void)//{// switch(TAIV)// {// case 2: break;// case 4: break;// case 10: P4OUT ^=BIT5;// break;// }//}//Timer A0 interrupt service routine//#pragma vector=TIMERA0_VECTOR//__interrupt void Timer_A (void)//{// P4OUT ^= BIT5;八:TimerB 定时/计数器//*************************************************************** /// MSP-FET430P140 Demo - Timer_B, Toggle P1.1, CCR0 Up Mode ISR, 32kHz ACLK// Description: Toggle P1.1 using software and the TB_0 ISR. Timer_B is// configured for up mode, thus the timer overflows when TBR counts // to CCR0. In this example, CCR0 is loaded with 1000-1.// Toggle rate = 32768Hz/(2*1000) = 16.384Hz// ACLK = TBCLK = 32kHz, MCLK = SMCLK = default DCO ~800kHz// //* An external watch crystal on XIN XOUT is required for ACLK *////// MSP430F149// ---------------// /|\| XIN|-// | | | 32kHz// --|RST XOUT|-// | |// | P1.1|-->LED//// 跳线:J10 Timer_A P0//*************************************************************** *#include <msp430x14x.h>void main(void){WDTCTL = WDTPW + WDTHOLD; // Stop WDTP1DIR |= 0x02; // Set P1.1 to output directionTBCTL = TBSSEL_1 + TBCLR; // ACLK, clear TBRTBCCTL0 = CCIE; // TRCCR0 interrupt enabledTBCCR0 = 1000-1;TBCTL = TBSSEL_1 + MC_1; // ACLK, upmode_BIS_SR(LPM3_bits + GIE); // Enter LPM3 w/ interrupt// Timer B0 interrupt service routine#pragma vector=TIMERB0_VECTOR__interrupt void Timer_B (void){P1OUT ^= 0x02; // Toggle P1.1 using exclusive-OR}九:串口通信实验一/**************************************************************** // MSP-FET430P140 Demo - USART0,//// Description: USART0 RX interrupt triggers TX Echo. Though not required,// Baud rate divider with 3.2768Mhz XTAL @9600 = 3.2768MHz/9600 = 0003h;// MSP430F149// -----------------// /|\| XIN|-// | | | 3.2768MHz// --|RST XOUT|-// | |// | P3.4|------------>// | | 9600// | P3.5|<------------//// 跳线串行( P8 P9) 数码管( P14 P15 P5 P6 P7 P8)***************************************************************** #include <msp430x14x.h>#include "led.h"#define uchar unsigned charextern unsigned char num[11];extern unsigned char wei[7];extern void display(uchar W,uchar sz);uchar aa;/*****************串口初试化设置********************/void uart_org(void){ME1 |= UTXE0 + URXE0; // Enable USART0 TXD/RXD //使能串口UCTL0 |= CHAR; // 8-bit character //数据格式为8位UTCTL0 |= SSEL0; // UCLK = ACLK //选择时钟来源 UBR00= 0x03; // 32768/9600 //波特率寄存器低字节UBR10= 0x00; //波特率寄存器高字节UMCTL0= 0x4a; //由于波特率计数有余数,填写波特率调整寄存器P3SEL |= 0x30; // P3.4,5 = USART0 TXD/RXD 定义串口功能引脚P3DIR |= 0x10; //P3.4口为输出,其余为输人口UCTL0 &= ~SWRST; // Initialize USART state machineIE1 |= URXIE0; // Enable USART0 RX interrupt 接受数据能中断}/*****************串口发送字符串程序*****************/void UartStr(unsigned char *p){ *p=0x02;//unsigned char strunsigned char i;for (i=0;*p!=0;i++) //准备要发送的数据{ //下句UTXIFG0=1则正在发送数据,即不再发送其它数据while (!(IFG1 & UTXIFG0)); // USART0 TX buffer ready?判断缓冲区是否为空TXBUF0 =*p++; // RXBUF0 to TXBUF0 //发送数据到串口while ((UTCTL0 & TXEPT) == 0); //判断数据是否发送完毕}_NOP();}void main(){WDTCTL=WDTPW+WDTHOLD; //关闭看门狗uart_org( ); //串口初始化_EINT(); //总中断开启UartStr("请输入abcdef之一!\r\t\n");UartStr("a--1,b--2,c--3,d--4,e--5,f--6\r\t\n");while(1){switch (aa){case 97:display(0,1); break;case 98:display(1,2);break;case 99:display(2,3);break;case 100:display(3,4);break;case 101:display(4,5);break;case 102:display(5,6);break;default:break;}_BIS_SR(LPM3_bits+GIE); //初始化完毕,进入睡眠状态 }}#pragma vector=UART0RX_VECTOR__interrupt void usart0_rx (void){aa=RXBUF0; //接收的数据赋值给 aa_BIC_SR_IRQ(LPM3_bits); //停止休眠}十:串口通信实验二/**************************************************************** // MSP-FET430P140 Demo - USART1,//// Description: USART0 RX interrupt triggers TX Echo. Though not required,// Baud rate divider with 3.2768Mhz XTAL @9600 = 3.2768MHz/9600 = 0003h;// MSP430F149// -----------------// /|\| XIN|-// | | | 3.2768MHz// --|RST XOUT|-// | |// | P3.6|------------>// | | 9600// | P3.7|<------------//// 跳线串行( P8 )***************************************************************** #include <msp430x14x.h>unsigned char send,NR,zs;unsigned char tx_buf[20];//***************延时**********************************void delay( char i){unsigned char aa=10;while(aa--)while(i--);}//**************串口初试化设置************************/void uart_org(void){ME2 |= UTXE1 + URXE1; // Enable USART1 TXD/RXD UCTL1 |= CHAR; // 8-bit characterUTCTL1 |= SSEL0; // UCLK = ACLKUBR01 = 0x03; // 32768/9600UBR11 = 0x00; //UMCTL1 = 0x4a; // modulationP3SEL |= 0xC0;UCTL1 &= ~SWRST; // Initialize USART state machineIE2 |= URXIE1; // Enable USART1 RX interrupt}//********************发送数据****************************void Uart_Str(unsigned char number,unsigned char *p){unsigned char i;for (i=0;i<number;i++)//准备要发送的数据{while (!(IFG2 & UTXIFG1));// USART0 TX buffer ready?TXBUF1 =*p++; // RXBUF0 to TXBUF0while ((UTCTL1 & TXEPT) == 0);}_NOP();}//********************发送数据****************************void UartStr(unsigned char *p){unsigned char i;for (i=0;*p!=0;i++)//准备要发送的数据{while (!(IFG2 & UTXIFG1));// USART0 TX buffer ready? TXBUF1 =*p++; // RXBUF0 to TXBUF0while ((UTCTL1 & TXEPT) == 0);}_NOP();}//***************接收串行数据***************************// void AddUsData(unsigned char sq0){if(NR<20){tx_buf[NR]=sq0;NR++;}}void main(void){WDTCTL=WDTPW+WDTHOLD;uart_org();//UartStr("unsigned char *p");while(1){delay(50);UartStr(tx_buf);// Uart_Str(zs,tx_buf);for(unsigned char i=zs;i>0;i--)tx_buf[i]=0;zs=0;NR=0;_BIS_SR(LPM3_bits+GIE);}}#pragma vector=UART1RX_VECTOR__interrupt void usart1_rx (void){zs++;AddUsData(RXBUF1);_BIC_SR_IRQ(LPM3_bits);}十一:AD转换实验//*************************************************************** *// MSP-FET430P140 Demo - ADC12, Sample A0, Set P1.0 if A0 > 0.5*AVcc //// Description: A single sample is made on A0 with reference to AVcc.// Software sets ADC10SC to start sample and conversion - ADC12SC // automatically cleared at EOC. ADC12 internal oscillator times sample (16x)// and conversion. In Mainloop MSP430 waits in LPM0 to save power until ADC12// conversion complete, ADC12_ISR will force exit from LPM0 in Mainloop on// reti. If A0 > 0.5*AVcc, P1.0 set, else reset.//// MSP430F149// -----------------// /|\| XIN|-// | | |// --|RST XOUT|-// | |// Vin-->|P6.7/A7 P2 |--> LED////*************************************************************** *#include <msp430x14x.h>#define led5_pout P2DIR|=BIT4 //通讯状态指示灯设置为输出口#define led5_high P2OUT|=BIT4 //通讯状态指示灯输出高点亮指示灯#define led5_low P2OUT&=~BIT4 //通讯状态指示灯输出低关闭指示灯#define led6_pout P2DIR|=BIT5 //通讯状态指示灯设置为输出口#define led6_high P2OUT|=BIT5 //通讯状态指示灯输出高点亮指示灯#define led6_low P2OUT&=~BIT5 //通讯状态指示灯输出低关闭指示灯#define led7_pout P2DIR|=BIT6 //通讯状态指示灯设置为输出口#define led7_high P2OUT|=BIT6 //通讯状态指示灯输出高点亮指示灯#define led7_low P2OUT&=~BIT6 //通讯状态指示灯输出低关闭指示灯#define led8_pout P2DIR|=BIT7 //通讯状态指示灯设置为输出口#define led8_high P2OUT|=BIT7 //通讯状态指示灯输出高点亮指示灯#define led8_low P2OUT&=~BIT7 //通讯状态指示灯输出低关闭指示灯void delay(unsigned int a){unsigned int i,j;for(j=a;j>0;j--)for(i=8;i>0;i--);}void main(void){WDTCTL = WDTPW + WDTHOLD; // Stop WDT_EINT();ADC12CTL0 = SHT0_2 + ADC12ON; // Set sampling time, turn on ADC12 //上面语句是打开ADC12电源,并设置采样时间=2^2*(4*clk)=16clk即为16个时钟ADC12CTL1 = CSTARTADD_7 + SHP; // Use sampling timerADC12MCTL7|=INCH_7;ADC12IE = 0x0080; // Enable interrupt 使能中断 ADC12IFG.0 对应于 ADC12MEM0ADC12CTL0 |= ENC; // Conversion enabled 使能转换P6SEL |= 0x80; // P6.0 ADC option select 定义P6.0为模拟输入通道0led5_pout;led6_pout;led7_pout;led8_pout;led5_low;led6_low;led7_low;led8_low;for (;;){ADC12CTL0 |= ADC12SC; // Sampling open 开始启动转换_NOP();// _BIS_SR(CPUOFF + GIE); // LPM0, ADC12_ISR will force exit }}// ADC12 interrupt service routine#pragma vector=ADC_VECTOR__interrupt void ADC12_ISR (void){if (ADC12MEM7 < 0x3FF)led5_low; // Clear P2.4 LED offelseled5_high; // Set P2.4 LED onif (ADC12MEM7 < 0x6FF)led6_low; // Clear P2.5 LED offelseled6_high;if (ADC12MEM7 < 0x9FF)led7_low; // Clear P2.6 LED offelseled7_high;if (ADC12MEM7 < 0xCFF)led8_low; // Clear P2.7 LED offelseled8_high;// _BIC_SR_IRQ(CPUOFF); // Clear CPUOFF bit from 0(SR) }十二:IIC总线与24c16综合实验主程序//*************************************************************** // 描述:// 开机发送数给24C16,然后将数据读出,并通过串口工具显示;//// 跳线: P6 P8 P9//*************************************************************** #include "msp430x14x.h"#include "Uart.h"#include "24c16.h"#define uchar unsigned charunsigned char *D,*M,add,ACK_FLAG,flag;unsigned char MPM[32];//unsigned char DDT[32]=// {// 0xf3,0x16,0x69,0x21,0xd3,0x15,0xc5,0x23,// 0xb6,0x28,0x85,0x25,0xc3,0x24,0xd7,0x16,// 0xf3,0x16,0x69,0x21,0xd3,0x15,0xc5,0x23,// 0xb6,0x28,0x85,0x25,0xc3,0x24,0xd7,0x16// };unsigned char DDT[32]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,//0 1 2 3 4 5 6 70x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46,//8 9 A B C D E F0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E, //G H I J K L M N0x4F,0x50,0x51,0x52,0x53,0x54,0x55,0x56, //O P Q R S T U V};void main(void){unsigned int i;WDTCTL=WDTPW+WDTHOLD;uart_org();UartStr("开机测试成功!\r\t\n");D=(unsigned char*)DDT;add=0; //24C01内数据读写首地址M=(unsigned char*)MPM;delay(100);for(i=0;i<4;i++){send_word();delay(1000);add+=8;}add=10;for(i=0;i<32;i++)receive_word(i);Uart_Str(32,&MPM[0]);TXBUF0 = MPM[7];}子程序 24C16#include <msp430x14x.h>#include "24c16.h"#define uchar unsigned charextern uchar ACK_FLAG,add,*D,MPM[32];void delay(unsigned int i){while(i-- > 0);}void start(void){SDA_OUT;SCL_OUT;SDA_0;SCL_0;delay(2);SDA_1;SCL_1;delay(2);SDA_0;delay(2);SCL_0;delay(3);SDA_1;}void stop(void){SDA_OUT;SCL_OUT;SDA_0;SCL_1;delay(2);SDA_1;}void send_byte(uchar data){uchar bi,i;bi=0x80;SDA_OUT;SCL_OUT;for(i=0;i<8;i++){if((data&bi)==bi) SDA_1;else SDA_0;SCL_1;delay(50);SCL_0;bi>>=1;}}uchar receive_byte(void){uchar i,temp=0x80,tempdata;tempdata=0;SDA_IN;SCL_OUT;for(i=0;i<8;i++){SCL_1;if((P5IN&BIT1)==BIT1) tempdata|=temp; temp>>=1;SCL_0;}return(tempdata);}void ack(void){SCL_OUT;SDA_IN;SCL_1;ACK_FLAG=0;if((P5IN&BIT1)) ACK_FLAG=1;SCL_0;delay(10);}void i2c_ack(uchar tm){SDA_OUT;SCL_OUT;if(tm==0) SDA_1;else SDA_0;delay(10);SCL_1;delay(10);SCL_0;delay(10);}void send_word(void){uchar i=0;while(1){start();delay(20);send_byte(0xa0);ack();if(ACK_FLAG) continue;send_byte(add);ack();if(ACK_FLAG) continue;for(i=0;i<8;i++) {send_byte(*D++);ack();if(ACK_FLAG)continue;}if(!ACK_FLAG) break;}stop();}void receive_word(uchar add){uchar i;while(1){start();send_byte(0xa0);ack();if(ACK_FLAG) continue;send_byte(add);ack();if(ACK_FLAG) continue;start();send_byte(0xa1);ack();if(ACK_FLAG) continue;MPM[i++]=receive_byte();delay(5);i2c_ack(1);if(!ACK_FLAG) break;}stop();}子程序:uart#include <msp430x14x.h>#include "Uart.h"/*****************串口初试化设置********************/void uart_org(void){ME1 |= UTXE0 + URXE0; // Enable USART0 TXD/RXD UCTL0 |= CHAR; // 8-bit characterUTCTL0 |= SSEL0; // UCLK = ACLKUBR00= 0x03; // 32768/9600UBR10= 0x00;UMCTL0= 0x4a;P3SEL |= 0x30; // P3.4,5 = USART0 TXD/RXD P3DIR |= 0x10;UCTL0 &= ~SWRST; // Initialize USART state machineIE1 |= URXIE0; // Enable USART0 RX interrupt}/*****************串口发送字符串程序*****************/void UartStr(unsigned char *p){unsigned char i;for (i=0;*p!=0;i++)//准备要发送的数据{while (!(IFG1 & UTXIFG0));// USART0 TX buffer ready?TXBUF0 =*p++; // RXBUF0 to TXBUF0while ((UTCTL0 & TXEPT) == 0);}_NOP();}/*****************串口发送字符串程序*****************/void Uart_Str(unsigned char number,unsigned char *p){unsigned char i;for (i=0;i<number;i++)//准备要发送的数据{while (!(IFG1 & UTXIFG0));// USART0 TX buffer ready?TXBUF0 =*p++; // RXBUF0 to TXBUF0while ((UTCTL0 & TXEPT) == 0);}_NOP();}(注:专业文档是经验性极强的领域,无法思考和涵盖全面,素材和资料部分来自网络,供参考。
这只是我在学习TI公司生产的16位超的功耗单片机MSP430的随笔,希望能对其他朋友有所借鉴,不对之处还请多指教。
下面,开始430之旅。
讲解430的书现在也有很多了,不过大多数都是详细说明底层硬件结构的,看了不免有些空洞和枯燥,我认为了解一个MCU的操作首先要对其基础特性有所了解,然后再仔细研究各模块的功能。
1、首先你要知道msp430的存储器结构。
典型微处理器的结构有两种:冯 ? 诺依曼结构----程序存储器和数据存储器统一编码;哈佛结构----程序存储器和数据存储器。
MSP430系列单片机属于前者,而常用的mcs51系列属于后者。
0-0xf特殊功能寄存器;0x10-0x1ff外围模块寄存器;0x200-?根据不同型号地址从低向高扩展;0x1000-0x107f seg_b0x1080_0x10ff seg_a 供flash信息存储,剩下的从0xffff 开始向下扩展,根据不同容量,例如149为60KB,0xffff-0x11002、复位信号是MCU工作的起点,430的复位型号有两种:上电复位信号POR和上电清楚信号PUC。
POR信号只在上电和RST/NMI复位管脚被设置为复位功能,且低电平时系统复位。
而PUC信号是POR信号产生,以及其他如看门狗定时溢出、安全键值出现错误是产生。
但是,无论那种信号触发的复位,都会使MSP430在地址0xffff处读取复位中断向量,然后程序从中断向量所指的地址开始执行。
复位后的状态不写了,详见参考书,嘿嘿。
3、系统时钟是一个程序运行的指挥官,时序和中断也是整个程序的核心和中轴线。
430最多有三个振荡器:DCO内部振荡器;LFXT1外接低频振荡器,常见的32768HZ,不用外接负载电容;也可接高频450KHZ-8M,需接负载电容;XT2接高频450KHZ-8M,加外接电容。
430有三种时钟信号:MCLK系统主时钟,可分频1/2/4/8,供CPU使用,其他外围模块在有选择情况下也可使用;SMCLK系统子时钟,供外围模块使用,可选则不同振荡器产生的时钟信号;ACLK辅助时钟,只能由LFXT1产生,供外围模块。
4、中断是430处理器的一大特色,因为几乎每个外围模块都能产生,430可以在没有任务时进入低功耗状态,有事件时中断唤醒CPU,处理完毕再次进入低功耗状态。
整个中断的响应过程是这样的,当有中断请求时,如果CPU处于活动状态,先完成当前命令;如果处于低功耗,先退出,将下一条指令的PC值压入堆栈;如果有多个中断请求,先响应优先级高的;执行完后,等待中断请求标志位复位,要注意,单中断源的中断请求标志位自动复位,而多中断的标志位需要软件复位;然后系统总中断允许位SR.GIE复位,相应的中断向量值装入PC,程序从这个地址继续执行。
这里要注意,中断允许位SR.GIE和中断嵌套问题。
如果当你执行中断程序过程中,希望可以响应更高级别的中断请求时,必须在进入第一个中断时把SR.GIE置位。
其实,其他的外围模块时钟沿着时钟和中断这个核心来执行的。
具体的结构我也不罗索了,可以参考430系列手册。
-----------------------------------------------------------上面把430单片机的基础特性交待了一下,让大家整体有了结构的印象,后面我想在写一下C语言对430编程的整体结构。
基本上属于框架结构,即整体的模块化编程,其实这也是硬件编程的基本法则拉(可不是我规定的法则哦)。
首先是程序的头文件,包括#include <MSP430x14x.h>,这是14系列,因为常用149;其他型号可自己修改。
还可以包括#include "data.h" 等数据库头文件,或函数变量声明头文件,都是你自己定义的哦。
接着就是函数和变量的声明 void Init_Sys(void);系统初始化。
系统初始化是个整体的概念,广义上讲包括所有外围模块的初始化,你可以把外围模块初始化的子函数写到Init_Sys ()中,也可以分别写各个模块的初始化。
但结构的简洁,最好写完系统的时钟初始化后,其他所用到的模块也在这里初始化。
void Init_Sys(){unsigned int i;BCSCTL1&=~XT2OFF; //打开XT2振荡器do{IFG1 &= ~OFIFG; // 清除振荡器失效标志for (i = 0xFF; i > 0; i--); // 延时,等待XT2起振}while ((IFG1 & OFIFG) != 0); // 判断XT2是否起振BCSCTL2 =SELM_2+SELS; //选择MCLK、SMCLK为XT2//以下对各种模块、中断、外围设备等进行初始化_EINT(); //打开全局中断控制}这里涉及到时钟问题,通常我们选择XT2为8M晶振,也即系统主时钟MCLK为8M,CPU执行命令以此时钟为准;但其他外围模块可以在相应的控制寄存器中选择其他的时钟,ACLK;当你对速度要求很低,定时时间间隔大时,就可以选择ACLK,例如在定时器Timea初始化中设置。
主程序: void main( void ){WDTCTL = WDTPW + WDTHOLD; //关闭看门狗InitSys(); //初始化//自己任务中的其他功能函数while(1);}主程序之后我要讲讲中断函数,中断是你做单片机任务中不可缺少的部分,也可以说是灵魂了(夸张吗)。
/***************************************************************************** 各中断函数,可按优先级依次书写******************************************************************************/举个定时中断的例子:初始化 void Init_Timer_A(void){TACTL = TASSEL0 + TACLR; // ACLK, clear TARCCTL0 = CCIE; // CCR0 中断使能CCR0=32768; //定时1sTACTL|=MC0; //增计数模式}中断服务 #pragma vector=TIMERA0_VECTOR__interrupt void TimerA0(){// 你自己要求中断执行的任务}当然,还有其他的定时和多种中断,各系列芯片的中断向量个数也不同。
整体的程序设计结构,包括了所有外围模块及内部时钟,中断,定时的初始化。
具体情况大家可以根据自己的需要添加或者减少,记住,模块化设计时最有力的武器。
这可是个人总结的经典啊,谢谢支持。
因为经常使用149,所以这是149的结构,其他的再更改,根据个人需要。
/***************************************************************************** 文件名:main.c描述:MSP430框架程序。
适用于MSP430F149,其他型号需要适当改变。
不使用的中断函数保留或者删除都可以,但保留时应确保不要打开不需要的中断。
*****************************************************************************/#include <MSP430x14x.h> //头文件void InitSys(); //函数声明int main( void ){WDTCTL = WDTPW + WDTHOLD; //关闭看门狗InitSys(); //初始化start://以下填充用户代码LPM3; //进入低功耗模式n,n:0~4。
若不希望进入低功耗模式,屏蔽本句goto start;}/*****************************************************************************系统初始化******************************************************************************/void InitSys(){unsigned int iq0;//使用XT2振荡器BCSCTL1&=~XT2OFF; //打开XT2振荡器do{IFG1 &= ~OFIFG; // 清除振荡器失效标志for (iq0 = 0xFF; iq0 > 0; iq0--); // 延时,等待XT2起振}while ((IFG1 & OFIFG) != 0); // 判断XT2是否起振BCSCTL2 =SELM_2+SELS; //选择MCLK、SMCLK为XT2//以下填充用户代码,对各种模块、中断、外围设备等进行初始化_EINT(); //打开全局中断控制,若不需要打开,可以屏蔽本句}/***************************************************************************** 端口1中断函数多中断中断源:P1IFG.0~P1IFG7进入中断后应首先判断中断源,退出中断前应清除中断标志,否则将再次引发中断******************************************************************************/ #pragma vector=PORT1_VECTOR__interrupt void Port1(){//以下为参考处理程序,不使用的端口应当删除其对于中断源的判断。
if((P1IFG&BIT0) == BIT0){//处理P1IN.0中断P1IFG &= ~BIT0; //清除中断标志//以下填充用户代码}else if((P1IFG&BIT1) ==BIT1){//处理P1IN.1中断P1IFG &= ~BIT1; //清除中断标志//以下填充用户代码}else if((P1IFG&BIT2) ==BIT2){//处理P1IN.2中断P1IFG &= ~BIT2; //清除中断标志//以下填充用户代码}else if((P1IFG&BIT3) ==BIT3){//处理P1IN.3中断P1IFG &= ~BIT3; //清除中断标志//以下填充用户代码}else if((P1IFG&BIT4) ==BIT4){//处理P1IN.4中断P1IFG &= ~BIT4; //清除中断标志//以下填充用户代码}else if((P1IFG&BIT5) ==BIT5){//处理P1IN.5中断P1IFG &= ~BIT5; //清除中断标志//以下填充用户代码}else if((P1IFG&BIT6) ==BIT6){//处理P1IN.6中断P1IFG &= ~BIT6; //清除中断标志//以下填充用户代码}else{//处理P1IN.7中断P1IFG &= ~BIT7; //清除中断标志//以下填充用户代码}LPM3_EXIT; //退出中断后退出低功耗模式。