树莓派开发笔记04-树莓派的PWM输出

news2024/9/21 16:44:20

github主页:https://github.com/snqx-lqh
gitee主页:https://gitee.com/snqx-lqh
本项目github地址:https://github.com/snqx-lqh/RaspberryPiLearningNotes
本项目gitee地址:https://gitee.com/snqx-lqh/RaspberryPiLearningNotes
欢迎交流

PWM说明

树莓派的硬件引脚PWM有4个引脚。GPIO.1、GPIO.26、GPIO.23、GPIO.24,对应到WiringPi就是1、26、23、24。但是不同的代码库能支持的输出是不同的。

wiringPi库可以支持硬件PWM和软件PWM,但是硬件PWM有个问题就是,1和26会同时设置,23和24会同时设置,暂时不知道为什么,后面找到BUG会更新博文。

bcm2835库只支持硬件PWM,bcm的引脚编号18、12、13、19,我写代码测试的时候,发现18、12会同时输出,13、19会同时输出。暂时不知道为什么

Python库,我的版本,只支持GPIO.1的引脚的硬件输出

在这里插入图片描述

代码

wiringPi

wiringPi 可以使用硬件PWM,也可以软件PWM输出

硬件Pwm

树莓派内部pwm发生器的基频为19.2MHz,输出频率 freq(Hz) = 19200000 / divisor / range

1、void pwmSetMode (int mode) ;

mode:PWM运行模式

pwm发生器可以运行在2种模式下,通过参数指定:

  • PWM_MODE_BAL :树莓派默认的PWM模式

  • PWM_MODE_MS :传统的pwm模式

我使用PWM_MODE_BAL怎么调都不对,就改成PWM_MODE_MS来使用了。

2、void pwmSetRange (unsigned int range) ;

range,范围的最大值 0~range,设置pwm发生器的数值范围,默认是1024

3、void pwmSetClock (int divisor)

设置时钟分频

4、void pwmWrite(int pin, int value) ;

设置占空比

下面是一个设置PWM输出的例子

#include <wiringPi.h>
#include <stdio.h>

#define PWM 1

int main(int argc,char **argv)
{   
    if(wiringPiSetup() < 0) //当使用这个函数初始化树莓派引脚时,程序使用的是wiringPi 引脚编号表。
        return 1;
    
    pinMode(PWM,PWM_OUTPUT); //设置引脚为PWM输出模式
    pwmSetMode (PWM_MODE_MS);
    pwmSetRange(1024);              // pwm脉宽范围 0~1024
    pwmSetClock(75);                // 250Hz,19.2MHz / 75 / 1024 = 250Hz
    pwmWrite(PWM,512);              // 设置高电平占的计数值

    while (1)
    {

    }
    return 0;
}

然后编译这段代码

cc -Wall -o main main.c -lwiringPi

-Wall 表示编译时显示所有警告,-lwiringPi 表示编译时动态加载 wiringPi 库

编译完成后调用生成的main文件

sudo ./main

然后可以用示波器啥的,或者自己连接的LED灯在这个引脚上,就可以查看到变化。、

想要停止这个程序,Ctrl+c即可。

软件pwm

除了硬件PWM,该库还支持软件PWM的输出

1、int softPwmCreate (int pin, int initialValue, int pwmRange)

pin:用来作为软件PWM输出的引脚

initalValue:引脚输出的初始值

pwmRange:PWM值的范围上限

返回:0表示成功。

2、void softPwmWrite (int pin, int value)

pin:通过softPwmCreate创建的引脚

value:PWM引脚输出的值

具体实现如下,频率设置为PWMfreq = 1 x 10^6 / (100 x range)

#include <wiringPi.h>
#include <stdio.h>

#include <softPwm.h>

#define PWM 4

int main(int argc,char **argv)
{   
    if(wiringPiSetup() < 0) //当使用这个函数初始化树莓派引脚时,程序使用的是wiringPi 引脚编号表。
        return 1;
    
    pinMode(PWM,OUTPUT); //设置引脚为 输出模式
    //PWMfreq = 1 x 10^6 / (100 x range)  需要50hz 
    softPwmCreate(PWM , 0, 200);// 设置周期分为200份
    softPwmWrite(PWM , 50); //占空比就是50/200

    while (1)
    {

    }
    return 0;
}

bcm2835库

bcm的引脚编号18、12、13、19,我写代码测试的时候,发现18、12会同时输出,13、19会同时输出。,暂时不知道为什么

1、void bcm2835_pwm_set_clock(uint32_t divisor);

设置时钟分频,分频方式有很多,可以转到定义处查看

2、void bcm2835_pwm_set_mode(uint8_t channel, uint8_t markspace, uint8_t enabled);

channel :设置PWM是通道0还是1

markspace:1是传统模式,0是BAL模式.

enabled:1为使能.

设置PWM模式

3、void bcm2835_pwm_set_range(uint8_t channel, uint32_t range);

channel :设置PWM是通道0还是1

range:设置最大范围.

4、void bcm2835_pwm_set_data(uint8_t channel, uint32_t data);

channel :设置PWM是通道0还是1

data:设置比例.

PWM输出频率 freq(Hz) = 19200000 / divisor/ range

bcm的引脚编号和wiringPi不同,注意,下面是一个实际例子

#include <bcm2835.h>

#define PWM 18
#define PWM_CHANNEL 0

int main(int argc,char **argv)
{
    if(!bcm2835_init()) //初始化BCM相关的
        return 1;

    // 配置引脚为PWM输出模式
    bcm2835_gpio_fsel(PWM, BCM2835_GPIO_FSEL_ALT5);
    
    // 时钟分频设置为16. 19.2Mhz/16 = 1.2Mhz
    bcm2835_pwm_set_clock(BCM2835_PWM_CLOCK_DIVIDER_16);
    // 设置模式
    bcm2835_pwm_set_mode(PWM_CHANNEL, 1, 1);
    // 1.2MHz/1024 = 1171.875Hz,  设置计数值
    bcm2835_pwm_set_range(PWM_CHANNEL, 1024);
    // 设置高电平时间
    bcm2835_pwm_set_data(PWM_CHANNEL, 256);

    while(1)
    {
         
    }
    
    bcm2835_close();
    return 0;
}

然后编译这段代码

gcc -Wall main.c -o main -lbcm2835

-Wall 表示编译时显示所有警告,-lbcm2835 表示编译时动态加载bcm2835 库

编译完成后调用生成的main文件

sudo ./main

然后可以用示波器啥的,就可以查看到变化。、

想要停止这个程序,Ctrl+c即可。

RPi.GPIO

直接给代码了,python硬件只能设置BCM编号18的引脚

#!/usr/bin/python
# -*- coding:utf-8 -*-
import RPi.GPIO as GPIO
import time

PWM = 18
 
GPIO.setmode(GPIO.BCM)     #设置编号方式
GPIO.setup(PWM, GPIO.OUT)  #设置 引脚为输出模式

p = GPIO.PWM(PWM, 50)  #将 引脚初始化为PWM实例 ,频率为50Hz
p.start(0)             #开始脉宽调制,参数范围为: (0.0 <= dc <= 100.0)

try:
    while 1:
        for dc in range(0, 101, 5):
            p.ChangeDutyCycle(dc)   #修改占空比 参数范围为: (0.0 <= dc <= 100.0)
            time.sleep(0.1)
        for dc in range(100, -1, -5):
            p.ChangeDutyCycle(dc)
            time.sleep(0.1)
except KeyboardInterrupt:
    pass

p.stop()          #停止输出PWM波
GPIO.cleanup()    #清除

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2051674.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

07结构型设计模式——装饰器模式

一、装饰器模式简介 装饰器模式&#xff08; Decorator Pattern&#xff09;又称包装模式。通过一种面向客户端透明的方式来扩展对象的功能&#xff0c;是继承关系的一个替换方案。装饰器模式就是把要添加的附加功能分别放在单独的类中&#xff0c;并让这个类包含它要装饰的对…

求前n项和5.3.1

求他的前n项和 #include <stdio.h>int main() {int n;int i;double sum0.0;scanf("%d", &n);for(i1; i<n; i){sum1.0/i;}printf("%f", sum);return 0; } 一个变量是输入的变量 一个变量要表达递增的 另外一个变量把他们加起来表示总和…

整数分解5.3.2

题 前面写过逆序的 最后一个数后面不要有空格 #include <stdio.h>int main() {int x;scanf("%d",&x);int d;do{dx%10;printf("%d",d);if(x>10){printf(" ");}x/10;}while(x>0);printf("\n");return 0; } 现在这个是…

0818---算法

牛牛快递 如何输入一个字符&#xff1f; java中Scanner类没有.nextChar import java.utol.Scanner; Scanner in new Scanner(System.in); char b in.next().charAt(0);思路&#xff1a; 创建一个Scanner对象&#xff0c;调用Scanner对象的next()方法获取控制台输入的字符串…

Java二十三种设计模式-备忘录模式(19/23)

本文深入探讨了备忘录模式&#xff0c;从定义、组成、实现到使用场景、优缺点、与其他模式的比较&#xff0c;以及最佳实践和替代方案&#xff0c;全面解析了如何在软件开发中有效地保存和恢复对象状态&#xff0c;以支持复杂的撤销操作和历史状态管理。 备忘录模式&#xff1a…

【JAVA OOP】Day09 抽象方法、抽象类、接口、引用类型数组

Day09目标&#xff1a; 理解抽象方法、抽象类的应用场景&#xff1b; 掌握抽象方法、抽象类的语法&#xff1b; 理解接口的应用场景&#xff1b; 掌握接口的语法、应用&#xff1b; 掌握引用类型数组的用法&#xff1b; 代码量&#xff1a;课上120行&#xff0c;课下240行…

AvaloniaChat—从源码构建指南

AvaloniaChat介绍 一个使用大型语言模型进行翻译的简单应用。 我自己的主要使用场景 在看英文文献的过程中&#xff0c;比较喜欢对照着翻译看&#xff0c;因此希望一边是英文一边是中文&#xff0c;虽然某些软件已经自带了翻译功能&#xff0c;但还是喜欢大语言模型的翻译&…

2-69 基于matlab的三坐标雷达目标跟踪数据融合

基于matlab的三坐标雷达目标跟踪数据融合,采用的是概率数据关联算法和EKF&#xff0c;展示了目标的真实轨迹和跟踪滤波轨迹&#xff0c;以及数据融合的轨迹。程序已调通&#xff0c;可直接运行。 2-69 三坐标雷达目标跟踪数据融合 - 小红书 (xiaohongshu.com)

『 Linux 』利用UDP套接字简单进行网络通信

文章目录 Socket常见API转网络字节序网络数据传输的读网络数据传输的写 简单的UDP网络程序服务端基本结构Init() 服务端的初始化Run() 服务端的运行服务端启动及测试 简单的UDP网络程序客户端服务端客户端相互通信测试服务端通过传入命令处理实现远程命令执行参考代码 Socket常…

STM32————串口发送和接收数据包

首先进行实验&#xff0c;对于代码在上一节的基础上&#xff0c;先定义新变量以及增加一个发送数据包函数&#xff1a; 本代码设置FF为包头&#xff0c;FE为包尾&#xff0c;中间为需要传输的数据&#xff0c;一次为4个&#xff0c;之后是接收数据包的函数 当标志位为1代表接收…

SpringBoot+Vue实现大文件上传(分片上传)

SpringBootVue实现大文件上传&#xff08;分片上传&#xff09; 1 环境 SpringBoot 3.2.1&#xff0c;Vue 2&#xff0c;ElementUI 2 问题 前几篇文章&#xff0c;可以用于较小文件的上传&#xff0c;对于较大文件来说&#xff0c;为了提高上传效率和可靠性&#xff0c;可以采…

LeetCode题练习与总结:二叉树的右视图--199

一、题目描述 给定一个二叉树的 根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 示例 1: 输入: [1,2,3,null,5,null,4] 输出: [1,3,4]示例 2: 输入: [1,null,3] 输出: [1,3]示例 3: 输入: [] 输出…

判别回形针的方向(clip.hdev)

1.1应用示例思路 (1) 利用Blob分析(一般步骤&#xff1a;图像阈值分割、获取连通区域、计算Blob的相关几何特征)&#xff0c;获取目标区域。 (2) 求目标区域的中心坐标和方向。 1.2应用实例代码 * clip.hdev: Orientation of clips*是否必须在活动的图形窗口中显示图标对象…

“论面向服务架构设计及其应用”写作框架,软考高级,系统架构设计师

论文真题 面向服务架构&#xff08;Service-Oriented Architecture, SOA&#xff09; 是一种应用框架&#xff0c;将日常的业务应用划分为单独的业务功能服务和流程&#xff0c;通过采用良好定义的接口和标准协议将这些服务关联起来。通过实施基于SOA的系统架构&#xff0c;用…

GPT-5 惊涛来袭:铸就智能新传奇

目录 引言&#xff1a; 正文&#xff1a; 方向一&#xff1a;人工智能发展现状 方向二&#xff1a;GPT-5技术突破预测 方向三&#xff1a;智能系统人类协作 方向四&#xff1a;迎接AI技术变革策略 结束语&#xff1a; 引言&#xff1a; 在科技浩渺浪潮澎湃翻涌的时代&…

ThinkPHP5 5.0.23 远程代码执行漏洞

目录 1、启动环境 2、漏洞利用 3、更改传参方式 4、修改参数 5、发送数据 1、启动环境 docker-compose up -d 2、访问靶机ip端口号8080 2、漏洞利用 使用burpsuite抓包软件抓包 3、更改传参方式 将 GET传参改为POST传参 4、修改参数 url参数 /index.php?scaptcha post参…

聚星文社,绘唐科技AI工具

聚星文社是一个文学创作社区&#xff0c;为广大创作者提供了一个交流和展示作品的平台。绘唐科技是一家AI技术公司&#xff0c;专注于开发人工智能工具和解决方案。绘唐科技与聚星文社合作&#xff0c;为聚星文社的创作者提供了一款AI工具&#xff0c;帮助创作者提升创作效率和…

ES+FileBeat+Kibana日志采集搭建体验

1.环境准备 需要linux操作系统&#xff0c;并安装了docker环境 此处使用虚拟机演示。&#xff08;虚拟机和docker看参考我之前写的文章&#xff09; VirtualBox安装Oracle Linux 7.9全流程-CSDN博客 VirtualBox上的Oracle Linux虚拟机安装Docker全流程-CSDN博客 简单演示搭建ES…

高可用集群keepalived 详细讲解

一&#xff1a;高可用集群keepalived LB&#xff1a;Load Balance 负载均衡 负载均衡&#xff0c;其含义就是指将负载&#xff08;工作任务&#xff09;进行平衡、分摊到多个操作单元上进行运行&#xff0c;例如FTP服务器、Web服务器、企业核心应用服务器和其它主要任务服务器…

git详细命令

git常用命令&#xff0c;待 1. 前言2. Git安装3. 公钥3.1 生成公钥3.2 配置SSH 密钥 4. 配置用户名和邮箱5. git常用命令5.1 创建仓库命令5.1.1 git init命令5.1.2 git clone[url] 命令 5.2 add 增加 / 删除文件 &#xff08;跟踪文件&#xff09;5.3 代码提交5.4 分支5.5 标签…