STM32 CubeMX 1ms定时中断的实现

      一、来由

         近来,要用到RS485转CAN2.0B协议,其中要求8ms发一级CAN包,100ms又发另一组CAN包,500ms还想让led闪烁,表示程序正常运行。因为刚用STM32F042,不熟悉,只能找些例子来看,还好,感谢网友,也算把它调试出来了。其中用“HAL_Dalay(1)”延时1ms,计数,调试用用还行,但觉得不精准,应该用定时器控制。

        网上找资料,找到:《STM32 Cubemx 配置定时器定时1mSSTM32 Cubemx 配置定时器定时1mS - osc_qimlgg8v的个人空间 - OSCHINA - 中文开源技术交流社区等文,照葫芦画瓢,画到最后,画不来(程序不理解、也无法实现功能),反复琢磨,最后成功了,也就想写出来,分享给大家,以少走弯路。

       照着STM32 Cubemx 配置定时器定时1mS - osc_qimlgg8v的个人空间 - OSCHINA - 中文开源技术交流社区介绍,走到最后一段,不知道怎么做了:

   最后使用定时器中断跟关闭定时器中断以及回调函数即可, 使用中断的时候注意要先开启中断

HAL_TIM_Base_Start_IT(&htim1); //使用定时器的时候调用这个函数启动

HAL_TIM_Base_Stop_IT(&htim1);  //停止定时器的时候调用这个函数关闭

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  if(htim->Instance == TIM1)
  {
    //编写回调逻辑,即定时器1定时1MS后的逻辑
  }
}

       定时器开中断好理解,定时器关中断也好理解,就是这个回调函数怎么用,不知道,文章到此结束了,相似内容的文章也有一些,但都是到此就结束了。不知道从何下手,无奈,只好自己想办法。

二、我的方法

       CubeMX定义好各种引脚、参数后会创建出工程文件来,我的RS485是中断接收的, 我也是在stm32f0xx_it.c(见下图手写“1”处)中添了几条语句实现串口中断接收的(见下图手写“2”处),stm32f0xx_it.c中也有定时器中断(我用的是定时器1)(见下图手写“3”处),每次1ms中断就让几个相关的数加1。

当然,要在stm32f0xx_it.c中把这几用到的变量名定义一下,见下图涂蓝部分。

在main.c中引用刚才定义的变量,见下图涂蓝部分

现在,这几个变量每1ms就会增加1,在while(1){   }中用几个条件语句就实现了8ms发一级CAN包,100ms又发另一组CAN包,500ms还让led闪烁。注意,必须设置语句启动定时器,否则定时器是不会的。代码如下(简化过):

nt main(void)
{
  /* USER CODE BEGIN 1 */
 extern unsigned char RS485RxBuffer[32];   //接收数据
 extern  unsigned char aRxBuffer;            //接收中断缓冲
 extern  unsigned char Uart2_Rx_Cnt;        //接收缓冲计数
    extern CAN_HandleTypeDef hcan;        //和初始化中的保持一致
    extern WWDG_HandleTypeDef hwwdg;
    extern int Led_flash,RepeatSendPri,RepeatSendSec;
    
  HAL_Init();


  SystemClock_Config();

 // CAN_HandleTypeDef hcan;
  HAL_StatusTypeDef    HAL_RetVal;
    CAN_TxHeaderTypeDef Can_Tx;
    CAN_RxHeaderTypeDef Can_Rx;
  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ADC_Init();
  MX_CRC_Init();
  MX_TIM1_Init();
  MX_CAN_Init();
  MX_USART2_UART_Init();
  MX_WWDG_Init();
  /* USER CODE BEGIN 2 */
  __HAL_TIM_CLEAR_IT(&htim1 ,TIM_IT_UPDATE ); //清除TIM1中断挂起
  HAL_TIM_Base_Start_IT(&htim1 );              //启动定时器TIM1中断
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */   
    
     //以下初始数据准备
      Uart2_Rx_Cnt = 0;
       RepeatSendPri=0;
      RepeatSendSec =0;
      Led_flash = 0;      
    
    while (1)
  {
          HAL_WWDG_Refresh(&hwwdg);     //复位看门狗     
             
          //定时器1ms中断计时(计数)        
        //以下每8ms发一组数据,CAN ID=0x0A发送
        if(RepeatSendPri >= 8)
        {
            RepeatSendPri  = 0 ;  //置0,重新开始
            //发之前先查询一下 邮箱是否满了,满了就等一下再发
            while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan) == 0 );
            //向 Tx 邮箱中增加一个消息,并且激活对应的传输请求
              HAL_RetVal = HAL_CAN_AddTxMessage(&hcan,&Can_Tx,CanTxdataPri,&pTxMailbox);  //CAN ID=0x0A发送
           
        }
        
        //以下每100ms发一组数据,CAN ID=0x0B发送
        if(RepeatSendSec >= 100)
        {
           RepeatSendSec =0;   //置0,重新开始
            
             //发之前先查询一下 邮箱是否满了,满了就等一下再发
            while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan) == 0 );
            //向 Tx 邮箱中增加一个消息,并且激活对应的传输请求
            HAL_RetVal = HAL_CAN_AddTxMessage(&hcan,&Can_Tx,CanTxdataSec,&pTxMailbox);   //CAN ID=0x0B发送
        
        }
                 
        //以下用于指示程序在运行,LED亮或灭中            
        if(Led_flash >=500)
        {
          Led_flash = 0;    //置0,重新开始
            LedFlash();   //使LED亮或灭,指示程序在运行     
   
       }
            
 }

}



三、小结

      感谢网友STM32 Cubemx 配置定时器定时1mS - osc_qimlgg8v的个人空间 - OSCHINA - 中文开源技术交流社区的分享,依照他的cubeMX配置是可行的,只是最后一段我不会用,改成了自己的,我也分享给用得着的朋友。

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值