无名飞控的时钟和延时

首先是飞控里面调用了

SystemInit(); //时钟初始化

这个里面
void SystemInit (void) { /* Reset the RCC clock configuration to the default reset state(for debug purpose) */ /* Set HSION bit */ RCC->CR |= (uint32_t)0x00000001; //RCC_CR寄存器最低位置1:打开HSI(内部高速时钟8M)/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */ #ifndef STM32F10X_CL RCC->CFGR &= (uint32_t)0xF8FF0000; #else RCC->CFGR &= (uint32_t)0xF0FF0000; ////RCC_CFGR寄存器初始化 #endif /* STM32F10X_CL *//* Reset HSEON, CSSON and PLLON bits */ RCC->CR &= (uint32_t)0xFEF6FFFF; ////将RCC_CR寄存器HSEON,CSSON,PLLON位置0/* Reset HSEBYP bit */ RCC->CR &= (uint32_t)0xFFFBFFFF; // //将RCC_CR寄存器HSEBYP位置0/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */ RCC->CFGR &= (uint32_t)0xFF80FFFF; ////将RCC_CFGR寄存器PLLSRC, PLLXTPRE, #ifdef STM32F10X_CL /* Reset PLL2ON and PLL3ON bits */ RCC->CR &= (uint32_t)0xEBFFFFFF; /* Disable all interrupts and clear pending bits*/ RCC->CIR = 0x00FF0000; /* Reset CFGR2 register */ RCC->CFGR2 = 0x00000000; #elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) /* Disable all interrupts and clear pending bits*/ RCC->CIR = 0x009F0000; //所有中断失能清理标志位/* Reset CFGR2 register */ RCC->CFGR2 = 0x00000000; //CFGR2初始化#else /* Disable all interrupts and clear pending bits*/ RCC->CIR = 0x009F0000; #endif /* STM32F10X_CL */#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL) #ifdef DATA_IN_ExtSRAM SystemInit_ExtMemCtl(); #endif /* DATA_IN_ExtSRAM */ #endif /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */ /* Configure the Flash Latency cycles and enable prefetch buffer */ SetSysClock(); #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 }



SetSysClock();
定义:

static void SetSysClock(void) { #ifdef SYSCLK_FREQ_HSE SetSysClockToHSE(); #elif defined SYSCLK_FREQ_24MHz SetSysClockTo24(); #elif defined SYSCLK_FREQ_36MHz SetSysClockTo36(); #elif defined SYSCLK_FREQ_48MHz SetSysClockTo48(); #elif defined SYSCLK_FREQ_56MHz SetSysClockTo56(); #elif defined SYSCLK_FREQ_72MHz SetSysClockTo72(); #endif

继续查找宏定义:
#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL) /* #define SYSCLK_FREQ_HSEHSE_VALUE */ #define SYSCLK_FREQ_24MHz24000000 #else /* #define SYSCLK_FREQ_HSEHSE_VALUE */ /* #define SYSCLK_FREQ_24MHz24000000 */ /* #define SYSCLK_FREQ_36MHz36000000 */ /* #define SYSCLK_FREQ_48MHz48000000 */ /* #define SYSCLK_FREQ_56MHz56000000 */ #define SYSCLK_FREQ_72MHz72000000 #endif

由于飞控用的是 主控STM32F103RCT6,则define SYSCLK_FREQ_72MHz72000000,于是SetSysClock(); 调用 SetSysClockTo72(); 打开定义

static void SetSysClockTo72(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ /* Enable HSE */ RCC->CR |= ((uint32_t)RCC_CR_HSEON); //((uint32_t)0x00010000) /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CR & RCC_CR_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if ((RCC->CR & RCC_CR_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; }if (HSEStatus == (uint32_t)0x01) { /* Enable Prefetch Buffer */ FLASH->ACR |= FLASH_ACR_PRFTBE; /* Flash 2 wait state */ FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; /* HCLK = SYSCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; #ifdef STM32F10X_CL /* Configure PLLs ------------------------------------------------------*/ /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5); /* Enable PLL2 */ RCC->CR |= RCC_CR_PLL2ON; /* Wait till PLL2 is ready */ while((RCC->CR & RCC_CR_PLL2RDY) == 0) { }/* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */ RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLMULL9); #else /*PLL configuration: PLLCLK = HSE * 9 = 72 MHz */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); #endif /* STM32F10X_CL *//* Enable PLL */ RCC->CR |= RCC_CR_PLLON; /* Wait till PLL is ready */ while((RCC->CR & RCC_CR_PLLRDY) == 0) { }/* Select PLL as system clock source */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) { } } else { /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */ } }

接着看对于 cycleCounterInit 【无名飞控的时钟和延时】
void cycleCounterInit(void) { RCC_ClocksTypeDef clocks; RCC_GetClocksFreq(&clocks); //返回不同片上时钟的频率 usTicks = clocks.SYSCLK_Frequency / 1000000; } // Return system uptime in microseconds (rollover in 70minutes)


SYSCLK_Frequency本应该等于72M,则usTicks=72; 接下来有:

SysTick_Config(SystemCoreClock / 1000); //SysTick开启系统tick定时器并初始化其中断

因有:
#elif defined SYSCLK_FREQ_72MHz uint32_t SystemCoreClock= SYSCLK_FREQ_72MHz;

其中
#define SYSCLK_FREQ_72MHz72000000

故函数输入为 SysTick_Config(72000)

打开定义:
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 */ }

systick 定时器初始化,为期装载初始值。 当中断发生时就

void SysTick_Handler(void) { sysTickUptime++; }

即计时系统运行了多少毫秒

对于函数delay_ms如:delay_ms(2000)
定义

void delay_ms(uint16_t nms) { uint32_t t0=micros(); while(micros() - t0 < nms * 1000); }

其中引入了了一个micros
uint32_t micros(void) { register uint32_t ms, cycle_cnt; do { ms = sysTickUptime; cycle_cnt = SysTick->VAL; } while (ms != sysTickUptime); return (ms * 1000) + (usTicks * 1000 - cycle_cnt) / usTicks; }

得到系统运行了多少微秒 总得来说就是通过系统时钟来延时







    推荐阅读