Linux PWM设备驱动及舵机控制

pwm归根到底就是调整高低电平在一个周期信号里的比例时间.
占空比: 指有效电平(通常高电平)在周期信号里的持续时间.
周期信号: 如从上升沿到下一个上升沿的时间。 100HZ表示1秒钟内有100个时钟周期。
pwm常用于调节LCD背光和对比度, 舵机, 调速马达,也可用于作时钟信号产生器。

这里写图片描述
如上图,就是四种在相同周期信号里的不同的占空比(每个周期里的高电平持续时间)


pwm调节LCD背光原理:
LCD背光通常是由LED作背光源, 调节LED的工作电压值可以改变LED的工作电流大小,从而改变了LCD的亮度.
但通过I/O口只能控制输出高(如3.3v)和低(0v)两种电平, 没法输出其它电压值. 所以通过pwm里的占空比,表示要输出的电压值大小, 再由芯片MP3202根据提供的pwm信号里的占空比输出相应比例的电压值.
如下图就是相应的电路:
这里写图片描述


一般的芯片都会提供pwm控制器,而全志H3里只提供了一个pwm控制器(电路上标的pwm1是不存在的)
这里写图片描述

在H3 linux 核里pwm控制器相关的配置:

make menuconfig ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
 Device Drivers  --->
    [*] Pulse-Width Modulation (PWM) Support  --->
    <*>   sunxi pwm support 

驱动代码在drivers/pwm/pwm-sunxi.c, 源文件里已实现相应的struct platform_device和platform_driver, 只需通过script.bin里打开pwm控制器功能即可.
同时需要注意的是, H3 pwm控制器的信号输出引脚PA05与uart0的rx脚是复用的, 所以PA05作pwm输出时就不可以使用uart0, 需要把其它的uart控制器作调试口使用,请参考http://blog.csdn.net/jklinux/article/details/79579145

在script.fex里pwm的配置:

[pwm0_para]
pwm_used = 1
pwm_positive = port:PA05<3><0><default><default>

修改script.bin和重编并使用新内核镜像后,pwm控制器应就驱动好了.


控制器驱动好的,就可以在设备驱动里通过下面相关的函数来调用控制器即可:

#include <linux/pwm.h>

struct pwm_device *pwm_request(int pwm_id, const char *label);
//请求使用pwm控制器, pwm_id是指第几个控制器

void pwm_free(struct pwm_device *pwm);
//释放请求的pwm控制器

int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns);
//duty_ns表示占空比时间, period_ns表示信号周期时间

int pwm_enable(struct pwm_device *pwm);
//启用pwm控制器

void pwm_disable(struct pwm_device *pwm);
//停用pwm控制器

enum pwm_polarity {
    PWM_POLARITY_NORMAL,   //占空比为高电平
    PWM_POLARITY_INVERSED, //低电平
};
int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity);
//设置pwm的有效电平是高电平/低电平

调用流程:

1  初始化
pwm_request
pwm_config
pwm_set_polarity
pwm_enable
2  修改占空比
pwm_disable
pwm_config
pwm_enable

3  停止pwm信号输出
pwm_disable
pwm_free


舵机:
这里写图片描述

红色线接电源, 棕色线接地, 橙色线接pwm


舵机控制原理, 通过一个为20ms(即50HZ)的周期信号,不同的占空比(0.5ms ~ 2.5ms)控制舵机的转向角度.
0.5ms————–舵机转动到0度
1.0ms————–舵机转动到45度
1.5ms————–舵机转动到90度
2.0ms————–舵机转动到135度
2.5ms————–舵机转动到180度

借用别人的一张动图,可以完整展示出转动到的角度与pwm信号的关系.
这里写图片描述


控制舵机的测试代码:


#include <linux/init.h>
#include <linux/module.h>
#include <linux/pwm.h>
#include <linux/delay.h>

struct pwm_device *pwm;
static int __init test_init(void)
{
    int ret = -ENODEV;
    pwm = pwm_request(0, "mypwmdev");
    if (NULL == pwm)
        goto err0;

    pwm_config(pwm, 500000, 20000000); // 0.5ms
    pwm_set_polarity(pwm, PWM_POLARITY_NORMAL);
    pwm_enable(pwm);

    msleep(3000);
    printk("change ...\n");
    pwm_disable(pwm);
    pwm_config(pwm, 1000000, 20000000); // 1ms
    pwm_enable(pwm);


    return 0;

err0:
    return ret;
}

static void __exit test_exit(void)
{
    pwm_disable(pwm);
    pwm_free(pwm);
}

module_init(test_init);
module_exit(test_exit);

MODULE_LICENSE("GPL");
  • 2
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
您可以使用74HC595芯片来实现PWM驱动单路舵机的控制。以下是一种可能的电路连接和代码示例: 首先,将芯片的引脚连接如下: - 将74HC595的VCC引脚连接到正电源(通常是5V)。 - 将74HC595的GND引脚连接到地。 - 将74HC595的SER(串行数据输入)引脚连接到单片机的数据输出引脚。 - 将74HC595的SRCLK(移位寄存器时钟)引脚连接到单片机的时钟输出引脚。 - 将74HC595的RCLK(输出锁存器时钟)引脚连接到单片机的另一个输出引脚。 - 将74HC595的OE(输出使能)引脚连接到地,以保持输出一直可用。 接下来,您可以使用以下代码示例来控制舵机: ``` #include <Arduino.h> // 定义74HC595芯片引脚 #define SER_PIN 2 // 数据输入 #define SRCLK_PIN 3 // 移位寄存器时钟 #define RCLK_PIN 4 // 输出锁存器时钟 // 舵机驱动函数 void servoWrite(int angle) { // 将角度映射到舵机控制信号范围 int pulseWidth = map(angle, 0, 180, 500, 2500); // 移位寄存器输出舵机控制信号 for (int i = 0; i < 16; i++) { // 将数据位写入SER引脚 digitalWrite(SER_PIN, (pulseWidth >> (15 - i)) & 0x01); // 移位寄存器时钟上升沿 digitalWrite(SRCLK_PIN, HIGH); digitalWrite(SRCLK_PIN, LOW); } // 输出锁存器时钟上升沿,输出舵机控制信号 digitalWrite(RCLK_PIN, HIGH); digitalWrite(RCLK_PIN, LOW); } void setup() { // 初始化74HC595引脚为输出模式 pinMode(SER_PIN, OUTPUT); pinMode(SRCLK_PIN, OUTPUT); pinMode(RCLK_PIN, OUTPUT); } void loop() { // 控制舵机转动到不同角度 for (int angle = 0; angle <= 180; angle += 10) { servoWrite(angle); delay(500); } } ``` 在以上代码示例中,我们定义了舵机驱动函数`servoWrite()`,它接受一个角度参数,并将其映射到舵机控制信号范围内的脉宽值。然后,我们使用移位寄存器逐位输出脉宽值,并通过输出锁存器将其锁定并输出到舵机。 请注意,以上代码示例中的引脚定义是示意性的,您需要根据实际硬件连接情况进行修改。 希望这可以帮助您实现74HC595芯片PWM驱动单路舵机的控制!如有其他问题,请随时提问。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值