描述
数字信号只有高/低电平两种状态。在连续的一段时间内,让同一个输出引脚上输出不同状态的高/低电平,可以实现输出方波信号。通过CPU控制GPIO引脚状态能够实现这种功能,但每次状态变化都需要CPU主动控制,会造成CPU计算资源的浪费。芯片的PWM模块无须CPU主动控制即可输出连续的方波信号。在有PWM模块的芯片中,CPU只需要向PWM模块设定方波的一些参数,就可以实现在没有CPU控制的情况下,输出一定频率的连续方波信号。另外,PWM模块可以控制输出方波在一个周期内高电平和低电平所占的时间比例,即占空比。
2. 板上资源
板上有两个蜂鸣器,都是接到GPIO9号端口上的。GPIO9又是和pwm0口复用的。
交通板和气体检测板上各有一个蜂鸣器,接到了GPIO9号口上。所以资源很清晰明了了,下一步就是开干写代码。
3. 代码逻辑
线程起来之后就是驱动蜂鸣器响,按下按键则蜂鸣器停止发声。
-
static void *PWMBeepTask(const char *arg)
-
{
-
while (1) {
-
if (g_beepState) {
-
IoTPwmStart(IOT_PWM_PORT_PWM0, 50, 4000);
-
} else {
-
IoTPwmStop(IOT_PWM_PORT_PWM0);
-
}
-
if (g_iState == 0xffff) {
-
g_iState = 0;
-
break;
-
}
-
}
-
}
-
-
static void OnButtonPressed(const char *arg)
-
{
-
(void) arg;
-
g_beepState = !g_beepState;
-
printf("PRESS_KEY!n");
-
g_iState++;
-
}
-
-
static void StartPWMBeepTask(void)
-
{
-
osThreadAttr_t attr;
-
-
IoTGpioInit(IOT_GPIO_KEY);
-
IoSetFunc(IOT_GPIO_KEY, 0);
-
IoTGpioSetDir(IOT_GPIO_KEY, IOT_GPIO_DIR_IN);
-
IoSetPull(IOT_GPIO_KEY, IOT_IO_PULL_UP);
-
IoTGpioRegisterIsrFunc(IOT_GPIO_KEY, IOT_INT_TYPE_EDGE, IOT_GPIO_EDGE_FALL_LEVEL_LOW, OnButtonPressed, NULL);
-
IoTGpioInit(IOT_PWM_BEEP);
-
IoSetFunc(IOT_PWM_BEEP, 5);
-
IoTGpioSetDir(IOT_PWM_BEEP, IOT_GPIO_DIR_OUT);
-
IoTPwmInit(IOT_PWM_PORT_PWM0);
-
IoTWatchDogDisable();
-
-
attr.name = "PWMBeepTask";
-
attr.attr_bits = 0U;
-
attr.cb_mem = NULL;
-
attr.cb_size = 0U;
-
attr.stack_mem = NULL;
-
attr.stack_size = 1024;
-
attr.priority = osPriorityNormal;
-
-
if (osThreadNew((osThreadFunc_t)PWMBeepTask, NULL, &attr) == NULL) {
-
printf("[StartPWMBeepTask] Falied to create PWMBeepTask!n");
-
}
-
}
复制代码
写完代码就是编译,编译前要修改device/soc/hisilicon/hi3861v100/sdk_liteos/build/config/usr_config.mk文件。在这个配置文件中打开I2C,PWM驱动宏。搜索字段CONFIG_I2C_SUPPORT,并打开I2C,PWM。配置如下:
# CONFIG_I2C_SUPPORT is not set
CONFIG_I2C_SUPPORT=y
# CONFIG_PWM_SUPPORT is not set
CONFIG_PWM_SUPPORT=y
4. 实物演示
见如下视频
Pwm驱动蜂鸣器,视频演示,详见作者原帖子内容。
打开APP阅读更多精彩内容