美文网首页嵌入式linux玩转树莓派程序员
【原创】树莓派3B开发Go语言(四)-自写库实现pwm输出

【原创】树莓派3B开发Go语言(四)-自写库实现pwm输出

作者: 爪爪熊 | 来源:发表于2017-08-31 21:47 被阅读499次

    在前一小节中介绍了点亮第一个LED灯,这里我们准备进阶尝试下,输出第一段PWM波形。(PWM也就是脉宽调制,一种可调占空比的技术,得到的效果就是:如果用示波器测量引脚会发现有方波输出,而且高电平、低电平的时间是可调的。)

    这里爪爪熊准备写成一个golang的库,并开源到github上,后续更新将直接更新到github中,如果你有兴趣可以简书和我联系。 github.com/dpawsbear/bear_rpi_go

    一、树莓派的PWM

    我在很多的教程中都看到说树莓派的PWM(硬件)只有一个GPIO能够输出,就是 GPIO1。这可是不小的打击,因为我想使用至少四个 PWM ,还是不死心,想通过硬件手册上找寻蛛丝马迹,看看究竟怎么回事。

    手册上找寻东西稍等下讲述,这里先提供一种方法测试 树莓派3BPWM 方法:用指令控制硬件PWM。

    #pwm 输出频率为4.8Mhz/1024 = 4.6875khz
    gpio mode 1 pwm    # 设置 gpio1 引脚为pwm模式
    gpio pwm-ms        # 设置 pwm 的模式为 pwm-ms Mark-space
    gpio pwmr 1024     # 设置 pwm 满计数为1024
    gpio pwmc 4        # 设置 pwm 的频率 4:4.8MHZ
    gpio pwm  1 512    # 设置 pwm 的占空比 为 512/1024 (50%)占空比
    

    这里通过指令的方式掌握了基本的pwm设置技巧,决定去翻一下手册看看到底PWM怎么回事,这里因为没有 BCM2837 的手册,根据之前文章引用官网所说, BCM2835BCM2837 应该是一样的。这里我们直接翻阅 BCM2835 的手册,直接找到 PWM 章节。找到了如下图:

    image.png

    图中可以看到在博通的命名规则中 GPIO 12、13、18、19、40、41、45、52、53 均可以作为PWM输出。但是只有两路PWM0 PWM1。根据我之前所学知识,不出意外应该是PWM0 和 PWM1可以输出不一样的占空比,但是频率应该是一样的。因为没有示波器,暂时不好测试。先找到下面对应图:

    image.png

    根据以上两个图对比可以发现如下规律:

    PWMn BCM引脚 GPIO引脚(NAME) 板子引脚 复用模式
    PWM0 GPIO 12 GPIO26 32 ALT0
    PWM0 GPIO 18 GPIO 1 12 ALT5
    PWM1 GPIO 13 GPIO23 33 ALT0
    PWM1 GPIO 19 GPIO24 35 ALT5

    对照上面的表可以看出从 BCM2837 中印出来的能够使用在PWM上的就这几个了。

    为了验证个人猜想是否正确,这里先直接使用指令的模式,模拟配置下是否能够正常输出。

    # 指令方式模拟配置 gpio为pwm
    gpio mode  1 pwm
    gpio mode 26 pwm
    gpio mode 23 pwm
    gpio mode 24 pwm
    gpio pwm-ms
    gpio pwmr 1024
    gpio pwm   1 100
    gpio pwm  26 512
    gpio pwm  23  10
    gpio pwm  24 256
    

    通过上面一系列指令模拟发现,(GPIO1、GPIO26)、(GPIO23、GPIO24)是绑定在一起的,调节任意一个,另外一个也会发生变化。也即是PWM0、PWM1虽然输出了两路,可以理解成两路其实都是连在一个输出口上。这里由于没有示波器或者逻辑分析仪这类设备(仅有一个LED灯),所以测试很简陋,下一步是使用示波器这类东西对频率以及信号稳定性进行下测试。

    小节:树莓派具有四路硬件输出PWM能力,但是四路中只能输出两个独立(占空比独立)的PWM,同时四路输出的频率均是恒定的。

    二、使用go语言操作PWM

    上面大概了解清楚了树莓派3B的PWM结构,接下来就是探究如何使用Go语言进行设置。

    因为拿到了手册,这里我想直接操作寄存器的方式进行设置,也是顺便学习下Go语言处理寄存器的过程。首先需要拿到pwm 系列寄存器的基地址,但是翻了一圈手册,发现只有偏移,没有找到基地址。

    经过了一段时间的努力后,决定写一个 树莓派3B golang包开源放在github上,只需要写相关程序进行调用就可以了,以下是相关demo(pwm)(在GPIO.12 上输出PWM波,放上LED灯会有呼吸灯的效果,具体多少频率还没有进行测试)

    2.1 使用方法

    go get github.com/dpawsbear/bear_rpi_go
    
    cd $gopath/src/github.com/dpawsbear/bear_rpi_go/example
    
    go build -ldflags "-w -s" pwm.go
    
    sudo ./pwm
    

    以下是demo(pwm) 源码

    package main
    
    import (
        "fmt"
        rpi "github.com/dpawsbear/bear_rpi_go"
        "time"
    )
    
    func main(){
        fmt.Println("starting...")
        if 0 != rpi.Bcm2837_init() {
            rpi.Bcm2837_close()
            panic(55)
            return
        }
    
    
    
        //test for pwm (GPIO.12 and GND)
        rpi.Bcm2837_gpio_fsel(rpi.RPI_3B_GPIO_J8_12,uint8(rpi.BCM2837_GPIO_FSEL_ALT5))
    
        rpi.Bcm2837_pwm_set_clock(rpi.BCM2837_PWM_CLOCK_DIVIDER_16)
    
        rpi.Bcm2837_pwm_set_mode(0, 1, 1 )
    
        rpi.Bcm2837_pwm_set_range(0,1024 )
    
        rpi.Bcm2837_pwm_set_data(0,10 )
    
        var data uint32 = 1
        for{
            for {
                time.Sleep(time.Millisecond*2)
                data ++
                if data > 768{
                    break
                }
                rpi.Bcm2837_pwm_set_data(0,data )
            }
            for {
                time.Sleep(time.Millisecond*2)
                data --
                if data < 2 {
                    data = 1
                    break
                }
                rpi.Bcm2837_pwm_set_data(0,data )
            }
    
        }
    }
    

    相关文章

      网友评论

      • 吉编辑:你好,我是和清华大学出版社合作的编辑,看到你写的关于go语言的文章,你对go语言了解的多吗?有兴趣写go语言的书出版吗?
        吉编辑:@爪爪熊 恩恩,不好意思,打扰了
        爪爪熊: @吉编辑 没有,谢谢哈,了解不多。刚学一个月
      • 0859068e38e8::kissing_heart::kissing_heart::kissing_heart:
        爪爪熊: @木木翻滚吧蛋炒饭 mumumumua~

      本文标题:【原创】树莓派3B开发Go语言(四)-自写库实现pwm输出

      本文链接:https://www.haomeiwen.com/subject/wwvcjxtx.html