重点内容
STM32F407VGT芯片的操作
1、时钟配置
void SetSysClock(void){
// ——————– 设置HSE时钟 ——————–
// 设置时钟
// 使用外部时钟源作为HSE,禁止内部振荡器
// 使用有源晶振
CLEAR_BIT(RCC->CR, RCC_CR_HSEBYP);
// 启用HSE
SET_BIT(RCC->CR, RCC_CR_HSEON);
// 等待HSE准备好
while(!(RCC->CR&RCC_CR_HSERDY)){
;
}
// -------------------- 设置PLL系数 --------------------
// 外部时钟源8MHz,系统时钟168MHz
MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLM, PLL_M <<0);
MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLN, PLL_N <<6);
MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLP, (PLL_P/2-1) <<16);
MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ, PLL_Q <<24);
// 将HSE作为PLL的输入
SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC_HSE);
// 使能PLL
SET_BIT(RCC->CR, RCC_CR_PLLON);
// 等待PLL稳定
while(!(RCC->CR&RCC_CR_PLLRDY)){
;
}
// -------------------- 设置预分频 --------------------
// 设置AHB分频 1
MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_CFGR_HPRE_DIV1);
// 设置APB1分频 4
MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_CFGR_PPRE1_DIV4);
// 设置APB2分频 2
MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, RCC_CFGR_PPRE2_DIV2);
// -------------------- 设置FLASH读延迟时间 --------------------
// 正确设置FLASH延迟时间
FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
// 检查设置是否成功
if((FLASH->ACR & FLASH_ACR_LATENCY) != FLASH_ACR_LATENCY_5WS){
// 失败后将无处可去
return;
}
// -------------------- 选择时钟源 --------------------
// 选择PLL为时钟源
MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);
// 等待设置成功
while((RCC->CFGR & RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL){
;
}
}
2、基本定时器配置,我用的基本定时器中的第七个TIM7
①//配置延时寄存器
void Delay()
{
// SCB->AIRCR = 0x05FA0000 | 0x400; //中断优先级分组 抢占:响应=3:1
//打开TIM7时钟
SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM7EN);
// 写进预设值,//对时钟84M进行8400分频,使得计数频率为10k
WRITE_REG(TIM7->PSC,8399);
//定时一秒
WRITE_REG(TIM7->ARR,10000);
//清空计数器,作为计数的大小
WRITE_REG(TIM7->CNT,0);
//自动重装载预装载使能 ,ARPE TIMx_ARR 寄存器进行缓冲。
SET_BIT(TIM7->CR1,TIM_CR1_ARPE);
// 使能计时器
SET_BIT(TIM7->CR1,TIM_CR1_CEN);
}
②配置中断计时器
// 配置中断寄存器
void Configure_Timer()
{
//中断优先级分组 抢占:响应=3:1
SCB->AIRCR = 0x05FA0000 | 0x400;
//打开TIM7时钟
SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM7EN);
// 写进预设值,//对时钟84M进行8400分频,使得计数频率为10k
WRITE_REG(TIM7->PSC,8399);
//定时一秒
WRITE_REG(TIM7->ARR,10000);
//清空计数器,作为计数的大小
WRITE_REG(TIM7->CNT,0);
//自动重装载预装载使能 ,ARPE TIMx_ARR 寄存器进行缓冲。
SET_BIT(TIM7->CR1,TIM_CR1_ARPE);
//使能中断
SET_BIT(TIM7->DIER,TIM_DIER_UIE);
//配置定时器7的优先级
NVIC->IP[55] = 0x80;
//中断使能寄存器,需要配置相关信息
NVIC->ISER[1] |= (1<<(55-32));
// 使能开始计时
SET_BIT(TIM7->CR1,TIM_CR1_CEN);
}
// 处理中断程序,内部函数,直接自行调用
void TIM7_IRQHandler(void)
{
if(TIM7->SR&TIM_SR_UIF)
{
//中断后,处理程序,i是全局变量,自行设计
i++;
if(i%2){
WRITE_REG(GPIOF->ODR,~GPIO_ODR_ODR_6);
} else
WRITE_REG(GPIOF->ODR,~GPIO_ODR_ODR_7);
//中断使能,值为0时,为发生更新
TIM7->SR &= ~(TIM_SR_UIF);
}
这里写代码片
#include <stm32f4xx.h>
void Delay();
void Configure_Timer();
void LightToOff();
int i =1;
int main ()
{
//使能GPIOF
SET_BIT(RCC->AHB1ENR,RCC_AHB1ENR_GPIOFEN);
//使能系统配置控制器时钟
SET_BIT(RCC->APB2ENR,RCC_APB2ENR_SYSCFGEN);
//输出PF6
SET_BIT(GPIOF->MODER,GPIO_MODER_MODER6_0);
//输出PF7
SET_BIT(GPIOF->MODER,GPIO_MODER_MODER7_0);
//拉高6和7引脚,通过ODR来操作
// SET_BIT(GPIOF->PUPDR,GPIO_PUPDR_PUPDR7_0);
// SET_BIT(GPIOF->PUPDR,GPIO_PUPDR_PUPDR6_0);
WRITE_REG(GPIOF->ODR,GPIO_ODR_ODR_7|GPIO_ODR_ODR_6);
// 拉低7和6引脚
WRITE_REG(GPIOF->ODR,~(GPIO_ODR_ODR_7|GPIO_ODR_ODR_6));
//利用延时做流水灯
/* while(1){
Delay();
LightToOff();
}*/
//利用中断做流水灯
Configure_Timer();
while(1){
}
}
//配置延时寄存器
void Delay()
{
// SCB->AIRCR = 0x05FA0000 | 0x400; //中断优先级分组 抢占:响应=3:1
//打开TIM7时钟
SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM7EN);
// 写进预设值,//对时钟84M进行8400分频,使得计数频率为10k
WRITE_REG(TIM7->PSC,8399);
//定时一秒
WRITE_REG(TIM7->ARR,10000);
//清空计数器,作为计数的大小
WRITE_REG(TIM7->CNT,0);
//自动重装载预装载使能 ,ARPE TIMx_ARR 寄存器进行缓冲。
SET_BIT(TIM7->CR1,TIM_CR1_ARPE);
// 使能计时器
SET_BIT(TIM7->CR1,TIM_CR1_CEN);
}
void LightToOff()
{
while(!TIM7->SR&TIM_SR_UIF){
;
}
TIM7->SR &= ~(TIM_SR_UIF);
TIM7->CR1 &= ~(TIM_CR1_CEN); //禁止计数器
i++;
if(i%2){
WRITE_REG(GPIOF->ODR,~GPIO_ODR_ODR_6);
} else{
WRITE_REG(GPIOF->ODR,~GPIO_ODR_ODR_7);
}
}
// 配置中断寄存器
void Configure_Timer()
{
//中断优先级分组 抢占:响应=3:1
SCB->AIRCR = 0x05FA0000 | 0x400;
//打开TIM7时钟
SET_BIT(RCC->APB1ENR, RCC_APB1ENR_TIM7EN);
// 写进预设值,//对时钟84M进行8400分频,使得计数频率为10k
WRITE_REG(TIM7->PSC,8399);
//定时一秒
WRITE_REG(TIM7->ARR,10000);
//清空计数器,作为计数的大小
WRITE_REG(TIM7->CNT,0);
//自动重装载预装载使能 ,ARPE TIMx_ARR 寄存器进行缓冲。
SET_BIT(TIM7->CR1,TIM_CR1_ARPE);
//使能中断
SET_BIT(TIM7->DIER,TIM_DIER_UIE);
//配置定时器7的优先级
NVIC->IP[55] = 0x80;
//中断使能寄存器,需要配置相关信息
NVIC->ISER[1] |= (1<<(55-32));
// 使能开始计时
SET_BIT(TIM7->CR1,TIM_CR1_CEN);
}
// 处理中断程序
void TIM7_IRQHandler(void)
{
if(TIM7->SR&TIM_SR_UIF)
{
i++;
if(i%2){
WRITE_REG(GPIOF->ODR,~GPIO_ODR_ODR_6);
} else
WRITE_REG(GPIOF->ODR,~GPIO_ODR_ODR_7);
//中断使能,值为0时,为发生更新
TIM7->SR &= ~(TIM_SR_UIF);
}
}