输入捕获/输出比较
(一)工作原理
1.输入捕获
:捕获外部输入信号波形
- 信号周期
- 高低电平持续时间
(1)捕获类型
- 上升沿捕获
- 下降沿捕获
(2)
测量原理
:以基本定时器计数周期为基本单位,测量信号持续时间(计数值的整数倍)
- 上升沿/下降沿 — 上升沿/下降沿:信号周期
- 上升沿 — 下降沿:高电平持续时间
- 下降沿 — 上升沿:低电平持续时间
2.输出比较
:输出不同类型的波形
(1)
输出原理
:以基本定时器计数周期为基本单位,输出不同时间的高低电平
(2)
输出类型
-
上计数模式下
-
连续计数模式下
-
上下计数模式下
(3)
PWM:脉宽调制波形
(可调占空比波形)
- 占空比:高电平与总周期的比值
-
输出比较波形的一种特例
(二)编程
1.编程流程
(1)输入捕获
- 引脚复用为输入捕获模式
-
功能配置
- 基本定时器配置
- 输入捕获模式
- 捕获类型
- 输入捕获使能
-
中断配置(输入捕获中断\定时器溢出中断)
- 中断源
- 中断优先级
- 中断使能
- 中断处理函数
(2)输出比较
- 引脚复用为输出比较模式
-
功能配置
- 基本定时器配置
- 输出比较模式
- 输出比较类型
- 输出比较值
- 输出比较起始电平
- 输出比较使能
-
中断配置(定时器溢出中断\输出比较值中断)
- 中断源
- 中断优先级
- 中断使能
- 中断处理函数
2.编程实例
(1)输入捕获
- 寄存器版本
#include "msp.h"
#include "driverlib.h"
void main()
{
//关闭看门狗
WDTCTL = WDTPW | WDTHOLD;
//GPIO复用为HFXT
PJ->SEL1 &=~(BIT2 | BIT3);
PJ->SEL0 |= (BIT2 | BIT3);
//解锁时钟寄存器(0x695A)
CS->KEY = CS_KEY;
//HCLK 16MHz
CS->CTL2 |= CS_CTL2_HFXTFREQ_2 | CS_CTL2_HFXTDRIVE | CS_CTL2_HFXT_EN;
//SMCLK 4MHz
CS->CTL1 |= CS_CTL1_DIVS_2 | CS_CTL1_SELS_5;
//SMCLK 时钟源使能
CS->CLKEN |= CS_CLKEN_SMCLK_EN;
//锁住时钟寄存器(0xA569)
CS->KEY = CS_KEY_KEY_OFS;
//GPIO复用为输入捕获模式
P2->SEL0 |= BIT4;
P2->SEL1 &=~BIT4;
//时钟选择(1MHz)
TIMER_A0->CTL |= TIMER_A_CTL_SSEL__SMCLK | TIMER_A_CTL_ID__4;
//计数值1ms
TIMER_A0->R = 999;
//上升计数模式,计数值清零
TIMER_A0->CTL |= TIMER_A_CTL_MC__UP | TIMER_A_CTL_CLR;
//输入捕获模式功能配置(时钟同步,外部引脚捕获源,上升沿捕获)
TIMER_A0->CCTL[1] |= TIMER_A_CCTLN_CAP | TIMER_A_CCTLN_SCS | TIMER_A_CCTLN_CCIS__CCIA | TIMER_A_CCTLN_CM__RISING;
//输入捕获模式中断标志位清零
TIMER_A0->CCTL[1] &=~TIMER_A_CCTLN_CCIFG;
//输入捕获模式中断使能
TIMER_A0->CCTL[1] |= TIMER_A_CCTLN_CCIE;
//清除中断标志位
TIMER_A0->CTL &= ~TIMER_A_CTL_IFG;
//Timer中断使能
TIMER_A0->CTL |= TIMER_A_CTL_IE;
while(1);
}
uint8_t timecount = 0;
void TA0_N_IRQHandler(void)
{
//时钟中断溢出
if(TIMER_A_CTL_IFG & TIMER_A0->CTL)
{
//中断标志位清零
TIMER_A0->CTL &= ~TIMER_A_CTL_IFG;
timecount++;
}
//输入捕获中断
if(TIMER_A_CCTLN_CCIFG & TIMER_A0->CCTL[0])
{
//中断标志位清零
TIMER_A0->CCTL[0] &=~TIMER_A_CCTLN_CCIFG;
uint32_t time = (timecount*(TIMER_A0->R + 1) + TIMER_A0->CCR[0])/1000000;
}
}
- 库函数版本
#include "msp.h"
#include "driverlib.h"
void main()
{
/* Stop watchdog timer */
MAP_WDT_A_holdTimer();
//GPIO复用为HFXT
GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ,GPIO_PIN3 | GPIO_PIN2, GPIO_PRIMARY_MODULE_FUNCTION);
//HCLK 16MHz
CS_setExternalClockSourceFrequency(32000,16000000);
CS_startHFXT(false);
//SMCLK 4MHz
CS_initClockSignal(CS_SMCLK,CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_4);
CS_enableClockRequest(CS_SMCLK);
//GPIO复用为输入捕获
GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P2, GPIO_PIN4,GPIO_PRIMARY_MODULE_FUNCTION);
//时基配置
Timer_A_UpModeConfig upModeConfig;
upModeConfig.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;
upModeConfig.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_4;
upModeConfig.timerPeriod = 999;
upModeConfig.timerClear = TIMER_A_DO_CLEAR;
upModeConfig.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_ENABLE;
Timer_A_configureUpMode(TIMER_A0_BASE, &upModeConfig);
//捕获模式配置
Timer_A_CaptureModeConfig captureModeConfig;
captureModeConfig.captureRegister = TIMER_A_CAPTURECOMPARE_REGISTER_1;
captureModeConfig.captureMode = TIMER_A_CAPTUREMODE_RISING_EDGE;
captureModeConfig.synchronizeCaptureSource = TIMER_A_CAPTURE_SYNCHRONOUS;
captureModeConfig.captureInputSelect = TIMER_A_CAPTURE_INPUTSELECT_CCIxB;
captureModeConfig.captureInterruptEnable = TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE;
Timer_A_initCapture(TIMER_A0_BASE, &captureModeConfig);
//开始计数
Timer_A_startCounter(TIMER_A0_BASE, TIMER_A_UP_MODE);
while(1);
return 0;
}
uint8_t timecount = 0;
void TA0_N_IRQHandler(void)
{
//时钟中断溢出
if(Timer_A_getInterruptStatus(TIMER_A0_BASE))
{
Timer_A_clearInterruptFlag(TIMER_A0_BASE);
timecount++;
}
//捕获中断
if(Timer_A_getCaptureCompareInterruptStatus(TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_1,TIMER_A_CAPTURECOMPARE_INTERRUPT_FLAG))
{
Timer_A_clearCaptureCompareInterrupt(TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_1);
uint32_t time = (timecount*Timer_A_getCounterValue(TIMER_A0_BASE) + Timer_A_getCaptureCompareCount(TIMER_A0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_1))/1000000;
}
}
(2)PWM
- 寄存器版本
#include "msp.h"
#include "driverlib.h"
void main()
{
WDTCTL = WDTPW + WDTHOLD; //关闭看门狗
//GPIO复用为HFXT
PJ->SEL1 &=~(BIT2 | BIT3);
PJ->SEL0 |= (BIT2 | BIT3);
//解锁时钟寄存器(0x695A)
CS->KEY = CS_KEY;
//HCLK 16MHz
CS->CTL2 |= CS_CTL2_HFXTFREQ_2 | CS_CTL2_HFXTDRIVE | CS_CTL2_HFXT_EN;
//SMCLK 4MHz
CS->CTL1 |= CS_CTL1_DIVS_2 | CS_CTL1_SELS_5;
//SMCLK 时钟源使能
CS->CLKEN |= CS_CLKEN_SMCLK_EN;
//锁住时钟寄存器(0xA569)
CS->KEY = CS_KEY_KEY_OFS;
//GPIO复用为PWM
P2->SEL0 |= BIT4;
P2->SEL1 &=~BIT4;
//时基配置
TIMER_A0->CTL |= TIMER_A_CTL_SSEL__SMCLK | TIMER_A_CTL_ID__8;
TIMER_A0->CTL |= TIMER_A_CTL_MC__UP | TIMER_A_CTL_CLR;
TIMER_A0->R = 49999;
//PWM配置(比较模式,翻转输出,起始输出低电平)
TIMER_A0->CCTL[0] |= TIMER_A_CCTLN_OUTMOD_4;
//占空比(50%)(24999 + 1)/(49999 + 1)
TIMER_A0->CCR[0] = 24999;
while(1);
}
- 库函数版本
#include "msp.h"
#include "driverlib.h"
void main()
{
/* Halting the watchdog */
MAP_WDT_A_holdTimer();
//GPIO复用为HFXT
GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ,GPIO_PIN3 | GPIO_PIN2, GPIO_PRIMARY_MODULE_FUNCTION);
//HCLK 16MHz
CS_setExternalClockSourceFrequency(32000,16000000);
CS_startHFXT(false);
//SMCLK 4MHz
CS_initClockSignal(CS_SMCLK,CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_4);
CS_enableClockRequest(CS_SMCLK);
//GPIO复用为PWM
MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, GPIO_PIN4,GPIO_PRIMARY_MODULE_FUNCTION);
//PWM功能配置
Timer_A_PWMConfig pwmConfig;
pwmConfig.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;
pwmConfig.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_4;
pwmConfig.compareOutputMode = TIMER_A_OUTPUTMODE_TOGGLE;
pwmConfig.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_0;
pwmConfig.timerPeriod = 49999;
pwmConfig.dutyCycle = 24999;
//PWM波生成
Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);
while(1);
}
版权声明:本文为weixin_45366970原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。