嵌入式系统:基本定时器

定时器

在这里插入图片描述


(一)工作原理

1.定时器:计数器,时钟脉冲计数

2.工作原理

(1)自动计数模式:在时钟条件下,系统自动计数到最大值溢出,代表一次定时完成

  • 时钟计数最大值由定时器的位数决定 2 n 2^n 2n

(2)调制计数模式:用户自定义定时时间,系统计时到自定义时间,代表一次定时完成

	由上可知,在调制计数模式上更有灵活性。

向上计数:向上计数到设定值后重新计数,周期循环

在这里插入图片描述

在这里插入图片描述


连续计数:向上计数到最大值后重新计数,周期循环

在这里插入图片描述
在这里插入图片描述


上/下计数:向上计数到设定值后,又从设定值向下计数
在这里插入图片描述
在这里插入图片描述


(二)分类

1.核内定时器

(1)SysTick定时器:系统时钟滴答定时器(定时作用)

  • 可用作操作系统任务调度时间片

(2)RTC:实时时钟

(3)WatchDog:看门狗时钟,用于异常复位


2.外设定时器

(1)基本定时器:定时作用,用作其他定时器功能的时基

(2)通用定时器

  • 输入捕获
  • 输出比较
  • PWM(输出比较模式中的一种特例)

(3)高级定时器

  • 通用定时器
  • 带死区控制的PWM
  • 三路移相波形(三相电机控制)

(三)编程

1.编程流程

(1)时钟配置

  • 时钟源
  • 分频系数

(2)功能配置

  • 计数模式
  • 重装载值
  • 计数值清零

(3)定时器使能

(4)中断配置

  • 中断源
  • 中断优先级
  • 中断使能

(5)中断处理函数


2.编程实例

(1)寄存器版本

#include "msp.h"
#include "driverlib.h"

int 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;
	
	//时钟选择(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->CTL &= ~TIMER_A_CTL_IFG;
	//Timer中断使能
	TIMER_A0->CTL |= TIMER_A_CTL_IE;
	
	
	P1->SEL0 &=~BIT0;
	P1->SEL1 &=~BIT0;
	
	P1->DIR |= BIT0;
	P1->OUT |= BIT0;

	while(1);

	return 0;
}

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(timecount == 10)
		{
			P1->OUT ^= BIT0;
		}
	}
}

(2)库函数版本

#include "msp.h"
#include "driverlib.h"

int main()
{
	//关闭看门狗
	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);
	
	//定时器功能配置
	Timer_A_UpModeConfig Timer_A_UpMode;
	
	Timer_A_UpMode.clockSource 								= TIMER_A_CLOCKSOURCE_SMCLK;
	Timer_A_UpMode.clockSourceDivider						= TIMER_A_CLOCKSOURCE_DIVIDER_4;
	Timer_A_UpMode.timerPeriod								= 999;
	Timer_A_UpMode.timerClear								= TIMER_A_DO_CLEAR;
	Timer_A_UpMode.timerInterruptEnable_TAIE				= TIMER_A_TAIE_INTERRUPT_DISABLE;
	Timer_A_UpMode.captureCompareInterruptEnable_CCR0_CCIE	= TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE;
	
	//定时器功能配置
	Timer_A_configureUpMode(TIMER_A0_BASE,&Timer_A_UpMode);
	//清除中断标志位
	Timer_A_clearInterruptFlag(TIMER_A0_BASE);
	//使能中断
	Timer_A_enableInterrupt(TIMER_A0_BASE);
	//使能定时器计数
	Timer_A_startCounter(TIMER_A0_BASE, TIMER_A_UP_MODE);

	while(1);

	return 0;
}


uint8_t timecount = 0;
void TA0_N_IRQHandler(void)
{
	uint32_t status = Timer_A_getInterruptStatus(TIMER_A0_BASE);
	//判断中断是否发生
	if(TIMER_A_CTL_IFG & status)
	{
		//中断标志位清零
		Timer_A_clearInterruptFlag(TIMER_A0_BASE);
		timecount++;
		if(timecount == 10)
		{
			GPIO_toggleOutputOnPin(GPIO_PORT_P1,GPIO_PIN0);
		}
	}
}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值