Linux定时器编程(基于SG90舵机实践)

本文介绍了如何利用Linux的itimerval结构体和setitimer函数创建定时器,结合signal函数处理定时信号。通过示例代码展示了如何设置定时器以1s间隔输出HelloWorld,并探讨了如何调整定时器以控制SG90舵机的不同转向角度,实现了50Hz PWM波的生成,对应不同时间戳控制舵机0°至180°转动。
摘要由CSDN通过智能技术生成

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

一、itimerval结构体原型

struct itimerval {
    struct timeval it_interval; /* next value */        //定时器的初始值,一般基于这个初始值进行加\减,看控制函数具体参数设置
    struct timeval it_value;    /* current value */     //程序跑起来之后,多久启动定时器    
};

用到的timeval结构体与先前获取当前的时间函数的第一个参数结构体类型相同( int gettimeofday(struct timeval* tv,struct timezone * tz ) )。

        struct timeval结构体原型:

struct timeval
{
    __time_t tv_sec;        /* Seconds. */            //记录秒
    __suseconds_t tv_usec;  /* Microseconds. */       //记录微秒
};

二、setitimer处理函数原型:

#include <sys/time.h> //函数申明

int setitimer(int which,const struct itimerval *new_val,struct itimerval *old_value);

        参数说明:

                1、which:控制的方法(三种类型)

                         ITIMER_REAL:数值为0,计时器的值实时递减,发送的信号是:SIGALRM

                        ITIMER_VIRTUAL:数值为1,进程执行时递减计时器的值,发送的信号是:SIGVTALRM

                        ITIMER_FROF: 数值为2,进程和系统执行时都递减计时器的值,信号是:SIGPROF

                2、new_val:配置的 struct itimerval结构体

                3、old_value:记录上一次的定时的时间参量,一般不使用,指定NULL

        返回值:成功执行时,返回0;失败,返回-1.

三、代码实例:

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

static int i = 0;

void sighandler(int signal)
{
        i++;
        if(i == 2000){
                printf("Hello World\n");
                i = 0;
        }
}

int main()
{

        struct itimerval iTimer1;

        iTimer1.it_interval.tv_sec = 0;
        iTimer1.it_interval.tv_usec = 500; //初始值设置,决定了定时器的定时时间

        iTimer1.it_value.tv_sec = 3;
        iTimer1.it_value.tv_usec = 0;  //程序跑到这之后多久启动

        if(setitimer(ITIMER_REAL,&iTimer1,NULL) == -1){
                perror("error\n");
                exit(-1);
        }

        signal(SIGALRM, sighandler);

        while(1);

        return 0;
}

  现象:循环间隔1s输出Hello World    

=========配合SG90舵机的开发=========        

分析:上方根据Linux定时器的开发,做到了固定的间隔时间循环输出,为了能够使SG90舵机得到不同的转向角度,需要用到定时器输出不同的PWM方波信号。PWM波的频率不能太高,50Hz,即周期 = 1/频率 = 1/50 = 0.02s,20ms左右的数据。

基本接线: 红色:5v

                   棕色:GND

                   橙色:信号

不同的方波对应不同的角度: t = 0.5ms——————-舵机会转动 0 °
                                                t = 1.0ms——————-舵机会转动 45°
                                                t = 1.5ms——————-舵机会转动 90°
                                                t = 2.0ms——————-舵机会转动 135°
                                                t = 2.5ms——————-舵机会转动180°

接线如图:

舵机控制代码:

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

#define duoJi 0  //接线端,舵机的信号线接入香橙派zero 2的wiringPi引脚0.

static int i = 0;

int jd = 1; //角度控制变量

void sighandler()
{
    i++;
    if(i <= jd){
        digitalWrite(duoJi,HIGH);
    }else{
        digitalWrite(duoJi,LOW);
    }   
    if(i == 2000){
        i = 0;
    }   
}

int main()
{

    if(wiringPiSetup() == -1){
        perror("wiringPi\n");
        exit(-1);
    }   

    pinMode(duoJi,OUTPUT);

    struct itimerval iTimer1;

    iTimer1.it_interval.tv_sec = 0;
    iTimer1.it_interval.tv_usec = 500; //初始值设置,决定了定时器的定时时间

    iTimer1.it_value.tv_sec = 1;
    iTimer1.it_value.tv_usec = 0;  //程序跑到这之后多久启动

    if(setitimer(ITIMER_REAL,&iTimer1,NULL) == -1){
        perror("error\n");
        exit(-1);
    }

    signal(SIGALRM, sighandler);

    while(1){
        printf("1-0 / 2-45 / 3-90 / 4-135 / 5-180\n");  //循环输入,实现多角度
        scanf("%d",&jd);
    }

    return 0;
}

======实现的结果======

0度

45度 

180度 

 

 总结:Linux下的舵机开发与先前基于C51的开发没有太大区别,主要在于对Linux定时器开发的步骤的掌握。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值