打印

为FreeRTOS和RTX5使用HAL库整理的两种HAL库时间基准方案

[复制链接]
240|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
专门为此教程准备的:
http://www.armbbs.cn/forum.php?mod=viewthread&tid=93149


HAL库默认是用的滴答定时器,而OS里面要使用,所以整理了两种方案。

一种是使用TIM7提供,另外一种是借用RTOS的API获取

/*
*********************************************************************************************************
*
*        模块名称 : HAL库时基
*        文件名称 : stm32h7xx_hal_timbase_tim.c
*        版    本 : V1.0
*        说    明 : 用于为HAL库提供时间基准
*        修改记录 :
*                版本号  日期         作者       说明
*                V1.0    2018-07-29  Eric2013   正式发布
*
*        Copyright (C), 2018-2030, 安富莱电子 www.armfly.com
*
*********************************************************************************************************
*/
#include "includes.h"


/* 采用TIM7方案或者RTX5内核时钟方案 */
#if 0

TIM_HandleTypeDef   TimHandle = {0};
        
/*
*********************************************************************************************************
*        函 数 名: System_Init
*        功能说明: 为HAL库配置1ms的时间基准,此函数会被HAL_Init和HAL_RCC_ClockConfig调用
*        形    参:TickPriority  定时器优先级
*        返 回 值: 无
*********************************************************************************************************
*/
HAL_StatusTypeDef HAL_InitTick (uint32_t TickPriority)
{

        RCC_ClkInitTypeDef    clkconfig;
        uint32_t              uwTimclock, uwAPB1Prescaler = 0U;
        uint32_t              uwPrescalerValue = 0U;
        uint32_t              pFLatency;

        
        /* 复位定时器7 */
        TimHandle.Instance = TIM7;
        if(HAL_TIM_Base_DeInit(&TimHandle) != HAL_OK)
        {
                Error_Handler(__FILE__, __LINE__);
        }
        
        /* 设置TIM7的中断优先级并使能 */
        HAL_NVIC_SetPriority(TIM7_IRQn, TickPriority ,0U);
        HAL_NVIC_EnableIRQ(TIM7_IRQn);

        /* 使能TIM7时钟 */
        __HAL_RCC_TIM7_CLK_ENABLE();

        /*-----------------------------------------------------------------------
        System Clock source       = PLL (HSE)
        SYSCLK(Hz)                = 400000000 (CPU Clock)
        HCLK(Hz)                  = 200000000 (AXI and AHBs Clock)
        AHB Prescaler             = 2
        D1 APB3 Prescaler         = 2 (APB3 Clock  100MHz)
        D2 APB1 Prescaler         = 2 (APB1 Clock  100MHz)
        D2 APB2 Prescaler         = 2 (APB2 Clock  100MHz)
        D3 APB4 Prescaler         = 2 (APB4 Clock  100MHz)

        因为APB1 prescaler != 1, 所以 APB1上的TIMxCLK = APB1 x 2 = 200MHz;
        因为APB2 prescaler != 1, 所以 APB2上的TIMxCLK = APB2 x 2 = 200MHz;
        APB4上面的TIMxCLK没有分频,所以就是100MHz;

        APB1 定时器有 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM7, TIM12, TIM13, TIM14,LPTIM1
        APB2 定时器有 TIM1, TIM8 , TIM15, TIM16,TIM17

        APB4 定时器有 LPTIM2,LPTIM3,LPTIM4,LPTIM5
        ----------------------------------------------------------------------- */
        /* 获取时钟配置 */
        HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);

        /* 获取APB1时钟 */
        uwAPB1Prescaler = clkconfig.APB1CLKDivider;

        /* 获得TIM7时钟 */
        if (uwAPB1Prescaler == RCC_HCLK_DIV1)
        {
                uwTimclock = HAL_RCC_GetPCLK1Freq();
        }
        else
        {
                uwTimclock = 2*HAL_RCC_GetPCLK1Freq();
        }

        /* TIM7分频到1MHz */
        uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000U) - 1U);

        /* TIM7CLK = uwTimclock / (Period + 1) / (Prescaler + 1) = 1KHz */
        TimHandle.Init.Period = (1000000U / 1000U) - 1U;
        TimHandle.Init.Prescaler = uwPrescalerValue;
        TimHandle.Init.ClockDivision = 0;
        TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
        if(HAL_TIM_Base_Init(&TimHandle) == HAL_OK)
        {
                /* 启动TIM7 */
                return HAL_TIM_Base_Start_IT(&TimHandle);
        }

        /* 返回错误 */
        return HAL_ERROR;
}

/*
*********************************************************************************************************
*        函 数 名: HAL_SuspendTick
*        功能说明: 关闭TIM7
*        形    参: 无
*        返 回 值: 无
*********************************************************************************************************
*/
void HAL_SuspendTick(void)
{
        __HAL_TIM_DISABLE_IT(&TimHandle, TIM_IT_UPDATE);
}

/*
*********************************************************************************************************
*        函 数 名: HAL_ResumeTick
*        功能说明: 使能TIM7
*        形    参: 无
*        返 回 值: 无
*********************************************************************************************************
*/
void HAL_ResumeTick(void)
{
        __HAL_TIM_ENABLE_IT(&TimHandle, TIM_IT_UPDATE);
}

/*
*********************************************************************************************************
*        函 数 名: TIM7_IRQHandler
*        功能说明: TIM7定时器中断服务程序
*        形    参: 无
*        返 回 值: 无
*********************************************************************************************************
*/
void TIM7_IRQHandler(void)
{
        if((TIM7->SR & TIM_FLAG_UPDATE) != RESET)
        {
                 TIM7->SR = ~ TIM_FLAG_UPDATE;
                 HAL_IncTick();
        }
}

#else
/*
*********************************************************************************************************
*        函 数 名: HAL_Delay
*        功能说明: 重定向毫秒延迟函数。替换HAL中的函数。因为HAL中的缺省函数依赖于Systick中断,如果在USB、SD卡
*             中断中有延迟函数,则会锁死。也可以通过函数HAL_NVIC_SetPriority提升Systick中断
*        形    参: 无
*        返 回 值: 无
*********************************************************************************************************
*/
void HAL_Delay(uint32_t Delay)
{
        bsp_DelayMS(Delay);
}

HAL_StatusTypeDef HAL_InitTick (uint32_t TickPriority)
{
        return HAL_OK;
}

uint32_t HAL_GetTick (void)
{
        static uint32_t ticks = 0U;
        uint32_t i;

        if (osKernelGetState () == osKernelRunning)
        {
                return ((uint32_t)osKernelGetTickCount ());
        }

        /* 如果RTX5还没有运行,采用下面方式 */
        for (i = (SystemCoreClock >> 14U); i > 0U; i--)
        {
                __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
                __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
        }
        
        return ++ticks;
}
#endif

/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

457

主题

483

帖子

1

粉丝