wiringpi库的应用 -- sg90 定时器 oled

sg 90舵机:  

接线: 
VCC  --    红
GND --    地
信号线  -- 黄 -- pwm

定时器: 

 
 先玩定时器: sg90 需要的pwm波需要定时器输出,so我们得先来玩一下定时器

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


先看itimerval的结构体


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

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;
};
 
it_interval:计时器的初始值,一般基于这个初始值来加或者来,看控制函数的参数配置
it_value:程序跑到这之后,多久启动定时器

setitimer()

int setitimer (__itimer_which_t __which,
const struct itimerval *__restrict __new,
struct itimerval *__restrict __old)
setitimer()将value指向的结构体设为计时器的当前值,如果ovalue不是NULL,将返回计时器原有值。
which:三种类型
ITIMER_REAL //数值为0,计时器的值实时递减,发送的信号是SIGALRM
ITIMER_VIRTUAL //数值为1,进程执行时递减计时器的值,发送的信号是SIGVTALRM。
ITIMER_PROF //数值为2,进程和系统执行时都递减计时器的值,发送的信号是SIGPROF。
很明显,这边需要捕获对应的信号进行逻辑相关处理 signal(SIGALRM,signal_handler);

返回说明:
成功执行时,返回0。失败返回-1

//perror 在stdlib.h中

=============================================


case: 实现定时器每隔一秒打印字符串


#include<stdio.h>
#include<sys/time.h>
#include<stdlib.h>
#include<signal.h>

static int i;
void signal_handler(int signum)
{
    i++;
    if(i==2000){//0.5ms *2000=1000ms =1s
        puts("mxjun");
        i=0;
    }

}


int main()
{
    struct itimerval itv;


    //设定定时器时间
    itv.it_interval.tv_sec=0;
    itv.it_interval.tv_usec=500;

    //设定开始生效时间,启动定时器的时间
    itv.it_value.tv_sec=1;
    itv.it_value.tv_usec=0;// 500us = 0.5ms

    //设定定时的方式 -- 一般ITIMER_REAL --数值为0,计时器的值实时递减,发送的信号是SIGALRM
    if(-1 ==setitimer(ITIMER_REAL,&itv,NULL)){
        perror("error");
        exit(-1);
    }

    //信号处理 -- 收到上面发的SIGALRM信号,用signal_handler去处理

    signal(SIGALRM,signal_handler);
    while(1);

    return 0;
}

============================================

 学会定时器的是使用后就能很快实现sg90了

 


sg90 实例:  输入一个数,让舵机旋转指定角度


#include<stdio.h>
#include<sys/time.h>
#include<stdlib.h>
#include<signal.h>
#include<wiringPi.h>

#define SG90 0  
int jd;

static int i;

// 在单片机中我们使用定时器中断来,处理,这里我们信号处理, 来绘制PWM波形
void signal_handler(int signum)
{

    if(i<=jd)
        digitalWrite(SG90,HIGH);
    else
        digitalWrite(SG90,LOW);
    if(i==40){//  20 ms
        i=0;
    }
    i++;

}


int main()
{
    struct itimerval itv;
    wiringPiSetup(); 
    pinMode(SG90,OUTPUT);
    jd=0;
    //设定定时时间
    itv.it_interval.tv_sec=0;
    itv.it_interval.tv_usec=500;

    //设定开始生效时间,启动定时器时间
    itv.it_value.tv_sec=1;
    itv.it_value.tv_usec=0;// 500us = 0.5ms

    //设定定时方式
    if(-1 ==setitimer(ITIMER_REAL,&itv,NULL)){// 这个递减宏对应返回的信号就是SIGALRM
        perror("error");
        exit(-1);
    }

    //信号处理

    signal(SIGALRM,signal_handler);
    while(1)
    {
      printf("input jd:1-0  2-45 3-90 4-135\n");
      scanf("%d",&jd);
    
    }

    return 0;
}

olde 

不了解诶olde的朋友请跳转:IIC协议--OLED-CSDN博客

/*
 * Copyright (c) 2015, Vladimir Komendantskiy
 * MIT License
 *
 * SSD1306 demo of block and font drawing.
 */

//
// fixed for OrangePiZero by HypHop
//

#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdint.h>

#include "oled.h"
#include "font.h"

int oled_show(struct display_info *disp) {
    int i;
    char buf[100];

    oled_putstrto(disp, 0, 9+1, "Welcome to My HomeAssitant");
    disp->font = font1;

    oled_putstrto(disp, 0, 20, "  ---Mr.MXJ Handsome--");
    disp->font = font1;

    oled_send_buffer(disp);


return 0;
}

void show_error(int err, int add) {
    //const gchar* errmsg;
    //errmsg = g_strerror(errno);
    printf("\nERROR: %i, %i\n\n", err, add);
    //printf("\nERROR\n");
}

void show_usage(char *progname) {
    printf("\nUsage:\n%s <I2C bus device node >\n", progname);
}

int main(int argc, char **argv) {
    int e;
    char filename[32];
    struct display_info disp;

    if (argc < 2) {
        show_usage(argv[0]);
        
        return -1;
    }

    memset(&disp, 0, sizeof(disp));
    sprintf(filename, "%s", argv[1]);
    disp.address = OLED_I2C_ADDR;
    disp.font = font2;

    e = oled_open(&disp, filename);
    e = oled_init(&disp);
    oled_show(&disp);


    return 0;
}
 

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

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

相关文章

快手本地生活服务商系统怎么操作?

当下&#xff0c;抖音和快手两大短视频巨头都已开始布局本地生活服务&#xff0c;想要在这一板块争得一席之地。而这也很多普通人看到了机遇&#xff0c;选择成为抖音和快手的本地生活服务商&#xff0c;通过将商家引进平台&#xff0c;并向其提供代运营服务&#xff0c;而成功…

深入探讨虚拟现实中的新型安全威胁:“盗梦攻击”及其防御策略

随着虚拟现实&#xff08;VR&#xff09;技术的飞速发展&#xff0c;用户体验达到了前所未有的沉浸水平&#xff0c;但也暴露在一系列新的安全威胁之下。本文着重介绍了近期出现的一种高度隐秘且影响深远的攻击手段——“盗梦攻击”。这一概念由芝加哥大学的研究人员提出&#…

前端打包webpack vite

起步 | webpack 中文文档 | webpack中文文档 | webpack中文网 npm run build 1webpack: mkdir webpack-demo cd webpack-demo npm init -y npm install webpack webpack-cli --save-dev vite : 快速上手 | Vue.js

【Entity Framework】闲话EF中批量配置

【Entity Framework】闲话EF中批量配置 文章目录 【Entity Framework】闲话EF中批量配置一、概述二、OnModelCreating中的批量配置元数据API的缺点 三、预先约定配置忽略类型默认类型映射预先约定配置的限制约定添加新约定替换现有约定约定实现注意事项 四、何时使用每种方法进…

游戏登录界面制作

登录界面制作 1.导入模块和初始化窗口 import subprocessimport tkinter as tkimport picklefrom tkinter import messageboxwindow tk.Tk()window.title(Welcome)window.geometry(450x300) 导入必要的模块&#xff0c;并初始化了主窗口window&#xff0c;设置了窗口的标题和…

修改taro-ui-vue3的tabs组件源码增加数字标签

需求&#xff1a;taro-ui-vue3的tabs组件上增加数字标记 步骤一&#xff1a;node_modules文件夹下找到taro-ui-vue3/lib/tabs/index.js 把173行的这一段替换成下面这段&#xff0c;然后写上样式 default: () > item.number ? [h(View, {class: at-tabs__item_in}, {defau…

Unity导出package

C#代码导出后为一个dll&#xff0c;原有的不同平台的库不变。 以下操作均在build PC 平台下操作。 1.在要导出的文件夹下建assembly definition (Any platform) 2.将项目文件夹下的\Library\ScriptAssemblies中的相应assembly definition的dll复制到要导出的文件夹下 3.在uni…

基于Java+SpringBoot+Vue前后端分离仓库管理系统

基于JavaSpringBootVue前后端分离仓库管理系统 &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定制系统 &#…

Vue3基本功能介绍

文章目录 Vue3组件中的模板结构可以没有根标签div组合式APIRefReactive函数回顾Vue2响应式Vue3实现响应式对比reactive和refSetup注意点计算属性与监听computedWatchWatchEffectVue3生命周期自定义hook函数toRef其他组合APIshallowReactiveshallowRefreadonly和shallowOnlyToRa…

赋能企业高效精准的EDM邮件群发推广

数字化营销日益成为商业增长引擎&#xff0c;云衔科技以其创新的智能EDM&#xff08;Electronic Direct Mail&#xff09;邮件群发推广解决方案&#xff0c;帮助企业客户突破传统营销模式&#xff0c;实现业绩飞跃和品牌影响力的大幅提升。 作为数字化广告营销及SaaS软件服务领…

安装mysql5.7.26一个报错问题

首先先安装mysql5.7.26,因为要求安装的版本要和原来的一样&#xff0c;数据路径也要和原来一致 一、安装mysql5.7.26 mysql官网各种版本下载网址 MySQL :: Download MySQL Community Server (Archived Versions) 1、下载mysql安装包 2、环境准备 centos7.9 mysql5.7.26包…

【简单介绍下Faiss原理和使用】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

有哪些公认好用且免费的云渲染网渲平台?渲染100邀请码1a12

现在云渲染是越来越火了&#xff0c;无论是在建筑设计、影视动画还是效果图行业都有它的身影&#xff0c;云渲染能缩短制作周期&#xff0c;提高工作效率&#xff0c;那么市面上有哪些公认好用且免费的云渲染平台呢&#xff1f;这次我们来了解下。 首先&#xff0c;我们来看看有…

牛客Linux高并发服务器开发学习第三天

静态库的使用(libxxx.a) 将lession04的文件复制到lession05中 lib里面一般放库文件 src里面放源文件。 将.c文件转换成可执行程序 gcc main.c -o app main.c当前目录下没有head.h gcc main.c -o app -I ./include 利用-I 和head所在的文件夹&#xff0c;找到head。 main.c…

Redis中的Lua脚本(五)

Lua脚本 脚本复制 复制EVALSHA命令 EVALSHA命令式所有与Lua脚本有关的命令中&#xff0c;复制操作最复杂的一个&#xff0c;因为主服务器与从服务器载入Lua脚本的情况可能有所不同&#xff0c;所以主服务器不能像复制EVAL命令、SCRIPT LOAD命令或者SCRIPT FLUSH命令那样&…

[大模型]Qwen-7B-Chat 接入langchain搭建知识库助手

Qwen-7B-Chat 接入langchain搭建知识库助手 环境准备 在autodl平台中租一个3090等24G显存的显卡机器&#xff0c;如下图所示镜像选择PyTorch–>2.0.0–>3.8(ubuntu20.04)–>11.8 接下来打开刚刚租用服务器的JupyterLab&#xff0c;并且打开其中的终端开始环境配置…

河北专升本(c语言各种编程题)

目录 第一类、递归调用 第二类、特殊数字 第三类、多维数组 第四类、字符处理 第五类、数学问题 第六类、排序算法 第七类、循环问题 第八类、进制转换 第九类、实际应用 第十类、图形输出 第一类、递归调用 1.汉诺塔&#xff1a;请输入盘子数&#xff0c;输出盘子移动…

05_Flutter屏幕适配

05_Flutter屏幕适配 一.屏幕适配方案 通过指定基准屏宽度&#xff0c;进行适配&#xff0c;基准屏宽度取决于设计图的基准宽度&#xff0c;以iphone 14 pro max为例&#xff0c; devicePixelRatio 物理宽度 / 逻辑宽度(基准宽度) iphone 14 pro max的物理尺寸宽度为1290&…

基于SSM的购物小程序01

4.1系统架构设计 购物系统设计的系统项目的概述设计分析&#xff0c;主要内容有学习平台的具体分析&#xff0c;进行数据库的是设计&#xff0c;数据采用mysql数据库&#xff0c;并且对于系统的设计采用比较人性化的操作设计&#xff0c;对于系统出现的错误信息可以及时做出处…

【Linux系统】地址空间 Linux内核进程调度队列

1.进程的地址空间 1.1 直接写代码&#xff0c;看现象 1 #include<stdio.h>2 #include<unistd.h>3 4 int g_val 100;5 6 int main()7 {8 int cnt 0;9 pid_t id fork();10 if(id 0)11 {12 while(1)13 {14 printf(&…