MSP430F6638单片机定时器Timer_A
[复制链接]
各种寄存器(x代表数字,比如我们用的TA1,那么x=1)
1 TAxR——16位计数器
16位定时器/计数器寄存器TAxR随时钟信号的每个上升沿递增或递减(取决于工作模式)。 可以使用软件读取或写入TAxR。 另外,定时器在溢出时可以产生中断。
可以通过将TAxCTL寄存器中的TACLR位置1来清零TAxR。 将该位置1会复位TAxR,定时器时钟分频器逻辑和计数方向。 TACLR位自动复位,始终读为0。
2 TAxCTL——时钟控制
TASSEL——选择时钟
MC——设置计数模式
MC Mode 中文 Description
00 Stop 停止计数 定时器停止
01 Up 增计数 定时器重复从零计数到TAxCCR0的值
10 Continuous 连续计数 定时器重复从零到0FFFFh。
11 Up/down 增减计数 定时器重复从零开始计数到TAxCCR0的值并返回到零。
TACLR——清空TAxR
TAIE——中断使能
3 TAxCCTLn——Timer_Ax捕捉/比较控制寄存器n
捕获比较模块一共7个,n=(0~6)
CAP——设置捕获模式/比较模式
OUTMOD——设置输出方式(共8种)
第一种是电平输出,可以指定输入的电平(OUT位)
模式 2, 3, 6, and 7 对于 TAxCCR0 是没有用的因为 EQUx = EQU0.
CCIE——中断使能
【注意】:这个是捕获比较的中断使能,和上面的Timer_A的中断不同。
4 TAxCCRn——捕捉/比较寄存器n
放数的
5 TAxIV——中断寄存器
用于查询是哪个中断到来
其中包含的中断事件不包括TAxCCR0中断
中断
1TAxCCR0中断
TAxCCR0 CCIFG具有最高的Timer_A中断优先级,并具有专用中断向量(TIMER0_A0_VECTOR)。 当TAxCCR0中断请求被服务时,TAxCCR0 CCIFG自动复位。
这是一个单源中断
2 TAxIV中断
TAxCCRy CCIFG和TAIFG被优先化并组合以获得单个中断向量。(这表明其优先级可以被软件设置,这和所谓中断优先级是两个概念) 这话大错特错!!优先级不能设置,写错了!
TAxIV用于确定请求中断的标志。
禁用Timer_A中断不会影响TAxIV值。
TAxIV寄存器的任何访问,读取或写入都会自动重置最高的待处理中断标志。 如果设置了另一个中断标志,则在服务初始中断后立即产生另一个中断。(如果你们做过实验会发现后边的串口通信也有这个性质)
这是一个多源中断,但是不用手动清中断标志位
程序
1 TA0CCR0 中断
下面程序采用增计数模式,那么增加到TA0CCR0 就会产生TA0CCR0 中断,然后计数器自动清零,重新计数
【注意】:这是一个单源中断
#include<msp430f6638.h>
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
}
2 TAxIV中断
下面程序,由于是连续计数模式,计数器会从0到FFFF重复计数,但是又未设置TA0CCRn的值,所以只在0FFFFh的时候才产生TAIFG这个中断,这个中断的查询在TAxIV=14的位置
【注意】:这是多源中断
#include<msp430f6638.h>
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;
}
}
|