定时器B和定时器A有很多相同之处,学习的时候注意回忆Timer_A的相关知识。注意,MSP430F5529中只有一个定时器B。
1 定时器B的简介
写这篇文章的目的
本人记性贼差,写过的代码总是忘,每次从头看数据手册,因此借CSDN平台,帮助自己第二次甚至第三次写同一个东西的时候能够有所回忆。
打代码之前的思考
了解串口
串口通信需要三根线,RX, TX, GND
串口数据格式,一个开始位+一字节数据+一个结束位
波特率:一种用于衡量每秒钟UART传输位数的单位程序思路
发送端
假设波特率为9600,也就是每秒钟需要传输9600位的数据,那么每传输一位就需要1/9600s,因此,在发送端我们只需要在发送数据时打开定时器,定时时间为1/9600,每进一次中断把端口设置成要发送的位数据。
接收端
接收端的实现需要依靠定时器的捕获功能,当捕获到端口下降沿的同时,打开定时器,每进一次定时中断读一次端口状态。
注意
1.因为接收端在最开始判断有没有数据需要依靠下降沿,所以在发送端,空闲状态下发送端口最好设置为高电平。
2.在定义发送数据的时候不要使用unsigned char 类型,因为需要一字节数据本身加上开始位和结束位需要十位数据大小。
计时器中断控制LED灯亮灭
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // 关闭看门狗
// get_clk();
P1DIR |= 0x01; // 将P1.0设为输出
TA0CCTL0 = CCIE; // CCR0中断允许
TA0CCR0 = 50000;
TA0CTL = TASSEL_2 + MC_1 + TACLR; // 参考时钟选择SMCLK, 增计数模式, 清除TAR计数器
__bis_SR_register(LPM0_bits + GIE); // 进入LPM0并使能全局中断
}
//TA0中断服务程序
#pragma vector=TIMER0_A0_VECTOR
__interrupt void TIMER0_A0_ISR(void)
{
P1OUT ^= 0x01; // 反转P1.0端口状态
}
之前一直感觉定时器有点难,但其实后来发现更多的是中断那块没太懂,中断以后会说的。先简单看下定时器吧。
一、基本
1.在user’s guide上看到的5529其实有3种定时器,A\B\D,这三种好像确实有些区别的,但是目前就只看A感觉就够了。
2.Timer_A是具有四种操作模式的16位定时器,7个比较器/捕获器
3.能够输出PWM波,具有8中PWM波形,但是要注意的是,这种输出只能在外围功能模块里使用,即之前说过的SEL。比如P1.2能够输出Timer_A0的比较器/捕获器1的波形,而在其他管脚上,就没有办法直接输出这种PWM波形。所以如果这个管脚被占用的话,或是不想用这个来整,其实用中断做PWM波也挺好用的。
4.能实现串行通信(其实我不太懂这块说的什么意思,也好像没用到,之后见到再补上吧)
5.捕获模式和比较模式的区别?
捕获模式是捕获上升沿和下降沿触发中断,而比较器是将一个值储存到CCR寄存器里面,将计数器的值和CCR相比较从触发中断。
二、寄存器
话不多说,先看寄存器吧
1、TAxCTL
(1)TASSEL:时钟选择,可以选择TAxCLK,ACLK,SMCLK,INCLK
(2)ID:分频系数
(3)MC:模式选择
一共有四种模式,UP模式:一直加到CCR0,再到0;
Continuous莫斯:一直加到FFFF,再到0
UP/DOWN模式,加到CCR0,再减到0;
Stop模式?
(4)TACLR:清零,需要注意的是TACLR会将TAxR寄存器,分频系数都清零
(5)TAIE:中断使能
(6)TAIFG:中断标志位
2、TAxR
计数寄存器
3、TAxCCTLn
CAP:0比较模式1捕获模式
OUTMOD:
有多种输出模式,可以输出多种类型的PWM波,当然这个是从对应的管脚中输出。 这个可以user’s guide里面看。
CCIE:中断使能
COV:比较溢出?不是很懂。
CCIFG:中断标志位
其他的感觉母亲用不太到。多数会在PUC的时候设置好
4、TAxCCRn
CCR寄存器。以u模式为例,就是当计数到这个值的时候,会触发中断。CCR0优先级最高。有单独的一个中断向量。CCR1以后的都共用一个中断向量。同时在UP模式中,计数到CCR0会 从0开始。
5、TAxIV
中断源标志寄存器。可以认为CCR1和CCR6的中断标志存在这个里面,在写中断函数的时候,这几个CCR需要用TAXIV判断是哪一个中断了。
找了一个例程
#pragma vector=TIMER1_A1_VECTOR
__interrupt void TIMER1_A1_ISR(void)
{
switch(__even_in_range(TA1IV,14))
{
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: P1OUT ^= 0x01; // overflow
break;
default: break;
}
}
这一段就是判断TA1IV中的值。然后在相应的值里面做操作。如果不用这个的话是没有办法做出来中断的!
6、TAxEX0
emmm好像没有用到过
三、基本步骤
1、设置时钟
2、TAxCTL选择模式、时钟等等
3、TAxCCRn设置CCR
4、设置中断
5、中断函数emmmm……太懒了懒得找例程解释一下了。不过无非就是配置下寄存器嘛。
定时器B和定时器A有很多相同之处,学习的时候注意回忆Timer_A的相关知识。注意,MSP430F5529中只有一个定时器B。
1 定时器B的简介
7.1.1 特性(了解):(1). 16位同步定时/计数,4种工作模式可选、4中长度可选;(2). 可选可配置时钟源;(3). 高达7个捕获/比较寄存器;(4). 可配置PWM输出;(5). 带有同步装载的双缓冲比较寄存器;(6). 快速解码的中断向量;7.2.2 与定时器A的比较(相同点与不同点)(1). TB的计数长度可以选择(8、10、12、16BITS),而TA只有16位;(2). TB0CCRn寄存器是双缓冲的,且可以分组;(3). 所有的TB输出可以被设为高阻状态;(4). TB没有SCCI,即捕获器输入信号CCI没有被锁存;看结构图,观察和TA有什么区别:
7.2 Timer0_B寄存器介绍及设置)声明:所有寄存器同样支持字和字节操作所有寄存器初始化都为0x00007.2.1 TB控制寄存器TB0CTL(最常用最基本)(和TA有一点不同)rw-(0)表示默认读写均为0TBCLGGRP:TB0CLn分组控制00:每个TB0CLn独立使用01:TB0CL1+TB0CL2作为一组(TB0CCR1的CLLD位控制整组数据更新)TB0CL3+TB0CL4作为一组(TB0CCR3的CLLD位控制整组数据更新)TB0CL5+TB0CL6作为一组(TB0CCR5的CLLD位控制整组数据更新)10:TB0CL1、2、3一组,(TB0CCR1的CLLD位控制整组数据更新)TB0CL4、5、6一组,(TB0CCR4的CLLD位控制整组数据更新)11:TB0CL0、1、2、3、4、5、6整合为一组,(TB0CCR1的CLLD位控制整组数据更新)CNTL:计数器长度控制00 16位,即最大可以计到0FFFFh01 12位,即最大可以计到0FFFh10 10位,即最大可以计到03FFh11 8位,即最大可以计到0FFhTBSSEL :时钟源选择。尽量不要选TACLK外部时钟源,因为如果TACLK和CPU时钟不同步,很容易出问题。(TB0CLK接P7.7引脚)00 TBCLK01 ACLK10 SMCLK11 ~TBCLKID:第一次分频控制。ID0-1分频;ID1-2分频;ID2-4分频;ID3-8分频MC:工作模式控制。(建议在修改定时器运行模式前先停止定时器(中断使能、中断标志、TACLR例外),以避免产生未知的误操作。)(和TA一样)00 停止模式:定时器停止01 增模式: 定时器计数到TB0CCR010 连续模式,定时器计数到0FFFH(16位)…12位、10位…11增减模式:定时器加计数到TB0CCR0然后减计数到0000HTBCLR:定时器清零位。该位置位会复位TA寄存器,时钟分频和计数方向。TACLR位会自动复位并置0TBIE:定时器中断使能0:中断禁止1:中断允许TBIFG:中断标志位0:没有中断发生1:有中断挂起7.2.2 计数值存放寄存器TB0R7.2.3 扩展寄存器TBEX0很简单,这个寄存器就是为了控制时钟源的二次分频(看结构图)。该寄存器的低3为定义为TBIDEX:000-111分别表示1-8分频7.2.4 捕获/比较寄存器TBCCR0-TBCCR6(共7个)比较模式下,用来设定计数终值;捕获模式下用来将捕获的TBR值存放进TBCCRx中。7.2.5 捕获/比较控制寄存器TB0CCTL0-TB0CCTL6:CM:捕获模式设定 00 不捕获 01 上升沿捕获 10 下降沿捕获 11上升和下降沿都捕获CCIS:捕获源的选择 00 CCIxA 01 CCIxB 10 GND 11 VCCSCS:同步捕获源,设定是否与时钟同步 0 异步捕获 1 同步捕获CLLD:比较寄存器缓冲装载模式选择。00 TB0CCRn的值(改变时)立即装载到TB0CLn 01 当TB0R的值计到0时,进行装载10 增模式或者连续模式下,TBR0值计到0时,进行装载 ;增减模式下,TBR0计数到TBCL0时,开始装载;11 TBR0计数到TBCL0时,开始装载;CAP: 0-比较模式 1-捕获模式OUTMOD:输出模式控制位。同TA一模一样CCIE:中断使能,该位允许相应的CCIFG标志中断请求 。0-中断禁止 1 -中断允许CCI :捕获比较输入,所选择的输入信号可以通过该位读取OUT : 对于输出模式0,该位直接控制输出状态 。0-输出低电平 1-输出高电平COV:捕获溢出位。该位表示一个捕获溢出发出,COV必须由软件复位。 0-没有捕获溢出发生 1-有捕获溢出发生CCIFG:捕获比较中断标志位。 0-没有中断挂起 1-有中断挂起7.2.6 中断向量寄存器TB0IV同TAIV一样,里面存放一个数字编号。7.3 重点讲TB和TA的不同之处7.3.1 没有再把CCI信号锁存了TA作捕获器的时候,CCI为捕获信号,然后CCI被锁存输出 为SCCI;但是,TB没有锁存。也就是说只能从CCI位查看输入信 号了。7.3.2 计数值位数可调了(其实无所谓,都可以16位那干嘛不用)TA的计数值寄存器TAR只能是16位(0XFFFFh);TB的计数值寄存器TBR可以选择是16、12、10、8位;7.3.3 两级缓冲比较器(比较模式下)TA里面,我们在TACCRn中写入要比较的数值,然后让TAR中的计数值和TACCRn比较,如果相等了,相应的标志位就会置位;TB里面,不仅有TB0CCRn,还多了一个二级缓存器TB0CLn。TB0CLn不能被直接进行操作,它的值只能来源于TB0CCRn。计数的时候,TB0R中的计数值不和TB0CCRn比较,而是和TB0CLn进行比较。二级缓冲是为了防止我们在修改TB0CCRn的值的时候,对计数产生影响。因为计数器不直接和TB0CCRn比较,而是TB0CCRn把值赋给TB0CLn,由TB0CLn去和TB0R进行比较。所以也就有了CLLD位控制比较寄存器缓冲装载模式:(当向TB0CCRn中重新写数时)00 TB0CCRn的值立即装载到TB0CLn01 当TB0R的值计到0时,进行装载10 增模式或者连续模式下,TBR0值计到0时,进行装载 ;增减模式下,TBR0计数到TBCL0时,开始装载;11 TBR0计数到TBCL0时,开始装载;7.3.4 比较器可以被分组TA没有二级缓冲寄存器,而且本来的TACCRn也只能被单 独使用。对于TB:TBCLGGRP:TB0CLn二级缓冲寄存器分组控制00:每个TB0CLn独立使用01:TB0CL1+TB0CL2作为一组(TB0CCR1的CLLD位控制整组数据更新)TB0CL3+TB0CL4作为一组(TB0CCR3的CLLD位控制整组数据更新)TB0CL5+TB0CL6作为一组(TB0CCR5的CLLD位控制整组数据更新)10:TB0CL1、2、3一组,(TB0CCR1的CLLD位控制整组数据更新)TB0CL4、5、6一组,(TB0CCR4的CLLD位控制整组数据更新)11:TB0CL0、1、2、3、4、5、6整合为一组,(TB0CCR1的CLLD位控制整组数据更新)所谓的分组,就是该组的数据要同时更新。以10模式下的TB0CL1、2、3这组为例:TB0CCTL1中的CLLD设置为01,即TB0R计数到0时,TB0CCR1就会把值装载(更新)到TB0CL2中,同时TB0CCR2就会把值装载(更新)到TB0CL2中,同时TB0CCR3也会把值装载(更新)到TB0CL3中。无论TB0CCRn中的值有几个发生了变化,但它们都只会同时更新TB0CLn。一个重要的应用:我们知道有一种H桥电路结构,该电路有一般有两个输入端,而且这两个输入端(1和2)严禁同时输入高电平。那么该怎么产生驱动该电路的信号呢:但是,如果我们想要在系统运行的时候,修改死区时间怎么办。那只有修改比较器里面的数值了。这样就有问题了,如果两个比较器数值没有同时修改,那么就有可能产生同时为高电平的情况,这就很危险了。所以,我们把比较器分组,这样数据同时更新,就不会有这样的担心了。文章摘录于:http://blog.lehu.shu.edu.cn/879836630/A450844.html转载于:https://www.cnblogs.com/qingfengshuimu/p/4357805.html