学习硬件测试04:触摸按键+PWM 驱动蜂鸣器+数码管(P62~P67、P71、P72) ...

  金牌会员 | 2024-8-4 07:49:36 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 975|帖子 975|积分 2925

一、触摸按键

1.1理论解说

1.1.1实验现象


  • 触摸按键 1 单击与长按,控制 LED1;
  • 触摸按键 2 单击与长按,控制 LED2;
  • 触摸按键 3 单击与长按,控制 LED3;
  • 触摸按键 4 单击与长按,控制继电器;
1.1.2硬件电路

是原理图上触摸按键、继电器、LED 灯三部分电路。
留意;按键一般为高电平,按下后为低电平,在设置时就要留意是降落沿触发。
1.1.3外部停止



1.1.4HAL库函数


第一行:读管脚状态,要么低电平,要么高电平。
第二行:写管脚状态,写高大概写低。
第三行:选择一个管脚,状态取反。
第四行:锁定管脚,举行保护状态,不能写了。
第五行:停止处理函数,软件主动生成的,后续解说。
第六行:外部停止的回调函数,其中的变量是指示详细管脚,是详细管脚的回调函数。(如PA~PA15共用一个外部停止,如上图,共用一个回调函数,通过变量去判断详细是哪一个管脚引起的停止)
1.2初始化

1.2.1继电器初始化

推挽输出,默认低电平,使其刚开始处于断开的模式。

1.2.2触摸按键初始化

一般为高电平,按下后为低电平,故设置成降落沿触发。
(假如配上升沿触发,单击按键松开才触发,长按不触发;假如设置成均触发,则单击触发两次,以是触发方式的设置和硬件精密相连)
留意不是设置成输入模式,而是设置成停止模式,背面软件编写也是启动停止的功能。
留意当按键 1 设置成停止时,与其共使用一个外部停止的其他引脚设置成的停止就会主动消散 


1.2.3设置按键的停止


1.3编程

在 main.c 中代码都是一样的,但是代码调用的代码是不一样的,岂论是软件主动生成的初始化代码,照旧我们自己编写的代码。

MyInit.Peripheral_Set() 自定义初始化代码如下:
  1. static void Peripheral_Set()
  2. {
  3.         printf("----此程序实现触摸按键单击与长按功能----\r\n");
  4.         printf("Initialization completed, system startup!\r\n");
  5.         printf("Software version is V%.1f\r\n\r\n",SoftWare_Version);
  6.        
  7.         printf("等待触摸按键:\r\n\r\n");
  8. }
复制代码
阐明:

  • 代码比力灵活,长按的时间可以自由设定。
  • 单击的时间也可以自由设定,可以不是10ms检查一次,可以是5ms检查一次,用户就不用等候那么长的时间。
  • 本测试中按键式停止,而且是不影响其他停止的运行大概被影响,当有别的停止并不会影响该停止检查是不是长按/ 单击的程序。
  • 留意上面说的别的停止,以及在其他任何项目中的一般停止,都要遵照“停止快进快出”的原则,运行几十微秒~几百微秒,问题都不大。
1.4实验现象

单击翻转 LED 灯的状态,长按 ≥2S 翻转两次 LED 灯的状态,两次隔断 200ms。
     触摸按键
  二、PWM 驱动蜂鸣器

2.1理论解说

2.1.1程序功能

上电后,无源蜂鸣器发作声音,通过触摸按键关闭或打开蜂鸣器。
2.1.2无源蜂鸣器

无源蜂鸣器没有振动源,驱动需要 PWM 波来驱动,通过改变 PWM 波的频率来改变蜂鸣器的声音。
2.1.3 PWM

英文全称 Pulse-Width Modulation,脉冲宽度调制,是使用微处理器的数字输出来对模拟电路举行控制的一种非常有效的技能,通过调占空比调节光的强度、声音、电机等。本次是通过通用定时器举行频率调节。
2.1.4通用定时器 TIMx

本次是通过通用定时器来调节 PWM 的频率,TIMx 器是一个通过可编程预分频器驱动的 16 位主动装载计数器构成。它适用于多种场合,包括测量输入信号的脉冲长度(输入捕捉)大概产生输出波形(输出比力和 PWM)。使用定时器预分频器和 RCC 时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调解,每个定时器都是完全独立的,没有互相共享任何资源,可以一起同步操作,包罗:


  • 计数器寄存器(TIMx_CNT)
  • 预分频器寄存器 (TIMx_PSC)
  • 主动装载寄存器 (TIMx_ARR)

2.1.5计数模式

在向上计数模式中,计数器从0计数到主动加载值(TIMx_ARR计数器的内容),然后重新从0开始计数而且产生一个计数器溢出变乱。如许的计数方式更加灵活,在计数中间时可以和另一个设定的值举行比力,举行其他需要的操作。
2.1.6 PWM模式

脉冲宽度调制模式可以产生一个由 TIMx_ARR 寄存器确定频率由TIMx_CCRx寄存器确定占空 比的信号

2.1.7HAL库函数


这些是定时器关于PWM的函数:

  • 上面4个是:初始化函数,不用我们写
  • 第4个:DMA功能,没用到
  • 第3个:停止,没用到
  • 第2个:启动、克制输出功能,后续就是通过触摸按键调用这两个函数打开大概关闭报警。
2.2软件初始化


2.2.1 框1

蜂鸣器的引脚为 PA8 ,在 Cubemx 中 PA8 只能设置成为定时器 1,定时器 1 是高级定时器,具有上面所讲的通用定时器的功能,我们也只使用通用定时器的功能,其他的功能不睁开解说和使用。
2.2.2 框2

Clock Source 时钟源:选择使用内部时钟
Channel1:输出 PWM 波
留意在这里设置完之后,引脚可能会主动跳变到默认引脚,这里是 PE9,还需要手动重新设置为我们蜂鸣器的 PA8。
2.2.3 框3

(1)预分频器


系统时钟 72M,AHB2 的时钟频率也是 72M ,故 PA8 的初始时钟也是 72M ,通过预分频器企图到达的目标评率为 1M 。
预分频器可以举行 0~65535 分频(因为零也算,以是背面要加一),计算预分频器详细分频数 X 的公式如下:


以是在软件设置的值为:72000000/1000000-1(目标频率是 1M )
(2)其他

Counter Mode 计数模式:向上
Counter Period 主动重装定时器:设置 PWM 波的频率
频率=预分频器频率/次数=1000000/1000=1000HZ


Internal Clock Division 内部时钟分频器:不需要
Repetition Counter 重复计数器:高级定时器功能,此处不需要
auto-reload preload 主动重新装载:必须使能,由于后续需要改变蜂鸣器的音色,就需要改变频率,该变频率就需要重装载。假如没有使能,后续即使改变 ARR 值夜不会重新装载进去。
2.2.4 框4

这里主要是设置占空比。

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 的状态)
状态:重置
2.2.5到达的状态

每隔一毫秒停止一次,占空比为 50% 。
2.3编程

2.3.1文件布局

Buzzer.c:控制蜂鸣器的开启,并记载其状态。
Timer6.c:通过定时器 6 改变频率,发出不同的声音。
触摸按键:触发停止关闭大概打开蜂鸣器。
2.3.2文件内容

(1)运行函数

常规的、根据软件生成的初始化代码。在 while(1) 循环函数中:
main.c → System.c 
运行函数中没有内容,因为这一次是通过按键停止来改变声音。

(2)蜂鸣器布局体

Buzzer.h

Buzzer.c
  1. #include "MyApplication.h"
  2. static void Buzzer_ON(void);
  3. static void Buzzer_OFF(void);
  4. //定义结构体
  5. Buzzer_t Buzzer =
  6. {
  7.         OFF_Status,//默认蜂鸣器初始状态是关闭
  8.        
  9.         Buzzer_ON,
  10.         Buzzer_OFF
  11.     //两个函数赋给函数指针,函数如下
  12. };
  13. static void Buzzer_ON(void)//打开蜂鸣器
  14. {
  15.         Buzzer.Status = ON_Status;//更新一下状态为打开状态
  16.         HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);//通过这个HAL库函数打开定时器(定时器1,通道1)
  17. }
  18. static void Buzzer_OFF(void)//关闭蜂鸣器,理论同上
  19. {
  20.         Buzzer.Status = OFF_Status;
  21.         HAL_TIM_PWM_Stop(&htim1,TIM_CHANNEL_1);
  22. }
复制代码
(3)Myinit.c

上电初始化只是打开蜂鸣器

(4)改变频率来改变音色

也是在 CallBack.c 文件中,共有三个参数:

  • f:频率 → 通过改变 ARR(1000:1ms;2000:2ms;500:0.5ms)
  • cnt:在某一频率是重复的时间长度
  1. #include "MyApplication.h"
  2. /*
  3.         * @name   HAL_TIM_PeriodElapsedCallback
  4.         * @brief  定时器中断回调函数
  5.         * @param  *htim -> 处理定时器的结构体指针
  6.         * @retval None      
  7. */
  8. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  9. {
  10.         static uint8_t Fre_Cnt = 0;
  11.        
  12.         if(htim->Instance == htim6.Instance)
  13.         {
  14.                 //程序支持运行,指示灯间隔1s闪烁
  15.                 if(++Timer6.usMCU_Run_Timer >= TIMER0_1S)
  16.                 {
  17.                         Timer6.usMCU_Run_Timer = 0;
  18.                        
  19.                         LED.LED_Flip(LED1);
  20.                 }
  21.                
  22.                 //控制PWM的频率长度与大小
  23.                 if(Fre_Cnt++ >= 2)
  24.                 {
  25.                         Fre_Cnt = 0;
  26.                        
  27.                         //定时器时钟 = 1MHz
  28.                         PWM频率 = 1/((1/1000000)*ARR) = 1000000/ARR  
  29.                         //ARR = 250, PWM频率为4KHz
  30.                         //ARR = 500, PWM频率为2KHz
  31.                         //ARR = 1000,PWM频率为1KHz
  32.                         //ARR = 2000,PWM频率为0.5KHZ
  33.                         TIM1->ARR -= 10;
  34.                         if(TIM1->ARR <= 500)
  35.                                 TIM1->ARR = 2000;
  36.                        
  37.                         //设置占空比为50%
  38.                         TIM1->CCR1 = TIM1->ARR / 2;
  39.                 }
  40.         }
  41. }
复制代码
(5)CallBack.c

只控制蜂鸣器打开大概关闭,按下按键就翻转蜂鸣器的状态。
  1. #include "MyApplication.h"
  2. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
  3. {
  4.         if(GPIO_Pin == KEY1_Pin)
  5.         {
  6.                 LED.LED_Flip(LED2);
  7.                
  8.                 //控制蜂鸣器开关
  9.                 if(Buzzer.Status == ON_Status)
  10.                 {
  11.                         Buzzer.OFF();
  12.                 }
  13.                 else
  14.                 {
  15.                         Buzzer.ON();
  16.                 }
  17.         }
  18. }
复制代码
2.3.3整体框架




2.3.4实验现象

     PWM波驱动蜂鸣器
  三、数码管

3.1数码管驱动 IC 手册阅读



3.2编程










免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表