二、STM32F407VET6使用定时器点灯

零、所需文件及环境 :


        1、第一章建立好的LED灯闪烁程序

        2、编译环境MDK5(KEIL5)   

        3、一个STM32F407VET6硬件

        4、一个下载器j-link 或 st-link等

        5.代码编辑器 Notepad++   (可以不要 用记事本也能编译  都是习惯的问题)

壹、复制LED灯闪烁程序
1.1 复制led灯闪烁程序并进行重命名

BSP_LED.h代码

2.1 仔细阅读参考手册找到GPIO寄存器地址,将一堆GPIO寄存器一层一层封装出来 方便控制 直接操作的是寄存器  可以自己写但没有必要,挨个核对寄存器地址时特别费时,所以我这里复制的 原子的sys.h里面的  将其添加进之前的BSP_LED.h里面   修改后的文件如图所示

#ifndef __BSP_LED_H
 
#define __BSP_LED_H
 
    #include "stm32f4xx.h"
//位带操作,实现51类似的GPIO控制功能
//具体实现思想,参考<<CM3权威指南>>第五章(87页~92页).M4同M3类似,只是寄存器地址变了.
//IO口操作宏定义
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr)) 
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum)) 
//IO口地址映射
#define GPIOA_ODR_Addr    (GPIOA_BASE+20) //0x40020014
#define GPIOB_ODR_Addr    (GPIOB_BASE+20) //0x40020414 
#define GPIOC_ODR_Addr    (GPIOC_BASE+20) //0x40020814 
#define GPIOD_ODR_Addr    (GPIOD_BASE+20) //0x40020C14 
#define GPIOE_ODR_Addr    (GPIOE_BASE+20) //0x40021014 
#define GPIOF_ODR_Addr    (GPIOF_BASE+20) //0x40021414    
#define GPIOG_ODR_Addr    (GPIOG_BASE+20) //0x40021814   
#define GPIOH_ODR_Addr    (GPIOH_BASE+20) //0x40021C14    
#define GPIOI_ODR_Addr    (GPIOI_BASE+20) //0x40022014     

#define GPIOA_IDR_Addr    (GPIOA_BASE+16) //0x40020010 
#define GPIOB_IDR_Addr    (GPIOB_BASE+16) //0x40020410 
#define GPIOC_IDR_Addr    (GPIOC_BASE+16) //0x40020810 
#define GPIOD_IDR_Addr    (GPIOD_BASE+16) //0x40020C10 
#define GPIOE_IDR_Addr    (GPIOE_BASE+16) //0x40021010 
#define GPIOF_IDR_Addr    (GPIOF_BASE+16) //0x40021410 
#define GPIOG_IDR_Addr    (GPIOG_BASE+16) //0x40021810 
#define GPIOH_IDR_Addr    (GPIOH_BASE+16) //0x40021C10 
#define GPIOI_IDR_Addr    (GPIOI_BASE+16) //0x40022010 
 
//IO口操作,只对单一的IO口!
//确保n的值小于16!
#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出 
#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //输入 

#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //输出 
#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //输入 

#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //输出 
#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //输入 

#define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //输出 
#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //输入 

#define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //输出 
#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //输入

#define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //输出 
#define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //输入

#define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //输出 
#define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //输入

#define PHout(n)   BIT_ADDR(GPIOH_ODR_Addr,n)  //输出 
#define PHin(n)    BIT_ADDR(GPIOH_IDR_Addr,n)  //输入

#define PIout(n)   BIT_ADDR(GPIOI_ODR_Addr,n)  //输出 
#define PIin(n)    BIT_ADDR(GPIOI_IDR_Addr,n)  //输入

#define CPU_LED PEout(1)

//定义一个宏 以后改起来方便只需要修改宏就可以
//根据实际情况选择哪一个口  我的硬件灯接的PE1
#define LED_PIN             GPIO_Pin_1
#define LED_GPIO_PORT       GPIOE                    
#define LED_GPIO_CLK        RCC_APB2Periph_GPIOE
 
 
//根据自己实际硬件定义  有的是输出高亮 有的是输出低亮
//GPIO_SetBits(LED_GPIO_PORT,LED_PIN);                               //输出高
//GPIO_ResetBits(LED_GPIO_PORT,LED_PIN);                               //输出低
 
#define CPU_LED_ON                  GPIO_ResetBits(LED_GPIO_PORT,LED_PIN)
#define CPU_LED_OFF                  GPIO_SetBits(LED_GPIO_PORT,LED_PIN)
    extern void BSP_LED_Init(void);
 
#endif
 

叁、编写BSP_TIMER.c与BSP_TIMER.h代码

3.1 进入USER/BSP文件夹下 复制BSP_LED文件夹改为BSP_TIMER 

3.2 进入USER/BSP/TIMER文件夹,修改文件名

3.3 打开BSP_TIMER.h修改为

#ifndef __BSP_TIMER_H
#define __BSP_TIMER_H
 
#include "stm32f4xx.h" 
 
 
extern void BSP_TIMER_Init(uint16_t arr,uint16_t psc);
 
 
#endif 
 
 
 

3.4 打开BSP_TIMER.c修改为

#include "BSP_TIMER.h"
#include "BSP_LED.h"
 
 
 
#define BSP_TIMERx                TIM3
#define BSP_TIMERx_IRQn           TIM3_IRQn
#define BSP_TIMERx_Priority       5                       //中断函数接口(见stm32f10x_it.c)
#define BSP_TIMERx_IRQHandler     TIM3_IRQHandler
#define BSP_TIMERx_CLK            RCC_APB1Periph_TIM3
 
//F1定时器中断时间 = (Period +1)*(Prescaler+1)/84M
//(8400 - 1+1)*(1000 - 1+1)/84M = 0.1S
 
//100ms定时器
void BSP_TIMER_Init(uint16_t arr,uint16_t psc)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    
    RCC_APB1PeriphClockCmd(BSP_TIMERx_CLK,ENABLE);  ///使能TIM3时钟
    
    TIM_TimeBaseInitStructure.TIM_Prescaler=psc;  //定时器分频
    TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
    TIM_TimeBaseInitStructure.TIM_Period=arr;   //自动重装载值
    TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; 
    
    TIM_TimeBaseInit(BSP_TIMERx,&TIM_TimeBaseInitStructure);
    
    TIM_ITConfig(BSP_TIMERx,TIM_IT_Update,ENABLE); //允许定时器3更新中断
    TIM_Cmd(BSP_TIMERx,ENABLE);
    
    NVIC_InitStructure.NVIC_IRQChannel=BSP_TIMERx_IRQn; //定时器3中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=BSP_TIMERx_Priority; //抢占优先级1
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; //子优先级3
    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
    NVIC_Init(&NVIC_InitStructure);    
}
 
 
/* 定时器中断向量 */
void BSP_TIMERx_IRQHandler(void)
{
    if(TIM_GetITStatus(BSP_TIMERx ,TIM_IT_Update)==SET) //溢出中断
    {
        CPU_LED = ~CPU_LED;
    }
    TIM_ClearITPendingBit(BSP_TIMERx ,TIM_IT_Update);  //清除中断标志位
}
 
 
 


 

肆、打开工程,将BSP_TIMER.c添加入工程并添加头文件路径

伍、修改main函数

#include "stm32f4xx.h"

#include "BSP_DELAY.h"
#include "BSP_LED.h"
#include "BSP_TIMER.h"

int main(void)
{
//    BSP_DELAY_Init(168);           //延时初始化
    BSP_LED_Init();              //LED初始化    
    BSP_TIMER_Init(8400,1000);

    while(1)
    {

//        CPU_LED_ON;
//        BSP_DELAY_ms(500);
//        CPU_LED_OFF;
//        BSP_DELAY_ms(500);
        
    
    }
}

陆、编译下载运行

  • 11
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值