把这几天的作业做一个小结:
第一版
MSP430G2553学习笔记
Createdon:2012-8-18
Author:zhangbin
学习笔记
formsp430g2553
redesignedbyzhang bin
2012-08-18
versions:12_08_01
一,MSP430G2553单片机的各个功用模块
(一),IO口模块,
1,咱们所用的MSP430G2553有两组IO口,P1和P2。
2,IO口的寄存器有:方向挑选寄存器PxDIR,输出寄存器PxOUT,输入寄存器PxIN,IO口内部上拉或下拉电阻使能寄存器PxREN,IO口功用挑选寄存器PxSEL和PxSEL2,IO口中止使能寄存器PxIE,中止沿挑选寄存器PxIES,IO口中止标志寄存器PxIFG。
3,一切的IO都带有中止,其间一切的P1口共用一个中止向量,一切的P2口共用一个中止向量。所以在运用中止时,当进入中止后,还要判别到底是哪一个IO口发生的中止,判别办法可所以判别各个IO口的电平。
4,中止标志PxIFG需求软件铲除,也能够用软件置位,然后用软件触发一个中止。
留意:在设置PxIESx时依据PxINx有或许会引起相应的PxIFGx置位(具体的状况见用户攻略),所以在初始化完IO口中止今后,正式运用IO中止前要先将对应的PxIFGx清零。程序如下:
voidIO_interrupt_init()//IO中止初始化函数
{
P1REN|=BIT4+BIT5+BIT6+BIT7;//pullup内部上拉电阻使能
//运用中止时,使能内部的上拉电阻这样当该脚悬空是,电平不会跳变,避免悬空时电平跳变不断的触发中止
P1OUT=BIT4+BIT5+BIT6+BIT7;//当引脚上的上拉或下拉电阻使能时,PxOUT挑选是上拉仍是下来
//0:下拉,1:上拉
P1IE|=BIT4+BIT5+BIT6+BIT7;//interruptenabledP13中止使能
P1IES|=BIT4+BIT5+BIT6+BIT7;//Hi/loedge下降沿中止
//P1IES&=~BIT3;//上升沿触发中止
P1IFG&=~(BIT4+BIT5+BIT6+BIT7);//中止标志位清零
}
5,PxOUT:假如引脚挑选了内部的上拉或下拉电阻使能,则PxOUT设定电阻是上拉仍是下拉,0:下拉,1:上拉
6,当IO口不必时,最好不要设为输入,且为起浮状况(这是IO口的默许状况),由于当输入为起浮时,输入电压有或许会在VIL和VIH之间,这样会发生击穿电流。所以不必的IO口能够设为输出状况,或设为输入状况但通过外围电路接至VCC或GND,或接一个上拉/下拉电阻。
7,当运用msp430g2553的IO口时要留意,由于g2553的IO口寄存器的操作,不像51,它不能独自针对某一位进行操作,有必要对整个寄存器进行操作。所以就不像51,g2553不能够界说bit型的数据。所以在运用msp的IO口时要留意对需求位的操作,而不要影响其他无关的位,能够用|&^等按位操作的符号。在运用IO都操控其他外围模块时也要留意要运用的IO口的界说,能够用如下的界说办法:
#defineCLR_RSP2OUT&=~BIT0;//RS=P2.0
#defineSET_RSP2OUT|=BIT0;
#defineCLR_RWP2OUT&=~BIT1;//RW=P2.1
#defineSET_RWP2OUT|=BIT1;
#defineCLR_ENP2OUT&=~BIT2;//EN=P2.2
#defineSET_ENP2OUT|=BIT2;
#defineDataPortP1OUT
8,g2553的P27和P26脚别离接外部晶体的输出和输入脚XOUT和XIN,默许是主动设为了晶振管脚功用,可是当想把它们用为一般的IO时,也能够,设置对应的SEL设为一般的IO即可,如下:
P2DIR|=BIT6+BIT7;//把P26和P27装备为一般IO并为输出脚默许为晶振的输入和输出引脚作为dac0832的
P2SEL&=~(BIT6+BIT7);//cs和wr操控端
P2SEL2&=~(BIT6+BIT7);
(二),时钟体系
1,msp430能做到超低功耗,合理的时钟模块是功不可没的。可是功用强大的时钟模块设置起来也相对杂乱一些。
2,msp430的时钟源有:
(1),外接低频晶振LFXT1CLK:低频形式接手表晶体32768Hz,高频形式450KHz~8MHz;
(2),外接高速晶振XT2CLK:8MHz;
(3),内部数字操控振荡器DCO:是一个可控的RC振荡器,频率在0~16MHz;
(4),超低功耗低频振荡器VLO:不可控,4~20KHz典型值为12KHz;
3,时钟模块:430的时钟模块有MCLKSMCLKACLK:
(1),主体系时钟MCLK:供给给MSP430的CPU时钟。能够来自LFXT1CLKXT2CLKDCOVLO可选,默许为DCO。
(2),子体系时钟SMCLK:供给给高速外设。能够来自LFXT1CLKXT2CLKDCOVLO可选,默许为DCO。
(3),辅佐体系时钟ACLK:供给给低速外设。可来自LFXT1CLKVLO。
4,内部的振荡器DCO和VLO供给的时钟频率不是很准确,随外部环境改变较大。
DCO默许的频率大约为800KHz,但我用示波器调查的为1.086MHz左右,当DCO设置的过高时,用示波器能够看到波形不再是方波,而是相似于正弦波。DCO能够用CCS供给的宏界说进行相对比较准确的设置,如下:
DCOCTL=CALDCO_12MHZ;//DCO设为12MHz这种办法设DCO频率比较准确,实践测得为12.08MHz左右正弦波
BCSCTL1=CALBC1_12MHZ;
用这种办法能够设置1,8,12,16MHz
宏界说如下:
#ifndef__DisableCalData
SFR_8BIT(CALDCO_16MHZ);
SFR_8BIT(CALBC1_16MHZ);
SFR_8BIT(CALDCO_12MHZ);
SFR_8BIT(CALBC1_12MHZ);
SFR_8BIT(CALDCO_8MHZ);
SFR_8BIT(CALBC1_8MHZ);
SFR_8BIT(CALDCO_1MHZ);
SFR_8BIT(CALBC1_1MHZ);
#endif
5,运用超低功耗低频振荡器VLO能够很大程度地下降体系功耗,下面的比如是设置ACLK为VLO,MCLK为VLO的8分频:
#include
//1延时
//#defineCPU_F((double)16000000)//cpufrequency16000000
#defineCPU_F((double)1630)//cpufrequency1630//CPU的实践MCLK大约为13.05/8=1.63KHz
#definedelay_us(x)__delay_cycles((long)(CPU_F*(double)x/1000000.0))
#definedelay_ms(x)__delay_cycles((long)(CPU_F*(double)x/1000.0))
voidmain(void)
{
volatileunsignedinti;//Volatiletopreventremoval
WDTCTL=WDTPW+WDTHOLD;//Stopwatchdogtimer
BCSCTL3|=LFXT1S_2;//LFXT1=VLO低频时钟挑选为VLOACLK选为VLO
IFG1&=~OFIFG;//ClearOSCFaultflag铲除振荡器过错中止标志
__bis_SR_register(SCG1+SCG0);//StopDCOSCG1制止SMCLKSCG0制止DCO
BCSCTL2|=SELM_3+DIVM_3;//MCLK=LFXT1/8
//由于前面现已挑选了LFXT1=VLO所以MCLK选为VLO8分频所以CPU的MCLK大约为1.5KHz
P1DIR=0xFF;//AllP1.xoutputs
P1OUT=0;//AllP1.xreset
P2DIR=0xFF;//AllP2.xoutputs
P2OUT=0;//AllP2.xreset
P1SEL|=BIT0+BIT4;//P10P14options功用挑选为外围模块
//p10输出ACLK,来自VLO,p14输出SMCLK,由于制止了SMCLK,所以P14脚无波形输出
//VLO典型值为12KHz实践用示波器测得为:13.05KHz左右动摇
//所以CPU的实践MCLK大约为13.05/8=1.63KHz
for(;;)
{
P1OUT^=BIT6;//P1.6闪耀
delay_ms(1000);
}
}
6,如上面的程序所示,其间的推迟函数用那种办法,运用体系的推迟周期函数__delay_cycles(intn);能够到达比较准确的推迟,如下:
//more_
//1延时
//#defineCPU_F((double)16000000)//cpufrequency16000000
#defineCPU_F((double)12000000)//cpufrequency12000000
#definedelay_us(x)__delay_cycles((long)(CPU_F*(double)x/1000000.0))
#definedelay_ms(x)__delay_cycles((long)(CPU_F*(double)x/1000.0))
//2空函数
#definenop()_NOP();
7,体系上电后默许运用的是DCO时钟,DCO默许的频率大约为800KHz,但我用示波器调查的为1.086MHz左右,当DCO设置的过高时,用示波器能够看到波形不再是方波,而是相似于正弦波。
(三),守时器Timer_A
1,MSP430g2553具有两个16位的守时器:Timer0_ATimer1_A。别离具有三个捕捉/比较寄存器,具有输入捕捉,输出比较功用。能够发生守时中止,也能够发生PWM。
2,发生PWM,比如如下:
#include
voidTimer_A0_1_init()//TA0.1输出PWM
{
TACTL|=TASSEL_1+MC_1;//ACLK,增计数
CCTL1=OUTMOD_7;//输出形式为复位/置位
CCR0=328;//时钟频率为32768HZ,100HZ
//CCR1=164;//时钟频率为32768HZ,占空比CCR1/CCR0=50%
CCR1=109;//占空比CCR1/CCR0=1/3TA0.1由P1.2P1.6输出
}
voidTimer_A1_2_init()//TA1.2输出PWM
{
TA1CTL|=TASSEL_1+MC_1;//ACLK,增计数
TA1CCTL2=OUTMOD_7;//输出形式为复位/置位,留意CCTL2要写为TA1CCTL2
TA1CCR0=164;//时钟频率为32768HZ,波形32768/CCR0=199HZ
TA1CCR2=41;//占空比CCR2/CCR0=1/4,留意CCR2要写成TA1CCR2TA1.2由P2.4P2.5输出
}
voidTimer_A1_1_init()//TA1.1输出PWM
{
TA1CCTL1=OUTMOD_7;
TA1CCR1=123;//占空比CCR1/CCR0=3/4,留意CCR1要写成TA1CCR1TA1.1由P2.1P2.2输出
}
voidIO_init()
{
P1SEL|=BIT2+BIT6;
P1DIR|=BIT2+BIT6;//P1.2P1.6输出TA0.1OUT1
P2SEL|=BIT4+BIT5;
P2DIR|=BIT4+BIT5;//P2.4P2.5输出TA1.2OUT2
P2SEL|=BIT1+BIT2;
P2DIR|=BIT1+BIT2;//P2.1P2.2输出TA1.1OUT1
}
voidmain(void){
WDTCTL=WDTPW+WDTHOLD;
IO_init();
Timer_A0_1_init();
Timer_A1_2_init();
Timer_A1_1_init();
_BIS_SR(CPUOFF);//EnterLPM0进入低功耗形式0SMCLKON,ACLKON
}
3,Timer_A的捕获/比较寄存器
TAR寄存器是Timer_A的16位的计数寄存器。TACCRx是Timer_A的捕获/比较寄存器,当为捕获形式时:当捕获发生时,把TAR的值装载到TACCRx中。当为比较形式时:TACCRx中装的是要与TAR寄存器相比较的值。
4,捕获形式
捕获外部输入的信号的上升沿或下降沿或上升沿下降沿都捕捉,当捕捉发生时,把TAR的值装载到TACCRx中,一起也能够进入中止,履行相应的操作。这样运用捕捉上升沿或下降沿就能够核算外部输入信号的周期,得出频率。运用捕捉上升沿和下降沿能够得出输入信号的高电平或低电平的持续时刻。也能够算出占空比。下面是一个比如,是Timer_A捕获初始化的程序:
voidtimer_init()//运用Timer1_A时要特别留意各个寄存器的写法,由于Timer0_A的寄存器都简写了,所以在写
//Timer1_A的寄存器时,要特别留意与Timer0_A的不同
{
P1SEL|=BIT2;//挑选P12作为捕捉的输入端子Timer0_A
//TACCTL1|=CM_3+SCS+CAP+CCIE;//上下沿都触发捕捉,用于测脉宽,同步形式、时能中止CCI1A
TACCTL1|=CM_1+SCS+CAP+CCIE;//上升沿触发捕捉,同步形式、时能中止CCI1A
TACTL|=TASSEL1+MC_2;//挑选SMCLK时钟作为计数时钟源,不分频增计数模式不可,有必要接连计数形式
P2SEL|=BIT1;//挑选P21作为捕捉的输入端子Timer1_A
//TA1CCTL1|=CM_3+SCS+CAP+CCIE;//上下沿都触发捕捉,用于测脉宽,同步形式、时能中止CCI1A
TA1CCTL1|=CM_1+SCS+CAP+CCIE;//上升沿触发捕捉,同步形式、时能中止CCI1A
TA1CTL|=TASSEL1+MC_2;//挑选SMCLK时钟作为计数时钟源,不分频增计数形式不可,有必要接连计数形式
}
相对应的中止函数如下:
#pragmavector=TIMER0_A1_VECTOR//Timer0_ACC1的中止向量
__interruptvoidTimer_A(void)
{
//CCI0A运用的捕捉比较寄存器是TA0CCR0,TA0CCR0独自分配给一个
//中止向量TIMER1_A0_VECTOR,所以进入中止后直接便是Timer0_ACC0发生的中止,不必通过相似
//下面的办法判别中止源了。
//Timer0_ACC1-4,TA0共用一个中止向量TIMER0_A1_VECTOR,所以进入了中止后还要用下面
//的办法进行判别是哪一个中止源发生的中止
switch(TAIV)//假如是Timer0_ACC1发生的中止
{
case2:
{
flag=1;
LPM1_EXIT;//退出低功耗形式
//_BIC_SR_IRQ(LPM1_bits);
//_bic_SR_register_on_exit(LPM1_bits);
break;
}
case4:break;
case10:break;
}
}
#pragmavector=TIMER1_A1_VECTOR//Timer1_ACC1的中止向量
__interruptvoidTimer_A1(void)
{
//P1OUT|=BIT0;//led调试用的
//LPM1_EXIT;//退出低功耗形式由于运用的是CCI0A运用的捕捉比较寄存器是TA1CCR0,TA1CCR0独自分配给一个
//中止向量TIMER1_A0_VECTOR,所以进入中止后直接便是Timer1_ACC0发生的中止,不必通过相似
//下面注释掉的办法判别。
//而Timer1_ACC1-4,TA1则共用一个中止向量TIMER1_A1_VECTOR,所以进入了中止后还要用下面
//的办法进行判别是哪一个中止源发生的中止
switch(TA1IV)//假如是Timer1_ACC1发生的中止
{
case2:
{
flag=2;
LPM1_EXIT;//退出低功耗形式
//_BIC_SR_IRQ(LPM1_bits);
//_bic_SR_register_on_exit(LPM1_bits);
break;
}
case4:break;
case10:break;
}
}
//假如要丈量更低频率的信号的话,能够在中止中判别溢出中止发生的次数,这样就能够得到溢出的次数,然后能够丈量更
//低频率的信号
5,Timer_A的计数形式
计数形式有:增计数形式,接连计数形式和增减计数形式。具体的各个形式的详解,拜见用户攻略。
6,守时器的守时中止
在运用守时器的守时中止时,要留意守时器计数形式的挑选。在运用中止时,要留意中止向量的运用和中止源的判别,下面就举一个比如,注释的也较具体:
#include
unsignedintt=0;
voidmain(void)
{
WDTCTL=WDTPW+WDTHOLD;//StopWDT
P1DIR|=0x01;//P1.0output
CCTL0=CCIE;//CCTLx是捕获/比较操控寄存器interruptenabledCCIE=0x0010时能守时器A中止
CCR0=50000;//捕获/比较寄存器设置计数器CCR0的初值16位寄存器,最大值为65535
//默许SMCLK运用的是DCO,默许的DCO大约为800KHz,而CCR0=50000,所以中止发生的频率大约为16Hz
TACTL=TASSEL_2+MC_2;//SMCLK,contmode接连计数形式从0计到0FFFFh
//TACTL=TASSEL_2+MC_1;//SMCLK,upmode增计数形式从0计到CCR0
_BIS_SR(LPM0_bits+GIE);//EnterLPM0w/interrupt进入低功耗形式0,答应中止
}
//TimerA0interruptserviceroutine
#pragmavector=TIMER0_A0_VECTOR
__interruptvoidTimer_A(void)//CCIFG中止被呼应后,该标志位主动清零
{
//P1OUT^=0x01;//ToggleP1.0
t++;
if(t==5)
{
P1OUT^=BIT0;//ToggleP1.0
t=0;
}
CCR0+=50000;//AddOffsettoCCR0添加CCR0偏移
//守时器总是从0开端往上计数,一直到计满再从0开端,在接连计数形式下,当守时器的值等于CCR0时,发生中止
//在中止中对CCR0添加50000,这样的话守时器从当时值到下一时刻再次等于CCR0时的距离为50000,稳定
//这样发生中止的时刻距离就相等了
//所以在接连计数形式下,要想使中止的时刻距离必定,就要有CCR0+=n;这句话
//在中止中CCR0不需求重新赋值,差异于51
}
中止的运用留意状况:仍是把举个比如吧:
#include
voidmain(void)
{
WDTCTL=WDTPW+WDTHOLD;//StopWDT
P1DIR|=0x01;//P1.0output
TACTL=TASSEL_2+MC_2+TAIE;//SMCLK,contmode,interruptTAIE答应守时器溢出中止
_BIS_SR(LPM0_bits+GIE);//EnterLPM0w/interruptGIE答应中止
}
//Timer_A3InterruptVector(TA0IV)handler
#pragmavector=TIMER0_A1_VECTOR
__interruptvoidTimer_A(void)
{
switch(TA0IV)//TAIV中止向量寄存器用于
{
case2:break;//CCR1notused捕获/比较器1
case4:break;//CCR2notused捕获/比较器2
case10:P1OUT^=0x01;//overflow守时器溢出
break;
}
}
7,留意:守时器Timer0_A的时钟能够挑选为外接时钟输入TACLK(P10),这样当外接一个信号时,守时器Timer0_A就适当于一个计数器运用。这样就能够用Timer0_A接外接信号,Timer1_A接规范的时钟如32768Hz的晶振,就能够完成等精度测频了。其实Timer1_A的时钟也能够外接的,可是在g2553中没有这个外接管脚(P37),所以就只能挑选正常的时钟了。
Timer0_A的外接时钟输入TACLK(P10)的设置如下:下面是我完成等精度测频时,两个守时器的初始化程序:
voidtimer0_init()
{
TACTL|=TASSEL_0+MC_2+TACLR;//挑选TACLK时钟作为计数时钟源,不分频有必要接连计数形式
P1SEL|=BIT0;//P10为Timer0_A的时钟TACLK输入,接外部待测信号,这样Timer0_A就当作计数器用
}
//Timer1_A选用ACLK作为时钟源计数,这样ACLK就适当所以规范信号,这样两个守时器适当于都作业在计数器方法,
//ACLK32768Hz作为规范信号,这样能够完成等精度测频
voidtimer1_init()
{
TA1CCTL0=CCIE;
TA1CCR0=32768;//1s守时
TA1CTL|=TASSEL_1+MC_2+TACLR;//挑选ACLK时钟作为计数时钟源,不分频有必要接连计数形式
}
8,用守时器和比较器能够完成DAC
运用守时器也能够完成串口通讯
声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qianrushi/yingjian/256240.html