- 實驗目的
(1)掌握嵌入式系統軟體設計方法,培養分析問題、解決問題、應用知識的能力和創新精神,全面提高綜合素質。
(2)熟悉嵌入式Linux開發環境,學會基于UP-CUP6410-II型平台的Linux開發環境的配置和使用,利用arm-linux-gcc交叉編譯程式,使用基于NFS的挂載方式進行GPIO實驗,了解嵌入式開發的基本過程;
(3)了解嵌入式Linux裁剪、移植及驅動的編寫。
- 實驗内容
(1)基礎實驗——熟悉嵌入式Linux開發環境,嵌入式資料庫應用實驗。
(2)圖形界面應用程式設計——安裝與建立QT桌面運作環境,使用Qt Designer。
(3)核心與根檔案系統實驗(選做)——Linux核心裁剪、編譯、移植,根檔案系統建立。
(4)嵌入式Linux驅動實驗——LED驅動及控制實驗。
- 實驗原理及實驗内容
1.實驗原理
S3C2440提供具備定時器功能的部件如下,都可以精确的每隔一段時間産生中斷:
(1)Timer0—Timer4共5個定時器, Timer0—Timer3可以通過TOUT0—TOUT3引腳輸出PWM波,Timer4沒有輸出引腳。對于每個定時器,每次開始計數時,硬體将TCNTBn 數值加載到TCNTn ,将TCMPBn 數值加載到TCMPn;之後每個計數時鐘周期TCNTn自減。
(2)其數值減到等于TCMPn時,TOUTn引腳上的電平發生反轉,減至0觸發INT_TIMERn内部中斷。 RTC實時時鐘部件具備毫秒級時間片計時器,産生時間片中斷INT_TICK,可以程式設計設定時間片,每次中斷時間最大為小于等于1秒。
(3)看門狗部件可以作為1個正常定時器,計數減到為0則觸發INT_WDT内部中斷(INT_WDT_AC97的子中斷)并自動加載計數。 另外,LED燈連接配接的引腳為GPB5(nLED1)、GPB6(nLED2)、GPB7(nLED3)、GPB8(nLED4),當引腳輸出低電平時,相應LED發光;輸出低電平時,相應LED滅。
2.實驗内容
S3C2440具有5個16為定時器,每個定時器可以按照中斷模式或DMA模式工作。定時器0、1、2、3具有PWM功能。定時器是一個内部定時器,不具有對外輸出口線。定時器0還具有死區發生器,通常用于大電流裝置。
在單次觸下發模式下,定時器完成一次倒計時并産生中斷請求後,定時器便停止了。如果要啟動下一次計時,需要重新向TCNBn中寫入計時值,并重新啟動定時器開始工作。
void Test_TimerInt(void)
{variable0 = 0;variable1 = 0;variable2 = 0;variable3 = 0;variable4 = 0;
/* Timer0,1,2,3,4 Interrupt service is available */
rINTMSK = ~(BIT_TIMER4 | BIT_TIMER3 | BIT_TIMER2 | BIT_TIMER1 | BIT_TIMER0);
// Uart_Printf("rINTMSK (After) = 0x%8x <= Timer4,3,2,1 Bit[14:10]\n",rINTMSK);
/* Timer0,1,2,3,4 Interrupt Service Routine Entry Point Determine */
pISR_TIMER0 = (int)Timer0Done;
pISR_TIMER1 = (int)Timer1Done;
pISR_TIMER2 = (int)Timer2Done;
pISR_TIMER3 = (int)Timer3Done;
pISR_TIMER4 = (int)Timer4Done;
Uart_Printf("\n[Timer 0,1,2,3,4 Interrupt Test]\n\n");
rTCFG0 = rTCFG0 & ~(0xffffff) | 0xff | 0xff<<8; //Dead zone=0,Prescaler1=255(0x0f),Prescaler0=255(0x0f)
rTCFG1 =rTCFG1 & ~(0xffffff) | 0x001233; //All interrupt,Mux4=1/2,Mux3=1/4,Mux2=1/8,Mux1=1/16,Mux0=1/16
rTCNTB0 = 30000;
rTCNTB1 = 30000;
rTCNTB2 = 30000;
rTCNTB3 = 30000;
rTCNTB4 = 30000;
rTCMPB0 = 15000;
rTCMPB1 = 15000;
rTCMPB2 = 15000;
rTCMPB3 = 15000;
rTCON = rTCON & ~(0xffffff) | 0x1<<1 | 0x1<<9 | 0x1<<13 | 0x1<<17 | 0x1<<21 ; //Manual update
rTCON = rTCON & ~(0xffffff) | 0x1 ; //Timer 0 Start, Auto-reload
rTCON = rTCON | 0x1<<8 ; //Timer 1 Start, Auto-reload
rTCON = rTCON | 0x1<<12 ; //Timer 2 Start, Auto-reload
rTCON = rTCON | 0x1<<16; //Timer 3 Start, Auto-reload
rTCON = rTCON | 0x1<<20; //Timer 4 Start, Auto-reload
while(1)
{
if(old_v3!=variable3)
{//重新啟動定時器3
rTCON= rTCON&0xf6ffff;
rTCON = rTCON | 0x1<<16 ;
old_v3=variable3;
}
if(old_v2!=variable2)
{ //重新啟動定時器2
rTCON= rTCON&0xff6fff;
rTCON = rTCON | 0x1<<12 ;
old_v2=variable2;
}
if(old_v1!=variable1)
{//重新啟動定時器1
rTCON= rTCON&0xfff6ff;
rTCON = rTCON | 0x1<<8 ;
old_v1=variable1;
}
if(old_v0!=variable0)
{//重新啟動定時器0
rTCON= rTCON&0xfffff6;
rTCON = rTCON | 0x1<<0 ;
old_v0=variable0;
}
if(old_v4!=variable4)
{//重新啟動定時器4
rTCON= rTCON&0x6fffff;
rTCON = rTCON | 0x1<<20 ;
old_v4=variable4;
}
if(variable4 == 8)
break;
}
//Delay(1); //To compensate timer error(<1 tick period)
rTCON = 0x0; //Stop Timers
if(variable4==8 && variable3==4 && variable2==2 && variable1==1 && variable0==1)
{Uart_Printf("Timer 0,1,2,3,4 Auto-reload Interrupt Test => OK!\n");}
else
{Uart_Printf("Timer 0,1,2,3,4 Auto-reload Interrupt Test => Fail............\n");}
Uart_Printf("Timer0: %d (=1)\nTimer1: %d (=1)\nTimer2: %d (=2)\nTimer3: %d (=4)\nTimer4: %d (=8)\n",
variable0,variable1,variable2,variable3,variable4);
/* Timer0,1,2,3,4 Interrupt Service is masked */
rINTMSK |= (BIT_TIMER4 | BIT_TIMER3 | BIT_TIMER2 | BIT_TIMER1 | BIT_TIMER0);
Uart_Printf("Press any key\n");
while(!Uart_Getch()); //Key board press check
}
定義變量old_v0——old_v4,在Timer.c檔案中變量variable0,variable1,variable2,variable3,variable4定義之處添加,如下:
Static volatile int dmaDone,variable0,variable1,variable2,variable3,variable4,old_v4,old_v3,old_v2,old_v1,old_v0;
初始化變量old_v0——old_v4,在void Test_TimerInt(void)函數中,如下:
variable0 = 0;variable1 = 0;variable2 = 0;variable3 = 0;variable4 = 0; old_v3=0;old_v4=0;old_v2=0;old_v1=0;old_v0=0;
- 實驗結果展示
在程式沒有改動之前,編譯程式,下載下傳到實驗箱運作,結果如下:
Timer0:1
Timer1:1
Timer2:2
Timer3:4
Timer4:8
編譯程式,下載下傳到實驗箱運作。運作結果為:
Timer0:1
Timer1:1
Timer2:2
Timer3:4
Timer4:8
- 創新點及存在問題
在實驗過程中,由于考慮問題不夠全面,在修改程式使定時器工作于單次觸發模式并完成本實驗相同的功能。我們隻考慮了定時器控制寄存器中Timer0、Timer1、Timer2、Timer3、Timer4的自動裝載位是否啟動。其中第3位、第11位、15位、19位、22位置0,使其工作于單次觸發模式下。是以我們隻把
rTCON = rTCON & ~(0xffffff) | 0x1;// | 0x1<<3 ; //Timer 0 Start,
rTCON = rTCON | 0x1<<8 ;//| 0x1<<11 ; //Timer 1 Start,
rTCON = rTCON | 0x1<<12;// | 0x1<<15 ; //Timer 2 Start, Auto-reload
rTCON = rTCON | 0x1<<16 ;//| 0x1<<19 ; //Timer 3 Start, Auto-reload
rTCON = rTCON | 0x1<<20;// | 0x1<<22 ; //Timer 4 Start, Auto-reload
結果在運作結果後,并沒有出現預想的結果。重新改正了程式,并得到了相同的結果。因為還需要在單次觸發模式下重新啟動定時器。
定時長度=計時常數/(pclk/(預分頻值+1))/分割器值)可以計算出T0:T1:T2:T3:T4=8:8:4:2:1,而中斷次數反比于定時長度(相同時間内)Tn0:Tn1:Tn2:Tn3:Tn4=1:1:2:4:8.進而得到了即Timer0——Timer4的中斷次數分别是1、1、2、4、8。
- 實驗總結
定時器控制寄存器(TCON)可進行定時器自動重載、手動更新、啟動/停止、輸入、輸入反轉及死區使能的設定功能。
