目錄
一、SysTick定時(shí)器
1、SysTick寄存器介紹
(1)控制及狀態(tài)寄存器
(2)重裝載數(shù)值寄存器
(3)當(dāng)前數(shù)值寄存器
2、SysTick寄存器配置函數(shù)
二、FreeRTOS中的SysTick定時(shí)器
1、SysTick配置函數(shù)及分析
2、SysTick中斷函數(shù)
三、其他操作配置FreeRTOS的SysTick
1、找到頭文件 FreeRTOSConfig.h 有如下定義。
2、搜索?configTICK_RATE_HZ,在port.c中。
3、搜索?portNVIC_SYSTICK_CTRL_REG,在port.c中。
4、下面證明地址是不是SYSTICK的配置地址。
?5、跳轉(zhuǎn)到 SysTick 定義處。
一、SysTick定時(shí)器
SysTick系統(tǒng)定時(shí)器是屬于內(nèi)核中的一個(gè)外設(shè),內(nèi)嵌在NVIC中。該定時(shí)器是一個(gè)24位的向下遞減的計(jì)數(shù)器。在裸機(jī)編程中常用做延時(shí)函數(shù),而在FreeRTOS中則用來(lái)給系統(tǒng)提供時(shí)鐘的,因此非常重要。
1、SysTick寄存器介紹
SysTick共有4個(gè)相關(guān)寄存器,通常只用到3個(gè)(校準(zhǔn)寄存器少用)。
寄存器名稱 | 寄存器描述 |
CTRL | SysTick控制及狀態(tài)寄存器 |
LOAD | SysTick重裝載數(shù)值寄存器 |
VAL | SysTick當(dāng)前數(shù)值寄存器 |
CALIB | SysTick校準(zhǔn)數(shù)值寄存器 |
(1)控制及狀態(tài)寄存器
可通過(guò)讀取第16位判斷計(jì)數(shù)是否到0。
(2)重裝載數(shù)值寄存器
?????? 用來(lái)存放重裝載數(shù)的,改變?cè)撝狄哉{(diào)節(jié)計(jì)數(shù)時(shí)間。數(shù)值范圍:0—(2^24-1)即(0-16777215)。
(3)當(dāng)前數(shù)值寄存器
?????? 該寄存器的值在遞減,計(jì)數(shù)到0時(shí)會(huì)自動(dòng)重載,數(shù)值為重裝載數(shù)值寄存器內(nèi)的值。
2、SysTick寄存器配置函數(shù)
????????在庫(kù)文件core_cm4.h (M4內(nèi)核)中有相關(guān)配置函數(shù),也可以重寫(xiě)。
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) /*參數(shù)ticks為計(jì)數(shù)值,最大2^24(已有減1操作)*/
{
if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1);/*判斷傳入的值是否滿足,不能超過(guò)0xffffff*/
SysTick->LOAD = ticks - 1; /*將數(shù)值傳入重裝載數(shù)值寄存器*/
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /*設(shè)置Systick中斷優(yōu)先級(jí)*/
SysTick->VAL = 0; /*清空當(dāng)前值寄存器*/
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk;
/* SysTick_CTRL_CLKSOURCE_Msk = 1<<2 */
/* SysTick_CTRL_TICKINT_Msk = 1<<1 */
/* SysTick_CTRL_ENABLE_Msk = 1<<0 */
/*將第0、1、2位置1,即使能定時(shí)器,使能中斷,選擇系統(tǒng)時(shí)鐘(168M或72M)*/
return (0);
}
二、FreeRTOS中的SysTick定時(shí)器
在FreeRTOS中SysTick定時(shí)器尤為重要,因?yàn)樗墙oFreeRTOS系統(tǒng)提供時(shí)鐘的。在FreeRTOS中任務(wù)的切換即每個(gè)任務(wù)運(yùn)行的時(shí)間是由SysTick定時(shí)器提供的。
1、SysTick配置函數(shù)及分析
在FreeRTOS中已經(jīng)提供了SysTick配置的函數(shù)vPortSetupTimerInterrupt(),函數(shù)在port.c文件中。當(dāng)調(diào)用了開(kāi)啟任務(wù)調(diào)度函數(shù)vTaskStartScheduler()后里面就會(huì)調(diào)用該函數(shù)完成SysTick的配置。vPortSetupTimerInterrupt()函數(shù)分析:
?
#if ( configOVERRIDE_DEFAULT_TICK_CONFIGURATION == 0 ) /*條件編譯*/
__weak void vPortSetupTimerInterrupt( void )
{
/* Calculate the constants required to configure the tick interrupt. */
#if ( configUSE_TICKLESS_IDLE == 1 ) /*條件編譯,這段不編譯*/
{
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ );
}
#endif /* configUSE_TICKLESS_IDLE */
portNVIC_SYSTICK_CTRL_REG = 0UL; /*清空控制及狀態(tài)寄存器*/
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /*清空當(dāng)前值寄存器*/
/*設(shè)置重裝載數(shù)值寄存器數(shù)值*/
/*168000000/1000= 168000重裝載值,168000/168M=0.001S=1MS*/
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
/*設(shè)置控制及狀態(tài)寄存器*/
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );
/*( 1UL << 2UL ) | ( 1UL << 1UL ) | ( 1UL << 0UL ) */
/*選擇處理器時(shí)鐘、開(kāi)定時(shí)器中斷、使能定時(shí)器*/
}
#endif /* configOVERRIDE_DEFAULT_TICK_CONFIGURATION */
?
2、SysTick中斷函數(shù)
在SysTick中斷函數(shù)中并不是直接執(zhí)行任務(wù)切換,而是將xTickCount進(jìn)行加1操作,xTickCount是FreeRTOS的系統(tǒng)時(shí)鐘節(jié)拍數(shù),具體實(shí)現(xiàn)函數(shù)則是xTaskIncrementTick(),該函數(shù)在中斷函數(shù)中被調(diào)用。中斷函數(shù)的實(shí)現(xiàn)在port.c文件中也有定義:xPortSysTickHandler(),因此在SysTick中斷函數(shù)中直接調(diào)用該函數(shù)即可。
void SysTick_Handler(void)
{
if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED) //系統(tǒng)已經(jīng)運(yùn)行
{
xPortSysTickHandler(); //調(diào)用port.c中已寫(xiě)好的中斷函數(shù)
}
}
三、其他操作配置FreeRTOS的SysTick
1、找到頭文件 FreeRTOSConfig.h 有如下定義。
#define configCPU_CLOCK_HZ ((unsigned long)168000000) //CPU頻率
#define configTICK_RATE_HZ (( portTickType )1000) //時(shí)鐘節(jié)拍頻率,這里設(shè)置為1000,周期就是1ms
2、搜索?configTICK_RATE_HZ,在port.c中。
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );
3、搜索?portNVIC_SYSTICK_CTRL_REG,在port.c中。
#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) )
#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) )
4、下面證明地址是不是SYSTICK的配置地址。
STM32庫(kù)函數(shù)中core_cm4.h中配置systick函數(shù)為?uint32_t SysTick_Config(uint32_t ticks)
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
SysTick->VAL = 0UL; /* 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 (0UL); /* Function successful
?5、跳轉(zhuǎn)到 SysTick 定義處。
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */
#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */
#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */
#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
FreeRTOS學(xué)習(xí)筆記——SysTick中斷-CSDN博客
STM32使用FreeRTOS時(shí)SysTick哪里配置的?_systic在哪配的-CSDN博客
FreeRTOS 之六 任務(wù)調(diào)度原理解析(Systick、PendSV、SVC)_freertos svc-CSDN博客文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-821527.html
【STM32/FreeRTOS】SysTick定時(shí)器及FreeRTOS系統(tǒng)節(jié)拍_freertos systick-CSDN博客文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-821527.html
到了這里,關(guān)于【STM32/FreeRTOS】SysTick定時(shí)器及FreeRTOS系統(tǒng)節(jié)拍的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!