第二篇 外设学习之驱动蜂鸣器

本文介绍了使用Hi3861开发板驱动有源蜂鸣器和LED灯的基本过程,包括电路连接、GPIO操作及代码示例。重点讲解了如何通过GPIO控制蜂鸣器的高电平触发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

系列文章目录

第一篇 外设学习之点亮LED灯
第二篇 外设学习之驱动蜂鸣器



前言

实验使用的开发板为Hi3861,使用的外设是有源蜂鸣器(高电平触发)


一、电路原理

三个引脚VCC,I/O,GND分别和Hi3861的3.3v,GPIO,GND连接。让GPIO输出高电平即可驱动蜂鸣器。

二、代码实现

1.编写步骤

1.初始化GPIO
GpioInit();
2.设置管脚功能–参数:引脚号,引脚功能
IoSetFunc(WIFI_IOT_IO_NAME_GPIO_6,WIFI_IOT_IO_FUNC_GPIO_2_GPIO);
3.设置管脚方向:引脚号,引脚方向
GpioSetDir(WIFI_IOT_IO_NAME_GPIO_6, WIFI_IOT_GPIO_DIR_OUT);
4.设置管脚高低电平
//设置引脚输出高低电平:引脚号,电平值(高电平点亮)
GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_6, 1);

2.示例代码

#include "ohos_init.h"
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"
// 延时函数需要用到的头文件
#include "unistd.h"
// 注:同一个IO的同一种电平只能输出给一个设备。

//创建led_example函数
void buzzer_example(void)
{
    // 初始化GPIO
    GpioInit();
    // 设置IO管脚复用功能--参数:引脚号,引脚功能
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_6,WIFI_IOT_IO_FUNC_GPIO_2_GPIO);
    // 设置GPIO方向为输出:引脚号,引脚方向
    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_6, WIFI_IOT_GPIO_DIR_OUT);
    // 循环点亮10次led灯
    for (int i = 0; i < 10; i++)
    {
        //设置引脚输出高低电平:引脚号,电平值(高电平点亮)
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_6, 1);
        //延时10的6次方微秒,也就是1秒
        usleep(1000000);
        //低电平熄灭
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_6,0);
        // 延时1秒
        usleep(1000000);

    }
    // 循环闪烁后再点亮LED灯
    GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_6,1);
    
       
}
// 应用层功能初始化时调用led_example
APP_FEATURE_INIT(led_example);

总结

蜂鸣器和LED灯的代码基本一样,都是对一个GPIO引脚进行操作。蜂鸣器只是在硬件接线上需要多接一个引脚。

### STM32 接收信号并控制蜂鸣器发声 为了使STM32能够接收信号并通过无源蜂鸣器发出声音,需完成几个主要部分的工作:初始化GPIO端口用于连接传感器或其他信号源以获取输入信号;设置另一个GPIO作为输出来驱动蜂鸣器;编写程序逻辑处理接收到的数据,并据此生成适当频率的PWM波形去激励蜂鸣器。 #### GPIO 配置 在开始之前,确保已经安装好必要的开发环境(如Keil MDK或TrueSTUDIO),并且下载了官方库文件。接下来按照下面的方法配置相应的引脚: - **输入模式**:选择一个合适的引脚作为外部事件触发源,将其设定为浮空输入或者下拉/上拉输入方式。 - **输出模式**:挑选另外一个通用I/O用来向蜂鸣器发送脉冲宽度调制(PWM)信号,这里可以采用推挽输出形式提高驱动能力[^1]。 ```c // 初始化GPIOA第0号针脚为输入, 用于检测外部信号. void GPIO_Init_Input(void){ GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOA_CLK_ENABLE(); // 开启GPIOA时钟 /* Configure PA0 as input floating */ GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA,&GPIO_InitStruct); } // 初始化TIM2通道1对应的PA0为PWM功能. void TIM_PWM_Configuration(uint16_t freqHz,uint8_t dutyCyclePercent){ TIM_HandleTypeDef htim2; __HAL_RCC_TIM2_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); TIM_OC_InitTypeDef sConfigOC={0}; GPIO_InitTypeDef GPIO_InitStruct ={0}; // 设置定时器参数... } ``` #### 定时器 PWM 输出 利用硬件定时器产生周期性的方波是非常高效的做法之一,在此选用TIM2定时器配合其捕获比较单元CCU1实现PWM输出至指定的GPIO管脚。具体步骤如下所示: - 创建`htim2`句柄实例化对象; - 调整预分频系数Prescaler使得计数值达到期望范围之内; - 设定自动重装载值ARR从而决定载波周期Tcarrier=ARR/(fclk/PSC)+1; - 计算CCR寄存器内的捕捉/比较值对应于所希望得到的占空比Duty Cycle%=(CCR/ARR)*100%; - 启动向上计数模式下的PWM输出特性[^3]。 ```c /* Initialize TIM2 for generating a square wave on channel 1 (PA0). */ static void MX_TIM2_Init(void) { ... htim2.Instance = TIM2; htim2.Init.Prescaler = 7999uL; // f_tim_clk / (PSC+1)=1kHz htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 999uL; // ARR+1=1ms period at 1kHz frequency htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; if(HAL_TIM_PWM_Init(&htim2)!= HAL_OK){Error_Handler();} sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 499uL; // CCR=50%, i.e., Duty cycle is set to be half of the full scale sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.FastMode = TIM_OCFAST_DISABLE; if(HAL_TIM_PWM_ConfigChannel(&htim2,&sConfigOC,TIM_CHANNEL_1)!= HAL_OK){Error_Handler();} HAL_TIM_MspPostInit(&htim2); // Enable interrupt and configure NVIC settings here } ``` #### 中断服务例程 ISR 和回调函数 Callback Function 当监测到特定类型的边沿变化时,比如上升沿、下降沿或是双边沿,则会产生一次中断请求IRQ给CPU核心。此时可以在ISR内部执行简单的操作,诸如切换状态标志位stateFlag变量的状态,进而影响主循环里的决策流程走向。另外一种做法就是注册callback function关联到某类外设事件的发生之上,这样做的好处是可以让应用程序代码结构更为清晰整洁[^2]。 ```c extern "C" void EXTI0_IRQHandler(void){ HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); } void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){ static uint8_t stateFlag=LOW_LEVEL; if((GPIO_Pin==GPIO_PIN_0)&&(stateFlag!=HIGH_LEVEL)){ stateFlag=~stateFlag; if(stateFlag==HIGH_LEVEL){ // Start playing sound when high level detected Play_Sound_Tone(1000,50); // Frequency:1kHz ; Volume:mid-level }else{ Stop_Playing_Sound(); } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程coding

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值