[imx6ull]PWM编程-蜂鸣器控制


一、PWM概述

PWM(脉冲宽度调制)是一种通过调节一系列脉冲的宽度来生成所需波形(包括形状和幅值),对模拟信号电平进行数字编码的技术。通过调节占空比来调节信号、能量等的变化。占空比是指在一个周期内,信号处于高电平的时间占据整个信号周期的百分比,例如方波的占空比为50%。PWM是一种非常有效的技术,利用微处理器的数字输出来控制模拟电路。
在这里插入图片描述

其中,交流调光电路(如手机充电的呼吸灯)是PWM技术的常见应用之一,也可以称为无级调光。通过调节PWM信号的占空比,可以实现灯光亮度的调节。当占空比较大时,高电平的时间较长,灯光亮度增加;当占空比较小时,高电平的时间较短,灯光亮度降低。然而,需要注意的是,为了避免人眼可察觉的闪烁,PWM信号的频率应大于人眼的识别频率,通常要求频率在80Hz以上。

除了交流调光电路,PWM技术在电机驱动、无源蜂鸣器驱动、LCD屏幕背光调节、逆变电路等领域也有广泛应用。通过调节PWM信号的占空比和频率,可以实现电机转速的精确控制、无源蜂鸣器的音调控制、LCD屏幕背光的亮度调节以及逆变电路的输出电压控制等。

二、PWM的参数

PWM(脉冲宽度调制)具有三个关键参数:频率、周期和占空比:

  1. PWM的频率:表示每秒钟PWM信号从高电平到低电平再到高电平的次数,也就是在1秒钟内PWM信号的周期数量,单位为赫兹(Hz)。
  2. PWM的周期:周期指完成一次从高电平到低电平再到高电平的时间,即一个完整的PWM信号周期的持续时间,单位为毫秒(ms)。
  3. 占空比:占空比指在一个脉冲周期中高电平的时间占整个周期的比例,通常以百分比表示。

示例:
在这里插入图片描述
周期:周期是描述一个脉冲信号的时间长度,而频率是描述单位时间内脉冲信号的周期数量。两者的关系是频率等于周期的倒数,即频率 = 1 / 周期。

脉宽时间:脉宽时间是指高电平的持续时间,也可以理解为脉冲信号中的高电平部分。脉宽时间占总周期的比例即为占空比,表示高电平时间在整个周期中所占的比例。

通过调节PWM信号的频率和占空比,可以实现对信号、能量或设备的精确控制。

三、驱动配置

我们可以知道开发板上有4路PWM分别为:

PWM1 ---> backlight //LCD背光
PWM2 ---> beep         //蜂鸣器
PWM7,PWM8 ---> 40pin扩展 //需要使能开启

想要使能40pin扩展口的PWM7和8的话,需要修改/run/media/mmcblk1p1路径下的config.txt文件如下:

# Enable PWM overlays, PWM8 conflict with UART8(NB-IoT/4G module)
dtoverlay_pwm=7 8

修改后重启系统,和gpio一样通过sysfs方式进行操作,在/sys/class/pwm路径下存在着我们PWM控制器的文件pwmchipN,我们可以在文件夹中看到几个比较重要的属性文件:

在这里插入图片描述

  • npwm:这是一个只读属性,可以通过cat命令去查看此PWM控制器共有几路输出
  • export:在使用PWM之前也需要将其导出,export属性与GPIO的控制中一样用于导出,导出方法如下:
echo 0 > export

导出后可以在pwmchipN文件中看见我们导出的一个pwm0的文件夹。

注意:echo导出的值必须小于我们npwm中看见的值

  • unexport:用于在我们使用完PWM之后将导出的pwm文件夹删除,删除方法如下:
echo 0 > unexport

注意:export文件和unexport文件都是只写的、没有读权限

四、PWM应用测试

1.应用程序

pwm_test.c

/*********************************************************************************
 *      Copyright:  (C) 2023 Deng Yonghao<dengyonghao2001@163.com>
 *                  All rights reserved.
 *
 *       Filename:  pwm_test.c
 *    Description:  This file use to test pwm
 *                 
 *        Version:  1.0.0(2023年03月17日)
 *         Author:  Deng Yonghao <dengyonghao2001@163.com>
 *      ChangeLog:  1, Release initial version on "2023年03月17日 11时54分08秒"
 *                 
 ********************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

static char pwm_path[100];

static int pwm_config(const char *attr, const char *val);//pwm配置函数声明,attr:属性文件名字,val属性的值(字符串)

int main(int argc, char **argv)
{
	char 	temp[100];
	int 	fd = -1;

	 /*传参校验*/
    if(4 != argc)
	{
        printf("usage: %s <id> <period> <duty>\n", argv[0]);
        exit(-1);//exit(0) 表示进程正常退出 exit(非0)表示异常退出
    }

	/*打印配置信息*/
    printf("PWM config: id<%s>, period<%s>, duty<%s>\n", argv[1], argv[2], argv[3]);

	/* 导出pwm 首先确定最终导出的文件夹路径*/
	memset(pwm_path, 0, sizeof(pwm_path));
	snprintf(pwm_path, sizeof(pwm_path), "/sys/class/pwm/pwmchip%s/pwm0", argv[1]);

	//如果pwm0目录不存在, 则导出
    memset(temp, 0, sizeof(temp));
    if(access(pwm_path, F_OK)) 
	{
        snprintf(temp, sizeof(temp) , "/sys/class/pwm/pwmchip%s/export", argv[1]);
        if(0 > (fd = open(temp, O_WRONLY))) 
		{
            printf("open pwmchip%s error\n", argv[1]);
            exit(-1);
        }
        //导出pwm0文件夹
        if(1 != write(fd, "0", 1)) 
		{
            printf("write '0' to  pwmchip%s/export error\n", argv[1]);
            close(fd);
            exit(-2);
        }

        close(fd);
    }

	/*配置PWM周期*/
	if(pwm_config("period",argv[2]))
	{
		exit(-1);
	}

	/*配置占空比*/
	if(pwm_config("duty_cycle", argv[3]))
	{
		exit(-1);
	}

	/*使能pwm*/
	pwm_config("enable", "1");

	return 0;
}

static int pwm_config(const char *attr, const char *val)
{
	char 	file_path[200];
	int 	len;
	int 	fd =-1;

	if(attr == NULL || val == NULL)
	{
		printf("[%s] argument error\n", __FUNCTION__);
		return -1;
	}

	memset(file_path, 0, sizeof(file_path));
	snprintf(file_path, sizeof(file_path), "%s/%s", pwm_path, attr);
	if(0 > (fd = open(file_path, O_WRONLY)))
	{
		printf("[%s] open %s error\n", __FUNCTION__, file_path);
		return fd;
	}

	len = strlen(val);
	if(len != write(fd, val, len))
	{
		printf("[%s] write %s to %s error\n", __FUNCTION__, val, file_path);
		close(fd);
		return -2;
	}
	
	close(fd);
	return 0;

}

2.makefile

代码如下(示例):

CC=arm-linux-gnueabihf-gcc
APP_NAME1=pwm_test

all:clean
    @${CC} ${APP_NAME1}.c -o ${APP_NAME1}

clean:
    @rm -f ${APP_NAME1}

3.运行测试

首先,通过在通过make命令编译好我们的测试程序,然后通过如下命令把编译好的可执行程序下载到开发板上,并赋予可执行权限:

tftp -gr pwm_test 192.168.137.101
chmod a+x pwm_test

然后我们运行此测试程序来测试PWM8管脚:

root@igkboard:~# ./pwm_test 3 10000 1000 

root@igkboard:~# ./pwm_test 3 10000 3000 

root@igkboard:~# ./pwm_test 3 10000 7000 

root@igkboard:~# ./pwm_test 3 10000 9000  

执行时可以看见led灯会随着我们的参数不同而变化,参数第一个代表pwmchip3,第二个为周期,越大越暗,第三个为占空比,越大灯越亮。

在这里插入图片描述
测试视频可见:PWM管脚led测试视频
然后我们可以测试蜂鸣器:
在这里插入图片描述
参数第一个代表pwmchip1蜂鸣器,第二个周期越大越小声,第三个占空比越大灯越大声,测试成功。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

邓永豪

打赏一下,好运来敲门!

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

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

打赏作者

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

抵扣说明:

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

余额充值