• 沒有找到結果。

面板掃描部分

在文檔中 中 華 大 學 (頁 52-68)

第四章、 程式設計

4.1 面板掃描部分

START

INITIAL( )

ubL_R_Scan ( ) 快速掃瞄左右訊號

依據回傳值 判斷為左板 或右板有訊號

ubLeft_TouchPad ( ) 掃瞄左板並傳送出

UART

ubRight_TouchPad ( ) 掃瞄右板並傳送出

UART

Left Right

No touch

0x55 0x00 0xXX 0xYY 0xAA 左右板 x 座標 y 座標

設有 watch_dog_timer 每秒會清除一次

避免 8254 卡在 RS-232 錯誤回圈

掃描左板 CH24~39 是否有訊號

只掃描 Channel 24~~39 理由是因為 Y 軸寬度較窄 可以簡單的就得知有無訊號

確認板上是否有 任何訊號

掃描右板 CH24~39 是否有訊號

START

掃描 CH1~23 確認 X 軸位置

Quality_Check ()

傳回 X 軸 三根訊號值 Y 軸 三根訊號值 可藉由調整可變電阻 調成理想的範圍值

ubL_R_Scan ( )

主要是快速檢測左右板 有沒有筆點下的訊號 若有則回傳 Left 或 Right (具有四段 倍率放大)

4.1.1

面板掃描

流程圖:

Yes

No

Yes

No

Yes

No

START

EBOOKCompare () 找出最大 X 軸 channel 最大 Y 軸 channel 並針對 其前後各兩個 channel 做穩定的掃描

MAX_ADCTL(); 穩定的掃描 Channel 0--39 並紀錄出各個 ch 最大 ADC 值

EBOOKPosition(X 軸最大 channel,Y 軸 最大 channel) 依照比例 轉換成 9x9 方格中的座標值

判斷筆的訊號是否持續壓住

SpecialNoiseRemainProtect()

因為在靠近板子的最邊邊,會產生一些微弱的誤動作訊號 因此需判斷是否有誤動作產生

判斷 P3_7 是否為 Low 若是則直接傳送出 座標值

判斷 比是否為第一次瞬間點下 若是則不傳送,直到第二次

傳送出正確的座標值

Yes

Yes

Yes

No

No

No

END

No Yes

ubLeft_TouchPad ( ) 及 ubRight_TouchPad( )

掃描出穩定的訊號 並且把訊號依照比例傳送相對的座標位置。

圖 49: 點讀機訊號比較流程圖

MAX_ADCTL ( )

增加充放電時間,使 ADC 值能充到穩定的値,並且把所有 channel 的 ADC 值,記錄到一個 ubEBOOK_ADC_VALUE[40]陣列中。

EBOOKCompare ( )

依照上面陣列中的 channel ADC 值,找出 X 軸最大 channel ( 0~~23 ) Y 軸 最大 channel ( 24~~39)。接著針對該軸 前後兩個 channel 做掃描,則可以 得出一個穩定的範圍值。

Ex: X 軸 最大 12 Y 軸最大 31 所以訊號在掃描如下圖

就可以找到一個穩定的三根訊號值

EBOOKPosition( X, Y)

依據 channel 的 ADC 值依照比例計算出 9x9 方格中的座標。

示意圖:

12 31

a. ch_1 < ch_3 且 相減值 > 中間區域範圍

b. ch_1 > ch_3 且 相減值 > 中間區域範圍

c. ch1 與 ch3相減值 大約為 中間區域範圍

2.依照比例細分出落在哪個格子中 由於每次掃描的訊號都會些許不同

所以需以中間當基準值作為判斷依據,才能精確的找出座標位置 示意圖:

Ex: Ch 1 ADC = 45

Ch 3 ADC = 85

Ch 2 ADC = 100

則 abs{45 - 85} = 40

因此比例為 40/100 = 40%

得出的比例則依照電路的特性細分出座標

1 2 3

1 2 3

1 2 3

1 2 3

10%

20%

20%

70%

50%

35%

35%

3.當書本變厚時,倍率放大產生的問題 一般情形下:

當書本厚度變深時

因此經過測量後變化情形如下

因此會發現如果以中間當住基準

來半段比例落在的範圍,會因為 的關係

所以需先減去 Channel 間移動的 橘色最長那根訊號的 ADC 值 如此比例才會正確 ( 就像下面用藍色蓋掉一樣)

示波器上掃描到的

示波器上掃描到的

壓在線上時

SpecialNoiseRemainProtect()

當筆點在板子的邊緣時,產生的訊號中

會有幾次衰弱或著不穩定的訊號,所以要避開

SpecialErrorDetect()

當筆點在格線上的時候, 產生的訊號中 會有幾次衰弱或著不穩定的訊號,所以要避開

因應特殊問題產生的判斷式

在筆點下去的瞬間,第一次掃到的訊號通常是不穩定或者由於人手的跳動現 象,導致錯誤所以取出座標值,需在第二次迴圈中才送出。

筆點下後持續壓住,但不送訊號,所需的判斷式

當訊號已送出後,需判斷筆有無離開板子,若無則不送出訊號

Watch dog 功能

主要目的是為了避免不正常的插拔,導致 MPC82E54 卡在 RS232 的迴圈中 所以才加入此功能。

經過示波器量測掃描板送出訊號,在最差的情形下,每筆 DATA 間格約在 358ms。由於 MPC82E54 WDT 設定的公式為

{1/[

(

CLK / 12

)

] *

(

2^15

)

}/ Bit 設定 Bit 設定

為三個 bit 決定 除頻 mode

000 / 2 001 / 4

因此 watch dog 設定為 100。

( 1 / [(11.0592 Mhz / 12)]*(2^15))/32 = 1.04857 S 所以設定要再每一秒結束前要更新 watch dog 的旗標

RS232 的協定

0xSS 0xTT 0xXX 0xYY 0xAA

0xSS 表示 X 軸低位元組

0xTT

表示 X 軸高位元組

0xXX 表示 Y 軸低位元組

0xYY 表示 Y 軸高位元組 0xAA 表示結束字元

4.1.2 掃描板程式Flow Chart 功能說明:

首先我們要先Initial 每一個Channel以確認線路一切正常,沒有異常訊號在 板上。

然後從Channel 1開始scan並將每次scan到的電壓值暫存在SRAM中,帶40個 Channel scan 完成後比對最高電壓位置。當確認到最高電壓位置後,立即進 入微調程序,判斷出更精細的定位座標。如果沒有電壓輸入則代表沒有感應到

4.1.3 MPC82E52 Sample code:

//定義變數名稱及初始參數

#define SELECT_4051 0x38

#define SELECT_CHANNEL 0x07

#define SELECT_A 0x40 //C:6th bit

#define SELECT_BC 0xC0 //B:7th, A:6th bits

#define SELECT_SWITCH0 0x04

#define MAX_X 16

#define MAX_Y 24

#define TOTAL_CHANNEL (MAX_X+MAX_Y)

#define ADCX_MID_VALUE_S 0x58 //ADC Voltage ~= 1.80V

#define ADCX_MID_VALUE_L 0x67 //ADC Voltage ~= 2.00V

#define ADCY_MID_VALUE_S 0x58 //ADC Voltage ~= 1.80V

#define ADCY_MID_VALUE_L 0x73 //ADC Voltage ~= 2.15V

//將每一Channel初始化

static void ChannelScanInit(void) {

TTL74164_Init();

GPIO_PORTC &= ~SELECT_SWITCH0;

H_byte=SELECT_A;

L_byte=SELECT_BC;

}

//選擇欲掃描的 Channel及delay時間

static void ChannelSelect(unsigned char ch, unsigned char msec) {

unsigned char Q543, Q210;

Q543 = ch/8;

H_byte &= ~SELECT_4051;

H_byte |= (Q543<<3);

Q210 = ch%8;

H_byte &= ~SELECT_CHANNEL;

H_byte |= Q210;

OutputData(H_byte,L_byte);

GPIO_PORTC |= SELECT_SWITCH0;

GPIO_PORTC &= ~SELECT_SWITCH0;

KeStallExecutionMilliseconds(msec);

}

//取回被掃描的 Channel的ADC值

static unsigned char ADCValueGet(void) {

// input channel select OPT2 ANAR_MicrophoneControl4 &= 0xFC;

ANAR_MicrophoneControl4 |= 0x01;

_g_adcv_get[0] = 0;

_g_adcv_get[0] = (ANAR_MicrophoneControl5<<6) + (ANAR_MicrophoneControl6>>2);

return _g_adcv_get[0];

}

//掃描每一Channel的ADC值 static void ChannelScan(void) {

unsigned char ch;

unsigned char xdata adcvx[MAX_X], adcvy[MAX_Y];

unsigned char digit;

ChannelScanInit();

for(ch=1; ch<TOTAL_CHANNEL; ch++;){

ChannelSelect(ch, 1);

if(ch<MAX_X){

adcvx[ch]=ADCValueGet();

}else{

adcvy[ch-MAX_X]=ADCValueGet();

}

}

//比對出最大的ADC值

static unsigned char MaxValueGet(unsigned char* var, unsigned int count) {

unsigned char maxv,posi;

unsigned char i;

maxv=var[0];

posi = 0;

for(i=1;i<count;i++){

if(var[i]>maxv){

maxv=var[i];

posi = i;

} } return posi;

}

//比對出更精確的座標位置

static void PositionJudge(unsigned char psx, unsigned char psy) {

unsigned char adcvx, adcvy;

ChannelSelect(psx, 50);

adcvx=ADCValueGet();

if(adcvx<=ADCX_MID_VALUE_S){

Draw8x6Icons(4,60,0);

}

else if(adcvx<=ADCX_MID_VALUE_L){

Draw8x6Icons(4,60,1);

} else

Draw8x6Icons(4,60,2);

ChannelSelect(psy, 50);

adcvy=ADCValueGet();

if(adcvy<=ADCY_MID_VALUE_S){

Draw8x6Icons(5,60,0);

}

else if(adcvy<=ADCY_MID_VALUE_L){

Draw8x6Icons(5,60,1);

}

else

Draw8x6Icons(5,60,2);

}

實驗:

我們利用 UART 傳輸軟體模擬,直接輸入座標值,模擬掃描板傳入資料及 MP3 主機之回應。

圖 50: MP3 座標模擬

速度調整、音量大小等等功能,且功能座標有著最高優先權處理程序,以便 User 操作。而發音座標部分則是關係著點讀機效能好壞的重點項目,如果發音 速度太慢,將造成 User 使用上的等候時間太長而不耐煩。如果發音內容錯誤 (可能為座標判斷錯誤),會讓 User 重複操作而浪費電力並影響學習意願。

所以發音座標輸入後,面板控制 IC 立即要判斷出是左頁還是右頁座標,接著 將存放在 NAND Flash 中的座標資料及 MP3 聲音資料載入 SRAM 中進行比對,如 果比對正確則將 MP3 聲音資料丟入 DSP 中進行播放。如果比對錯誤則代表此筆 座標在此頁中無發音。

MP3 主機之時序圖:

圖 51: 點讀機時序圖

圖 52: MP3 語音撥放流程圖

等待座標輸入

功能鍵 or 內容?

進入功能選 單程式

進入座標轉 換程序

取出當頁的所有聲音檔座標及 聲音索引並開始比對

有無在範圍內?

依照聲音位置索引至 MP3 file 中尋找資料

為無效位置,回到主 程式

播放 MP3 聲音

//搜尋 MP3 聲音位置

/////////////////////////////////////////////////////////////////

//開始比對座標資料

// Y channel

// (0000,0000) Y0 Y15 Y16 Y31 (0000,0180)

// X0 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

// X1 + ++ +

// + ++ +

// + ++ +

// + ++ +

// + ++ +

// X + ++ +

//channel + ++ +

// + ++ +

// + ++ +

// + ++ +

// + ++ +

// + ++ +

// + ++ +

// X23 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

// (0120,0000) (0120,00C0) (0120,0180)

//

//

UCHAR SearchMusicFile() {

UCHAR j,kkk=0,kkj;

UINT X_start, X_end, Y_start, Y_end;

DrawEBOOKIcon( Page_Index+kkk, 1, 25 ); //get left page NOT number 左頁 Tag 數量 kkj=NOT;

/* for(kkk=0;kkk<20;kkk++) {

DrawEBOOKIcon( Page_Index+kkk, 1, 25 ); //get correct table block data send to DMA buffer(0xF000-F080)

}

*/

for(j=0; j<64; j+=16){

X_start= XBYTE[0xF000+j]<<8 | (XBYTE[0xF001+j]);

Y_start= XBYTE[0xF002+j]<<8 | (XBYTE[0xF003+j]);

X_end= XBYTE[0xF004+j]<<8 | (XBYTE[0xF005+j]);

Y_end= XBYTE[0xF006+j]<<8 | (XBYTE[0xF007+j]);

if(

X_start <= CheckX &&

CheckX <=X_end &&

Y_start <= CheckY &&

CheckY <=Y_end ){

return XBYTE[0xF008+j];

} } }

4.3 播放 MP3 語音程序

void MusicPlayingRoutine() {

if ( TimeFlag ) {

// for variable bit rate

if( CurrentMediaType == MP3_TYPE ) {

DSP_GetSampleRateAndBitRate();

if( !VBR ) {

if( BitRate != MaxBitRate ) {

VBR = 1;

DSP_SetMaxSpeed();

}

在文檔中 中 華 大 學 (頁 52-68)

相關文件