# 微處理機課堂筆記-基本人機介面
### 班級:資工三乙
### 座號:046
### 姓名:陳德恩
### 學號:1110832098
### 一.實驗標題:基本人機介面
### 二.指導老師:林宏益 老師
### 三.報告內容:
#### 1.實驗目的:
認識人機介面實作方式,建立硬體開發之實務能力,建立硬體開發之技能。
#### 2.實驗原理:
透過Arduino C程式語言以及KTduino積極開發版來實際開發人機介面。
#### 3實驗材料:
|開發版 | 傳輸線 | 杜邦線 |變壓器|
| -------- | -------- | -------- |-------- |
| KTduino積極開發版 x1 | usb A to mini usb cable x1 | 約15~20條|專用變壓器|
#### 4.人機介面簡介:
建立一個可以給使用者輸入資料的介面,達到與機器互動的效果,早期透過按鈕去完成,現今有的透過觸控螢幕來達到互動的目的。
#### 5.實驗步驟:
STEP1:建立Arduino 程式碼,透過Arduino專用編譯器撰寫所需之程式碼,程式碼可參考課本與老師提供的上課簡報。
STEP2:開始組裝硬體的線路,參考課本的接線圖,進行線路串接。
STEP3:通電,燒錄程式碼,開始測試裝置是否運作成功。
STEP4:修改程式的不當撰寫方式,增加程式可讀性,減少未來開發時的技術負載,同時也可增加未來的擴充性,改善程式的品質也可以減少維護所需的時間。
STEP5:硬體線路整理,將線路進行整理,可透過束帶或者其他綑綁工具進行線路整理,此舉不僅可以增加成品美觀,也可減少維修所需的時間,此外也可提升未來擴充升級的空間。
#### 6.成品說明:
按下0-15號的按鈕,會顯示出一個數字並且把前面的數字向左推移
#### 顯示的數字:1-9號按鈕則顯示對應數字,按鈕0以及按鈕10-15則顯示數字0
#### 7.原本的程式碼:
``` clike=
// 範例 ch4_7_3, 七節顯示器之G~A連接在12~6腳, 七節顯示器之com1~com4連接在5~2腳
const int SEG[8] = {6,7,8,9,10,11,12}; // 宣告顯示信號接腳
const int scan[4] = {2,3,4,5}; // 宣告掃描信號接腳(row)
const int SEG_code[10] = { // 宣告七節顯示碼陣列
0xc0, 0xf9, 0xa4, // 0~3
0xb0, 0x99, 0x92, // 4~6
0x82,0xf8,0x80, // 5~8
0x90 }; // 9
const int column[4]={A2,A3,A4,A5}; // keyin port
const int BZ=13; // 蜂鳴器
unsigned char KN; // 按鍵值
int disp[4]={0,0,0,0}; // 宣告顯示緩衝區陣列
int DISP; // 宣告顯示變數
void beep(int pin, int counts); // 宣告嗶聲函數原型, prototyping
//函式宣告
// Initialization
void setup() {
for(int i = 0; i < 7; i++) // 設定顯示信號接腳為輸出接腳
pinMode(SEG[i], OUTPUT);
for(int i = 0; i < 4; i++) {
pinMode(scan[i], OUTPUT); // 設定顯示掃描接腳為輸出接腳
pinMode(column[i], INPUT); // 設定行接腳為輸入接腳
}
pinMode(BZ, OUTPUT); // 設定蜂鳴器接腳為輸出接腳
}
// Beep Function
void beep(int pin, int counts) {
for(int i = 0; i < counts; i++) { //執行counts次
tone(pin, 1000, 100); //發聲(1kHz,0.1秒)
delay(100); //靜音(0.1秒)
}
}
void loop() {
for(int i = 0; i < 4; i++) { //掃描週期
//關閉七節顯示器(防殘影)
for(int j = 0; j < 8; j++) digitalWrite(SEG[j],1); //輸出顯示信號1(關閉)
//輸出掃描線
for(int j = 0; j < 4; j++) digitalWrite(scan[j],1); //掃描信號全部為1
digitalWrite(scan[i],0); //輸出掃描線
//輸出七節顯示器顯示信號
DISP=SEG_code[disp[i]]; // 讀取顯示信號
for(int j = 0; j < 8; j++) { // 並列資料串列輸出
if(bitRead(DISP,j)) digitalWrite(SEG[j],1);
else digitalWrite(SEG[j],0);
}
//判讀按鍵狀態
for(int col = 0; col < 4; col++) {
if(!digitalRead(column[col])) { //有按鍵
while(!digitalRead(column[col])); //等待放開
KN = 4*i + col; //計算鍵值
beep(BZ,1); //嗶一聲
if (KN >= 0 && KN < 10) { //測試鍵值
//若是數字鍵,先移位,再將鍵值放入個位數
//disp[3]:千位數, disp[2]:百位數, disp[1]:十位數,disp[0]:個位數
for(int j = 0; j < 3; j++)
disp[3-j] = disp[2-j]; //移位
disp[0] = KN; //鍵值放入個位數
}
delay(3); //延遲3ms
break; //跳出
}
}
}
}
```
### 8.修改程式碼(加分項目):
### 此程式為修改後版本,主要針對迴圈以及流程控制的程式片段進行修正,將迴圈與if-else條件判斷的部分透過大括號標記,增加程式可讀性,此外,也透過註解來說明程式的作用,註解部分採用英文註解,如果未來有把程式上傳在國外的平台的話,使用英文會比較恰當。
``` clike=
//MCU LESSON1-BASIC Human Machine Interface
//variable information
const int SEG[8] = {6,7,8,9,10,11,12};
const int scan[4] = {2,3,4,5};
const int SEG_code[10] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92,0x82,0xf8,0x80,0x90};
const int column[4]={A2,A3,A4,A5};
const int BZ=13;
unsigned char KN;
int disp[4]={0,0,0,0};
int DISP;
//fuuction creation
void beep(int pin, int counts);
//setup area
void setup() {
for(int i = 0; i < 7; i++)
{
pinMode(SEG[i], OUTPUT);
}
for(int i = 0; i < 4; i++)
{
pinMode(scan[i], OUTPUT);
pinMode(column[i], INPUT);
}
pinMode(BZ, OUTPUT);
}
//beep-function creation
void beep(int pin, int counts)
{
for(int i = 0; i < counts; i++)
{
tone(pin, 1000, 100);
delay(100);
}
}
void loop()
{
for(int i = 0; i < 4; i++)
{
for(int j = 0; j < 8; j++)
{
digitalWrite(SEG[j],1);
}
for(int j = 0; j < 4; j++)
{
digitalWrite(scan[j],1);
}
digitalWrite(scan[i],0);
DISP=SEG_code[disp[i]];
for(int j = 0; j < 8; j++)
{
if(bitRead(DISP,j))
{
digitalWrite(SEG[j],1);
}
else
{
digitalWrite(SEG[j],0);
}
}
for(int col = 0; col < 4; col++)
{
if(digitalRead(column[col])==false)
{
while(digitalRead(column[col])==false)
{
KN = 4*i + col;
beep(BZ,1);
}
if (KN >= 0 && KN < 10)
{
for(int j = 0; j < 3; j++)
{
disp[3-j] = disp[2-j];
}
disp[0] = KN;
}
delay(3);
break;
}
}
}
}
```
#### 9.實驗結果:
我們這組的程式碼試過三組設備,總共組裝了四次才完全成功。
第一次:蜂鳴器可以發聲,但沒有畫面
第二次:在別人組裝好的設備上測試,測試結果完全正常
第三次:重新修改接線,此次測試完成度接近80%,但四位數7段顯示器有一個數字無法顯示
第四次:經過確認之後,發現問題是少接一條線,修正後,設備正常運作,實驗順利成功

### 圖片一.7段顯示器顯示0000初始化狀態

### 圖二.按下1號按鈕後,7段顯示器顯示0001

### 圖三.線路整理-全部線路綁一起

### 圖四.線路分區放置,提升維修效率
#### 8.實驗討論:
實驗過程中,我們有先檢查軟體是否可以正常編譯,但是我們卻在硬體層面忽略了一個重要的環節-檢查線路,我們沒有先看看線路有沒有都接上才測試功能是否正常運作,如果有先查看線路是否正確布置,可以減少維修處理的時間,倘若裝置還是無法正確運作,我們可以進一步去了解是否為線材的問題或開發版的問題。
#### 10.實驗心得:
學習開發Arduino也有一年半了,以前還是以業餘玩家的身分在開發與學習,當時的我專注在麵包版電路設計,在程式以及微處理機結構部分並沒有詳細學習研究,如今修了這們課之後,不僅複習了以前學過的C語言,也增加了許多微處理機的知識,此外,透過KTduino積極開發版來進行實驗,能夠讓我們更專注在微處理機的開發,此外,在這堂課擔任助教的職務讓我學會如何教導別人,也學會如何團隊合作與溝通,我想這些都是未來在職場上必備的技能,我想如果能夠將這門課程所學習到的專業技能搭配以前業餘學習學到的經驗以及創意創客思維,必定能夠開發出更多不一樣的產品,並且透過這些產品來改善人類的生活,增進人類福祉。
#### 11.參考文獻:
艾迪諾 西元2015年 Arduino全能微處理機實習強效解析 p.4-50~p.4-55
李啟龍 西元2019年 C語言學習手冊與挑戰APCS p.48~p.60