STM32Cube 通用定时器

STM32共有三类定时器,高级,通用,基本。
在这里插入图片描述
STM32103C8 没有TIM5 6 7

一、一些概念
影子寄存器:
一个是程序员可以写入或读出的寄存器,称为preload register(预装载寄存器),另一个是程序员看不见的、但在操作中真正起作用的寄存器,称为shadow register(影子寄存器)

输入滤波机制
省略

二、时钟树
在这里插入图片描述
当APB1或APB2的时钟分频数为1的时候,定时器时钟就为PCLK1/PCLK2时钟。
分频不为1的时候,定时器时钟为PCLK1/PCLK2的2倍。
参考下面的图更清楚:
在这里插入图片描述
从上图可以看出,内部时钟HCLK(有的地方也叫CK_INT)------>经过APB1/2分频后------->再乘以一个系数(1或2)------>则得到定时器的输入时钟TIMXCLK。

三、计数器
在这里插入图片描述
计数器之前还有一个分频器,定时器输入时钟TIMXCLK----->经过一个预分频器PSC-------->计数器CNT, 当计数器计到ARR自动装载值时,清0从头开始计数。如果使能了中断,变会产生中断。

四、程序
以TIM3为例
在这里插入图片描述

  TIM_MasterConfigTypeDef sMasterConfig;
  TIM_OC_InitTypeDef sConfigOC;

  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 71;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 99;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

在这里插入图片描述

void TIM_Base_SetConfig(TIM_TypeDef *TIMx, TIM_Base_InitTypeDef *Structure)
{
  uint32_t tmpcr1 = 0U;
  tmpcr1 = TIMx->CR1;//读取CR1

  /* Set TIM Time Base Unit parameters ---------------------------------------*/
  if (IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx))
  {
    /* Select the Counter Mode */
    tmpcr1 &= ~(TIM_CR1_DIR | TIM_CR1_CMS);//清空计数方向bit4, 对齐模式bit5-6
    tmpcr1 |= Structure->CounterMode;//写入新的计数方向和对齐模式
  }

  if(IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx))
  {
    /* Set the clock division */
    tmpcr1 &= ~TIM_CR1_CKD;//写入新的频率与数字滤波分频因子bit8  bit9
    tmpcr1 |= (uint32_t)Structure->ClockDivision;
  }

  /* Set the auto-reload preload */
  tmpcr1 &= ~TIM_CR1_ARPE;//写入新的自动重载 bit7
  tmpcr1 |= (uint32_t)Structure->AutoReloadPreload;

  TIMx->CR1 = tmpcr1;

  /* Set the Autoreload value */
  TIMx->ARR = (uint32_t)Structure->Period ;//写入重载寄存器的值

  /* Set the Prescaler value */
  TIMx->PSC = (uint32_t)Structure->Prescaler;//写入预分频寄存器的值

  if (IS_TIM_REPETITION_COUNTER_INSTANCE(TIMx))
  {
    /* Set the Repetition Counter value */
    TIMx->RCR = Structure->RepetitionCounter;//如果是定时器1,写入重新计数次数
  }

  /* Generate an update event to reload the Prescaler 
     and the repetition counter(only for TIM1 and TIM8) value immediatly */
  TIMx->EGR = TIM_EGR_UG;//溢出时,重新计数并产生更新事件
}
定时器初始化流程
设置CR1的 bit4-9位
写入自动重载ARR的值
写入预分频PSC值
如果是定时器1还可以设置重复次数
设置EGR的UG位

初始化完成后,还有两步呢

1、 HAL_TIM_Base_Start_IT(&htim3);//开启中断,实际是把DIER的bit0置1,允许更新时中断
2、 HAL_TIM_Base_Start(&htim3);//开始计数,CR1的bit0置1
3、  在中断服务函数中取反一个IO 
 void TIM3_IRQHandler(void)
{
  HAL_GPIO_TogglePin(LED3_GPIO_Port,LED3_Pin);
  HAL_TIM_IRQHandler(&htim3);
}

测试得最后的输出频率是 18M输入频率/(71+1分频率)=250K,计数到100,则定时器中断为2.5K,每次中断取反,中断两次1个周期,所以最后LED3脚输出频率为1.25K

STM32Cube生成软件时别忘记开总中断 HAL_NVIC_EnableIRQ(TIM3_IRQn);

问题:
这两天遇到定时器仿真的时候可以,下载到板子就不行。一时找不到原因,后来仔细检查发现是 没有自动重载, 复制程序的时候没看清楚
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值