EDA365电子论坛网

标题: 迅为4412开发板Qt下控制硬件 [打印本页]

作者: 阳阳天    时间: 2021-3-25 14:33
标题: 迅为4412开发板Qt下控制硬件
我们在 QT 上要怎么操作驱动呢?比如,我们要点亮一个 led 灯,我们在 C 语言中可以使用 open,read,write,ioctl 函数来进行操作,但是 QT 上我们使用的语言是 C++,那我们要怎么来操作驱动呢?
7 q- F; z* M8 S9 E我们可以使用 C 和 C++进行混合编程,我们先来看一个控制蜂鸣器的 APP 代码,这里以终结者 I.MX6ULL为例,iTOP-4412 可参考测例程代码,代码如下:
% t5 G% J+ z, G' ~# a#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) R; F& D& \! @) o6 d
#define BEEPON 1" V) p4 e2 W4 |7 T8 M
/*
+ H+ G0 N4 s9 `* @description : main 主程序
9 \1 }2 ?, L; a) Z; q) A0 i# s* @param - argc : argv 数组元素个数
2 r4 y6 r6 f( L) M  }8 b7 Z* @param - argv : 具体参数% E3 P+ D# |% C7 P. V3 \( q: J
* @return : 0 成功;其他 失败2 v* x: H0 {  O6 Q+ |3 }
*/) W$ R3 z% V7 l' q1 l  R* W, P
int main(int argc, char *argv[])
! h: I  G# `  h{
! S& I% S1 q# r, N4 b" s4 A3 A+ ?int fd, retvalue;
  n) A- [9 v7 O1 schar *filename;
, @+ S  j4 C- Funsigned char databuf[1];3 p4 u. X7 F' D
if(argc != 3){- l1 I/ T4 Z5 ^& T
printf("Error Usage!\r\n");! C9 }) e* Z& v' @
return -1;
# [4 G6 h$ m7 v% N" i; L; h# M}
! K% ~3 J" ^! M0 S; v% Kfilename = argv[1];
, U  f$ W& j9 ?7 V) w4 K( f+ ]/* 打开 beep 驱动 */
  y! O' ^% ]9 V: m2 f) Cfd = open(filename, O_RDWR);
6 o2 I! h3 l) H1 F7 T, h  aif(fd < 0){
+ g* `/ g1 @! D# G5 \' Lprintf("file %s open failed!\r\n", argv[1]);
* ~( u) k; y9 [2 O5 Oreturn -1;1 a6 @0 W& D5 z- j* e
}
2 C/ g* u9 ~8 I5 H+ sdatabuf[0] = atoi(argv[2]); /* 要执行的操作:打开或关闭 */
5 c: K& j0 G: V" p3 F+ J/* 向/dev/beep 文件写入数据 */
' v: M) L" _3 I% r/ \8 mretvalue = write(fd, databuf, sizeof(databuf));
- J* [7 f7 E2 _if(retvalue < 0){
! ~. \+ x' c1 [, J) Iprintf("BEEP Control Failed!\r\n");! d. l; f; n- T' H
close(fd);0 g6 G# ?% E, [% @. W! R
return -1;. _6 R9 ~; x+ w/ L, o8 u* d, B
}
5 r& u+ z# X; `& Q/ I) q9 i  e& Lretvalue = close(fd); /* 关闭文件 */
+ {! z# P/ I( s8 d# oif(retvalue < 0){
3 ?6 N5 ~  `" E' u- `+ V" Zprintf("file %s close failed!\r\n", argv[1]);
; ~0 }# H5 \! ~return -1;
' _! s) ?; X! b7 e: c) ?+ n}/ U' u- O; ~9 P+ q) l. c) L
return 0;! R) ]& u7 K* I/ s7 c9 D$ W
}
1 H: H0 n+ ~8 u* P通过上面的代码我们可以发现,使用 C 语言来控制一个蜂鸣器,无非就是打开设备节点,然后通过 write来写入数据就可以控制蜂鸣器了。既然我们可以使用 C 和 C++混合编程,那么我们是不是只需要把这个 C控制蜂鸣器的代码直接加到 QT 程序里面就可以了,那我们我们要怎么进行混合编程呢?; \( {# g5 O: s4 o- r
我们先新建一个 QT 工程,然后添加俩个按钮来控制蜂鸣器的打开和关闭,UI 界面如图 62.4.1:" Q- J; d, p/ u$ I6 o

& }  I- U9 V- _然后我们开始移植代码,因为 C++是面向对象的,C 是面向过程的,所以在 QT 上,我们要用面向对象的思想来进行编程,所以我们第一步,就是要先创建一个类,把 C 语音控制蜂鸣器的代码封装成一个类。; k9 D5 x+ o8 Q% a" F
我们右键选中这个工程,然后选择添加新文件,添加 C++ Class 如图 62.4.2:
+ y1 }" k1 C' ?. b5 w
" L2 O/ B6 o6 T7 b0 i; t8 Q7 R. K然后我们添加类的名字,因为我们操作的是蜂鸣器,所以我们这里写成 Beep,如图 62.4.3:
0 r$ i; w- }. }2 L0 V( d8 C; b! S0 T' u) A
第一步,我们把 C 语言控制蜂鸣器代码的头文件,添加到我们刚才添加 Beep 类生成的文件 beep.h 里面,但是头文件我们不能直接复制过去,我们要用 extern “C”{}括起来,代码如下:' _* ~8 q- j/ f& w+ ~! E+ Y
extern "C"{
+ N+ _6 [( {" r4 v#include "stdio.h" #include "unistd.h" #include "sys/types.h" #include "sys/stat.h" #include "fcntl.h" #include "stdlib.h" #include "string.h" }0 A4 _1 @5 c/ W5 W% R1 T! w! B
添加完成如图 62.4.4 所示:9 m: `" m2 I( A; U3 R1 B

. g4 @* b. H& G# f图 62.4.4
. Q9 j- @2 [+ t) ]" W" P/ d: |8 D第二步,把我们 C 语言控制蜂鸣器里面的参数定义复制到 public 下面,代码如下:0 D1 n' \- R6 X: k. u
int fd, retvalue;2 ]. |" ~8 l; l! \* g
char *filename;2 Z& r0 D6 J; o9 i
unsigned char databuf[1];# Z$ j5 L. Q  Q5 b% H8 s
添加完如图 62.4.5 所示:
" J+ f6 Y' C! U2 {! w9 I4 c# }& m" Q3 L( D4 K4 n
然后我们打开 beep.cpp,把 C 语言控制蜂鸣器里面的打开设备节点的代码复制到构造函数里面,注意,QT 里面我们不能使用 printf,代码如下:
7 Z# y' I! K$ Y/* 打开 beep 驱动 */: {+ b! m; u6 y9 H& n; K
fd = open(filename, O_RDWR);6 |: l6 V/ C# I1 u* {7 s1 t6 N
if(fd < 0){
( P; ?4 U0 z- l& ereturn ;
: a* B+ M; `( Q. G5 m! k9 {: O}/ e/ ?' S0 \$ b2 j
添加完如图 62.4.6 所示:
% R6 a5 m1 d% f. a
3 K/ {* X) ?7 @, o) k* [图 62.4.6
" e1 O5 ^( p0 r0 e0 t, D然后我们创建一个打开蜂鸣器和一个关闭蜂鸣器的函数,第一步,现在 beep.h 里面声明,然后在
- M, v8 D& h" w& e4 W8 sbeep.cpp 里面实现。
5 e& C6 i0 E. _% U: j  y声明:
+ H. T" U6 j* U! d代码如下:
4 ^5 ?2 i( ~1 E( {. tvoid Beep_On();" p. t4 p) B- M. f2 d6 h
void Beep_Off();
$ d% d- [+ \; a7 r6 H添加完如图 62.4.7 所示:) n' g3 o* T" J1 H4 {
: m- v) I. A% c: v( i( a: X
图 62.4.7
# T2 I5 r$ G4 B5 [实现:/ @9 q6 U) H: m8 N% v
代码如下,注意 c 语言函数前面要加::,表示这个函数是 C 函数。
$ e; g( w# j: B+ w2 v- L. Ovoid Beep::Beep_On()
; n- @$ ^7 A+ F5 j$ J# D{
; O& d2 z9 E' k) S% ~4 P( g/* 向/dev/beep 文件写入数据 */, Q9 |- A: K' X1 z+ {% {+ J
databuf[0] = 1;& }( E6 U' t; L" p* V1 y4 b
retvalue = ::write(fd, databuf, sizeof(databuf));1 @5 ~; @% I' i4 l+ X- L$ K8 Z
if(retvalue < 0){# E$ A; U) C3 O* u! ^& U
::close(fd);
' ]9 R- Q/ s. k- w1 k" H) N1 `, lreturn ;
# F  g2 t, ]6 n4 Q, v}
6 Q6 S3 ^  E* U/ q1 R+ x4 c: `* Z}
- q2 `1 M; @% S* t$ ^void Beep::Beep_Off()7 y' O! O: E% v) I$ n$ S; ^7 O. }
{
8 {! s$ o& Z9 V- {databuf[0] = 0;+ Z, v. ^4 Z' Y1 l
retvalue = ::write(fd, databuf, sizeof(databuf));: J3 m9 P1 m6 k, ?# B  p
if(retvalue < 0){
% }: ?- V, P8 n7 B, G! l; _8 D& ~' k::close(fd);, X. W* R: j( K; Z6 {$ `
return ;7 p) M* O$ x6 \8 E
}  E5 e. ?2 p& G: l2 M+ Y4 R' S0 G
}
  X, y* B( m) o1 x" z/ S添加完如图 62.4.8 所示:
* x0 N% S/ g7 g" P; a$ S0 Z% P' _6 O# |
图 62.4.8
. _# a* o& f& `1 E+ J3 T添加好了之后,我们直接使用这个类就可以了,我们先在 widget 里面新建一个 beep,( o* @" h4 y, n0 I- M$ I' R) q
然后我们在构造函数里面新建一个对象,如图 62.4.9 所示:
  ~6 X8 i% u8 ^
* A1 O( A2 `, J) W* \图 62.4.9
& C$ \' `9 I* B# ]- L然后我们在槽函数里面执行对应的打开和关闭动作即可,如图 62.4.10 所示:) C; K! w! c9 L5 D+ Z% i  R5 h

$ _  ]" h$ m1 S0 A! b0 F7 I
- T2 ?3 m8 G8 `
作者: messed    时间: 2021-3-31 09:39
                                                   




欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/) Powered by Discuz! X3.2