timer & keypad

18
Timer & KEYPAD 11/24

Upload: prescott-peck

Post on 03-Jan-2016

76 views

Category:

Documents


0 download

DESCRIPTION

Timer & KEYPAD. 11/24. 實習基礎. S3C4510B 提供了兩個 32 位元計時器 (timer0 、 timer1) ,固定 以下數方式進行計數 。而其操作的方式可分為兩種,其分別為 間隔 (interval) 模式 與 雙態 (toggle) 模式 ,這兩種模式的差別在於輸出波形的不同。. 下數計數器. 波形產生器. Time out. 脈波訊號. System Clock. 計時器模式. 間隔 Interval Mode: 計時器計數結束即會產生一個脈波, - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Timer & KEYPAD

Timer & KEYPAD

11/24

Page 2: Timer & KEYPAD

實習基礎 S3C4510B 提供了兩個 32 位元計時器 (timer0 、 timer1) ,

固定以下數方式進行計數。而其操作的方式可分為兩種,其分別為間隔 (interval) 模式與雙態 (toggle) 模式,這兩種模式的差別在於輸出波形的不同。

下數計數器 波形產生器Time out 脈波訊號

System Clock

Page 3: Timer & KEYPAD

計時器模式

間隔 Interval Mode: 計時器計數結束即會產生一個脈波,

輸出頻率 fTOUT = fMCLK / 計時器資料值

雙態 Toggle Mode: 計時器計數結束進行波形轉態動作,

輸出頻率 fTOUT = fMCLK / ( 計時器資料值 x 2)

CPU 工作頻率 fMCLK = 50MHz

Page 4: Timer & KEYPAD

32 位元計時器方塊圖

TDATA 暫存器

TCNT暫存器

產生中斷訊號system clock

time outTMOD計時器

模式設定

給予下數數值

Page 5: Timer & KEYPAD

計時器模式暫存器 計時器模式暫存器 (TMOD) ,使用於控制 2 個 32 位元計時器的操作

Register Offset Address R/W Description Reset Value

TMOD 0x6000 R/W Timer mode register 0x00000000

TCLR1 TDM1 TE1 TCLR0 TDM0 TE0

31 5 4 3 2 1 0

TE0: Timer0 致能控制

0 = disable timer0

1 = enable timer0

TMD0: Timer0 模式選擇

0 = 間隔模式 (interval)

1 = 雙態模式 (toggle)

TCLR0: Timer0 脈波輸出腳位 (TOUT0) 初始化 0 = 在 toggle 模式下,初始化為 0 1 = 在 toggle 模式下,初始化為 1

TE1: Timer1 致能控制

0 = disable timer0

1 = enable timer0

TMD1: Timer1 模式選擇

0 = 間隔模式 (interval)

1 = 雙態模式 (toggle)

TCLR1: Timer1 脈波輸出腳位 (TOUT0) 初始化 0 = 在 toggle 模式下,初始化為 0 1 = 在 toggle 模式下,初始化為 1

Page 6: Timer & KEYPAD

計時器資料暫存器 (TDATA0 、 TDATA1) 指明計時器 count value 計數總量( time-out 的時間間隔 )

計時器計數暫存器 (TCNT0 、 TCNT1) 存放一般操作期間的 timer0 和 timer1 的目前計數值

Time-out Data

31 0

Timer Count

31 0

Register Offset Address R/W Description Reset Value

TDATA0 0x6004 R/W Timer0 data register 0x00000000

TDATA1 0x6008 R/W Timer1 data register 0x00000000

Register Offset Address R/W Description Reset Value

TCNT0 0x600C R/W Timer0 counter register 0xFFFFFFFF

TCNT1 0x6010 R/W Timer1 counter register 0xFFFFFFFF

Page 7: Timer & KEYPAD

Example 在間隔 Interval Mode 產生週期 1ms 的 clock 輸出 (time out =

1ms)(1) 產生 1ms 的 clock : fTOUT = 1000 Hz

Interval Mode 輸出頻率公式 : fTOUT = fMCLK / 計時器資料值 CPU 工作頻率 fMCLK = 50MHz 故計時器資料值 = 50000

fTOUT = 50MHz / 50000 = 1000 Hz

time out = 1/ (1000 Hz) = 1ms

(2) fMCLK = 50MHz => 週期 = 20ns = 計時器每 20ns 計數一次 若 計時器資料值 (count value) = 50000 50000 x 20ns = 1ms 的 clock 輸出

Page 8: Timer & KEYPAD

相關暫存器位址 creator_ram.pcm 之系統記憶體映射

Special Register Bank

16MB SDRAMOx000000

0

Ox1000000

Ox3FF0000

Ox3FFFFFF

2MB Flash ROM

64K I/O

Ox1800000

Ox19FFFFF

Ox3F00000

Ox3F0FFFF

TCNT1: 0x3FF6010TCNT0: 0x3FF600C TDATA1: 0x3FF6008TDATA0: 0x3FF6004

TMOD: 0x3FF6000

.

.

.

INTMSK: 0x3FF4008

INTPND: 0x3FF4004

INTMOD: 0x3FF4000

Page 9: Timer & KEYPAD

暫存器變數宣告 timer/4510addr.h

/*============================================================;Timers control registers;============================================================*/#define TMOD ( *(volatile unsigned *) 0x03FF6000)

#define TDATA0 ( *(volatile unsigned *) 0x03FF6004) #define TCNT0 ( *(volatile unsigned *) 0x03FF600C) #define TDATA1 ( *(volatile unsigned *) 0x03FF6008) #define TCNT1 ( *(volatile unsigned *) 0x03FF6010)

Page 10: Timer & KEYPAD

範例程式 (timer)/*************************************************************************System Initialize*************************************************************************/void Initial_Creator(void){ InitialHandler_ISR(); // 初始化中斷向量表格 init_TIMER0(); // 初始化 TIMER0 函式}

/*************************************************************************MAIN Program *************************************************************************/int main(void){

__enable_interrupt(); // 致能系統中斷服務

Initial_Creator(); // 此函式做 Creator 的初始化

EnableInterrupt(BIT_GMASK); // 致能中斷服務遮罩

while (1){}

DisableInterrupt(BIT_GMASK); // 禁能中斷服務遮罩return(0);

}

Page 11: Timer & KEYPAD

Init_timer0() (drive.c)void init_TIMER0(void){

TMOD = 0x00000001;TDATA0 = 50000000; //=50000000*20ns = 1s

// install interrupt source and its service functionInstallHandler_ISR(TIMER0, Timer_ISR_function);

ClearPending(BIT_TIMER0); // 清除中斷 PendingEnableInterrupt(BIT_TIMER0); // 致能中斷服務

}

使用 Timer0, 間隔模式(interval)

Timer中斷服務副程式

Page 12: Timer & KEYPAD

中斷副程式 Timer_ISR_function (drive.c)int LED_light=0;

void Timer_ISR_function(void){

switch(LED_light) { case 0: IO_REG2 = 0xf000;

LED_light=1; break;

case 1: IO_REG2 = 0x0f00; LED_light=0; break;

default: break; } ClearPending(BIT_TIMER0);}

左半邊4個 LED 燈號亮

右半邊4個 LED 燈號亮

Page 13: Timer & KEYPAD

4X4 KEYPAD

藉由程式對 SCAN_Ox 設定” 0” 進行掃描,而由 SCAN_Ix 讀取資料可以判斷該列那一個 KEY 被按下。

Page 14: Timer & KEYPAD

各 I/O 之位元定義7 6 5 4 3 2 1 0

15 14 13 12 11 10 9 8

IO_REG0SEG_H SEG_G SEG_F SEG_E SEG_D SEG_C SEG_B SEG_A

COM3 COM2 COM1 COM0

IO_REG1S1.7 S1.6 S1.5 S1.4 S1.3 S1.2 S1.1 S1.0

SCAN_

I3

SCAN_

I2

SCAN_

I1

SCAN_

I0

IO_REG2

SCAN_O3

SCAN_O2

SCAN_O1

SCAN_O0

D7 D6 D5 D4 D3 D2 D1 D0

Page 15: Timer & KEYPAD

範例程式while (1) {

// 執行掃描for (i=0;i<4;i++) {

// 掃描第 i 行 keypadIO_REG2 =keyOutvalue[i] ;Delay (ms);// 設定 buff= 掃描結果buff = (0x0F00 & IO_REG1);

// 如果結果有掃描到if(buff != 0x0f00 ) {

keypad(i,buff, 1);Delay(2000);

}}

}

Page 16: Timer & KEYPAD

範例程式void keypad(UI i,UI buff,UI k){

UI j, ms=100;// 判別哪一列被按下for (j=0;j<4;j++) {

// 如果第 i 列被按下if( buff == keyInvalue[j] ) {

// 如果是第 i 行掃描到if( i==0)

SHOW7SEG(seg_com[k], j );if (i==1)

SHOW7SEG(seg_com[k], j+4 );if (i==2)

SHOW7SEG(seg_com[k], j+8 );if (i==3)

SHOW7SEG(seg_com[k], j+12);}

} }

Page 17: Timer & KEYPAD

實習 實習一:

修改範例程式 (timer) ,設定 Timer0 的 time-out 時間為 5 秒 (S) 。

實習二:修改範例程式 (timer) ,使用附錄 A 的副程式 (TEST_ISR) 替換掉Timer_ISR_function ,作為 timer0 產生中斷時的中斷服務呼叫。

實習三:修改範例程式 (keypad) ,將按鍵輸出在不同的七階顯示器上面。 (keypad 第 1 次按下的鍵輸出在 COM0)

(keypad 第 2 次按下的鍵輸出在 COM1)(keypad 第 3 次按下的鍵輸出在 COM2)(keypad 第 4 次按下的鍵輸出在 COM3)(keypad 第 5 次按下的鍵輸出在 COM0) 一次輸出一個數字即可

Page 18: Timer & KEYPAD

附錄 Aint i;

void TEST_ISR(void){

switch(i) { case 0: IO_REG0 = 0x0ec0;

break;

case 1: IO_REG0 = 0x0ef9; break;

case 2: IO_REG0 = 0x0ea4; break;

case 3: IO_REG0 = 0x0eb0; break;

default:i=0;IO_REG0 = 0x0ec0;

break; } i++; ClearPending(BIT_TIMER0);}