完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一:端口配置 1:P1DIR 设置为1,相应管脚为输出。设置为0.相应管脚 为输入状态。 2:P1IE 设置为1,相应管脚具有中断功能。设置为0, 相应管脚没有中断功能。 3:P1IES 设置为1,选择下降沿触发方式,设置为0,选 择上升沿触发方式。 4:P1IFG P1端口的中断标志寄存器,如果P1端口当某 个管脚设置成中断管脚,当有中断触发时,想应比特为1 ; 如果没有中断触发,相应比特为0. 5: P1IN P1端口输入寄存器,在输入模式下,读取该寄 存器相应管脚上的数据。 6: P1OUT P1端口的输出去寄存器,在输出模式下,如 果该寄存器相应比特设置为1时,相应管脚输出高电平; 如果该寄存器相应比特为0时,相应管脚输出低电平。 7: P1SEL寄存器 P1端口功能选择寄存器,该寄存器主要 控制P1端口的I/O管脚作为一般I/O还是外围模块的功能 端口,该寄存器的相应比特为1时候,相应管脚为外围功能 模块,当该寄存器为0时,相应管脚为一般I/O管脚。 二 LaunchPad 写程序的必要头文件和格式: /*=================================================== #include"msp430g2553.h" Void main() { WDTCTL=WDTPW+WDTHOLD;//关闭看门狗。 //WDTPW 是看门狗的密码,写错了会导致系统复位。 **(程序) } =====================================================*/ 三 点亮LED 仅仅是对IO 口的输入输出操作。与51 很不相同。 P1DIR|=BIT0;//设置P1.0 为输出方向。===P1DIR|=0x01; //{P1DIR=BIT0;是设置P1.0 为输出,其他全部为输入方向。} //注意:LaunchPad 中很多操作是与,或,非等操作组成,时刻注意。 P1OUT|=BIT0;//这条指令就是设置P1.0 输出为高电平。 这样,就点亮了LED(接在P1.0 上的LED); 具体程序: #include"msp430g2553.h" Void main() { WDTCTL=WDTPW+WDTHOLD; P1DIR|=BIT0; P1OUT|=BIT0; While(1); } 四: 闪烁LED LaunchPad 上面自带有2 个LED,一个接在P1.0 上,一个接在P1.6 上。 我们用2 个交替闪烁。 #include"msp430g2553.h" Void main();第一个字母大写 { WDTCTL=WDTPW+WDTHOLD; P1DIR|=BIT0+BIT6;//设置P1.0 和P1.6 为输出 P1OUT|=BIT0;//线让LED0 亮。 While(1) { Unsigned int i=50000; While(i--); P1OUT^=0x41;//对P1.0 和P1.6 取反,所以LED0 和LED1 会交替闪烁。 } } 五:中断系统 LaunchPad 的中断系统功能相当强大,51 只有5 个中断源,2 个定时,2 个外部, 一个串行口。但是LaunchPad 的中断源几乎是所有的引脚和所用的定时器。 在这里,最重要的就是中断向量的判断了。 定时器一般都是: vector=tiMER0_A0_VECTOR vector=TIMER0_A1_VECTOR vector=TIMER1_A0_VECTOR vector=TIMER1_A1_VECTOR 引脚中断的向量: vector=PORT1_VECTOR; P1 口的中断向量。 判断是哪个引脚的话,有2 种办法: 举例子:P1.3 和P1.4 都是中断的输入引脚。现在进了中断,我如何判断是那个引 脚引起的呢? 第一种方法: vector=PORT1_VECTOR __interruput void Port1 (void) { If(P1IFG&BIT3);判断的是P1.3 产生的中断。 { ;要执行的函数。 P1IFG=0x00;//清0 中断标志位。 } If(P1IFG&BIT4) { ;P1.4 产生的中端,执行相应的函数。 P1IFG=0x00; } } 第二种方法: vector=PORT1_VECTOR __interruput void Port1 (void) { P1IFG&=BIT3+BIT4;//因为只用到了P1.0 和P1.4,其他的中断标志全部清零。 (或者:P1IFG=P1IFG&0x18) Switch(P1IFG) { Case 0x08: vector=3;break; //P1.3 产生的中断 Case 0x10:vector=4;break;//P1.4 产生的中断 } } 切记:进入中断函数后要做的第一件事是,清除中断标志。 例程: #include Void main(void) { WDTCTL=WDTPW+WDTHOLD; P1DIR|=BIT0; // 设置P1.0输出 P1IES |=BIT3; // 设置从高到底跳变触发 P1IFG&=~BIT3// 清除中断标志位 P1IE |=BIT3 // 使P1.3能中断 _BIS_SR(LPM_bits+GIE);// 启动LMP4节能模式 } #proagma vector=PORT1_VECTOR _interrupt void Port_1(void) { If(P1IFG&BIT3) { P1OUT^=BIT0; P1IFG&=~BIT3; } } 程序一开始 1 WDTCTL=WDTPW+WDTHOLD; HOLD住看门狗 2 P1DIR|=BIT0;将P1.0 设置为输出口。lunchpad上的P1.O接有一个LED. 3. 接下来到P1IES |= BIT3; 在上一节中已经介绍了,P1IES 寄存器是中断沿选择寄存器。这里是选择位下降沿触发中断。 4. P1IFG &= ~BIT3; 为清除中断标志,保证程序正常运行,当然此句可以不写,这里只是做为例子 5. P1IE |= BIT3; 在上一节中已经介绍了,P1IE寄存器是使能中断事件发生的寄存器。
[tr][td] #pragma vector= 中断向量源 __interrupt void 函数名(void) [/td][/tr] [tr][td] [/td][/tr] 摁住“Ctrl + 左键”点击PORT1_VECTOR即可查看到所有的“中断向量” 在上面的中断向量中,加黑的位中断向量源,写入中断函数编写语法规则里面即可。而函数名则可以任意编写。比如我要编写一个有定时器1,CCR0寄存器溢出产生的中断,则可以这样编写 [tr][td] #pragma vector= TIMER1_A0_VECTOR __interrupt void T1A0Int(void) { //程序代码。。。 } [/td][/tr] 假如是多IO输入中断,则如下所写。 [tr][td] vector=PORT1_VECTOR __interrupt void Port1() { [/td][td] [/td][/tr] [tr][td=2,1] //以下为参考处理程序,不使用的端口应当删除其对于中断源的判断。 if((P1IFG&BIT0) == BIT0) { P2OUT&=~BIT0; //处理P1IN.0中断 P1IFG &= ~BIT0; //清除中断标志 //以下填充用户代码 } else if((P1IFG&BIT1) ==BIT1) { P2OUT&=~BIT1; //处理P1IN.1中断 P1IFG &= ~BIT1; //清除中断标志 //以下填充用户代码 } else if((P1IFG&BIT2) ==BIT2) { P2OUT&=~BIT2; //处理P1IN.2中断 P1IFG &= ~BIT2; //清除中断标志 //以下填充用户代码 } else if((P1IFG&BIT3) ==BIT3) { //处理P1IN.3中断 P1IFG &= ~BIT3; //清除中断标志 //以下填充用户代码 } else if((P1IFG&BIT4) ==BIT4) { P2OUT&=~BIT4; //处理P1IN.4中断 P1IFG &= ~BIT4; //清除中断标志 //以下填充用户代码 } else if((P1IFG&BIT5) ==BIT5) { //处理P1IN.5中断 P1IFG &= ~BIT5; //清除中断标志 //以下填充用户代码 } else if((P1IFG&BIT6) ==BIT6) { //处理P1IN.6中断 P1IFG &= ~BIT6; //清除中断标志 //以下填充用户代码 [tr][td] } else { //处理P1IN.7中断 P1IFG &= ~BIT7; //清除中断标志 //以下填充用户代码 } LPM3_EXIT; //退出中断后退出低功耗模式。若退出中断后要保留低功耗模式,将本句屏蔽 } [/td][/tr] [/td][/tr] 六 定时器模块 文先,介绍几个英文缩写的意思以及一些注意的地方。 1. Timer0/1 定时器0/1,在User's Guide中用的是TimerA/B,所指的也是Timer0/1 。G2553Datasheet中用的是Timer0/1 ,本文以G2553Datasheet为准。全文以Timer0为例,Timer1类同。 2. TAxR(x = 0/1)定时器x对应的计数器,这是一个只读寄存器。硬件自动驱动计数。
定时器简介 MSPG2553共有两个定时器,Timer0、Timer1,他们都是十六位的定时、计数器,内含三个捕获、比较寄存器。两个定时器均支持多个捕获、PWM输出、间歇性计时,定时器包含多个中断源,可以是计数溢出中断、捕获中断等等。 定时器包含: 同步十六位定时,计数器运行模式。 时钟源从MCLK、SMCLK、ACLK任意选择 三个比较,捕获寄存器。 中断向量寄存器能快速解码的所有定时器中断 Timer0组成框图 下面简要介绍一下该硬件框图的意思,从左上角看,首先是一个时钟源选择寄存器TASSELx,通过该寄存器选择定时器的时钟源,选择了时钟源后有一个分频器Divider,相应的设置寄存器是IDx,再过来就到一个定时器的核心部分,一个16位的定时器TAR。其右侧有一个定时器的计数模块,MCx寄存器用来设置计数模式。接下来,TAR正下方有三个横线,右侧标有CCR0、CCR1、CCR2,意思是CCR1、CCR0的框图和下方CCR2的框图是一样的。此处省略不写。在CCR中,左上角为一个捕获源选择寄存器。可以从CCI2A、CCI2B、GND或者VCC选择捕获源,选择捕获源后有一个选择捕获模式寄存器Capture Mode,然后过来有一个捕获溢出状态寄存器COV,SCS同步/异步捕获模式选择位,然后连接到捕获比较寄存器。下方为模式选择寄存器,具体设置可以查看相应的寄存器设置。 这里仅是大概介绍一下Timer0的寄存器,具体的设置使用还看参考相应的寄存器并结合例程慢慢学习理解。 定时器运行方式 下面简要重点介绍定时器计数模块的四种模式以及7种输出模式。 Timer0有一个在不断计数的只读寄存器TA0R。计数器的计数模式共有四种, 停止模式(Stop mode)、连续增计数模式(Up mode)、递增计数模式(continuous mode)、增减计数模式(Up/down mode)。由上图可知,这四种模式可以通过MCx寄存器进行设置。 以上四种模式可以由下图可以很好理解。 1. Stop模式计数器不工作。 2. 连续计数模式为计数器从零开始连续增计数一直到0xFFFF即65535,然后又重新从零开始计数。 3. 递增计数模式与连续计数模式仅有一点点区别,递增模式为计数器连续增加到TA0CCR0(即图中的CCR0)中的值后又重新从零开始计数。TA0CCR0的值时可以在程序中直接赋值的。 4. 递增递减模式也很好理解,计数器从零开始计数到CCR0后又自动减数,到零后又增计数,就像三角波一样。 每一个捕获比较模块都有一个输出单元,这个输出单元专门用来产生以下如PWM的波形信号,每一个输出单元都可以通过配置OUTMOD寄存器的值来设定八种信号输出模式, 接下来再介绍一下定时器的捕获/比较功能,具体应查看技术手册。 捕获模式 捕获模式可以用来速度计算或时间测量.CCIxA ,CCIxB的捕获源可以连接到外部引脚或者内部信号,可以设定CCIDx,CMx,位让寄存器捕获上升,下降,或者两个信号的边缘.输入信号的电平可以通过CCI位的读取. 当设置寄存器CAP=1时,使能捕获模块. 比较模式 比较模式设置CAP = 0的情况向,比较模式用于产生PWM信号。或者在指定时间里输出终端信号,当TAxR计数到TACCRx时 建立起CCIFG位 中断事件发生标志位EQUx=1 EQUx的隐含改变将影响输出模式 输入信号CCI被锁上SCCI
2. 递增计数模式下的输出 *
**************************************************************** / / ****************************************************************** * TACTL寄存器,Timer_A 控制寄存器 * TASSEL_x:TA时钟源选择寄存器 * 00 TACLK * 01 ACLK * 10 SMCLK * 11 INCLK * IDx: 时钟源分频寄存器。为输入时钟分频选择 * 00 /1 * 01 /2 * 10 /4 * 11 /8 * * ************************************************************** / * 定时计数模块 =四中模式+7种输出方式 / ***************************************************************** * * MCx: 计数模式寄存器 模式控制,当TA不用于节省功耗时,将MCx=00h * 00 停止模式:定时器停止 * 01 增模式 :定时器计数到TACCR0 * 10 连续模式:定时器计数到0FFFFh * 11 增减模式:定时器计数到TACCR0 然后减到000h * * TACLR: 定时器清零。置位时会复位TAR,时钟分频和计数方向。 * TACLR位会自动复位并读出值为零。 * * TAIE: TA中断允许。改为允许TAIFG中断请求 * 0 中断禁止 * 1 中断允许 * TAIFG: TA中断标志位 * 0 无中断挂起 * 1 中断挂起 * ************************************************************** / / ***************************************************************** * * * TACCTLx,捕获比较控制寄存器 * CMx: 捕获模式 * 00 不捕获 * 01 上升沿捕获 * 10 下降沿捕获 * 11 上升和下降同时捕 * CCISx: 捕获比较选择,改为选择TACCRx的输入信号 * 00 CCIxA * 01 CCIxB * 10 GND * 11 VCC * SCS: 同步捕获源,改为用于将捕获通信和同步时钟 * 0 异步捕获 * 1 同步捕获 * SCCI:同步的捕获/比较输入,所选择的输入信号由EQUx信号所存, * 并可通过该位读取 * CAP: 捕获模式 * 0 比较模式 * 1 捕获模式 *OUTMODx:输出模式位,对TACCR0无效 * 000 OUT 位的值 * 001 置位 * 010 翻转/复位 * 011 复位/复位 * 100 翻转 * 101 复位 * 110 翻转/置位 * 111 复位/置位 * CCIE: 捕获比较中断允许位 * 0 中断禁止 * 1 中断允许 * CCI: 捕获比较输入 * OUT: 对于输出模式0,该位直接控制输出状态 * COV: 捕获溢出位。该位表示一个捕获溢出发生,由软件复位 * CCIFG:捕获比较中断标志位 * 0 没有中断挂起 * 1 有中断挂起 * ***************************************************************/ #include unsigned int A=10, B=20 ; void main (void) { WDTCTL = WDTPW + WDTHOLD; TACTL|=TASSEL_2+TACLR+MC_1+ID_3; // SMCLK时钟 ;定时器清零;增模式 8分频 CCTL0=CCIE; //捕获中断允许 CCR0=B; //TACCR0 装载值 CCTL1=OUTMOD_7; //输出模式复位 CCR1=A; // BCSCTL1 P1DIR=BIT6; P1SEL=BIT6; // _EINT(); //使能所有中断 while(1); } /*#pragma vector=TIMER0_A0_VECTOR __interrupt void ta0_isr(void) { unsigned int i; for(i=0;i pwm=i; }*/ 定时器中断 这里以定时器0为例,定时器1同。 定时器的中断可有定时器TA0CCR0溢出产生,也可由TA0CCRx(x =1/2)溢出产生、捕获/比较事件发生引起的中断,前者有一个专用的中断向量,TIMER0_A0_VECTOR,而后者用的TIMER0_A1_VECTOR,至于是哪一个中断时间发生,还要根据标志位来判断。 下面以官方例程LaunchPad Lab2为例介绍定时器A的操作。 例一 [tr][td] #include void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF) { while(1); // If calibration constants erased, trap CPU!! } BCSCTL1 = CALBC1_1MHZ; // Set range DCOCTL = CALDCO_1MHZ; // Set DCO step + modulation BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO P1DIR = 0x40; // P1.6 output (green LED) P1OUT = 0; // LED off IFG1 &= ~OFIFG; // Clear OSCFault flag BCSCTL1 |= DIVA_3; // ACLK = VLO/8 BCSCTL2 |= SELM_3 + DIVM_3 + DIVS_3; // MCLK = DCO/8, SMCLK = DCO/8 // Configure TimerA TACTL = TASSEL_1 + MC_1 + TAIE; // Source: ACLK, UP mode CCR0 = 5100; //Timer count 5100 CCR1 = 2000; //Timer count 100 CCTL0 = CCIE; //CCR0 interrupt enabled CCTL1 = CCIE; //CCR1 interrupt enabled _BIS_SR(GIE); for(;;); [tr][td] } // Timer A0 interrupt service routine #pragma vector=TIMER0_A0_VECTOR __interrupt void Timer_A0 (void) { P1OUT |= BIT6; // P1.6 output High } // Timer A1 Interrupt Vector (TA0IV) handler #pragma vector=TIMER0_A1_VECTOR __interrupt void Timer_A1(void) { switch( TA0IV ) { case 2: P1OUT &= ~BIT6; // P1.6 output Low [tr][td] break; case 10: break; } } [/td][/tr] [/td][/tr] [/td][/tr] 程序一开始关闭看门狗,if语句作为时钟校准的范例,可以删去。BCSCTL3 |= LFXT1S_2; 选择超低频时钟源。然后设定输出口,清除中断标志,时钟源分频设定,接下里组建定时器A,即定时器0,在详细介绍代码之前,首先看头文件关于定时器相关寄存器的设定。 例二 下面举一个无需中断服务函数、硬件自动实现产生两路PWM的例子。 代码很简单,初始化一下即可。 [tr][td] #include void Set_TimerB_PWM(void) { //使用系统初始化时的默认时钟1MHz,定时器B专门用于产生PWM 波形。 TA1CTL = TASSEL_2 + MC_1 + TACLR;//使用系统次主机SMCKL、增计数模式、清楚定时器B时钟 TA1CCR0 = 5001 - 1;//在1MHz的主频率下,1*10^6/5000=200Hz的中断频率 TA1CCR1 = 3751 - 2;//当寄存器TACCR1的值小于3750时,输出口保持高电平。5000*3/4=3750,此路产生3:1的PWM波形。 TA1CCR2 = 1251 - 2;//当寄存器TACCR1的值小于1250时,输出口保持高电平。5000*1/4=1250,产生1:3的PWM波 TA1CCTL1 = OUTMOD_7;//输出模式7,计数器计数到5000计数器自动置位,无需中断服务子函数。 TA1CCTL2 = OUTMOD_7;//输出模式7,计数器计数到5000计数器自动置位,无需中断服务子函数。 P2SEL |= BIT1 + BIT5;//只有这两路可选(为什么是这两路?在G2553Datasheet中有特别指明)。做第二功能使用(PWM输出) P1DIR |= BIT6; //电机控制口CTL//这里与本例无关 P1OUT &= ~BIT6; //start with 0 -->IN2,4为1,灭//这里与本例无关 } [/td][/tr] 初始化时钟后直接调用该函数即可。 我这里使用的是定时器B(即Timer1)。详细的介绍见以上备注。 七 时钟配置 时钟源: 外部晶体振荡器 超低频率振荡器(VLO) 数字控制振荡器(DCO) 时钟信号: ACLK :Auxiliary clock.辅助时钟。 MCLK :Master clock主时钟。 SMCLK :Second Master clock次主机时钟。 内部晶体振荡器产生时钟后经过DCOR、SCG0、RSELx、DCO等各个寄存器为MCLK、SMCLK提供时钟源 内部时钟还有一个超低频率内置晶体振荡器(VLO)在上图的最上方。可作为低频时钟源。 另外一个部分是系统的外部时钟,外部晶振经过LFXT等各个寄存器设置后可以为MCLK、ACLK提供时钟源。 上图中SELM、SELS为时钟源选择寄存器。 上图中DIVA、DIVM、DIVS都是分频器,时钟源可以经过1/2/4/8分频后为CPU提供时钟,以降低功耗。 ADC10的时钟部分框图 Timer_A的结构框图 Timer_A不能选择MCLK作为Timer_A的时钟 CPU是处理器的核心部分,它使用的时钟始终是MCLK。 上电后,系统默认使用的主系统时钟MCLK和子系统时钟SMCLK是同为DCOCLK产生的1MHz时钟,而辅助时钟ACLK则为内部VLOCLK产生的12KHz时钟 MSP430低功耗模式 单片机中,功耗最低的单片机要MSP430单片机,这是做手持设备最优选择,MSP430中,用到5种低功耗,LPM0,LPM1,LPM2,LPM3,LPM4,这五种低功耗各种解释如下 : LPM0:CPU停止工作,MCLK时钟停止,SMCLK、ACLK时钟还在工作。 LPM1:CPU停止工作,MCLK时钟停止,在活动模式如果DCO没有作为MCLK和SMCLK时钟时,则直流发生器被禁止,否则就保持活动状态,SMCLK、ACLK时钟依然还在工作。 LPM2:CPU停止工作,MCLK、SMCLK时钟停止工作,如果DCO没有作为MCLK、SMCLK,自动被禁止直流发生器保持有效,ACLK还处于工作中。 LPM3:CPU停止工作,MCLK、SMCLK时钟停止工作,DCO时钟也停止工作,仅ACLK时钟还处于工作状态。 LPM4:CPU停止工作,MCLK、SMCLK时钟停止工作,DCO时钟也停止工作,ACLK也停止工作。此时功耗最低。 一般情况下,处理器进入低功耗模式后,由中断来唤醒,外部中断或内部中断。 如果想进入低功耗1,则程序可以为:_BIS_SR(LPM1_bits + GIE);退出低功耗1,则程序可以为:LPM1_EXIT; 进入其他低功耗和退出低功耗一样。 低功耗执行的一个过程:程序从main函数入口开始执行程序,当遇到进入低功耗程序时,如:_BIS_SR(LPM1_bits + GIE);此时相当于下面的程序处于停止状态不再执行,当有一个中断来到,则会进入中断处理程序,自动退出低功耗,如果在中断中没有没有退出低功耗,当中断服务程序执行完成后,又会重新进入低功耗。 完整的Word格式文档电子发烧友下载地址: |
|
相关推荐
|
|
只有小组成员才能发言,加入小组>>
NA555DR VCC最低电压需要在5V供电,为什么用3.3V供电搭了个单稳态触发器也使用正常?
694 浏览 3 评论
MSP430F249TPMR出现高温存储后失效了的情况,怎么解决?
605 浏览 1 评论
对于多级放大电路板,在PCB布局中,电源摆放的位置应该注意什么?
1065 浏览 1 评论
757 浏览 0 评论
普中科技F28335开发板每次上电复位后数码管都会显示,如何熄灭它?
529 浏览 1 评论
请问下tpa3220实际测试引脚功能和官方资料不符,哪位大佬可以帮忙解答下
171浏览 20评论
请教下关于TAS5825PEVM评估模块原理图中不太明白的地方,寻求答疑
133浏览 14评论
在使用3254进行录音的时候出现一个奇怪的现象,右声道有吱吱声,请教一下,是否是什么寄存器设置存在问题?
129浏览 13评论
TLV320芯片内部自带数字滤波功能,请问linein进来的模拟信号是否是先经过ADC的超采样?
126浏览 12评论
GD32F303RCT6配置PA4 ADC引脚,将PA2代替key功能,PA2连接时无法实现预期功能,为什么?
64浏览 10评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-29 01:03 , Processed in 0.932741 second(s), Total 76, Slave 58 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号