1. 程式人生 > 其它 >樹莓派c++實驗三:按鍵監測實驗

樹莓派c++實驗三:按鍵監測實驗

一、實驗目的
1、 瞭解樹莓派處理中斷的方式
2、 瞭解樹莓派是如何通過事件來代替傳統中斷的
3、 掌握利用C++語言,通過樹莓派的 GPIO 口讀取3按鈕模組的按下狀態
4、 利用QT編寫一個視窗介面,在介面中顯示按鈕被按下的狀態

二、實驗原理
本實驗以樹莓派作為控制器,以 C++ 作為開發工具,利用樹莓派的 GPIO,讀取一 個 3 按鈕模組的狀態,使用一個全域性變數 X,當按下綠色按鈕,X 加 1;當按下黃色按鈕, X 清零;當按下紅色按鈕,X 減 1。並在 LED 模組中顯示 X;利用 QT 編寫一個視窗介面, 將X的資料實時顯示出來,並顯示按鈕狀態

三、使用儀器、材料
1.樹莓派的GPIO模組 (General Purpose Input/Output通用型輸入輸出)

2.4位LED顯示模組
3.按鈕模組
4.直流電源
5.電源模組
6.開發工具:基於QT上的C++開發樹莓派

四、實驗步驟

  1. 連線:用杜邦線,將樹莓派、電源模組、1個LED模組、按鍵模組的相應引腳連起來;
  2. 編制LED模組顯示程式,能顯示給定數字;
  3. 用按鍵對全域性變數分別進行加、減、清零操作,並在LED 中顯示;
  4. 編制QT的視窗介面,在顯示器上顯示全域性變數的值、顯示各個按鍵輸出的值(0還是 1?)。5. 實驗完成後,反向上述步驟斷電、拆線並整理收拾好

五、實驗過程原始記錄(計算機原始碼)

#ifndef THREAD1_H
#define THREAD1_H
#include "wiringPi.h"
// #include <QThread>// class Thread1 : public QThread// { Q_OBJECT public: Thread1();// protected: void run();// signals:// 用於傳送的訊號函式 void send(int a, int b, int c, int d); }; #endif #ifndef THREAD2_H #define THREAD2_H #include "wiringPi.h"// #include <QThread>// static unsigned
char LED_f[] ={ // 0 1 2 3 4 5 6 7 8 9 A B C D E F 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x8c, 0xbf, 0xc6, 0xa1, 0x8e, 0xbf, 0xff, 0x7f, 0xbf }; class Thread2 : public QThread// { Q_OBJECT public: Thread2();// int SCLK = 0, RCLK = 2, DIO = 3;//LED的SCLK(序列時鐘),RCLK(接收時鐘),DIO(資料),分別連線GPIO的三個數字引腳 void LED_init(){// wiringPiSetup(); pinMode(SCLK, OUTPUT); pinMode(RCLK, OUTPUT); pinMode(DIO, OUTPUT); } //在SCLK上輸出脈衝訊號 void LED_out(char data){ for (int i = 8; i >= 1; i--) // 迴圈8次為1位元組 { if (data & 0x80) digitalWrite(DIO, HIGH); else digitalWrite(DIO, LOW); delayMicroseconds(1); data <<= 1; digitalWrite(SCLK, LOW); delayMicroseconds(1); digitalWrite(SCLK, HIGH); delayMicroseconds(1); } } // 在RCLK上輸出脈衝訊號 void LED_display(unsigned char p, int v){ unsigned char* led_table; unsigned char i; led_table = LED_f + v;// i = *led_table; LED_out(i); LED_out(p); digitalWrite(RCLK, LOW);// delayMicroseconds(1); digitalWrite(RCLK, HIGH); delayMicroseconds(1); } //在4位的LED上顯示一個4位資料 void LED_loop(int data) { LED_display(0x08, data / 1000 % 10); delayMicroseconds(10); LED_display(0x04, data / 100 % 10); delayMicroseconds(10); LED_display(0x02, data / 10 % 10); delayMicroseconds(10); LED_display(0x01, data % 10); delayMicroseconds(10); } protected:// void run(); }; #endif #ifndef MAINWINDOW_H #define MAINWINDOW_H #include "thread1.h" #include "thread2.h"// #include <QMainWindow>// namespace Ui { class MainWindow; } class MainWindow : public QMainWindow{// Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); Thread1 *th_1; Thread2 *th_2; private:// Ui::MainWindow *ui; public slots:// 用於接收的槽函式 void receive(int a, int b, int c, int d); }; #endif #include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow){ ui->setupUi(this); th_1 = new Thread1();// 建立執行緒和開啟執行緒 th_2 = new Thread2(); th_1 -> start();// th_2 -> start(); connect(th_1,SIGNAL(send(int, int, int, int)),this,SLOT(receive(int, int, int, int))); // 連線訊號與槽 } MainWindow::~MainWindow(){ delete ui; } void MainWindow::receive(int a, int b, int c, int d){ // 將資料顯示到Qt介面 ui -> label_5 -> setText(QString::fromStdString(std::to_string(a))); ui -> label_6 -> setText(QString::fromStdString(std::to_string(b))); ui -> label_7 -> setText(QString::fromStdString(std::to_string(c))); ui -> label_8 -> setText(QString::fromStdString(std::to_string(d))); } #include "thread1.h" #include "thread2.h"// #include "wiringPi.h"// static int data1 = 0,data2 = 0,data3 = 0;// static int value = 10; static int nums[3] = {12,13,14};//定義陣列,代表按鍵模組k1\k2\k3連線的GPIO數字引腳編號 void key_interrupt_service_1() // 中斷函式 { delay(20); // 按鍵消抖 if (digitalRead(12) == 0){ data1 = 1; data2 = 0; data3 = 0; value++; } if (digitalRead(14) == 0){ data1 = 0; data2 = 1; data3 = 0; if(value > 0){ value--; } } if (digitalRead(13) == 0){ data1 = 0; data2 = 0; data3 = 1; value=0; } } void key_init() {// wiringPiSetup();// 初始化wiringPi for(int i = 0;i<3;i++){ pinMode(nums[i], INPUT); pullUpDnControl(nums[i], PUD_UP); // 設定上拉電阻 wiringPiISR(nums[i], INT_EDGE_FALLING, &key_interrupt_service_1); // 註冊中斷程式 } } Thread1::Thread1() {} void Thread1::run(){// key_init(); // 初始化按鍵 while (1){ delay(10); emit send(value, data1, data2, data3); delay(1000); } } Thread2::Thread2() {} void Thread2::run(){// LED_init(); // 初始化LED while(1){ LED_loop(value); // } }

實驗結果
在這裡插入圖片描述