實驗(四)6位數七字節顯示

History Key

  • New content
  • Removed content

Recent Versions

Choose two versions to compare, or click the link to view it.

  1. 5. over 3 years by fellong
  2. 4. over 3 years by fellong
  3. 3. over 3 years by fellong
  4. 2. over 3 years by fellong
  5. 1. over 3 years by fellong
 

(教學教材內容保留所有版權~欲轉載請註明出處~謝謝)

實驗(四) 6位數7字節顯示單元

實驗目的:

本節在實現6位數7字節顯示單元模組。

實驗一:

7字節單8顯示上數

實驗二:

6位數顯示上數

實驗三:

6位數碼表設計,按下SW2則數字歸零,按下SW1啟動計數,再按下SW1停止計數。顯示範圍分鐘、秒數、百分之1秒

I/O腳位定義:

///                                         SEG_COM0                     equ  pf.0
///                                         SEG_COM1                     equ  pf.1
///                                         SEG_COM2                     equ  pf.2
///                                         SEG_COM3                     equ  pf.3
///                                         SEG_COM4                     equ  pf.4
///                                         SEG_COM5                     equ  pf.5
///                                         SEG_PORT                      equ  ph;

模組函式規畫:

/// 單1個七字節

/// ======== START Public 函式 ========

void Initial_SEG7( void );                              /// 初始化 IO

void SEG7_SetS1( void );                              /// 七字節單一輸出

/// ======== END Public 函式 ========

 

/// 6位數的七字節

/// ======== START Public 函式 ========

void Initial_SEG7( void );                              /// 初始化 IO

void SEG7_Control( void );                           /// 七字節 6 個位數作掃描控制

 

void SEG7_SetS1( void );                              /// 設定 S1 字節的值為 a,對應 8 BITS 腳位

void SEG7_SetS2( void );                              /// 設定 S2 字節的值為 a,對應 8 BITS 腳位

void SEG7_SetS3( void );                              /// 設定 S3 字節的值為 a,對應 8 BITS 腳位

void SEG7_SetS4( void );                              /// 設定 S4 字節的值為 a,對應 8 BITS 腳位

void SEG7_SetS5( void );                              /// 設定 S5 字節的值為 a,對應 8 BITS 腳位

void SEG7_SetS6( void );                              /// 設定 S6 字節的值為 a,對應 8 BITS 腳位

/// ======== END Public 函式 ========

模組函式設計:

操作函式設計:...............略。

上列函式規畫有二種,前一種是只有單一個七字節顯示的時候的函式規畫方式,此時的七字節就如同8顆LED的顯示單元一樣,只是單純的設定LED埠的狀態,程式設計非常簡單。

第二種則是同時要顯示6位數的七字節時的函式規畫方式,此時由於硬體規畫是採同COM點掃描的方式來顯示6個七字節的內容(也必須如此,否則會需要大量的I/O腳位),因此我們需要一個控式函式來作COM點掃描的動作,也就是SEG7_Control()。

系統在每次叫用SEG7_Control()的時候,模組就要負責去切換到某一個COM點對七字節埠作輸出,並且把其它COM點清除,系統不斷的叫用控制函式,模組就不斷的進行COM點的切換,來達到掃描的目的。

這裡用到的技巧也是模組設計的時候經常會用到的方法,把模組要完成的工作,分階段來完成,藉著系統的調用來達到分時處理的目的,同樣的技巧也可以再擴充,把模組設計成類似狀態機,把系統調用當成一個GLOBAL的TIMER,每次的調用就會讓模組「運作起來」並且「流向」不同的狀態,有點OS的味道。

 

控制函式的實作:

控制函式也很容易實現(因為我們規畫的目標明確),只需要在不同的時間對不同的COM點作輸出即可。

void SEG7_Control( void )                            /// 七字節掃描控制

{

           SEG_COM0 = 1;

           SEG_COM1 = 1;

           SEG_COM2 = 1;

           SEG_COM3 = 1;

           SEG_COM4 = 1;

           SEG_COM5 = 1;

           switch( seg7_index )

           {

           case 0:

                                SEG_PORT = seg7_s1;

                                SEG_COM0 = 0;

                                break;

           case 1:

                                SEG_PORT = seg7_s2;

                                SEG_COM1 = 0;

                                break;

           case 2:

                                SEG_PORT = seg7_s3;

                                SEG_COM2 = 0;

                                break;

           case 3:

                                SEG_PORT = seg7_s4;

                                SEG_COM3 = 0;

                                break;

           case 4:

                                SEG_PORT = seg7_s5;

                                SEG_COM4 = 0;

                                break;

           case 5:

                                SEG_PORT = seg7_s6;

                                SEG_COM5 = 0;

                                break;

           }

           if( seg7_index < MAX_SEG7_COM )

                     seg7_index++;

           else

                     seg7_index = 0;

}

實驗實作:

實驗一:

7字節單8顯示上數。

略。

實驗二:

6位數顯示上數。

底下是系統主程序,其實就是定時去調用控制函式,也就是作七字節掃描。

void   FPPA0 (void)

{

                     /// 初始化...略

           while (1)

           {         /// 多位數七字節控制 LOOP

                     SEG7_Control();

                     delay 250;

                     delay 250;

           }

}

在這裡我們看到delay這個指令,目的在控制掃描頻率,掃描頻率不同會影響七字節顯示的亮度,太慢的掃描頻率亦可能會造成七字節閃爍的情形。

至於要顯示的內容,只要去呼叫SEG7_SetS1()~SEG7_SetS6() 作設定即可。

範例程式是很簡單的用一個timer中斷來累加一些變數,再把這些變數設定到各別對應的七字節至於timer中斷的設定方式請參考「FPPA教學簡報」第四章「FPPA程式設計」,C語言代碼如下:

void Initial_Timer()

{

/// 100= internal high RC, 11=(ClockSource/64)=4us/T, 111=bit15,(32768*Timer)

t16m = 0b10011111;                                       

           t16reset = 32768-2500;                         ///       2500*4us = 10000us = 10ms

           stt16  t16reset ;                                     /// Restart timer tick

}

 

void Initial_ISR()

{

           intrq = 0b00000000;                              /// clear interrpt reqest register

           inten = 0b00000100;                             /// bit-2: Timer16                       

           engint;                                                    /// Enable Interrupt

}

這邊同時展示了FPPA查表指令的用法:

/// 使用組合語言...
add    a, la@Seg7DigitCode;
           mov   lb@digitIndex, a;
           mov   a, ha@Seg7DigitCode;
           mov   hb@digitIndex, a;
           addc  hb@digitIndex;
           ldtabl digitIndex;

           /// 使用Mini-C語言...
digitIndex = Seg7DigitCode + a;
           a = *digitIndex$L;

Seg7DigitCode:
dc      0b00111111, 0b00000110, 0b01011011, 0b01001111, 0b01100110, 0b01101101, 0b01111101, 0b00100111, 0b01111111, 0b01101111;

Seg7DigitCode標記著資料的位址,也就是資料在ROM中的位址,程式執行的時候把一個指標指到這個位址,然後再加上一個OFFSET下標指到表中的某一筆資料。

顯然Mini-C的用法比較簡潔一點,不過要特別注意這並非傳統C的用。

實驗三:

6位數碼表設計,按下SW2則數字歸零,按下SW1啟動計數,再按下SW1停止計數。顯示範圍分鐘、秒數、百分之1秒。

這個實驗便能很完整的體驗出模組整合的優勢,系統設計師只要拿到這些己經設計好的模組「SW1」、「SW2」、「Seg76c」看一下各模組標頭檔(.h)的說明,就能很快的整合出系統所要求的功能,程式設計的時候就像是一個建築師,大架構出來了,再把各個輸入、輸出、剌激、反應的神經管線連接好就OK了。

同時我們也看到了FPPA多核的優勢,由於有多核可用,且一般的系統會整合到的模組其實也不多(當然也是要看系統複雜度),我們可以把各個模組的控制函式,直接分配給不同的核心來運行處理,簡化了整合的複雜度同時也提升了系統的穩定度,因此系統設計時要著眼的就只剩下模組之間的交互運作的邏輯問題以及核心間同步的問題。

void   FPPA0 (void)

{

           /// 初始化...略

           while (1)

           {         /// 多位數七字節控制 LOOP

                     SEG7_Control();

                     delay 250;

                     delay 250;

           }

}

 

void   FPPA1 (void)

{

           while (1)

           {         /// 按鈕控制 LOOP

                     SW1_Control();

                     SW2_Control();

           }

}