12_QT跨平臺執行之使用QT控制蜂鳴器

爱吃冰激凌的黄某某發表於2024-04-17

QT跨平臺執行之使用QT控制蜂鳴器

QT****下操作硬體

我們在QT上要怎麼操作驅動呢?比如,我們要點亮一個led燈,我們在C語言中可以使用open,read,write,ioctl函式來進行操作,但是QT上我們使用的語言是C++,那我們要怎麼來操作驅動呢?

我們可以使用C和C++進行混合程式設計,我們先來看一個控制蜂鳴器的APP程式碼,這裡以終結者I.MX6ULL為例,程式碼如下:

#include "stdio.h"
#include "unistd.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "fcntl.h"
#include "stdlib.h"
#include "string.h"

#define BEEPOFF 0
#define BEEPON 1

/*
 * @description : main 主程式
 * @param - argc : argv 陣列元素個數
 * @param - argv : 具體引數
 * @return : 0 成功;其他 失敗
 */
int main(int argc, char *argv[])
{
	int fd, retvalue;
	char *filename;
	unsigned char databuf[1];

	if(argc != 3){
		printf("Error Usage!\r\n");
		return -1;
	}

	filename = argv[1];

	/* 開啟 beep 驅動 */
	fd = open(filename, O_RDWR);
	if(fd < 0){
		printf("file %s open failed!\r\n", argv[1]);
		return -1;
	}

	databuf[0] = atoi(argv[2]); /* 要執行的操作:開啟或關閉 */

	/* 向/dev/beep 檔案寫入資料 */
	retvalue = write(fd, databuf, sizeof(databuf));
	if(retvalue < 0){
		printf("BEEP Control Failed!\r\n");
		close(fd);
		return -1;
	}

	retvalue = close(fd); /* 關閉檔案 */
	if(retvalue < 0){
		printf("file %s close failed!\r\n", argv[1]);
		return -1;
	}
	return 0;
}

透過上面的程式碼我們可以發現,使用C語言來控制一個蜂鳴器,無非就是開啟裝置節點,然後透過write來寫入資料就可以控制蜂鳴器了。既然我們可以使用C和C++混合程式設計,那麼我們是不是隻需要把這個C控制蜂鳴器的程式碼直接加到QT程式裡面就可以了,那我們我們要怎麼進行混合程式設計呢?

我們先新建一個QT工程,然後新增倆個按鈕來控制蜂鳴器的開啟和關閉,UI介面如下:

img

然後我們開始移植程式碼,因為C++是物件導向的,C是程序導向的,所以在QT上,我們要用物件導向的思想來進行程式設計,所以我們第一步,就是要先建立一個類,把C語音控制蜂鳴器的程式碼封裝成一個類。

我們右鍵選中這個工程,然後選擇新增新檔案,新增C++ Class如下:

img

然後我們新增類的名字,因為我們操作是的蜂鳴器,所以我們這裡寫成Beep,如下圖:

img

第一步,我們把C語言控制蜂鳴器程式碼的標頭檔案,新增到我們剛才新增Beep類生成的檔案beep.h裡面,但是標頭檔案我們不能直接複製過去,我們要用extern “C”{}括起來,程式碼如下:

extern "C"{
    #include "stdio.h"
    #include "unistd.h"
    #include "sys/types.h"
    #include "sys/stat.h"
    #include "fcntl.h"
    #include "stdlib.h"
    #include "string.h"
}

新增完成如下圖所示:

img

第二步,把我們C語言控制蜂鳴器裡面的引數定義複製到public下面,程式碼如下:

int fd, retvalue;
char *filename;
unsigned char databuf[1];

新增完如下圖所示:

img

然後我們開啟beep.cpp,把C語言控制蜂鳴器裡面的開啟裝置節點的程式碼複製到建構函式里面,注意,QT裡面我們不能使用printf,程式碼如下:

/* 開啟 beep 驅動 */
fd = open(filename, O_RDWR);
if(fd < 0){
	return ;
}

新增完如下圖所示:

img

然後我們建立一個開啟蜂鳴器和一個關閉蜂鳴器的函式,第一步,現在beep.h裡面宣告,然後在beep.cpp裡面實現。

宣告:

程式碼如下:

void Beep_On();
void Beep_Off();

新增完如下圖所示:

img

實現:

程式碼如下,注意c語言函式前面要加::,表示這個函式是C函式。

void Beep::Beep_On()
{
    /* 向/dev/beep 檔案寫入資料 */
    databuf[0] = 1;
    retvalue = ::write(fd, databuf, sizeof(databuf));
     if(retvalue < 0){
          ::close(fd);
          return ;
     }
}

void Beep::Beep_Off()
{
    databuf[0] = 0;
    retvalue = ::write(fd, databuf, sizeof(databuf));
    if(retvalue < 0){
         ::close(fd);
         return ;
    }
}

新增完如下圖所示:

img

新增好了之後,我們直接使用這個類就可以了,我們先在widget裡面新建一個beep,如下圖所示:

然後我們在建構函式里面新建一個物件,如下圖所示:

img

然後我們在槽函式里面執行對應的開啟和關閉動作即可,如下圖所示:

img

使用"insmod beep.ko"載入蜂鳴器驅動, 會出現"/dev/beep"節點

使用"./beep"執行程式

相關文章