转载务必注明出处,谢谢!
很久没更新,把最近做的一点小东西写上来以作备忘。
最近在折腾WRTnode,感觉还不错。
回归主题。
PWM 指的是脉冲宽度调制,通常控制舵机或者步进电机,无刷电机会用到。今天我们就讲下怎么样基于wrtnode实现这个功能。
默认wrtnode是不集成PWM的,甚至,连代码也木有。为啥嘞?因为 openwrt在3.14内核之后取消了pwm over gpio了,而我们当前的系统版本为3.10.49,悲催。经过寻找,我们找到了官方最后的源码(https://dev.openwrt.org/browser/trunk/target/linux/generic/files/drivers/pwm?rev=35328&order=name)
把里面的 gpio-pwm.c Kconfig Makefile pwm.c 四个文件下载下来,放到我们的目录下(wrtnode-sdk/target/linux/generic/files/drivers/pwm)。当然,记得include下的pwm.h也不要忘记哦(wrtnode-sdk/target/linux/generic/files/include/linux/pwm)
然后我们需要的就是make menuconfig
Kernel modules
Other modules
选中kmod-pwm kmod-pwm-gpio 这两项,保存。
另外,make kernel_menuconfig
内核参数GPIO support项目里面,sysfs这项最好选上。
kernel_menuconfig --> File Systems --> Pseudo Filesystems --> Userspace-Driven configuration system (必须是* ,built-in方式)
蓝后嘞,make V=s 编译。没多久,固件就编译完成了。
当然你需要刷写固件,因为文件系统咱们更改了,添加了 Userspace-Driven configuration system的支持。
刷机过后,就可以把(wrtnode-sdk/bin/ramips/packages/base/)下我们的ipk安装包拿出来了,快去安装吧~
当然啦,你安装好了,总得测试嘛。
-
#准备目录
-
mkdir -p /config
-
mount -t configfs config /config
-
mkdir -p /config/gpio_pwm/72
-
# 启用GPIO端口, 72是端口号
-
echo 1 > /sys/class/pwm/gpio_pwm:72/export
-
# 配置频率与占空比,(本例是10% on 90% off,周期的单位是纳秒,1秒=10的9次方纳秒)
-
echo 1000000000 > /sys/class/pwm/gpio_pwm:72/period_ns
-
echo 100000000 > /sys/class/pwm/gpio_pwm:72/duty_ns
-
# 运行,启动GPIO端口按设定的PWM输出
-
echo 1 > /sys/class/pwm/gpio_pwm:72/run
-
# 停止
-
echo 0 > /sys/class/pwm/gpio_pwm:72/run
-
echo 1 > /sys/class/pwm/gpio_pwm:72/unexport
-
# 清除配置
-
rm -rf /config/gpio_pwm/72
附注上我写的一个Linux C LED呼吸灯小程序。
-
/*
-
* Write By Lee at 201506010
-
*/
-
#include <unistd.h>
-
#include <fcntl.h>
-
#include <stdio.h>
-
#include <sys/types.h>
-
#include <sys/stat.h>
-
#include <errno.h>
-
#include <string.h>
-
-
int main(int argc, char **argv)
-
{
-
/* init */
-
int fd_period_ns,fd_duty_ns;
-
int value_period_ns,value_duty_ns;
-
char path_period_ns[]="/sys/class/pwm/gpio_pwm:72/period_ns";
-
char path_duty_ns[]="/sys/class/pwm/gpio_pwm:72/duty_ns";
-
char str_period_ns[ 32 ]={'\0'};
-
char str_duty_ns[ 32 ]={'\0'};
-
int len = 0;
-
int step = 500000;
-
int value_total = 10000000;
-
unsigned int wait_time = 50*1000;
-
-
/* open file */
-
if ((fd_period_ns = open(path_period_ns, O_WRONLY)) == -1) {
-
fprintf(stderr, "Open %s Error:%s\n", path_period_ns, strerror(errno));
-
return(-1);
-
}
-
/* open file */
-
if ((fd_duty_ns = open(path_duty_ns, O_WRONLY)) == -1) {
-
fprintf(stderr, "Open %s Error:%s\n", path_duty_ns, strerror(errno));
-
return(-1);
-
}
-
-
/* set value */
-
value_period_ns=value_total;
-
/* write value */
-
len=sprintf(str_period_ns,"%d",value_period_ns);
-
write(fd_period_ns,str_period_ns,len);
-
-
-
while(1){
-
/* set value */
-
value_duty_ns=1;
-
while(value_duty_ns < value_period_ns){
-
//printf("----value_duty_ns %d value_period_ns %d\n",value_duty_ns,value_period_ns);
-
/* write value */
-
len=sprintf(str_duty_ns,"%d",value_duty_ns);
-
write(fd_duty_ns,str_duty_ns,len);
-
if(value_duty_ns > (value_total/3))
-
value_duty_ns+=(step/4);
-
else
-
value_duty_ns+=step;
-
usleep(wait_time);
-
}
-
value_duty_ns=value_total;
-
while(value_duty_ns > 0){
-
//printf("----value_duty_ns %d value_period_ns %d\n",value_duty_ns,value_period_ns);
-
/* write value */
-
len=sprintf(str_duty_ns,"%d",value_duty_ns);
-
write(fd_duty_ns,str_duty_ns,len);
-
if(value_duty_ns > (value_total/3))
-
value_duty_ns-=(step/4);
-
else
-
value_duty_ns-=step;
-
usleep(wait_time);
-
}
-
}
-
/* uninit */
-
close(fd_period_ns);
-
/* uninit */
-
close(fd_duty_ns);
-
-
return 0;
-
}
运行之前,需要
-
mkdir -p /config
-
mount -t configfs config /config
-
mkdir -p /config/gpio_pwm/72
-
echo 1 > /sys/class/pwm/gpio_pwm:72/export
-
echo 1 > /sys/class/pwm/gpio_pwm:72/run
-
That’s all 仅此。
PS:
在制作PWM的过程中遇到了很多问题,有的我自己并没能解决,请教了WRTnode官方群里的 ( 小子De我 ) ,在此感谢!
参考资料:
Thx for Vmmgrs :
(this uses a customized firmware, if you like to try , you can get here )
转载务必注明出处,谢谢!
阅读(7694) | 评论(0) | 转发(1) |