STM32F4(正点原子)学习笔记(一):GPIO及其小实验
SysTick定时器
一、SysTick概述
1.SysTick timer(STK)是一个 24 位的倒计数定时器,当计到 0 时,将从 RELOAD 寄存器中自动重装载定时初值。只要不把它在 SysTick 控制及状态寄存器中的使能位清除,就永不停息。
2.利用 STM32的内部 SysTick (on-chip)来实现延时,这样既不占用中断,也不占用系统定时器。
3.SysTick定时器被捆绑在NVIC(内嵌向量中断控制器Nested Vectored Interrupt Controller)中,用于产生SYSTICK异常(异常号:15)。
4.SysTick中断的优先级可以被设置。
二、SysTick相关寄存器
(一)SysTick控制和状态寄存器(SysTick Control and Status Register)
1. 第一位TICKINT表示是否产生中断
2.对于stm32,外部时钟源是HCLK(AHB总线时钟)的1/8,内核时钟是HCLK时钟
3.配置函数:SysTick_CLKSourceConfig();
(二)SysTick重装载数值寄存器(SysTick Reload Value Register)
(三)SysTick当前数值寄存器(SysTick Current Value Register)
static void SetSysClockTo72(void)
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
/* 使能HSE */
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
/* 等待HSE就绪并做超时处理 */
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;//如果标志位为1,则HSEStatus为1
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if ((RCC->CR & RCC_CR_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}//再判断一遍
else
{
HSEStatus = (uint32_t)0x00;
}
//HSE启动成功则继续往下执行
if (HSEStatus == (uint32_t)0x01)
{
//使能预处理指令,即一条指令取出另一条指令已经准备好被取
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 = 72M*/
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK = 72M*/
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
/* PCLK1 = HCLK = 36M*/
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
/* 配置锁相环: 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 */
/*使能锁相环 */
RCC->CR |= RCC_CR_PLLON;
/* 等待PLL稳定*/
while((RCC->CR & RCC_CR_PLLRDY) == 0)
{
}
/*选项PLLCLK作为系统时钟*/
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
/* 等待PLLCLK切换为系统时钟 */
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 */
}
}
#endif