中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何解決SysTick定時器錯誤問題

發布時間:2021-10-15 09:42:13 來源:億速云 閱讀:436 作者:iii 欄目:web開發

這篇文章主要介紹“如何解決SysTick定時器錯誤問題”,在日常操作中,相信很多人在如何解決SysTick定時器錯誤問題問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”如何解決SysTick定時器錯誤問題”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

01坑的由來

使用的就是systick定時器,具體代碼如下

void delay_us(uint32_t nus) {   uint32_t temp;   SysTick->LOAD = RCC_Clocks.HCLK_Frequency/1000000/8*nus;   SysTick->VAL=0X00;//清空計數器   SysTick->CTRL=0X01;//使能,減到零是無動作,采用外部時鐘源   do   {     temp=SysTick->CTRL;//讀取當前倒計數值   }while((temp&0x01)&&(!(temp&(1<<16))));//等待時間到達   SysTick->CTRL=0x00; //關閉計數器   SysTick->VAL =0X00; //清空計數器 } void delay_ms(uint16_t nms) {   uint32_t temp;   SysTick->LOAD = RCC_Clocks.HCLK_Frequency/1000/8*nms;   SysTick->VAL=0X00;//清空計數器   SysTick->CTRL=0X01;//使能,減到零是無動作,采用外部時鐘源   do   {     temp=SysTick->CTRL;//讀取當前倒計數值   }while((temp&0x01)&&(!(temp&(1<<16))));//等待時間到達   SysTick->CTRL=0x00; //關閉計數器   SysTick->VAL =0X00; //清空計數器 }

對于《STM32延時的四種方法》文中所說的內容如下

如何解決SysTick定時器錯誤問題

也就是下面代碼中/8的原因。

SysTick->LOAD = RCC_Clocks.HCLK_Frequency/1000/8*nms;

我對此深信不疑,并在STM32F207參考手冊(RM0033)上找到“證據”。

如何解決SysTick定時器錯誤問題

上圖①處直接是8分頻,而不像②出的1/2/4/8分頻。所以我確信是SYSTICK的時鐘固定為HCLK時鐘的1/8。

我在學習RTThread的時候,看到配置SysTick定制器代碼如下

如何解決SysTick定時器錯誤問題

我心里一堆問號,STM32官方手冊,明明寫了SYSTICK的時鐘固定為HCLK時鐘的1/8。我使用示波器測量,RTThread的配置是沒有問題,可以正常延時的。

02填坑

如何解決SysTick定時器錯誤問題

位2置1,表示時鐘頻率為AHB,也就是默認的120000000Hz。

位2清0,表示時鐘頻率為AHB/8,也就是120000000/8Hz。

RTThread配置為內部時鐘

如何解決SysTick定時器錯誤問題

之前的文章配置為外部時鐘源

如何解決SysTick定時器錯誤問題


這個細節我沒有留意,導致我看RTThread代碼時有點懵逼。

如何解決SysTick定時器錯誤問題

準確的描述是:

SYSTICK的時鐘可以為HCLK時鐘的1分頻或8分頻,在這里我們選用外部時鐘源120M,所以SYSTICK的時鐘為(120/8)M。

特此更正。

關于這點,STM32的標準外設庫提供的SysTick_Config函數,也是使用內部時鐘的

/** \brief  System Tick Configuration      This function initialises the system tick timer and its interrupt and start the system tick timer.     Counter is in free running mode to generate periodical interrupts.      \param [in]  ticks  Number of ticks between two interrupts     \return          0  Function succeeded     \return          1  Function failed  */ static __INLINE uint32_t SysTick_Config(uint32_t ticks) {   if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */    SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register */   NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Cortex-M0 System Interrupts */   SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */   SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |                    SysTick_CTRL_TICKINT_Msk   |                    SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */   return (0);                                                  /* Function successful */ }

調用方法,產生1ms中斷調用方法

SysTick_Config(SystemCoreClock / 1000);

關于時鐘源的選擇,除了操作寄存器外,還有庫函數可以選擇。

/**   * @brief  Configures the SysTick clock source.   * @param  SysTick_CLKSource: specifies the SysTick clock source.   *   This parameter can be one of the following values:   *     @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source.   *     @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source.   * @retval None   */ void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource) {   /* Check the parameters */   assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));   if (SysTick_CLKSource == SysTick_CLKSource_HCLK)   {     SysTick->CTRL |= SysTick_CLKSource_HCLK;   }   else   {     SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;   } }

除上外,我找到了其他證據來說明,SYSTICK的時鐘可以為HCLK時鐘的1分頻或8分頻。

如何解決SysTick定時器錯誤問題

在STM32CubeMx配置軟件中,可以選擇1分頻或8分頻。

03修改代碼驗證

把涉及的代碼修改成1分頻的。

void delay_ms(uint16_t nms) {   uint32_t temp;   SysTick->LOAD = RCC_Clocks.HCLK_Frequency/1000*nms-1;   SysTick->VAL=0X00;//清空計數器   SysTick->CTRL=0X01;   SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);   do   {     temp=SysTick->CTRL;//讀取當前倒計數值   }while((temp&0x01)&&(!(temp&(1<<16))));//等待時間到達   SysTick->CTRL=0x00; //關閉計數器   SysTick->VAL =0X00; //清空計數器 }

然后調用

GPIO_SetBits(GPIOE,GPIO_Pin_4);  //熄滅LED燈                      delay_ms(500);//延時500ms GPIO_ResetBits(GPIOE,GPIO_Pin_4);//點亮LED燈                      delay_ms(500);//延時500ms

就踩到另一個坑,延時不準。

原因是:此時SYSTICK時鐘頻率是120MHz的24位的倒計數定時器,也就是說一個周期,最多定時139.810125ms。不能延時500ms。

這里再更正之前的一個錯誤,如下圖

如何解決SysTick定時器錯誤問題

這個計數器的值,我們減去了1,這樣才更準確。

到此,關于“如何解決SysTick定時器錯誤問題”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

志丹县| 商洛市| 九寨沟县| 太康县| 将乐县| 军事| 射洪县| 虞城县| 永昌县| 嘉峪关市| 惠东县| 额尔古纳市| 京山县| 邵武市| 抚宁县| 南召县| 磐安县| 察雅县| 崇义县| 阳城县| 财经| 忻城县| 弥勒县| 苍溪县| 鸡东县| 土默特右旗| 商水县| 伊宁县| 凤凰县| 武城县| 南平市| 武穴市| 洛浦县| 哈密市| 都昌县| 河间市| 无棣县| 蓬莱市| 三河市| 东方市| 四子王旗|