本帖最后由 freeelectron 于 2022-7-12 19:53 编辑
#申请原创#
1、前言: 官方的demo用的阻塞方式点灯,即就是死等,在等待期间mcu干不了其他事情(中断除外),这种方式不太友好,本文使用非阻塞方式点灯。
2、硬件连接
3、思路 利用定时器中断,每1ms中断一次,整个系统维护一个tick计数; 记录某一时刻的tick,用A表示,再获取当前的tick,用B表示,如果当前的B-A大于等于500(这里500ms闪烁一次),那么就执行一次led翻转,同时也更新A的值。
4、软件实现 (1)利用定时器中断,每1ms中断一次,整个系统维护一个tick计数,本文使用基础定时器1 static uint32_t SystemTick=0;
void TimerConfig(void)
{
RCC_APBPeriphClk_Enable2(RCC_APB2_PERIPH_BTIM,ENABLE);
NVIC_EnableIRQ(BTIM1_IRQn);
BTIM_TimeBaseInitTypeDef BTIM_TimeBaseInitStruct;//1000000
BTIM_TimeBaseInitStruct.BTIM_Mode = BTIM_Mode_TIMER;
BTIM_TimeBaseInitStruct.BTIM_Period = 999;
BTIM_TimeBaseInitStruct.BTIM_Prescaler = BTIM_PRS_DIV64; //64分频
BTIM_TimeBaseInit(CW_BTIM1, &BTIM_TimeBaseInitStruct);
BTIM_ITConfig(CW_BTIM1, BTIM_IT_OV, ENABLE);
BTIM_Cmd(CW_BTIM1, ENABLE);
}
void BTIM1_IRQHandler(void)
{
if (BTIM_GetITStatus(CW_BTIM1, BTIM_IT_OV))
{
BTIM_ClearITPendingBit(CW_BTIM1, BTIM_IT_OV);
SystemTick++;
}
}
uint32_t SystemGetTick(void)
{
return SystemTick;
}
(2)时钟切换到PLL 默认的是HSI,本文使用HSE,再切换到PLL至64MHZ。 RCC_AHBPeriphClk_Enable(RCC_AHB_PERIPH_FLASH, ENABLE); //打开FLASH时钟
RCC_HSE_Enable(RCC_HSE_MODE_OSC, 16000000, RCC_HSE_DRIVER_NORMAL,RCC_HSE_FLT_CLOSE);
RCC_PLL_Enable(RCC_PLLSOURCE_HSECLK, 16000000, 4);
FLASH_SetLatency(FLASH_Latency_2); //频率大于24M需要配置FlashWait=2
while(RCC_SysClk_Switch( RCC_SYSCLKSRC_PLL ));
RCC_SYSCLKSRC_Config(RCC_SYSCLKSRC_PLL);
RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
(3)点灯 void LedInit(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_AHBPeriphClk_Enable(RCC_AHB_PERIPH_GPIOB,ENABLE);
GPIO_InitStruct.IT = GPIO_IT_NONE;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pins = GPIO_PIN_8 | GPIO_PIN_9;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_Init(CW_GPIOB, &GPIO_InitStruct);
}
void SystemRun(void)
{
static uint32_t curtick=0;
if(SystemGetTick()-curtick>=500)
{
GPIO_TogglePin(CW_GPIOB, GPIO_PIN_8 | GPIO_PIN_9);
curtick=SystemGetTick();
}
}
5、现象
|