一、SG90舵機(jī)開發(fā)
舵機(jī)基本介紹
二、Linux定時(shí)器
- signal 函數(shù)
- setitimer 函數(shù)原型
- signal、setitimer函數(shù)API調(diào)用
三、舵機(jī) 軟件PWM實(shí)現(xiàn)
一、SG90舵機(jī)開發(fā)
舵機(jī)基本介紹
如下圖所示,最便宜的舵機(jī)sg90,常用三根或者四根接線,黃色為PWM信號(hào)控制用處:
垃圾桶項(xiàng)目開蓋用、智能小車的全比例轉(zhuǎn)向、攝像頭云臺(tái)、機(jī)械臂等
常見的有0-90°、0-180°、0-360°
怎么控制轉(zhuǎn)角
向黃色信號(hào)線“灌入”PWM信號(hào)。
PWM波的頻率不能太高,50hz,即周期=1/頻率=1/50=0.02s,20ms左右數(shù)據(jù):
不同的PWM波形對(duì)應(yīng)不同的旋轉(zhuǎn)角度,以20ms為周期,50hz為頻率的PWM波
二、Linux定時(shí)器
signal 函數(shù)
signal
函數(shù)是一個(gè)用于設(shè)置信號(hào)處理函數(shù)的C標(biāo)準(zhǔn)庫(kù)函數(shù),可用于捕獲和處理信號(hào)。信號(hào)是在UNIX和類UNIX操作系統(tǒng)中用于通知進(jìn)程發(fā)生了特定事件的一種異步通知機(jī)制。signal
函數(shù)的原型如下:
#include <signal.h>
void (*signal(int signum, void (*handler)(int)))(int);
參數(shù)說(shuō)明:
-
signum
:要捕獲和處理的信號(hào)的編號(hào),它是一個(gè)整數(shù),如SIGINT
(中斷信號(hào))、SIGTERM
(終止信號(hào))等。 -
handler
:一個(gè)函數(shù)指針,指向你自己編寫的信號(hào)處理函數(shù),用于處理接收到的信號(hào)。
signal
函數(shù)允許你為指定的信號(hào)注冊(cè)一個(gè)自定義的處理函數(shù),該處理函數(shù)會(huì)在程序接收到相應(yīng)的信號(hào)時(shí)被調(diào)用。處理函數(shù)的原型如下:
void handler_function(int signum);
示例用法:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
// 自定義信號(hào)處理函數(shù)
void sigint_handler(int signum) {
printf("Received SIGINT (Ctrl+C) signal. Exiting...\n");
exit(0);
}
int main() {
// 注冊(cè)自定義信號(hào)處理函數(shù),用于捕獲SIGINT信號(hào)(Ctrl+C)
signal(SIGINT, sigint_handler);
printf("Press Ctrl+C to trigger the custom signal handler.\n");
while (1) {
// 無(wú)限循環(huán)等待信號(hào)
}
return 0;
}
在上述示例中,signal
函數(shù)用于注冊(cè)一個(gè)自定義的信號(hào)處理函數(shù) sigint_handler
,用于捕獲 SIGINT
信號(hào)(通常由Ctrl+C觸發(fā))。當(dāng)用戶按下Ctrl+C時(shí),程序會(huì)執(zhí)行自定義處理函數(shù),然后退出。這使你能夠在程序中捕獲和處理特定的信號(hào),以采取適當(dāng)?shù)男袆?dòng)。不同的信號(hào)有不同的用途,可以用于控制程序的行為。
setitimer 函數(shù)原型
分析:實(shí)現(xiàn)定時(shí)器,通過(guò)itimerval
結(jié)構(gòu)體以及函數(shù)setitimer
產(chǎn)生的信號(hào),系統(tǒng)隨之使用signal
信號(hào)處理函數(shù)
來(lái)處理產(chǎn)生的定時(shí)信號(hào)。從而實(shí)現(xiàn)定時(shí)器。
setitimer
是一個(gè)UNIX系統(tǒng)上的系統(tǒng)調(diào)用函數(shù),用于設(shè)置和管理定時(shí)器。它通常用于定期觸發(fā)信號(hào)或執(zhí)行某些操作。setitimer
函數(shù)的原型如下:
#include <sys/time.h>
int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);
參數(shù)說(shuō)明:
-
which
:指定要設(shè)置的定時(shí)器類型,可以是ITIMER_REAL
、ITIMER_VIRTUAL
或ITIMER_PROF
中的一個(gè)。-
ITIMER_REAL
:以實(shí)際時(shí)間計(jì)時(shí),通常用于實(shí)現(xiàn)定時(shí)器功能。 -
ITIMER_VIRTUAL
:以進(jìn)程的虛擬時(shí)間(CPU時(shí)間)計(jì)時(shí)。 -
ITIMER_PROF
:以進(jìn)程的虛擬時(shí)間和系統(tǒng)時(shí)間(CPU和墻鐘時(shí)間)計(jì)時(shí)。
-
-
new_value
:一個(gè)struct itimerval
結(jié)構(gòu),用于指定新的定時(shí)器值。 -
old_value
:一個(gè)struct itimerval
結(jié)構(gòu),用于存儲(chǔ)舊的定時(shí)器值(可選參數(shù))。
struct itimerval
結(jié)構(gòu)定義如下:
struct itimerval {
struct timeval it_interval; // 定時(shí)器重復(fù)的間隔時(shí)間
struct timeval it_value; // 定時(shí)器的初始值
};
setitimer
允許你設(shè)置定時(shí)器的初始值和重復(fù)間隔。一旦定時(shí)器啟動(dòng),它將在到期時(shí)觸發(fā)一個(gè)信號(hào),通常是 SIGALRM
信號(hào)。你可以捕獲這個(gè)信號(hào)并執(zhí)行相應(yīng)的操作。
示例用法:
#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
void timer_handler(int signum) {
// 定時(shí)器到期時(shí)觸發(fā)的處理函數(shù)
printf("Timer expired! (Signum: %d)\n", signum);
}
int main() {
struct itimerval timer;
timer.it_value.tv_sec = 1; // 初始定時(shí)器值為1秒
timer.it_value.tv_usec = 0;
timer.it_interval.tv_sec = 2; // 重復(fù)間隔為2秒
timer.it_interval.tv_usec = 0;
// 設(shè)置定時(shí)器并關(guān)聯(lián)處理函數(shù)
signal(SIGALRM, timer_handler);
setitimer(ITIMER_REAL, &timer, NULL);
// 讓程序保持運(yùn)行
while (1) {
}
return 0;
}
上述示例設(shè)置了一個(gè)每隔1秒觸發(fā)一次的定時(shí)器,并在定時(shí)器到期時(shí)觸發(fā) SIGALRM
信號(hào),執(zhí)行 timer_handler
處理函數(shù)。你可以根據(jù)需要修改定時(shí)器的初始值和重復(fù)間隔以實(shí)現(xiàn)不同的定時(shí)任務(wù)。
signal、setitimer函數(shù)API調(diào)用
/*該代碼實(shí)現(xiàn)的功能是: 1s后開啟定時(shí)器,然后每隔1s向終端打印hello。*/
#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){
printf("hello\n");
i = 0;
}
}
int main()
{
struct itimerval itv;
//設(shè)定定時(shí)時(shí)間
itv.it_interval.tv_sec = 0;
itv.it_interval.tv_usec = 500;
//設(shè)定開始生效,啟動(dòng)定時(shí)器的時(shí)間
itv.it_value.tv_sec = 1;
itv.it_value.tv_usec = 0;
//設(shè)定定時(shí)方式
if (setitimer(ITIMER_REAL, &itv, NULL) == -1){
perror("error");
exit(-1);
}
//信號(hào)處理
signal(SIGALRM, signal_handler);
while(1);
return 0;
}
這種方法需要注意的是,一個(gè)進(jìn)程只能創(chuàng)建一個(gè)定時(shí)器
三、舵機(jī) 軟件PWM實(shí)現(xiàn)
SG90編程實(shí)現(xiàn):鍵盤輸入不同的值,讓舵機(jī)轉(zhuǎn)動(dòng),軟件PWM實(shí)現(xiàn)
#include <stdio.h>
#include <sys/time.h>
#include <stdlib.h>
#include <signal.h>
#include <wiringPi.h>
#define SG90Pin 5
int angle;
static int i = 0;
void signal_handler(int signum)
{
if(i <= angle){
digitalWrite(SG90Pin, HIGH);
}else{
digitalWrite(SG90Pin, LOW);
}
if (i == 40){
i = 0;
}
i++;
}
int main()
{
struct itimerval itv;
angle = 0;
wiringPiSetup();
pinMode(SG90Pin, OUTPUT);
//設(shè)定定時(shí)時(shí)間0.5ms
itv.it_interval.tv_sec = 0;
itv.it_interval.tv_usec = 500;
//設(shè)定開始生效,啟動(dòng)定時(shí)器的時(shí)間
itv.it_value.tv_sec = 1;
itv.it_value.tv_usec = 0;
//設(shè)定定時(shí)方式
if (setitimer(ITIMER_REAL, &itv, NULL) == -1){
perror("error");
exit(-1);
}
//信號(hào)處理
signal(SIGALRM, signal_handler);
while (1){
printf("input angle: 1-0 2-45 3-90 4-135 5-180.\n");
scanf("%d", &angle);
}
return 0;
}
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-745734.html
轉(zhuǎn)圈圈文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-745734.html
到了這里,關(guān)于【Orangepi Zero2 全志H616】驅(qū)動(dòng)舵機(jī)控制 / Linux定時(shí)器(signal、setitimer)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!