Timer & KEYPAD
-
Upload
prescott-peck -
Category
Documents
-
view
60 -
download
0
description
Transcript of Timer & KEYPAD
Timer & KEYPAD
11/24
實習基礎 S3C4510B 提供了兩個 32 位元計時器 (timer0 、 timer1) ,
固定以下數方式進行計數。而其操作的方式可分為兩種,其分別為間隔 (interval) 模式與雙態 (toggle) 模式,這兩種模式的差別在於輸出波形的不同。
下數計數器 波形產生器Time out 脈波訊號
System Clock
計時器模式
間隔 Interval Mode: 計時器計數結束即會產生一個脈波,
輸出頻率 fTOUT = fMCLK / 計時器資料值
雙態 Toggle Mode: 計時器計數結束進行波形轉態動作,
輸出頻率 fTOUT = fMCLK / ( 計時器資料值 x 2)
CPU 工作頻率 fMCLK = 50MHz
32 位元計時器方塊圖
TDATA 暫存器
TCNT暫存器
產生中斷訊號system clock
time outTMOD計時器
模式設定
給予下數數值
計時器模式暫存器 計時器模式暫存器 (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
計時器資料暫存器 (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
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 輸出
相關暫存器位址 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
暫存器變數宣告 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)
範例程式 (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);
}
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中斷服務副程式
中斷副程式 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 燈號亮
4X4 KEYPAD
藉由程式對 SCAN_Ox 設定” 0” 進行掃描,而由 SCAN_Ix 讀取資料可以判斷該列那一個 KEY 被按下。
各 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
範例程式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);
}}
}
範例程式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);}
} }
實習 實習一:
修改範例程式 (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) 一次輸出一個數字即可
附錄 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);}