stm32f407移植rt-thread后rt_thread_delay阻塞延时函数运行时间偏差很大

之前刚在stm32f407ZGT核心板移植完RT-Thread后进行简单的测试的时候,发现rt_thread_delay()阻塞延时函数不能按照正常的时钟进行一次,具体是情况是1s的延时粗略算起来大概延时了3s左右,在网上找了很多资料都没有完全解决的,结合网友的各种建议再结合认真看了一遍f407的时钟树配置以后总算是解决了,记录问题解决过程。

F407系统时钟树

在这里插入图片描述

截图比较模糊,建议直接看手册的时钟树。

为了解决rt-thread的系统时钟配置,这里我们只需要注意SYSCLK的配置过程。SYSCLK来源有三个:

  • HSE:高速外部时钟(一般是4-24M左右的频率),高速外部时钟信号 (HSE) 有 2 个时钟源:(1) HSE 外部晶振/陶瓷谐振器(核心板或开发板上的一般为8M)、(2)HSE 外部用户时钟
  • HSI:高速内部时钟(芯片内部的16M),HSI 时钟信号由内部 16 MHz RC 振荡器生成,可直接用作系统时钟,或者用作 PLL 输入。
  • PLL:倍频输出时钟。

我们使用f407这样的芯片,肯定还是想要它能跑的更快的,所以单靠HSE,HSI本身的时钟频率无法满足要求,所以绝大多数情况下SYSCLK都是来自PLL倍频输出时钟。

SYSCLK的配置

  • PLL简介
  1. 主 PLL(PLL)由 HSE 或者 HSI 提供时钟信号(通过选择器),并具有两个不同的输出时钟。主PLL时钟计算方式:PLL=8MHz * N/ (MP)=8MHz 336 /(8*2) = 168MHz (就是分频和倍频:外部晶振选择 8MHz PLL_M=8,倍频器倍频系数 PLL_N=336,分频器分频系数 PLL_P=2 )第一个输出 PLLP 用于生成高速的系统时钟(最高 168MHz)第二个输出 PLLQ 用于生成 USB OTG FS 的时钟(48MHz),随机数发生器的时钟和 SDIO时钟
  2. 专用 PLL(PLLI2S)用于生成精确时钟,从而在 I2S 接口实现高品质音频性能

由上述的主PLL时钟(也就是SYSCLK)计算方式可知,配置好SYSCLK由HSE为源后,需要将几个分频和倍频因子配置好,这样SYSCLK才算是配置完成。

再由源代码来看这个过程:

  • 首先上电后板子进入汇编的这段复位程序后加载系统时钟配置 SystemInit
   ; Reset handler
    Reset_Handler    PROC
                     EXPORT  Reset_Handler             [WEAK]
            IMPORT  SystemInit
            IMPORT  __main
    
                     LDR     R0, =SystemInit
                     BLX     R0
                     LDR     R0, =__main
                     BX      R0
                     ENDP
  • 在 system_stm32f4xx.c 中找到系统时钟配置函数原型,这里主要是进行了RCC相关寄存器的复位,然后进入 SetSysClock(); 函数。
void SystemInit(void)
    {
   
      /* FPU settings ------------------------------------------------------------*/
      #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
        SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
      #endif
      /* Reset the RCC clock configuration to the default reset state ------------*/
      /* Set HSION bit */
      RCC->CR |= (uint32_t)0x00000001;
    
      /* Reset CFGR register */
      RCC->CFGR = 0x00000000;
    
      /* Reset HSEON, CSSON and PLLON bits */
      RCC->CR &= (uint32_t)0xFEF6FFFF;
    
      /* Reset PLLCFGR register */
      RCC->PLLCFGR = 0x24003010;
    
      /* Reset HSEBYP bit */
      RCC->CR &= (uint32_t)0xFFFBFFFF;
    
      /* Disable all interrupts */
      RCC->CIR = 0x00000000;
    
    #if defined(DATA_IN_ExtSRAM) || defined(DATA_IN_ExtSDRAM)
      SystemInit_ExtMemCtl(); 
    #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
             
      /* Configure the System clock source, PLL Multiplier and Divider factors, 
         AHB/APBx prescalers and Flash settings ----------------------------------*/
      SetSysClock();
    
      /* Configure the Vector Table location add offset address ------------------*/
    #ifdef VECT_TAB_SRAM
      SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
    #else
      SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
    #endif
    }
  • 同样在 system_stm32f4xx.c 中找到 SetSysClock(); 函数原型。由于诸多的宏条件编译,代码很长,但是这里最主要的任务就是选择HSE为源(注意:如果HSE时钟源没有就绪或者没有HSE,那么就会使用HSI为系统时钟),配置好系统时钟和AHB,APB2,APB1的总线时钟。
  static void SetSysClock(void)
    {
   
    #if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F401xx) || defined(STM32F412xG) || defined(STM32F413_423xx) || defined(STM32F446xx)|| defined(STM32F469_479xx)
    /******************************************************************************/
    /*            PLL (clocked by HSE) used as System clock source                */
    /******************************************************************************/
      __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
      
      /* Enable HSE */
      RCC->CR |
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32F407芯片上移植RT-Thread的LCD程序可以按照以下步骤进行: 1. 首先,需要了解RT-Thread的LCD设备驱动框架。RT-Thread提供了通用的LCD驱动框架,通过配置相关的参数,可以适配不同的LCD驱动芯片。根据RT-Thread的文档,可以选择合适的驱动框架。 2. 接下来,根据LCD驱动芯片的手册或者数据手册,了解该芯片的寄存器配置和工作原理。在移植过程中,需要对这些寄存器进行适当的配置。 3. 在RT-Thread的操作系统层面,需要根据移植的要求进行修改。首先,在操作系统的配置中,开启LCD驱动相关的选项,启用LCD驱动的支持。然后,修改LCD设备的配置文件,指定LCD驱动的名称和参数。 4. 接着,实现LCD设备驱动程序。根据所选择的LCD驱动框架,编写适配LCD芯片的驱动程序。在驱动程序中,需要对LCD寄存器进行配置,控制屏幕显示和刷新。 5. 最后,在应用层面进行测试。可以编写一小段示例代码,调用LCD设备的相关接口,进行显示测试。如果显示效果正常,说明RT-Thread的LCD移植工作完成。 当然,移植LCD程序可能会遇到一些问题和挑战。例如,涉及到芯片的外设时钟配置、中断配置和DMA传输等。需要根据具体情况进行调试和修改。此外,还需要根据具体的LCD驱动芯片和显示模组的特性,处理涉及到像素点的像素格式、显示方向、亮度和对比度等问题。 需要注意的是,在移植LCD程序时,需要仔细查阅RT-Thread的文档和相关资料,对RT-Thread和LCD芯片的技术细节有较为充分的了解。并且,在移植过程中应该注意对现有代码的保护,确保整个系统的稳定性和可靠性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值