main.c
/********************************************************
实验名称: 定时器中断实验
硬件模块: STM32F407核心板V2.0
硬件接线:
实验现象: 由定时器完成8个LED灯不同频率的闪烁。
********************************************************/
#include "stm32f4xx.h"
#include "delay.h"
#include "led.h"
#include "timer.h"
int main(void)
{
//使用中断,配置优先级组别0
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
Delay_Init(); //延时初始化
LED_Hardware_Init(); //LED初始化
TIM3_Hardware_Init(1000-1,84-1); //定时器3初始化中断的时间长度为1ms
/*************************************************************************
定时器计算公式为:
单位时间(1s)/最大频率(84000000)*分频系数(84)*计数/重装值(1000)=0.001s
即1ms中断一次。
*************************************************************************/
while(1)
{
}
}
delay.c
#include "stm32f4xx.h"
#include "delay.h"
static uint32_t fam_nus = 0;
static uint32_t fam_nms = 0;
/**********************************************************
功 能: 延时初始化
参 数: 无
返回值: 无
**********************************************************/
void Delay_Init(void)
{
//关闭计时、不触发中断、计数时钟为AHB/8
SysTick->CTRL = 0x0;
//微秒级初值
fam_nus = SystemCoreClock/8000000;
//毫秒级初值
fam_nms = fam_nus * 1000;
//计数器清零
SysTick->VAL = 0;
}
/**********************************************************
功 能: 毫秒级延时
参 数: ctr 微秒倍数、例如 ctr = 1 则 延时1ms
最大延时Delay_ms(798);
返回值: 无
**********************************************************/
void Delay_ms(uint16_t ctr)
{
uint32_t tick_flag = 0;
SysTick->LOAD = ctr * fam_nms;
SysTick->VAL = 0;
SysTick->CTRL = 0x01;
do
{
tick_flag = SysTick->CTRL;
}
while(!(tick_flag & (1<<16)) && (tick_flag & 0x01));
SysTick->CTRL = 0x00;
}
/**********************************************************
功 能: 微秒级延时
参 数: ctr 微秒倍数、例如 ctr = 1 则 延时1us
返回值: 无
**********************************************************/
void Delay_us(uint16_t ctr)
{
uint32_t tick_flag = 0;
//定时器初值
SysTick->LOAD = ctr*fam_nus;
//计数器清零
SysTick->VAL = 0;
//开启定时器
SysTick->CTRL |= 0x01;
do
{
//获取定时器状态
tick_flag = SysTick->CTRL;
}
//状态判断
while(!(tick_flag&(1<<16)) && (tick_flag&0x01));
//关闭计时
SysTick->CTRL = 0x00;
}
led.c
#include "stm32f4xx.h"
#include "delay.h"
#include "led.h"
/**********************************************************
功 能:LED初始化配置函数
参 数:无
返回值:无
**********************************************************/
void LED_Hardware_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//开启时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOF,ENABLE);
//选择端口
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
//输出模式
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
//推挽输出
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
//输出速度
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
//初始化配置
GPIO_Init(GPIOF,&GPIO_InitStructure);
//选择端口
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2
| GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
//初始化配置
GPIO_Init(GPIOC,&GPIO_InitStructure);
//初始化引脚后熄灭LED
GPIO_SetBits(GPIOF, GPIO_Pin_9 | GPIO_Pin_10);
GPIO_SetBits(GPIOC, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2
| GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5);
}
/****************************************************************
功 能:流水灯测试函数
参 数:无
返回值:无
*****************************************************************/
void LED_Test(void)
{
LED0(1); //点亮LED0
Delay_ms(200); //延时等待
LED0(0); //熄灭LED0
LED1(1); //点亮LED1
Delay_ms(200); //延时等待
LED1(0); //熄灭LED1
LED2(1); //点亮LED2
Delay_ms(200); //延时等待
LED2(0); //熄灭LED2
LED3(1); //点亮LED3
Delay_ms(200); //延时等待
LED3(0); //熄灭LED3
LED4(1); //点亮LED4
Delay_ms(200); //延时等待
LED4(0); //熄灭LED4
LED5(1); //点亮LED5
Delay_ms(200); //延时等待
LED5(0); //熄灭LED5
LED6(1); //点亮LED6
Delay_ms(200); //延时等待
LED6(0); //熄灭LED6
LED7(1); //点亮LED7
Delay_ms(200); //延时等待
LED7(0); //熄灭LED7
}
timer.c
#include "stm32f4xx.h"
#include "led.h"
#include "timer.h"
//全局变量,记录中断次数
uint16_t tim3_count = 0;
/**********************************************************
功 能:定时器3初始化配置函数
参 数: arr:自动重装值
psc:时钟预分频数
返回值:无
**********************************************************/
void TIM3_Hardware_Init(uint16_t arr,uint16_t psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//开启时钟
自己补充完整
//定时器初始化配置
自己补充完整
//选择中断通道
NVIC_InitStructure.NVIC_IRQChannel=自己补充完整;
//设置先占优先级
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x00;
//设置从优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x07;
//设置中断通道开启
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
//初始化配置中断优先级
NVIC_Init(&NVIC_InitStructure);
}
/**********************************************************
功 能:定时器3中断服务函数
参 数:无
返回值:无
**********************************************************/
void TIM3_IRQHandler(void)
{
//判断定时器是否溢出中断
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)
{
//记录中断次数,根据中断次数控制时间间隔完成不同功能
tim3_count++;
//16s执行一次 LED0状态翻转
自己补充完整
//8s执行一次 LED1状态翻转
自己补充完整
//4s执行一次 LED2状态翻转
自己补充完整
//2s执行一次 LED3状态翻转
自己补充完整
//1s执行一次 LED4状态翻转
自己 补充完整
//500ms执行一次 LED5状态翻转
自己补充完整
//250ms执行一次 LED6状态翻转
自己补充完整
//125ms执行一次 LED7状态翻转
自己补充完整
//记数清零,清零判断值取上述所有判断值的最小倍数
if(tim3_count == 16000 )
tim3_count = 0;
}
//清除定时器3中断标志位
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
}