| 本帖最后由 xyzjacky 于 2020-1-8 12:52 编辑 
 
 首先,使用RTthread OS时,要配置它的系统节拍rt_tick (划重点)系统节拍 ·        系统节拍是特定的周期中断,可以看作是系统心跳,中断之间的时间间隔取决于系统的需求,一般是 1ms–100ms,系统节拍率越快,系统的额外开销就越大,从系统启动开始计数的时钟节拍数称为系统时间。 ·        RT-Thread 中,系统节拍的长度可以根据 RT_TICK_PER_SECOND 的定义来调整,等于1/RT_TICK_PER_SECOND 秒。系统节拍实现方式 ·        系统节拍由配置为中断触发模式的硬件定时器产生,当中断到来时,将调用一次:void rt_tick_increase(void),通知操作系统已经过去一个系统时钟   先看这段代码: 1.  void SysTick_Handler(void)   2.  {   3.      /* enter interrupt */   4.      rt_interrupt_enter();   5.     6.      rt_tick_increase();   7.     8.      /* leave interrupt */   9.      rt_interrupt_leave();   10. }   
   其中函数rt_tick_increase()的代码是: 
 1.  void rt_tick_increase(void)   2.  {   3.      struct rt_thread *thread;   4.     5.      /* increase the global tick */   6.  #ifdef RT_USING_SMP   7.      rt_cpu_self()->tick ++;   8.  #else   9.      ++ rt_tick;   10. #endif   11.    12.     /* check time slice */   13.     thread = rt_thread_self();   14.    15.     -- thread->remaining_tick;   16.     if (thread->remaining_tick == 0)   17.     {   18.         /* change to initialized tick */   19.         thread->remaining_tick = thread->init_tick;   20.    21.         /* yield */   22.         rt_thread_yield();   23.     }   24.    25.     /* check timer */   26.     rt_timer_check();   27. }   
 
 若系统的硬件是外置8MHz晶振,系统时钟每秒节拍数1000表示1s内rt_tick增加1000,即时钟节拍为1ms;若设为100,则rt_tick每隔10ms加1,时钟节拍为10ms。 
 SysTick_Handler是STM32的硬件滴答时钟的中断库函数,既然是一个时钟,那么类似定时器,它应该有一个时间间隔才产生一次中断。这个时间间隔就由以下这个函数来设置: 
 HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/ RT_TICK_PER_SECOND); 
 其中RT_TICK_PER_SECOND定义在rtconfig.h中: 1.  /* Tick per Second */   2.  #define RT_TICK_PER_SECOND 1000   
 RT thread对于此处代码的解释是,等于 1/RT_TICK_PER_SECOND 秒,RT_TICK_PER_SECOND默认是1000。 
 又因HAL_RCC_GetHCLKFreq()的返回值是SystemCoreClock,所以就要查找SystemCoreClock在哪里赋值的。所以继续查看代码,找到: rtthread_startup() -> rt_hw_board_init()-> SystemClock_Config() -> SystemCoreClockUpdate () 
 在函数SystemCoreClockUpdate()中有如下一段代码(关键部份为橙色): 1.  /* Get SYSCLK source -------------------------------------------------------*/   2.    switch (RCC->CFGR & RCC_CFGR_SWS)   3.    {   4.      case 0x00:  /* MSI used as system clock source */   5.        SystemCoreClock = msirange;   6.        break;   7.     8.      case 0x04:  /* HSI used as system clock source */   9.        SystemCoreClock = HSI_VALUE;   10.       break;   11.    12.     case 0x08:  /* HSE used as system clock source */   13.       SystemCoreClock = HSE_VALUE;   14.       break;   15.    16.     case 0x0C:  /* PLL used as system clock  source */   17.       /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN  18.          SYSCLK = PLL_VCO / PLLR  19.          */   20.       pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);   21.       pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> 4U) + 1U ;   22.    23.       switch (pllsource)   24.       {   25.         case 0x02:  /* HSI used as PLL clock source */   26.           pllvco = (HSI_VALUE / pllm);   27.           break;   28.    29.         case 0x03:  /* HSE used as PLL clock source */   30.           pllvco = (HSE_VALUE / pllm);   31.           break;   32.    33.         default:    /* MSI used as PLL clock source */   34.           pllvco = (msirange / pllm);   35.           break;   36.       }   37.       pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 8U);   38.       pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 25U) + 1U) * 2U;   39.       SystemCoreClock = pllvco/pllr;   40.       break;   41.    42.     default:   43.       SystemCoreClock = msirange;   44.       break;   45.   }   46.      47. /* Compute HCLK clock frequency --------------------------------------------*/   48.   /* Get HCLK prescaler */   49.   tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)];   50.   /* HCLK clock frequency */   51.   SystemCoreClock >>= tmp;   
   在代码中,switch (RCC->CFGR &RCC_CFGR_SWS)显然就是硬件的时钟寄存器,一般STM32F103系列电路板上用的是外部晶振,所以就是0x08的值在起作用。 1.  case 0x08:  /* HSE used as system clock source */   2.        SystemCoreClock = HSE_VALUE;   
 
 查找HSE_VALUE的定义,果然能找到 #define HSE_VALUE    ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */   一般电路板上这个外部晶振都是8MHz,所以此处HSE_VALUE为8000000U 
 同时,看这段代码: 52. /* Get HCLK prescaler */   53.   tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)];   54.   /* HCLK clock frequency */   55. SystemCoreClock >>= tmp;   
 注释Get HCLK prescaler,意思是取得AHB的预分频; 注释HCLK clock frequency,意思是HCLK的频率。 一般我们都会将HCLK调整为72MHz,由此可知,SystemCoreClock算出来的值是72000000。 
 |