打印

【转】BeagleBone Black板测试PWM功能

[复制链接]
1179|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
BBB板第十课:测试PWM功能
上一节课我们初步学习了BBB板上ADC数据的读取方法,本节课将把学到的PWM的知识贡献给和我一样的初学者。以下这张彩图来自网上,详细标明了14个PWM和四个定时器的引脚位置。本实验中,我们只测试其中的P8_13引脚,名称为eHRPWM2B。
需要准备的实验工具:一个二极管发光管和数字万用表及其他小线材

一、PWM知识(部分知识直接摘自网上)
PWM全称Pulse WidthModulation,脉冲宽度调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。简单的说,使用PWM可以实现平时我们常用的电阻器调压,可以控制电灯亮度、电机转速、音量大小等所有想得到的调节功能。
简而言之,PWM是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。PWM信号仍然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有(ON),要么完全无(OFF)。电压或电流源是以一种通(ON)或断(OFF)的重复脉冲序列被加到模拟负载上去的。通的时候即是直流供电被加到负载上的时候,断的时候即是供电被断开的时候。只要带宽足够,任何模拟值都可以使用PWM进行编码。


       图1显示了三种不同的PWM信号。图1a是一个占空比为10%的PWM输出,即在信号周期中,10%的时间通,其余90%的时间断。图1b和图1c显示的分别是占空比为50%和90%的PWM输出。这三种PWM输出编码的分别是强度为满度值的10%、50%和90%的三种不同模拟信号值。例如,假设供电电源为9V,占空比为10%,则对应的是一个幅度为0.9V的模拟信号。

       图2是一个可以使用PWM进行驱动的简单电路。图中使用9V电池来给一个白炽灯泡供电。如果将连接电池和灯泡的开关闭合50ms,灯泡在这段时间中将得到9V供电。如果在下一个50ms中将开关断开,灯泡得到的供电将为0V。如果在1秒钟内将此过程重复10次,灯泡将会点亮并象连接到了一个4.5V电池(9V的50%)上一样。这种情况下,占空比为50%,调制频率为10Hz。
      大多数负载(无论是电感性负载还是电容性负载)需要的调制频率高于10Hz。设想一下如果灯泡先接通5秒再断开5秒,然后再接通、再断开……。占空比仍然是50%,但灯泡在头5秒钟内将点亮,在下一个5秒钟内将熄灭。要让灯泡取得4.5V电压的供电效果,通断循环周期与负载对开关状态变化的响应时间相比必须足够短。要想取得调光灯(但保持点亮)的效果,必须提高调制频率。在其他PWM应用场合也有同样的要求。通常调制频率为1kHz到200kHz之间。
      BBB板包含有PWM控制器,实现14个PWM单独操作,每一个都可以选择接通时间和周期。占空比是接通时间与周期之比;调制频率为周期的倒数。具体说一下,其实频率就是1秒内完成周期的个数,100Hz就是每秒一百个周期,一个周期的时间为1/100秒;100KHz就是每秒实现100000个周期,一个周期时间为10us;比如我们熟悉的交流正弦波的一个周期由正半周和负半周组成的;而占空比就是一个周期中脉冲存在时间的百分比。
BBB板中,操作PWM用到duty(duty_ns)、period(period_ns)、polarity、run共四个参数,其中period就是频率参数(周期时间),duty为占空比,polarity为使能标志(1为使能,0为禁用),run 是执行命令(1为运行,0为关闭),period和duty的参数单位为纳秒(ns),1s=1000ms=1000000us=1000000000ns,所以period最大的取值范围为0—1000000000,而duty则取值0—period值之间,后面我们实验测试时会用大,到时会通过一组实验数据来理解这两个参数之间关系。
程序中PWM操作进行以下工作:
          * 设置PWM输出的方向,打开使能标志
          * 设置提供调制方波的片上定时器/计数器的周期period值
          * 设置接通时间duty占空比
       * 启动定时器

二、加载PWM驱动
PWM设备驱动和ADC一样不是默认打开的,需要时才手动启动。
下图显示查询到的BBB板所以PWM设备树文件,文件名正好对应14个PWM引脚编号:
1、查看当前加载设备树情况
进入sys/devices/bone_capemgr.9(加载设备树的目录),cat slots命令可以查看当年加载的驱动情况:只有一个内存卡和HDMI高清的驱动加载了。

2、加载:P8.13引脚的PWM驱动
加载PWM需要的两个驱动 am33xx_pwm-00A0.dtbo(公用设备树)和bone_pwm_P8_13-00A0.dtbo
root@beaglebone:/sys/devices/bone_capemgr.9#echo bone_pwm_P8_13 > slots
root@beaglebone:/sys/devices/bone_capemgr.9#echo am33xx_pwm > slots

如果只加载bone_pwm_P8_13-00A0.dtbo是不行的,不加载am33xx_pwm 在/sys/class/pwm目录下仍然没有产生新文件,只有再加载am33xx_pwm,这个工作目录下才会生成新文件:


实验中我在P8_13引脚上接了二极管指示灯,加载这两个设备文件后,灯就会点亮,电压输出值约为3.32V(接了二极管指示灯后电压实测为2.40V 负载拉低了电压)

加载成功后,进入/sys/class/pwm设备工作目录,会发现新增了pwmchip0  pwmchip2 pwmchip3  pwmchip5  pwmchip7共5个目录文件
可以试着打开其中的pwmchip0,看看里面有什么参数文件:
主要有两个参数base和npwm,其中base就是pwmchip的编号pwmchip0的base=0,其他 pwmchip2  pwmchip3 pwmchip5  pwmchip7分别对应2、3、5、7;npwm这个参数暂时不知道有什么意思,里面的值就是数字1或2:
pwmchip0_npwm=2      pwmchip2_npwm=1
pwmchip3_npwm=2      pwmchip5_npwm=2
pwmchip7_npwm=1

3、查找加载PWM后相关文件
由于没有参考资料,只能以测试的办法,查找出加载PWM后相关文件,再慢慢实验,看哪些文件操作会对P8_13的电压调压有效,由于还不熟悉其中的原理,暂时只能采用这种摸着石头过河的笨办法了找到参数文件进行测试。
通过关键字:P8_13查找,加载那两个设备驱动后,还在其他目录产生了相关文件:
其中/proc/device-tree/pinmux@44e10800/pinmux_pwm_P8_13_pins目录下有三个参数文件

其实这三个参数文件就是bone_pwm_P8_13-00A0.dts 子节点fragment@0的引脚功能配置的三个参数linux,phandle phandle 和 pinctrl-single,pins
另一个相关的目录/proc/device-tree/ocp/pwm_test_P8_13:
这些文件参数也是bone_pwm_P8_13-00A0.dts里面的,子节点fragment@1 有关pwm_P8_13驱动参数定义,共有8个参数。

4、实验测试一
模仿网上一个打开PWM命令,在/sys/class/pwm执行以下命令:
root@beaglebone:/sys/class/pwm#echo 1 > export
为什么是打开编号1,具体暂时不清楚,我测试了0-9之间,好像除了一个6还是7提示出错外,其余都可生成一个目标目录,像这个 echo 1 > export 就产生了一个目录文件pwm1:
进入这个pwm1目录后就看到了我们需要的操作PWM的参数文件了
操作PWM必须的四个参数:duty_ns  period_ns polarity 和  run
它们的默认值都是0,可以通过 cat命令查看
   但是我试着改变其中的参数值,当然使能标志polarity设为1,duty_ns和period_ns  也设置了值,特别是执行 echo 0 > run 关闭运行PWM,P8_13 引脚的电压无变化,我接的二极管指示灯仍然在亮,并不能关闭,证明生成的这些pwm1 或其他对P8_13是无效的。
具体是对哪个操作暂时不清楚,以后了解了再另行讨论。



相关帖子

沙发
5、实验测试二
进入之前查找到的其他目录,/proc/device-tree/ocp/pwm_test_P8_13.15和
/sys/bus/platform/drivers/pwm_test/pwm_test_P8_13.15这两个目录是一样的,都有几个参数文件, duty  modalias period  polarity  run ,比生成的pwm1目录中多了一个modalias参数,显示值为:platform:pwm_test_P8_13.15

经过测试,发现在这个目录下操作有效,之前不是说过,加载驱动后,接在P8_13引脚的灯会常亮,在这个目录下执行echo 0 > run 灯就灭了,再执行echo 1 > run 又亮了,证明加载的那两个设备树产生的控制文件就在这两个目录下了。
在period为原来500000的情况下,简单通过改变duty 的值(取值0-500000之间),可以使灯变暗些(改变输出电压),比如:
echo250000 > duty
echo350000 > duty
注意事项:在更改参数之前需要先关闭,执行 echo 0 > run ,更改参数后再运行echo 1 > run
实验初步显示:duty 值越大,输出电压越小(灯变暗)








6、实验测试三
数据说明一切,在P8_13引脚上接一个数字万用表(精度为0.01),做电压输出测试。
下面表格是通过分别变更duty和period的值得到的电压值:
PWM实验数据表(P8_13针脚)
period
duty
电压值

period
duty
电压值

period
duty
电压值
1000
0
3.32

100
0
3.32

100000
0
3.32
1000
10
3.29

100
10
3.15

100000
10
3.32
1000
20
3.25

100
20
2.59

100000
100
3.31
1000
30
3.22

100
30
2.20

100000
200
3.31
1000
40
3.18 

100
40
1.96

100000
300
3.31
1000
50
3.15

100
50-59
1.65

100000
500
3.30
1000
60
3.11

100
60-69
1.25

100000
1000
3.28
1000
70
3.08

100
70-79
0.94

100000
1500
3.27
1000
80
3.05

100
80-89
0.67

100000
2000
3.25
1000
90
3.01

100
90-89
0.31

100000
2500
3.23
1000
100
2.98

100
100
0

100000
3000
3.22
1000
200
2.65





100000
3500
3.20
1000
300
2.32





100000
9000
3.02
1000
400
1.98





100000
10000
2.99
1000
500
1.65





100000
20000
2.65
1000
600
1.32





100000
30000
2.32
1000
700
0.99





100000
40000
1.99
1000
800
0.66





100000
50000
1.66
1000
900
0.33





100000
60000
1.32
1000
1000
0





100000
100000
0























通过这组数据可以总结出以下几个结论:
    A、duty取值范围为0-period,而且有个变化量的限制,当period=100Hz时,duty的变化量为10,电压调节档只有10个档,最小值0.31V;当period=1000Hz时,duty的变化量为10,电压调节档有100个档,最小值约为0.03V,精度明显提高;
当period=100000Hz时,duty的变化量为500,电压调节档有200个档,最小值0.01V,精度更高。
B、period 频率设置值越大,PWM控制电压输出更精细
C、两上参数值的关系duty<=period ,duty 设大了就会提示出错;duty=0,电压值都等于参考电压3.32V;duty=period,电压值为0
D、推算出PWM调压计算公式: Vo=((period-duty)÷period)×Vi ,其中Vi为引脚基准电压,在BBB板中,Vi=3.32V,可做为常数;Vo为输出电压;根据这个公式计算和实测数据比较,period取值100时,误差较大,period取值1000或100000时,公式得到的电压值和实测的值误差在0.001,还是非常准确的。有了这个公式,就可以根据所需要的目标电压值,反过来推算出程序中所需要的period 和duty 值。
Duty=0,Vo=Vi;duty=period,Vo=0
E、图解下period和duty的关系
只能从个人理解角度描述下,并没有专业知识,请高手指点。
在period不变的情况下,duyt取值越大,高电平的方波占用时间(占空比)1/duty值就越小,所以输出的电压就越小


7、计数器/定时器
关于TIMER4-7这四个定时器的使用本节课未讲到,因为实验中一直不用设置定时器,P8_13引脚已经实现调压输出,可能已经有个默认值吧,具体使用方法以及和PWM的关系以后再说了。

使用特权

评论回复
板凳
isseed| | 2016-9-4 22:56 | 只看该作者
这个有相关的教程的。

使用特权

评论回复
地板
isseed| | 2016-9-4 22:59 | 只看该作者
可以搜索找找看,很全面的。

使用特权

评论回复
5
dirtwillfly| | 2016-9-5 08:24 | 只看该作者

使用特权

评论回复
6
uptown| | 2016-9-5 17:03 | 只看该作者
被大学上了四年 发表于 2016-9-3 23:03
5、实验测试二进入之前查找到的其他目录,/proc/device-tree/ocp/pwm_test_P8_13.15和/sys/bus/platform/dr ...

这个是怎么编程到内部实现?

使用特权

评论回复
7
uptown| | 2016-9-5 17:06 | 只看该作者
被大学上了四年 发表于 2016-9-3 23:03
5、实验测试二进入之前查找到的其他目录,/proc/device-tree/ocp/pwm_test_P8_13.15和/sys/bus/platform/dr ...

例如驱动一个舵机等等。

使用特权

评论回复
8
10299823| | 2016-9-6 22:39 | 只看该作者
uptown 发表于 2016-9-5 17:06
例如驱动一个舵机等等。

好像有人在论坛发布这个程序过。

使用特权

评论回复
9
10299823| | 2016-9-6 22:40 | 只看该作者
uptown 发表于 2016-9-5 17:06
例如驱动一个舵机等等。

写入内部周期参数应该就可以了。

使用特权

评论回复
10
uptown 发表于 2016-9-5 17:03
这个是怎么编程到内部实现?

电脑上写好程序,然后交叉编译,
再把可执行文件拷贝到系统上,
就可以正常运行了,
用到编译库的要一起拷贝过去,
路径不能变!

使用特权

评论回复
11
10299823 发表于 2016-9-6 22:39
好像有人在论坛发布这个程序过。

恩,网上很多的,可以自己搜一下!

使用特权

评论回复
12
htmlme| | 2016-9-7 22:49 | 只看该作者
可以直接写C代码进行控制吗

使用特权

评论回复
13
htmlme| | 2016-9-7 22:50 | 只看该作者
看楼主这是控制命令,不是代码的

使用特权

评论回复
14
pl202| | 2016-9-8 16:46 | 只看该作者
感觉现在玩beaglebone的不多了。

使用特权

评论回复
15
isseed| | 2016-9-9 16:46 | 只看该作者
只能执行相关的操作命令吗?

使用特权

评论回复
16
isseed| | 2016-9-9 16:47 | 只看该作者
函数操作怎么能够编译到c语言里面

使用特权

评论回复
17
好牛逼的猪坚强|  楼主 | 2016-9-10 00:02 | 只看该作者
pl202 发表于 2016-9-8 16:46
感觉现在玩beaglebone的不多了。

恩,确实,现在嵌入式开发板太多了!
比如树莓派什么的,价格都很低,
开源成都也好,所以玩BB的越来越少了!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

60

主题

116

帖子

0

粉丝