F407_12_基本定时器_定时实验

1> 功能框图

1


111


2> 时序图

计数36;
11


2.1> UEV时序图

11


3> 实验_寄存器版

用Timer6定时,实现间隔1s, led状态翻转1次;

/* 核心代码 */
void timer6_init(void)
{
	RCC->APB1ENR |= 1 << 4;			// Enable TIM6 Clock;
	TIM6->CNT = 0; 					// Clean Register;
	
	TIM6->PSC = 8400-1;				// CLK_INT = 84000000Hz; Prescaler value;
	TIM6->ARR = 10000-1;			// Auto Reload Register; 1s;
	
	TIM6->CR1 = 0;
	TIM6->CR1 |= 1 << 2;
	
	TIM6->DIER |= 1 << 0;				// Enable Update Interrupt;
	
	HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 2, 0);    // 借用下HAL库的^_^, 自己实现也可;
    HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
	
    TIM6->CR1 |= 1 << 0;				// Enable TIM6;           
}


void TIM6_DAC_IRQHandler(void)
{

	if(TIM6->SR & (0x1 << 0)) {
		TIM6->SR &= ~(1 << 0);	// Claean Update interrupt flag;
		bsp_led_toggle();
	}
}

84000000 / 8400Hz = 10000Hz; // 计数1s 需要数10000次个时钟

4> 实验_HAL库版

用Timer6定时,实现间隔1s, led状态翻转1次;

4.1> 初始化

void bsp_tim6_init(void);
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle);

TIM_HandleTypeDef htim6;

/* TIM6 init function */
void bsp_tim6_init(void)
{
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  htim6.Instance = TIM6;
  htim6.Init.Prescaler = 8400-1;
  htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim6.Init.Period = 10000-1;
  htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }

}

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
{

  if(tim_baseHandle->Instance==TIM6)
  {
 
    /* TIM6 clock enable */
    __HAL_RCC_TIM6_CLK_ENABLE();

    /* TIM6 interrupt Init */
    HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 2, 0);
    HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
  }
}

4.2> 启动_中断方式

HAL_TIM_Base_Start_IT(&htim6);

4.3> 中断处理

void TIM6_DAC_IRQHandler(void)
{
  
  HAL_TIM_IRQHandler(&htim6);

}


/**
  * @brief  Period elapsed callback in non-blocking mode
  * @param  htim TIM handle
  * @retval None
  */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	bsp_led_toggle();
}

5> 总结总结

1》 HAL库对寄存器,操作进行了封装,需熟悉他的套路,自己的代码,先模仿,再优化;
2》 HAL库处理中断时,把中断标志位已清除,用户只需实现回调函数功能;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,这是一个比较基础的单片机定时器实验,下面是代码实现: ```c #include <reg52.h> sbit LED1 = P1^0; sbit LED2 = P1^1; void timer0_init(){ //设置定时器0为16位自动重载模式 TMOD &= 0xF0; TMOD |= 0x01; //设置计数初值 TH0 = 0xFC; TL0 = 0x67; //使能定时器0中断 ET0 = 1; //启动定时器0 TR0 = 1; //开启总中断 EA = 1; } void timer1_init(){ //设置定时器1为16位自动重载模式 TMOD &= 0x0F; TMOD |= 0x10; //设置计数初值 TH1 = 0xF8; TL1 = 0x30; //使能定时器1中断 ET1 = 1; //启动定时器1 TR1 = 1; //开启总中断 EA = 1; } void main() { timer0_init(); timer1_init(); while(1); } //定时器0中断处理函数,控制LED1输出1s方波 void timer0_isr() interrupt 1{ LED1 = ~LED1; } //定时器1中断处理函数,控制LED2输出2s方波 void timer1_isr() interrupt 3{ LED2 = ~LED2; } ``` 我们在程序中定义了两个LED引脚,分别对应P1.0和P1.1,然后编写了两个定时器初始化函数timer0_init()和timer1_init(),分别用来初始化定时器0和定时器1。 在timer0_init()函数中,我们将定时器0设置为16位自动重载模式,并设置了计数初值,使能了定时器0中断,并启动了定时器0。在timer1_init()函数中,同样设置了定时器1的模式、计数初值和中断,然后启动了定时器1。 在主函数中,我们调用了这两个初始化函数,并进入了一个死循环,等待中断事件的发生。 最后,我们还定义了两个中断处理函数timer0_isr()和timer1_isr(),分别控制LED1和LED2的状态变化,实现了1s和2s的方波信号输出。注意,中断处理函数需要使用`interrupt`关键字来修饰。 希望这个例子能够帮助你理解如何使用定时器进行定时

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值