当前位置: 首页 > news >正文

香橙派使用外设驱动库wiringOP 配合定时器来驱动舵机

舵机认识和硬件接线

关于舵机也是使用过很多次了,详见:

使用PWM波控制开发SG90-CSDN博客

同时再次回顾香橙派的物理引脚对应:

所以舵机的VCC接 2,GND接 6,PWM接 7(此处写的是物理引脚编号

Linux定时器

驱动舵机必不可少的就是生成PWM波,上节超声波测距的时间计算学习了Linux自带的时间函数,本节生成PWM就正式学习香橙派的定时器,用定时器来生成PWM波!

由于香橙派跑的系统就是Linux,所以其实就是使用Linux来实现定时器,根据舵机的原理,一般使用50Hz频率(周期为20ms)的PWM波来控制,而角度的大小就取决于高电平的占比,20ms中有0.5ms,1.0ms,1.5ms,2.0ms,2.5ms的高电平就分别对应舵机转0度,45度,90度,135度,180度。所以本质上,只要能实现出一个定时0.5ms(500us)的定时器,并让他定时1次,2次,3次,4次,5次就可以实现所有的角度。

Linux定时器的实现,是通过 itimerval 结构体以及函数 setitimer 产生的信号,系统随之使用signal信号处理函数 来处理产生的定时信号,从而实现定时器。

itimerval结构体

struct itimerval
{
/* Value to put into `it_value' when the timer expires. */struct timeval it_interval;
/* Time to the next timer expiration. */struct timeval it_value;
};struct timeval
{__time_t tv_sec; /* Seconds. */__suseconds_t tv_usec; /* Microseconds. */
};

可见,itimerval结构体中有两个成员,这两个成员都属于timeval结构体,timeval结构体上节课接触过,有两个分别代表秒和微秒的成员。

  • it_interval:计时器的初始值,一般基于这个初始值来加或者来减,看控制函数的参数配置
  • it_value:程序跑到这之后,多久启动定时器 

setitimer函数

setitimer()将value指向的结构体设为计时器的当前值,如果ovalue不是NULL,将返回计时器原有值

#include <sys/time.h>int setitimer (__itimer_which_t __which, const struct itimerval *__restrict __new, struct itimerval *__restrict __old)
  • which:控制的方法,有以下三种类型
  • ITIMER_REAL //数值为0,计时器的值实时递减,发送的信号是SIGALRM
  • ITIMER_VIRTUAL //数值为1,进程执行时递减计时器的值,发送的信号是SIGVTALRM
  • ITIMER_PROF //数值为2,进程和系统执行时都递减计时器的值,发送的信号是SIGPROF
  • new:指向 itimerval 结构体的指针
  • old: 一般不用,设置为NULL
  • 返回值:成功返回0,失败返回-1

 

signal函数

之前在系统编程部分学过,详见:

信号-CSDN博客

#include <signal.h>typedef void (*sighandler_t)(int); //一个指向“传入参数是int 返回值是void的函数”,名为“sighandler_t”的指针sighandler_t signal(int signum, sighandler_t handler);
  • signum:信号编号
  • handler:函数指针,指向信号处理函数;也可以使用宏,比如使用“SIG_IGN”,则忽略信号

这种方法需要注意的是,一个进程只能创建一个定时器!

代码验证 

timer_test.c:

/*该代码实现的功能是: 1s后开启定时器,然后每隔1s向终端打印hello。*/#include <stdio.h>
#include <sys/time.h>
#include <signal.h>
#include <stdlib.h>static int i;void signal_handler(int signum)
{i++;if(i == 2000){ //计时2000*500 = 1000000us = 1sprintf("hello\n");i = 0;}
}int main()
{struct itimerval itv;//设定定时时间为500usitv.it_interval.tv_sec = 0;itv.it_interval.tv_usec = 500;//设定开始生效,启动定时器的时间为1秒后itv.it_value.tv_sec = 1;itv.it_value.tv_usec = 0;//设定定时方式if( -1 == setitimer(ITIMER_REAL, &itv, NULL)){perror("timer");exit(-1);}//信号处理signal(SIGALRM,signal_handler);while(1); //防止程序退出return 0;
}

代码编写 

SG90_test.c:

#include <stdio.h>
#include <sys/time.h>
#include <signal.h>
#include <stdlib.h>
#include <wiringPi.h>#define PWM 2int angle;
static int i;void signal_handler(int signum)
{if(i <= angle){digitalWrite(PWM, HIGH);}else{digitalWrite(PWM, LOW);}if(i == 40){ //40*500 = 20000us = 20msi = 0;}i++;}int main()
{struct itimerval itv;wiringPiSetup () ;pinMode (PWM, OUTPUT);//设定定时时间itv.it_interval.tv_sec = 0;itv.it_interval.tv_usec = 500;//设定开始生效,启动定时器的时间itv.it_value.tv_sec = 1;itv.it_value.tv_usec = 0;//设定定时方式if( -1 == setitimer(ITIMER_REAL, &itv, NULL)){perror("error");exit(-1);}//信号处理signal(SIGALRM,signal_handler);while(1){printf("enter the angle: 1 -> 0; 2 -> 45; 3 -> 90; 4 -> 135; 5 -> 180\n");scanf("%d",&angle);i = 0;}return 0;

实现效果:

在Linux界面输入角度值,舵机就会相应的转动多少度:

(缠黑纱绑带的一段视为方向指示端)

相关文章:

香橙派使用外设驱动库wiringOP 配合定时器来驱动舵机

舵机认识和硬件接线 关于舵机也是使用过很多次了&#xff0c;详见&#xff1a; 使用PWM波控制开发SG90-CSDN博客 同时再次回顾香橙派的物理引脚对应&#xff1a; 所以舵机的VCC接 2&#xff0c;GND接 6&#xff0c;PWM接 7&#xff08;此处写的是物理引脚编号&#xff09; Li…...

C++学习笔记--函数重载(2)

文章目录 1.3、Function Templates Handling1.3.1、Template Argument Deduction1.3.2、Template Argument Substitution 1.4、Overload Resolution1.4.1、Candidate functions1.4.2、Viable functions1.4.3、Tiebreakers 1.5、走一遍完整的流程1.6、Name Mangling1.7、总结 1.…...

代码随想录算法训练营Day56 || ● 583. 两个字符串的删除操作 ● 72. 编辑距离

今天接触到了真正的距离&#xff0c;但可以通过增删改操作来逼近。 问题1&#xff1a;583. 两个字符串的删除操作 - 力扣&#xff08;LeetCode&#xff09; 给定两个单词 word1 和 word2 &#xff0c;返回使得 word1 和 word2 相同所需的最小步数。 每步 可以删除任意一个字…...

chrome_elf.dll丢失怎么办?修复chrome_elf.dll文件的方法

Chrome是目前最受欢迎的网络浏览器之一&#xff0c;然而有时用户可能会遇到Chrome_elf.dll丢失的问题。该DLL文件是Chrome浏览器的一个重要组成部分&#xff0c;负责启动和管理程序的各种功能。当Chrome_elf.dll丢失时&#xff0c;用户可能无法正常启动Chrome或执行某些功能。本…...

代码随想录32|738.单调递增的数字,968.监控二叉树,56. 合并区间

738.单调递增的数字 链接地址 class Solution { public:int monotoneIncreasingDigits(int n) {string str to_string(n);int flag str.size();for (int i str.size() - 1; i > 0; i--) {if (str[i] < str[i - 1]) {str[i - 1] - 1;flag i;}}for (int j flag; j <…...

BIO NIO AIO演变

Netty是一个提供异步事件驱动的网络应用框架&#xff0c;用以快速开发高性能、高可靠的网络服务器和客户端程序。Netty简化了网络程序的开发&#xff0c;是很多框架和公司都在使用的技术。 Netty并非横空出世&#xff0c;它是在BIO&#xff0c;NIO&#xff0c;AIO演变中的产物…...

JVM GC垃圾回收

一、GC垃圾回收算法 标记-清除算法 算法分为“标记”和“清除”阶段&#xff1a;标记存活的对象&#xff0c; 统一回收所有未被标记的对象(一般选择这种)&#xff1b;也可以反过来&#xff0c;标记出所有需要回收的对象&#xff0c;在标记完成后统一回收所有被标记的对象 。它…...

【数据结构】队列知识点总结--定义;基本操作;队列的顺序实现;链式存储;双端队列;循环队列

欢迎各位看官^_^ 目录 1.队列的定义 2.队列的基本操作 2.1初始化队列 2.2判断队列是否为空 2.3判断队列是否已满 2.4入队 2.5出队 2.6完整代码 3.队列的顺序实现 4.队列的链式存储 5.双端队列 6.循环队列 1.队列的定义 队列&#xff08;Queue&#xff09;是一种先…...

嵌入式学习之链表

对于链表&#xff0c;要重点掌握链表和数组区别和实现&#xff0c;链表静态添加和动态遍历&#xff0c;链表中pointpoint-next,链表节点个数的查找&#xff0c;以及链表从指定节点后方插入新节点的知识。...

静态代理和动态代理笔记

总体分为: 1.静态代理: 代理类和被代理类需要实现同一个接口.在代理类中初始化被代理类对象.在代理类的方法中调 用被代理类的方法.可以选择性的在该方法执行前后增加功能或者控制访问 2.动态代理: 在程序执行过程中,实用JDK的反射机制,创建代理对象,并动态的指定要…...

[SM6225][Android13]user版本默认允许root和remount

开发平台基本信息 芯片: 高通SM6225版本: Android 13kernel: msm-5.15 问题描述 刚刚从Framework踏入性能的小殿堂&#xff0c;User版本默认是不会开启root权限的&#xff0c;而且一般调试需要设置一下CPU GPU DDR performance模式或者修改一些schedule util等调核调频节点去…...

pyinstaller打包exe,使用wexpect的问题

参考github首先打包wexpect 1.进入wexpect目录执行 pyinstaller __main__.py -n wexpect 会生成dist文件夹 2.python代码A.py中使用wexpect&#xff0c;注意wexpect.spawn前后必须按照下面添加代码 import sys,os,wexpect #spawn前 real_executable sys.executable try:if sy…...

OpenCV(三十三):计算轮廓面积与轮廓长度

1.介绍轮廓面积与轮廓长度 轮廓面积&#xff08;Contour Area&#xff09;是指轮廓所包围的区域的总面积。通常情况下&#xff0c;轮廓面积的单位是像素的平方。 轮廓长度&#xff08;Contour Length&#xff09;又称周长&#xff08;Perimeter&#xff09;&#xff0c;表示轮廓…...

9.11作业

实现一个对数组求和的函数&#xff0c;数组通过实参传递给函数 sum0 arr(11 22 33 44 55) Sum() {for i in ${arr[*]}do$((sumi))donereturn $sum } Sum ${arr[*]} var$? echo $var写一个函数&#xff0c;输出当前用户的uid和gid&#xff0c;并使用变量接收结果 Sum() {aid -…...

AI伦理与未来社会:探讨人工智能的道德挑战与机会

引言 引出AI伦理和社会影响的主题&#xff0c;强调AI的快速发展和广泛应用。 概述博客的主要内容&#xff1a;探讨AI的伦理挑战以及它对社会的影响。 第一部分&#xff1a;AI的伦理挑战 算法偏见&#xff1a; 解释什么是算法偏见&#xff0c;以及它为何在AI中成为一个重要问题。…...

Android窗口层级(Window Type)分析

前言 Android的窗口Window分为三种类型&#xff1a; 应用Window&#xff0c;比如Activity、Dialog&#xff1b;子Window&#xff0c;比如PopupWindow&#xff1b;系统Window&#xff0c;比如Toast、系统状态栏、导航栏等等。 应用Window的Z-Ordered最低&#xff0c;就是在系…...

微信小程序基础加强总结

本篇文章给大家带来了关于微信小程序的相关问题&#xff0c;其中主要介绍了一些基础内容&#xff0c;包括了自定义组件、样式隔离、数据、方法和属性等等内容&#xff0c;下面一起来看一下&#xff0c;希望对大家有帮助。 1、自定义组件 1.1、创建组件 在项目的根目录中&…...

【JAVA - List】差集removeAll() 四种方法实现与优化

一、场景&#xff1a; 二、结论&#xff1a; 1. 四种方法耗时 三、代码&#xff1a; 一、场景&#xff1a; 求差集 List1 - Lsit2 二、结论&#xff1a; 1. 四种方法耗时 初始条件方法名方法思路耗时 List1.size319418 List2.size284900 List..removeAll(Lsit2)1036987ms…...

sql注入基本概念

死在山野的风里&#xff0c;活在自由的梦里 sql注入基本概念 MYSQL基本语法union合并查询2个特性&#xff1a;order by 排序三个重要的信息 Sql Server MYSQL 基本语法 登录 mysql -h ip -u user -p pass基本操作 show databases; 查看数据库crea…...

AIGC系列:1.chatgpt可以用来做哪些事情?

上图的意思&#xff1a;神器轩辕剑 那么&#xff0c;在现在AI盛行的信息时代&#xff0c; 你是否知道如何获得和利用ChatGPT这一把轩辕剑来提升你的攻击力和生存能力呢&#xff1f; 故事 程序员小张&#xff1a; 刚毕业&#xff0c;参加工作1年左右&#xff0c;日常工作是C…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

【iOS】 Block再学习

iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...

【深尚想】TPS54618CQRTERQ1汽车级同步降压转换器电源芯片全面解析

1. 元器件定义与技术特点 TPS54618CQRTERQ1 是德州仪器&#xff08;TI&#xff09;推出的一款 汽车级同步降压转换器&#xff08;DC-DC开关稳压器&#xff09;&#xff0c;属于高性能电源管理芯片。核心特性包括&#xff1a; 输入电压范围&#xff1a;2.95V–6V&#xff0c;输…...

C++11 constexpr和字面类型:从入门到精通

文章目录 引言一、constexpr的基本概念与使用1.1 constexpr的定义与作用1.2 constexpr变量1.3 constexpr函数1.4 constexpr在类构造函数中的应用1.5 constexpr的优势 二、字面类型的基本概念与使用2.1 字面类型的定义与作用2.2 字面类型的应用场景2.2.1 常量定义2.2.2 模板参数…...

PostgreSQL 与 SQL 基础:为 Fast API 打下数据基础

在构建任何动态、数据驱动的Web API时&#xff0c;一个稳定高效的数据存储方案是不可或缺的。对于使用Python FastAPI的开发者来说&#xff0c;深入理解关系型数据库的工作原理、掌握SQL这门与数据库“对话”的语言&#xff0c;以及学会如何在Python中操作数据库&#xff0c;是…...

标注工具核心架构分析——主窗口的图像显示

&#x1f3d7;️ 标注工具核心架构分析 &#x1f4cb; 系统概述 主要有两个核心类&#xff0c;采用经典的 Scene-View 架构模式&#xff1a; &#x1f3af; 核心类结构 1. AnnotationScene (QGraphicsScene子类) 主要负责标注场景的管理和交互 &#x1f527; 关键函数&…...