Linux定时器的使用

实现定时器,通过 itimerval结构体 以及函数 setitimer 产生的信号,系统随之使用 signal 信号处理
函数来处理产生的定时信号。从而实现定时器。
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:多久后启动定时器

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


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(信号类型,信号处理函数); //开启定时器处理事件

定时器实验1(每1秒打印内容) 

 

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

static int i = 0;


void t_handler(int signum)
{
    //每500微妙进入一次
    i++;
    if(i==2000){ 
    //当 2000次时候也就是 500*2000 = 1000000(1秒)时运行
    printf("hello world!\n");
    i=0;
    }
}


int main()
{
   struct itimerval itv;
    //1.设定定时器的初始值
    itv.it_interval.tv_sec = 0;
    itv.it_interval.tv_usec = 500;
    printf("the timer start\n");
    
    //2.设置定时器什么时候开始
    itv.it_value.tv_sec = 1;
    itv.it_value.tv_usec= 0;

     //3.定时方式
    setitimer(ITIMER_REAL,&itv,NULL);
    
    //4.信号处理
    signal(SIGALRM,t_handler);

    for(;;);

    return 0;
}

 运行结果

 

定时器实验2 (控制SG90舵机)

 本实验使用SG90舵机进行软件PWM控制

怎么控制舵机角度旋转?

向PWM信号线输入信号,PWM的频率不能过高,这里使用50HZ作为频率

周期计算 : 周期 = 1/频率 = 1/50 = 0.02s = 20ms

不同的 PWM 波形对应不同的旋转角度,以 20ms 为周期, 50hz 为频率的 PWM

定时器需要定时20ms作为一个运行的周期,我们可以将定时器的初始值定义为0.5ms

这样就有40个0.5ms组成一个完整的20ms周期 (20ms = 0.5ms * 40

代码实现(控制舵机)

向键盘输入数字1-5控制舵机的角度

注意:一个进程只能创建一个定时器

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

#define SG90 5
char mark = 0;
static int i = 0;
 int jd ;
int bak_jd;

void t_handler(int signum)
{
    if(i<=jd)
    {
        digitalWrite(SG90,HIGH);
    }else{ digitalWrite(SG90,LOW);}

    if(i==40){
    bak_jd = jd;
    i=0;
    }
    i++;
}

int main()
{
    wiringPiSetup();
    pinMode(SG90,OUTPUT);
    jd = 5;
    bak_jd = 0;
    struct itimerval itv;
    //1.设定定时器的初始值
    itv.it_interval.tv_sec = 0;
    itv.it_interval.tv_usec = 500;
    //2.设置定时器多久后开始
    itv.it_value.tv_sec = 1;
    itv.it_value.tv_usec= 0;
    //3.定时方式
    setitimer(ITIMER_REAL,&itv,NULL);
    //4.信号处理
    signal(SIGALRM,t_handler);
    for(;;){
        printf("请输入角度:(0度-1 45度-2 90度-3 145度-4 180度-5)\n");
        printf(">");
        scanf("%d",&jd);
        if(jd>5){
            printf("error input\n");
            continue;
        }
    }
    return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值