STM32F407VET6底层驱动之定时器寄存器封装

更新时间:2023-07-04 10:15:19 阅读: 评论:0

STM32F407VET6底层驱动之定时器寄存器封装
  因为在项⽬中引⼊了操作系统,所以使⽤定时器的地⽅不多,因此这⾥只⽤了三个定时器,每个定时器可以注册⼗个任务。
1、定时器封装接⼝如下:
  a、定时器初始化:unsigned int tim_init(eTimType_t tim, unsigned short interval, unsigned char prio)
  b、定时器禁能:unsigned int tim_stop(eTimType_t tim)
  c、定时器重新开始计时:unsigned int tim_restart(eTimType_t tim)
  d、定时器任务注册:unsigned int tim_task_append(void (*pfunc)(void *), const void *parg, unsigned int interval, eTimType_t tim)
programme  e、定时器任务删除:unsigned int tim_task_delete(void (*pfunc)(void *), eTimType_t tim)
  f、定时器任务禁能:unsigned int tim_task_stop(void (*pfunc)(void *), eTimType_t tim)
  g、定时器任务使能:unsigned int tim_task_start(void (*pfunc)(void *), eTimType_t tim)
2、定时器模块对外开放的枚举类型如下:
// 定时器类型
typedef enum _eTimType
{
  eTIM2,
  eTIM3,
  eTIM4,
  eTIM_COUNT, // 注:这不是定时器类型,不可删除,仅⽤做数量统计
}eTimType_t;
#define TIM_TASK_COUNT ((unsigned char)10) // 每个定时器⽀持的任务个数
3、定时器模块代码实现如下:
短期培训学校/
/ 定时器任务数据结构
#pragma pack(push, 1)
typedef struct _sTimTaskList
{
  bool enable; // 任务使能标志位
  unsigned int task_count; // 定时任务计数器
jav008  unsigned int tim_interval; // 定时中断时间间隔,单位:微秒
  unsigned int task_interval; // 定时任务执⾏时间间隔,单位:毫秒
  void (*pCallBack)(void *); // 定时器回调函数指针
  void *parg; // 定时器回调函数形参
}sTimTaskList_t;
#pragma pack(pop)
// 定时器任务链表(STM32F407最多⽀持8个定时器)
static sTimTaskList_t sTimTaskList[eTIM_COUNT][TIM_TASK_COUNT] = {0};
小学生校园安全知识/********************************************************
* 函数功能:定时器中断优先级设置(组4),注意优先级不能超过设
定的组的范围否则会有意想不到的错误。组划分如下:
组0:0位抢占优先级,4位响应优先级
组1:1位抢占优先级,3位响应优先级
组2:2位抢占优先级,2位响应优先级
组3:3位抢占优先级,1位响应优先级
组4:4位抢占优先级,0位响应优先级
critical是什么意思
抢占优先级和响应优先级的数值越⼩,优先级越⾼,处理器优
先⽐较抢占优先级然后再看响应优先级。
* 形参:prio:抢占优先级(分组4的响应优先级固定为0)
channel:中断通道
* 返回值:⽆
********************************************************/
static void tim_nvic_t(unsigned char prio, unsigned char channel)
{
// unsigned int temp, temp1;
  // 设置分组
  unsigned char nvic_group = 4; // 0 - 4
/
/ temp1 = (~nvic_group) & 0x07; // 取后三位
// temp1 = temp1 << 8;
// temp = SCB->AIRCR;  // 读取先前的设置
// temp &= 0x0000F8FF; // 清空先前分组
// temp |= 0x05FA0000; // 写⼊钥匙
// temp |= temp1;
// SCB->AIRCR = temp; // 设置分组
  // 设置NVIC
  unsigned int temp;
  unsigned char sub_prio = 0; // 分组4的响应优先级固定为0
  // 注:优先级的设置必须要⼤于configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY
  // 否则不能在中断服务函数中调⽤FreeRTOS相关的API函数
  if(prio <= 5)
  {
      prio = 6;
  }
  el if(prio > 15)
  {
    prio = 15;
  }
  temp = prio << (4 - nvic_group);
  temp |= sub_prio & (0x0F >> nvic_group);
  temp = temp & 0xF; // 取低四位
  NVIC->ISER[channel >> 5] |= 1 << (channel % 32); // 使能中断位(要清除的话,设置ICER对应位为1即可)  NVIC->IP[channel] |= temp << 4; // 设置响应优先级和抢断优先级
}
/********************************************************
* 函数功能:定时器初始化(初始化完成后定时器⾃动启动,重复初始化会将该定时器下的所有任务清空)
* 形参:tim:指定定时器(定时器时钟频率1MHz,递增计数模式)
interval:定时器中断时间间隔,单位:微秒
prio:中断优先级(范围:6 - 15,数值越⼩优先级越⾼)
* 返回值:0=成功
1=定时器类型错误
2=定时周期错误
********************************************************/
unsigned int tim_init(eTimType_t tim, unsigned short interval, unsigned char prio)
{
  if(tim >= eTIM_COUNT)
  {
    return 1;
  }
  if(interval == 0)
  {
    return 2;
  }
  // 清空该定时器下的所有任务
  for(unsigned char i = 0; i < TIM_TASK_COUNT; i++)
  {
    sTimTaskList[tim][i].parg = NULL;
    sTimTaskList[tim][i].enable = fal;
    sTimTaskList[tim][i].task_count = 0;
    sTimTaskList[tim][i].pCallBack = NULL;
    sTimTaskList[tim][i].task_interval = 0;
    sTimTaskList[tim][i].tim_interval = interval;
  }
  unsigned char bit = 0;
  unsigned char IRQn = 0;
  TIM_TypeDef *TIMx = NULL;
  switch(tim)
  {
    ca eTIM2: TIMx = TIM2; IRQn = TIM2_IRQn; bit = 0; break;
    ca eTIM3: TIMx = TIM3; IRQn = TIM3_IRQn; bit = 1; break;
    ca eTIM4: TIMx = TIM4; IRQn = TIM4_IRQn; bit = 2; break;
    default: return 1;
  }
jnu  // ⾼级定时器timer1, timer8以及通⽤定时器timer9, timer10, timer11的时钟来源是APB2总线
  // 通⽤定时器timer2~timer5,通⽤定时器timer12~timer14以及基本定时器timer6,timer7的时钟来源是APB1总线  RCC->APB1ENR |= 0x1 << bit; // 定时器时钟使能
  TIMx->CNT = 0;  // 计数器清零
  TIMx->ARR = interval; // 设定计数器⾃动重装值
  TIMx->PSC = 84 - 1;  // 预分频器(时钟频率1MHz)
  TIMx->DIER |= 0x01;  // 使能更新中断(计数器更新)
  TIMx->CR1 |= 0x01;  // 使能计数器(递增模式)
  tim_nvic_t(prio, IRQn); // 抢占优先级10,响应优先级0,优先级分组4
  return 0;
}
/********************************************************
* 函数功能:定时器停⽌计数
* 形参:tim:指定定时器
* 返回值:0=成功
1=定时器类型错误
********************************************************/
unsigned int tim_stop(eTimType_t tim)
{
  if(tim >= eTIM_COUNT)
  {
      return 1;
  }
  TIM_TypeDef *TIMx = NULL;
  switch(tim)
  {
    ca eTIM2: TIMx = TIM2; break;
      ca eTIM3: TIMx = TIM3; break;
    ca eTIM4: TIMx = TIM4; break;
    default: return 1;
  }
  TIMx->CNT = 0;  // 计数器清零
  TIMx->DIER &= ~0x01; // 禁能更新中断(计数器更新)
  TIMx->CR1 &= ~0x01;  // 禁能计数器(递增模式)
  return 0;
}
/********************************************************
* 函数功能:定时器重新开始计数
* 形参:tim:指定定时器
* 返回值:0=成功
1=定时器类型错误
********************************************************/
unsigned int tim_restart(eTimType_t tim)
{
come back  if(tim >= eTIM_COUNT)
  {
    return 1;
  }
  TIM_TypeDef *TIMx = NULL;
  switch(tim)
  {
    ca eTIM2: TIMx = TIM2; break;伤感英文歌
    ca eTIM3: TIMx = TIM3; break;
    ca eTIM4: TIMx = TIM4; break;
    default: return 1;
  }
  TIMx->CNT = 0;  // 计数器清零
  TIMx->DIER |= 0x01; // 使能更新中断(计数器更新)
  TIMx->CR1 |= 0x01; // 使能计数器(递增模式)
  return 0;
}
/********************************************************
* 函数功能:定时器任务追加(任务⽴即进⼊运⾏状态)
* 形参:pfunc:任务函数指针
parg:任务函数形参
interval:任务执⾏时间间隔,单位:微秒
tim:指定定时器
* 返回值:0=成功
1=任务链表满了,⽆法再追加任务
2=任务函数指针为NULL
3=定时器类型错误
4=任务执⾏时间间隔错误
* 开发者:王志超
* 维护⽇期:2020年5⽉5⽇
* 修订⽇志:开发
********************************************************/
unsigned int tim_task_append(void (*pfunc)(void *), const void *parg, unsigned int interval, eTimType_t tim) {
  if(pfunc == NULL)
  {
    return 2;
  }
  if(tim >= eTIM_COUNT)
  {
    return 3;
  }
  if(interval == 0)
  {
    return 4;
  }
  for(unsigned char i = 0; i < TIM_TASK_COUNT; i++)
  {
    if(sTimTaskList[tim][i].enable == fal)
    {
      sTimTaskList[tim][i].task_count = 0;
      sTimTaskList[tim][i].task_interval = interval; // 单位:微秒
hermes怎么读      sTimTaskList[tim][i].parg = (void *)parg;
      sTimTaskList[tim][i].pCallBack = pfunc;
      sTimTaskList[tim][i].enable = true;
      return 0; // 任务添加成功
    }
  }
  return 1; // 任务链表满了,⽆法再追加任务
}
/********************************************************
* 函数功能:定时器任务删除
* 形参:pfunc:任务函数指针
tim:指定定时器
* 返回值:0=成功
1=未找到与之匹配的任务
2=任务函数指针为NULL
3=定时器类型错误
********************************************************/
unsigned int tim_task_delete(void (*pfunc)(void *), eTimType_t tim)
{
  if(pfunc == NULL)
  {
    return 2;
  }
  if(tim >= eTIM_COUNT)
  {
    return 3;
  }
  for(unsigned char i = 0; i < TIM_TASK_COUNT; i++)
  {
    if(sTimTaskList[tim][i].pCallBack == pfunc)
    {
no problem      sTimTaskList[tim][i].enable = fal;
      sTimTaskList[tim][i].parg = NULL;
      sTimTaskList[tim][i].task_count = 0;
      sTimTaskList[tim][i].tim_interval = 0;
      sTimTaskList[tim][i].task_interval = 0;
      sTimTaskList[tim][i].pCallBack = NULL;
      return 0;
    }
  }
  return 1; // 未找到与之匹配的任务
}
/********************************************************
* 函数功能:定时器任务停⽌运⾏
* 形参:pfunc:任务函数指针
tim:指定定时器
* 返回值:0=成功
1=未找到与之匹配的任务
2=任务函数指针为NULL
3=定时器类型错误
********************************************************/
unsigned int tim_task_stop(void (*pfunc)(void *), eTimType_t tim) {
  if(pfunc == NULL)
  {
    return 2;
  }
  if(tim >= eTIM_COUNT)
  {
    return 3;
  }
  for(unsigned char i = 0; i < TIM_TASK_COUNT; i++)
  {
    if(sTimTaskList[tim][i].pCallBack == pfunc)
    {
      sTimTaskList[tim][i].enable = fal;
      return 0; // 任务停⽌成功
    }
  }
  return 1; // 未找到与之匹配的任务
}
/********************************************************
* 函数功能:定时器任务启动运⾏(从上次的停⽌时的状态继续运⾏) * 形参:pfunc:任务函数指针
tim:指定定时器
* 返回值:0=成功
1=未找到与之匹配的任务
2=任务函数指针为NULL
3=定时器类型错误
********************************************************/
unsigned int tim_task_start(void (*pfunc)(void *), eTimType_t tim) {
  if(pfunc == NULL)
  {
    return 2;
  }
  if(tim >= eTIM_COUNT)
  {
    return 3;
  }
  for(unsigned char i = 0; i < TIM_TASK_COUNT; i++)
  {
    if(sTimTaskList[tim][i].pCallBack == pfunc)
    {
      sTimTaskList[tim][i].enable = true;
      return 0; // 任务启动成功
    }
  }

本文发布于:2023-07-04 10:15:19,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/90/166674.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:任务   中断   函数   计数器   功能   设置
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图