AT91SAM9G45 PWM应用
2013-04-07 22:52
344 查看
最近在玩AT91SAM9G45的板子, 发现Linux系统下的PWM输出频率仅有100Hz. 通常情况下PWM频率可调是个必要功能, 现在和大家分享一下实现方法.
环境: AT91SAM9G45 +linux-3.5
步骤1:
make menuconfig配置内核, 开启PWM输出功能.
步骤2:
修改arch/arm/mach-at91/board-sam9m10g45ek.c
----------------------------------------
修改.gpio成员指定PWM通道, AT91SAM9G45一共有四个PWM通道.
步骤3:
编译内核, 下载烧写. 如果一切顺利, 输入下列命令即可从PD31输出越100Hz的方波.
占空比为127/256 ≈ 49.6%
步骤4:
为了修改PWM输出频率, 我们现在分析下驱动源码.
打开驱动文件"drivers/leds/leds-atmel-pwm.c",找到pwmled_probe()函数, 重点关注下面几条语句
--------------------------------
a.led->pwmc.mck = 133333333, 外部总线时钟
b.标蓝部分设置的是PWM模块的时钟分频系数, 参照手册PWM_CMR设置得知tmp=5(二进制0101)为MCK/32
c.tmp = (led->pwmc.mck / (1 << 5))/ 100;
这里的100为将要设置的目标频率. 如果分频系数为5, 那么最大可达到的目标频率约为16kHz.
好的, 我们已经找到了这两个关键的设置点, 下面以设置PWM输出38kHz为例, 计算参数
CPRD= 总线时钟/分频系数/目标频率
由上表可以看出, 分频系数2的小数部分最小, 误差也最小, 为最优选择. 但最终的目标频率不是精确的38kHz, 有误差的哟请务必注意.
代码如下
环境: AT91SAM9G45 +linux-3.5
步骤1:
make menuconfig配置内核, 开启PWM输出功能.
Device Drivers ---> Misc devices ---> <*>Atmel AT32/AT91 PWM support [*] LEDSupport ---> <*> LED Support usingAtmel PWM outputs
步骤2:
修改arch/arm/mach-at91/board-sam9m10g45ek.c
static struct gpio_ledek_pwm_led[] = { #ifdefined(CONFIG_LEDS_ATMEL_PWM) || defined(CONFIG_LEDS_ATMEL_PWM_MODULE) { /* "right" led, green, userled1, pwm1 */ .name = "d7", .gpio = 1<< AT91_PWM1, /* is PWM channel number */ .active_low = 1, .default_trigger = "none", }, #endif };
----------------------------------------
修改.gpio成员指定PWM通道, AT91SAM9G45一共有四个PWM通道.
步骤3:
编译内核, 下载烧写. 如果一切顺利, 输入下列命令即可从PD31输出越100Hz的方波.
echo127 > /sys/class/leds/pd7/brightness
占空比为127/256 ≈ 49.6%
步骤4:
为了修改PWM输出频率, 我们现在分析下驱动源码.
打开驱动文件"drivers/leds/leds-atmel-pwm.c",找到pwmled_probe()函数, 重点关注下面几条语句
tmp = 5; if (!led->active_low) tmp |= PWM_CPR_CPOL; pwm_channel_writel(&led->pwmc,PWM_CMR, tmp); /* * Pick a period so PWM cycles at 100+ Hz; anda multiplier * for scaling duty cycle: brightness * mult. */ tmp = (led->pwmc.mck / (1 << 5))/ 100; tmp /= 255; led->mult = tmp; pwm_channel_writel(&led->pwmc,PWM_CDTY, led->cdev.brightness * 255); pwm_channel_writel(&led->pwmc,PWM_CPRD, LED_FULL * tmp);
--------------------------------
a.led->pwmc.mck = 133333333, 外部总线时钟
b.标蓝部分设置的是PWM模块的时钟分频系数, 参照手册PWM_CMR设置得知tmp=5(二进制0101)为MCK/32
c.tmp = (led->pwmc.mck / (1 << 5))/ 100;
这里的100为将要设置的目标频率. 如果分频系数为5, 那么最大可达到的目标频率约为16kHz.
好的, 我们已经找到了这两个关键的设置点, 下面以设置PWM输出38kHz为例, 计算参数
CPRD= 总线时钟/分频系数/目标频率
由上表可以看出, 分频系数2的小数部分最小, 误差也最小, 为最优选择. 但最终的目标频率不是精确的38kHz, 有误差的哟请务必注意.
代码如下
tmp = 2; if (!led->active_low) tmp |= PWM_CPR_CPOL; pwm_channel_writel(&led->pwmc,PWM_CMR, tmp); /* * Pick a period so PWM cycles at 100+ Hz; anda multiplier * for scaling duty cycle: brightness * mult. */ tmp = (led->pwmc.mck / (1 << 2))/38000; tmp /= 255; led->mult = tmp; pwm_channel_writel(&led->pwmc,PWM_CDTY, led->cdev.brightness * 255); pwm_channel_writel(&led->pwmc,PWM_CPRD, LED_FULL * tmp);------------------------------------------------------------
相关文章推荐
- PWM的基本原理及应用实例
- s3c2440 的pwm应用
- s3c2440的PWM应用
- S3C2440裸机驱动--PWM应用
- PWM的基本原理及其应用实例
- PWM(脉宽调制)的基本原理 及其 应用实例
- s3c2440的PWM应用
- s3c2440的PWM应用
- iOS设备与蓝牙4.0应用例程之 三色灯控制(PWM控制)
- 脉宽调制(PWM)的基本原理及其应用实例
- dsPIC33EP 高速PWM模块初始化设置及应用
- 脉宽调制(PWM)的基本原理及其应用实例
- linux pwm 应用
- 51单片机的PWM应用
- ESP32电机PWM简单应用
- STM8单片机PWM应用(跟着别人学)
- 9260的TC应用案例--配置红外发送38K PWM波形(1/2占空比)
- 定时器应用之PWM输出
- STM32F4——定时器原理及应用(中断、输入捕获、PWM输出)
- STC15F2K60S2芯片PWM的应用