#define ZERO_ADDR ((void*)0)
void bsp_init(void)
{
/* 配置flash预取缓冲器*/
#if (PREFETCH_ENABLE != 0)
#if defined(STM32F101x6) || defined(STM32F101xB) || defined(STM32F101xE) || defined(STM32F101xG) || \
defined(STM32F102x6) || defined(STM32F102xB) || \
defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || \
defined(STM32F105xC) || defined(STM32F107xC)
/*
* 开启预取缓冲器
* 当电源电压小于2.1V时必须关闭
*/
FLASH->ACR |= FLASH_ACR_PRFTBE;
#endif
#endif /* PREFETCH_ENABLE */
/*
* 设置中断优先级分组为4
* 4bits均为抢占优先级
*/
SCB->AIRCR |= (uint32_t)(0x05FA0000 | ((uint32_t)(NVIC_PRIORITYGROUP_4&0x07)<<8));
}
void bsp_system_init(void)
{
/* 外部高速时钟使能 */
RCC->CR |= RCC_HSE_ON;
/* 等待外部高速时钟就绪 */
while((RCC->CR&RCC_CR_HSERDY) == RESET);
/*
锁相环关闭
锁相环在关闭状态时,才可对以下位进行写操作
RCC_CFGR_PLLXTPRE
RCC_CFGR_PLLSRC
RCC_CFGR_PLLMULL
*/
RCC->CR &= ~RCC_CR_PLLON;
/* 等待锁相环关闭完成 */
while((RCC->CR&RCC_CR_PLLRDY) != RESET);
/* 外部高速时钟不分频作为锁相环时钟源 */
RCC->CFGR = ( \
((RCC->CFGR)&(~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE))) | \
(RCC_PLLSOURCE_HSE | RCC_HSE_PREDIV_DIV1) \
);
/* 锁相环时钟9倍频输出 */
RCC->CFGR = (((RCC->CFGR)&(~RCC_CFGR_PLLMULL)) | RCC_CFGR_PLLMULL9);
/* 锁相环使能 */
RCC->CR |= RCC_CR_PLLON;
/* 等待锁相环就绪 */
while((RCC->CR&RCC_CR_PLLRDY) == RESET);
/*
设置flash等待周期,否则程序会跑飞
FLASH_LATENCY_0,0 < SYSCLK <= 24MHz
FLASH_LATENCY_1,24 < SYSCLK <= 48MHz
FLASH_LATENCY_2,48 < SYSCLK <= 72MHz
*/
FLASH->ACR = ((FLASH->ACR&(~FLASH_ACR_LATENCY)) | (FLASH_LATENCY_2));
/* 锁相环倍频输出时钟作为系统时钟源 */
RCC->CFGR = (((RCC->CFGR)&(~RCC_CFGR_SW)) | RCC_SYSCLKSOURCE_PLLCLK);
/* 等待系统时钟切换完成 */
while(((RCC->CFGR & RCC_CFGR_SWS)>>2) != RCC_SYSCLKSOURCE_PLLCLK);
/*
设置各总线时钟
系统时钟2分频作为AHB时钟
AHB时钟不分频作为APB1时钟
AHB时钟不分频作为AHB2时钟
*/
RCC->CFGR = ( \
((RCC->CFGR)&(~(RCC_CFGR_HPRE | RCC_CFGR_PPRE1 | RCC_CFGR_PPRE2))) | \
(RCC_SYSCLK_DIV2 | RCC_HCLK_DIV1 | RCC_HCLK_DIV1) \
);
}
void bsp_tim2_init(uint16_t psc, uint16_t arr)
{
/* TIM2时钟使能 */
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
/* 设置抢占优先级为1 */
NVIC->IP[TIM2_IRQn] |= 0x10;
/* TIM2中断使能 */
NVIC->ISER[(((uint32_t)TIM2_IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)TIM2_IRQn) & 0x1FUL));
/* 重装值 */
TIM2->ARR = arr;
/* 预分频数 */
TIM2->PSC = psc;
/* 向上计数模式、边沿对齐,不分频,TIMx->ARR的值不装入缓冲器 */
TIM2->CR1 = ( \
((TIM2->CR1) & (~(TIM_CR1_DIR | TIM_CR1_CMS | TIM_CR1_CKD))) | \
((TIM_COUNTERMODE_UP | TIM_CLOCKDIVISION_DIV1) & (~TIM_CR1_ARPE)) \
);
/* 初始化计数器,产生一个更新事件 */
TIM2->EGR |= TIM_EGR_UG;//0x00000001;
/* 允许更新中断 */
TIM2->DIER |= TIM_IT_UPDATE;
/* 计数器使能 */
TIM2->CR1 |= TIM_CR1_CEN;
}
void TIM2_IRQHandler(void)
{
/* 判断更新中断标志位 */
if (((TIM2->SR & TIM_FLAG_UPDATE) == TIM_FLAG_UPDATE))
{
/* 判断更新中断使能位 */
if ((TIM2->DIER & TIM_IT_UPDATE) == TIM_IT_UPDATE)
{
/* 清更新中断标志位 */
TIM2->SR &= ~TIM_IT_UPDATE;
/* 中断回调函数 */
HAL_TIM_PeriodElapsedCallback(ZERO_ADDR);
}
}
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/* 计时时间到达后要做的操作 */
}