最新CUBEMX的HAL库的低功耗模式CAN唤醒实验(STM32F412)

15人阅读 评论(0) 收藏 举报
分类:
最近利用HAL库的F4低功耗模式(STOP),利用CAN总线来唤醒F4MCU       先吐槽HAL库的坑还是有点多,在清除中断的顺序方面还是做的不够好。
    大体思路:利用CAN总线RX引脚 触发外部中断来激活MCU。

     由于CAN唤醒实验用到了基本定时器TIM7,做个100ms的中断检测CAN总线是否有信号。
   这里涉及到了一个先进中断后进中断的问题:
HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim)
{
  /* Check the parameters */
  assert_param(IS_TIM_INSTANCE(htim->Instance));

  /* Enable the TIM Update interrupt */
  __HAL_TIM_ENABLE_IT(htim, TIM_IT_UPDATE);

  /* Enable the Peripheral */
  __HAL_TIM_ENABLE(htim);

  /* Return function status */
  return HAL_OK;
}

函数中的 使能TIM 更新中断和使能外设函数的顺序决定了是先中断一次还是先计数
HAL库中的是先进入一次中断。

配置CAN的函数这里就不说了,见上一个帖子

方向是:如果CAN总线没有信号进来,则认为总线空闲,进入低功耗。
初始化先初始化CAN TIM7 开启更新中断直接进入一次中断,在中断中会检测CAN的FIFO的邮箱中是否有报文,
如果有报文则说明CAN总线处于ongoing状态,否则则进入低功耗模式,这里我们直接在TIM7的CALLBACK中进入低功耗模式。
进入低功耗函数如下:
void STOP_MODE_ENTER(void)
{
     printf("\r\nSTOP模式");
     HAL_TIM_Base_Stop_IT(&htim7);//关闭TIM7定时器
     HAL_CAN_DeInit(&hcan1);//失能 CAN1
     HAL_CAN_DeInit(&hcan2);//失能CAN2

    __HAL_RCC_GPIOH_CLK_DISABLE();//失能GPIO时钟
    __HAL_RCC_GPIOB_CLK_DISABLE();
    __HAL_RCC_GPIOC_CLK_DISABLE();
    __HAL_RCC_GPIOA_CLK_DISABLE();

    GPIO_InitTypeDef GPIO_InitStruct1;        
    GPIO_InitStruct1.Pin  = GPIO_PIN_12;
    GPIO_InitStruct1.Mode = GPIO_MODE_IT_RISING;
    GPIO_InitStruct1.Pull = GPIO_PULLDOWN;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct1);

    HAL_NVIC_SetPriority(EXTI15_10_IRQn,3,0);
    HAL_NVIC_EnableIRQ(EXTI15_10_IRQn); 
   __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_12);

    HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON,PWR_STOPENTRY_WFI);

    SystemClock_Config();
    MX_GPIO_Init();
    HAL_GPIO_DeInit(GPIOB,GPIO_PIN_12);
    HAL_NVIC_DisableIRQ(EXTI15_10_IRQn);
    MX_CAN1_Init();
    MX_CAN2_Init();
    printf("\r\nCAN2 ERROR IS %d",HAL_CAN_GetError(&hcan2));
    printf("\r\nCAN1 ERROR IS %d",HAL_CAN_GetError(&hcan1));
    printf("\r\n启动CAN总线");
     __HAL_TIM_ENABLE(&htim7);
     __HAL_TIM_ENABLE_IT(&htim7, TIM_IT_UPDATE);

}


函数中在进入低功耗模式之前先关闭GPIO的时钟,如果追求极限低功耗可以把所有的外设都失能,GPIO全部反初始化。
在开启外部中断时一定要先清理一次中断标志位,这个是为了意外没有清除EXTI的PR 导致程序进不去停止模式,手册上有详细说明。
必须先清除外部中断标志位和RTC的闹钟标志位否则程序将跳过停止模式。
关键的函数:
void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
Regulator选择PWR_LOWPOWERREGULATOR_ON  :让电压调节器处于低功耗模式
和STOPEntry:PWR_STOPENTRY_WFI  : 外部中断触发
再选择外部晶振
之后开启CAN 以及其他外设 最后开启定时器。
这里我们选择先计数再进入更新中断的选择是因为在第一个上升沿到来时,这一帧CAN数据要舍弃,在下一帧数据进行读取。

在外部中断到来时,切记要在中断回调函数中失能外部中断,因为CAN总线上的信号是一段高低电平,否则会一直触发中断。
   HAL_GPIO_DeInit(GPIOB,GPIO_PIN_12);//失能GPIO12 
   HAL_NVIC_DisableIRQ(EXTI15_10_IRQn);失能15-10中断线

下面来看一下定时器中断函数的回调函数:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{

  if(htim==&htim7)
  {
       printf("\r\ntim7 IS  %d",((&hcan2)->Instance->RF1R & 0x03) );
       if (((&hcan2)->Instance->RF1R & 0x03) == RESET)//如果邮箱没有报文
    {  
        STOP_MODE_ENTER();
    }     
  }

}

简单的判断邮箱值是否为零,这里需要注意的是我选择的波特率是500kps 取样为90%
如果数据的传输速率不够快的化这个邮箱值会一直为零,因为在CAN中断函数中已经处理了。处理完毕之后会清零,就不会进入停止模式。

如果有问题 欢迎滴滴我,通过此次的低功耗,通过操作寄存器的方式比HAL库更便捷,但是HAL库降低了门槛,更快速上手。
查看评论

cubemx_tim_base源码分析

stm32的定时器分为三种:基本,通用,高级。功能肯定是越来越强的。今天我们讲的是最简单的基本定时器。 基本定时器的作用就是定时一定的时间,当然在更新事件来的时候可以产生中断和DMA请求,还可以触发...
  • king_qg
  • king_qg
  • 2017-02-02 13:31:38
  • 557

stm32CubeMX HAL库中延时的几种方式解析

stm32CubeMX HAL库中延时的几种方式解析 HAL_Dalay()是毫秒级延时,为了使用微秒级延时最近学习了一下,总结如下,推荐使用最后一种方式。 /* * 本文件包括...
  • hxkrrzq
  • hxkrrzq
  • 2016-10-13 17:11:49
  • 12643

M0内核TIME3和TIME7的应用

TIME3的应用:用TIME产生PWM波   TIME3的初始化         void MX_TIM3_Init(void) {   TIM_ClockConfigTypeDef s...
  • baiyibin0530
  • baiyibin0530
  • 2016-10-27 13:47:34
  • 656

用time3产生PWM,用time7做定时器

1、time3产生PWM void MX_TIM3_Init(void) {   TIM_ClockConfigTypeDef sClockSourceConfig;   TIM_Master...
  • baiyibin0530
  • baiyibin0530
  • 2016-11-18 12:05:57
  • 864

STM32CUBEMX_STM32F0_TIM17

用CUBEMX设置定时器,如果只用到溢出中断,设置非常简单,如下 下面接着设置定时器中断溢出周期:图中红框内即设置的两个重要参数 计算溢出周期的方法  T=((PSC+1)*(ARR+1))/系统...
  • liuxinyong236
  • liuxinyong236
  • 2017-07-20 09:32:09
  • 376

STM32定时器 相关函数介绍

相关具体内容参考 stm32f4xx_hal_time.h 几种模式函数的类型都差不多,包括基本类型(Base),输出比较(OC),输入捕获(IC),pwm(PWM),单脉冲(One_Pulse)和...
  • qq_30567891
  • qq_30567891
  • 2018-01-07 14:48:15
  • 137

STM32Cubemx下实现通用定时器微秒级延时

因为STM32 HAL库中仅有对HAl_Delay()毫秒级的延时,为实现精确的微秒级延时,就不得不修改Systick,但由于HAL库内部使用其作为超时判断等操作,对其修改会发生不可预期的错误,不建议...
  • qq_22252423
  • qq_22252423
  • 2017-07-24 16:59:03
  • 1412

STM32F042 基于CubeMX HAL库CAN的配置

STM32F042 基于CubeMX  HAL库CAN的配置 首先说说使用时候的两个坑。 (1)要使能Swap PA9/10 –>PA11/12,这个时候PA11和PA12引脚才能出现。 ...
  • ZenNaiHeQiao
  • ZenNaiHeQiao
  • 2017-10-18 23:28:29
  • 1586

STM32CubeMX(stm32F030C8T6) 之RTC闹钟唤醒停机模式-STM32开发实战 (2)

一、概述 本例程是用STOP休眠模式,用RTC的周期性自动唤醒功能来唤醒芯片。 根据手册的说明:这里有个可编程的可自动重装的向下计数器,按照相应的时钟频率赋予适当的值,每当...
  • xiaoeleis
  • xiaoeleis
  • 2017-05-19 14:50:12
  • 2193

学习STM32CubeMX与HAL库吐槽

最近因为一个小项目(智能穿戴),用到了STM32L0(低功耗 Cortex M0)系列的MCU, 查了官网,居然没有提供固件库,只有HAL库,于是STM32CubeMX生成了HAL库的工程,学习HA...
  • tinyfar
  • tinyfar
  • 2017-06-24 23:48:39
  • 1682
    个人资料
    等级:
    访问量: 2368
    积分: 34
    排名: 194万+
    文章分类
    文章存档