嵌入式系统:输入捕获/输出比较

  • Post author:
  • Post category:其他




输入捕获/输出比较

在这里插入图片描述




(一)工作原理


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 版权协议,转载请附上原文出处链接和本声明。