点击查看代码
/**
******************************************************************************
* @file main.c
* @author
* @version
* @date 2024/06/28
* @brief 实现利用基本定时器TIM6实现定时500ms,每隔500ms触发一次中断,实现控制
蜂鸣器的鸣叫
******************************************************************************
**/
#include "stm32f4xx.h" //必须包含
//LED的初始化
void LED_Config()
{
//1.定义GPIO外设的结构体变量
GPIO_InitTypeDef GPIO_InitStructure;
//2.打开GPIOF端口的时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
//3.配置PF9引脚为输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
//4.对GPIOF端口进行初始化
GPIO_Init(GPIOF, &GPIO_InitStructure);
GPIO_SetBits(GPIOF,GPIO_Pin_9);//LED不亮
}
//BEEP的初始化
void BEEP_Config()
{
//1.定义GPIO外设的结构体变量
GPIO_InitTypeDef GPIO_InitStructure;
//2.打开GPIOF端口的时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
//3.配置PF9引脚为输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
//4.对GPIOF端口进行初始化
GPIO_Init(GPIOF, &GPIO_InitStructure);
GPIO_ResetBits(GPIOF,GPIO_Pin_8);//BEEP默认不响
}
//延时微秒 注意:Systick是24bit的递减计数器 约等于798915us,所以参数不可以超过这个值
void delay_us(u32 nus)
{
SysTick->CTRL = 0; // 向控制状态寄存器中写入0,目的关闭系统嘀嗒定时器
SysTick->LOAD = (nus * 21) - 1;// 指的是计数次数,定时时间 = 计数次数 * 计数周期
SysTick->VAL = 0; // 清除当前数值寄存器的值
SysTick->CTRL = 1; // 开启了定时器,并且定时器的时钟源选择了21MHZ--> 计数周期 = 1/21us
while ((SysTick->CTRL & 0x00010000)==0);//等待延时时间到达
SysTick->CTRL = 0; // 向控制状态寄存器中写入0,目的关闭系统嘀嗒定时器
}
//延时毫秒 注意:Systick是24bit的递减计数器 约等于798ms,所以参数不可以超过这个值
void delay_ms(u32 nms)
{
SysTick->CTRL = 0; // 向控制状态寄存器中写入0,目的关闭系统嘀嗒定时器
SysTick->LOAD = (nms * 21*1000) - 1;// 指的是计数次数,定时时间 = 计数次数 * 计数周期
SysTick->VAL = 0; // 清除当前数值寄存器的值
SysTick->CTRL = 1; // 开启了定时器,并且定时器的时钟源选择了21MHZ--> 计数周期 = 1/21us
while ((SysTick->CTRL & 0x00010000)==0);//等待延时时间到达
SysTick->CTRL = 0; // 向控制状态寄存器中写入0,目的关闭系统嘀嗒定时器
}
//延时秒
void delay_s(u32 ns)
{
while(ns--)
{
delay_ms(500);
delay_ms(500);
}
}
//TIM6的中断服务程序
void TIM6_DAC_IRQHandler(void)
{
//判断中断是否发生
if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET)
{
GPIO_ToggleBits(GPIOF,GPIO_Pin_8);//BEEP每隔500ms电平翻转一次
//清除TIM6的中断标志
TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
}
}
//TIM6的初始化
void TIM6_Config()
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//1.打开TIM6的时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
//2.定义结构体变量并对结构体变量的成员进行赋值
TIM_TimeBaseStructure.TIM_Prescaler = 8400-1; //预分频值,TIM6的时钟是84MHZ,所以可以降低频率 100us计数一次
TIM_TimeBaseStructure.TIM_Period = 5000-1; //计数次数,这个值会写入自动重载寄存器 100us * 5000 = 500ms
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数模式,基本定时器TIM6和TIM7只允许递增计数
//3.对定时器进行初始化
TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
//4.配置NVIC外设+对NVIC外设进行初始化
NVIC_InitStructure.NVIC_IRQChannel = TIM6_DAC_IRQn; //中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//5.选择TIM6的中断源 基本定时器TIM6和TIM7只能选择更新中断
TIM_ITConfig(TIM6,TIM_IT_Update , ENABLE);
//6.打开定时器TIM6
TIM_Cmd(TIM6, ENABLE);
}
int main()
{
//1.硬件的初始化
LED_Config();
BEEP_Config();
TIM6_Config();
while(1)
{
}
}