STM32F407VGT芯片的操作之流水灯

重点内容
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); 


  }  
}  

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值