赞
踩
是原理图上触摸按键、继电器、LED 灯三部分电路。
注意;按键一般为高电平,按下后为低电平,在配置时就要注意是下降沿触发。
第一行:读管脚状态,要么低电平,要么高电平。
第二行:写管脚状态,写高或者写低。
第三行:选择一个管脚,状态取反。
第四行:锁定管脚,进行保护状态,不能写了。
第五行:中断处理函数,软件自动生成的,后续讲解。
第六行:外部中断的回调函数,其中的变量是指示具体管脚,是具体管脚的回调函数。(如PA~PA15共用一个外部中断,如上图,共用一个回调函数,通过变量去判断具体是哪一个管脚引起的中断)
推挽输出,默认低电平,使其刚开始处于断开的模式。
一般为高电平,按下后为低电平,故配置成下降沿触发。
(如果配上升沿触发,单击按键松开才触发,长按不触发;如果配置成均触发,则单击触发两次,所以触发方式的配置和硬件紧密相连)
注意不是配置成输入模式,而是配置成中断模式,后面软件编写也是启动中断的功能。
注意当按键 1 配置成中断时,与其共使用一个外部中断的其他引脚配置成的中断就会自动消失
在 main.c 中代码都是一样的,但是代码调用的代码是不一样的,不论是软件自动生成的初始化代码,还是我们自己编写的代码。
MyInit.Peripheral_Set() 自定义初始化代码如下:
- static void Peripheral_Set()
- {
- printf("----此程序实现触摸按键单击与长按功能----\r\n");
- printf("Initialization completed, system startup!\r\n");
- printf("Software version is V%.1f\r\n\r\n",SoftWare_Version);
-
- printf("等待触摸按键:\r\n\r\n");
- }
说明:
单击翻转 LED 灯的状态,长按 ≥2S 翻转两次 LED 灯的状态,两次间隔 200ms。
触摸按键
上电后,无源蜂鸣器发出声音,通过触摸按键关闭或打开蜂鸣器。
无源蜂鸣器没有振动源,驱动需要 PWM 波来驱动,通过改变 PWM 波的频率来改变蜂鸣器的声音。
英文全称 Pulse-Width Modulation,脉冲宽度调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,通过调占空比调节光的强度、声音、电机等。本次是通过通用定时器进行频率调节。
本次是通过通用定时器来调节 PWM 的频率,TIMx 器是一个通过可编程预分频器驱动的 16 位自动装载计数器构成。它适用于多种场合,包括测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和 PWM)。使用定时器预分频器和 RCC 时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整,每个定时器都是完全独立的,没有互相共享任何资源,可以一起同步操作,包含:
在向上计数模式中,计数器从0计数到自动加载值(TIMx_ARR计数器的内容),然后重新从0开始计数并且产生一个计数器溢出事件。这样的计数方式更加灵活,在计数中间时可以和另一个设定的值进行比较,进行其他需要的操作。
脉冲宽度调制模式可以产生一个由 TIMx_ARR 寄存器确定频率、由TIMx_CCRx寄存器确定占空 比的信号。
这些是定时器关于PWM的函数:
蜂鸣器的引脚为 PA8 ,在 Cubemx 中 PA8 只能设置成为定时器 1,定时器 1 是高级定时器,具有上面所讲的通用定时器的功能,我们也只使用通用定时器的功能,其他的功能不展开讲解和使用。
Clock Source 时钟源:选择使用内部时钟
Channel1:输出 PWM 波
注意在这里设置完之后,引脚可能会自动跳变到默认引脚,这里是 PE9,还需要手动重新设置为我们蜂鸣器的 PA8。
系统时钟 72M,AHB2 的时钟频率也是 72M ,故 PA8 的初始时钟也是 72M ,通过预分频器企图达到的目标评率为 1M 。
预分频器可以进行 0~65535 分频(因为零也算,所以后面要加一),计算预分频器具体分频数 X 的公式如下:
所以在软件配置的值为:72000000/1000000-1(目标频率是 1M )
Counter Mode 计数模式:向上
Counter Period 自动重装定时器:设置 PWM 波的频率
频率=预分频器频率/次数=1000000/1000=1000HZ
Internal Clock Division 内部时钟分频器:不需要
Repetition Counter 重复计数器:高级定时器功能,此处不需要
auto-reload preload 自动重新装载:必须使能,由于后续需要改变蜂鸣器的音色,就需要改变频率,该变频率就需要重装载。如果没有使能,后续即使改变 ARR 值夜不会重新装载进去。
这里主要是设置占空比。
Mode 模式:PWM 模式 1
Pulse 脉冲(16 位值):500,这个值就是 CCR
(你可以这么理解,通过预分频器最后的时钟频率是1M,但是我还要自己更加灵活的控制PWM的频率,灵机一动想到了计数的方式。
所以才有了通过上面的设置让计数 1000 次(ARR),周期就变成了 1M×1000 =1ms 。
就这么利用一下这个计数,未免也太浪费资源了吧,既然它在向上计数,那就在中间设计一个比较值 CCR,利用 CCR 来调节占空比,小于 CCR 时 PWM 波输出高电平,大于 CCR 是 PWM 波输出低电平。)
Qutput compare preload 输出比较预加载:使能(可以改变占空比,而不是固定占空比)
极速模式:关闭
CH 极性:高(小于 CCR 的状态)
状态:重置
每隔一毫秒中断一次,占空比为 50% 。
Buzzer.c:控制蜂鸣器的开启,并记录其状态。
Timer6.c:通过定时器 6 改变频率,发出不同的声音。
触摸按键:触发中断关闭或者打开蜂鸣器。
main.c → System.c
运行函数中没有内容,因为这一次是通过按键中断来改变声音。
Buzzer.h
Buzzer.c
- #include "MyApplication.h"
-
-
- static void Buzzer_ON(void);
- static void Buzzer_OFF(void);
-
- //定义结构体
- Buzzer_t Buzzer =
- {
- OFF_Status,//默认蜂鸣器初始状态是关闭
-
- Buzzer_ON,
- Buzzer_OFF
- //两个函数赋给函数指针,函数如下
- };
-
-
- static void Buzzer_ON(void)//打开蜂鸣器
- {
- Buzzer.Status = ON_Status;//更新一下状态为打开状态
- HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);//通过这个HAL库函数打开定时器(定时器1,通道1)
- }
-
-
- static void Buzzer_OFF(void)//关闭蜂鸣器,理论同上
- {
- Buzzer.Status = OFF_Status;
- HAL_TIM_PWM_Stop(&htim1,TIM_CHANNEL_1);
- }
上电初始化只是打开蜂鸣器
也是在 CallBack.c 文件中,共有三个参数:
- #include "MyApplication.h"
-
- /*
- * @name HAL_TIM_PeriodElapsedCallback
- * @brief 定时器中断回调函数
- * @param *htim -> 处理定时器的结构体指针
- * @retval None
- */
- void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
- {
- static uint8_t Fre_Cnt = 0;
-
- if(htim->Instance == htim6.Instance)
- {
- //程序支持运行,指示灯间隔1s闪烁
- if(++Timer6.usMCU_Run_Timer >= TIMER0_1S)
- {
- Timer6.usMCU_Run_Timer = 0;
-
- LED.LED_Flip(LED1);
- }
-
- //控制PWM的频率长度与大小
- if(Fre_Cnt++ >= 2)
- {
- Fre_Cnt = 0;
-
- //定时器时钟 = 1MHz
- PWM频率 = 1/((1/1000000)*ARR) = 1000000/ARR
- //ARR = 250, PWM频率为4KHz
- //ARR = 500, PWM频率为2KHz
- //ARR = 1000,PWM频率为1KHz
- //ARR = 2000,PWM频率为0.5KHZ
- TIM1->ARR -= 10;
- if(TIM1->ARR <= 500)
- TIM1->ARR = 2000;
-
- //设置占空比为50%
- TIM1->CCR1 = TIM1->ARR / 2;
- }
- }
- }
只控制蜂鸣器打开或者关闭,按下按键就翻转蜂鸣器的状态。
- #include "MyApplication.h"
-
- void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
- {
- if(GPIO_Pin == KEY1_Pin)
- {
- LED.LED_Flip(LED2);
-
- //控制蜂鸣器开关
- if(Buzzer.Status == ON_Status)
- {
- Buzzer.OFF();
- }
- else
- {
- Buzzer.ON();
- }
- }
- }
等我明天(8.3)画出来,等我!
PWM波驱动蜂鸣器
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。