实现定时器,通过
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;
}