文章目錄
- 1 實驗任務
- 2 系統框圖
- 3 軟件設計
1 實驗任務
本實驗任務是通過CPU私有定時器來計算按鍵按下的時間長短。
2 系統框圖
參見7.1。
3 軟件設計
注意事項:
- 定時器是遞減計數的,需要考慮StartCount<EndCount的情況。
/***************************** Include Files ********************************/
#include <stdio.h>
#include "xparameters.h"
#include "xgpiops.h"
#include "xscutimer.h"
#include "xstatus.h"
/************************** Constant Definitions ****************************/
#define GPIO_DEVICE_ID XPAR_XGPIOPS_0_DEVICE_ID
#define TIMER_DEVICE_ID XPAR_XSCUTIMER_0_DEVICE_ID#define PS_KEY0_GPIO_PIN 50#define TIMER_LOAD_VALUE 0xFFFFFFFF#define TIMER_CLK_FREQ XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ / 2
/**************************** Type Definitions ******************************//***************** Macros (Inline Functions) Definitions ********************//************************** Function Prototypes *****************************/
int GpioInit(XGpioPs* GpioInstPtr);
int TimerInit(XScuTimer* TimerInstPtr);
/************************** Variable Definitions ****************************/
XGpioPs GpioInst;
XScuTimer TimerInst;u32 StartCount = 0;
u32 EndCount = 0;
/****************************************************************************/int GpioInit(XGpioPs* GpioInstPtr)
{//int Status;XGpioPs_Config* GpioPsConfigPtr;//GpioPsConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);Status = XGpioPs_CfgInitialize(GpioInstPtr, GpioPsConfigPtr, GpioPsConfigPtr->BaseAddr);if (Status != XST_SUCCESS) {return XST_FAILURE;}// 設置輸入XGpioPs_SetDirectionPin(GpioInstPtr, PS_KEY0_GPIO_PIN, 0);//return XST_SUCCESS;
}int TimerInit(XScuTimer* TimerInstPtr)
{//int Status;XScuTimer_Config* TimerConfigPtr;//TimerConfigPtr = XScuTimer_LookupConfig(TIMER_DEVICE_ID);Status = XScuTimer_CfgInitialize(TimerInstPtr, TimerConfigPtr, TimerConfigPtr->BaseAddr);if (Status != XST_SUCCESS) {return XST_FAILURE;}// 自動加載XScuTimer_EnableAutoReload(TimerInstPtr);// 加載初值XScuTimer_LoadTimer(TimerInstPtr, TIMER_LOAD_VALUE);//return XST_SUCCESS;
}int main()
{//int Status;u32 KeyValue;u32 CountDiff;u32 TimerClkFreq = TIMER_CLK_FREQ;float PressedTime;//Status = GpioInit(&GpioInst);if (Status == XST_FAILURE) {printf("GPIO Init Failed.\n");}//Status = TimerInit(&TimerInst);if (Status == XST_FAILURE) {printf("Timer Init Failed.\n");}// 啟動定時器XScuTimer_Start(&TimerInst);//printf("Press the key to start timing...\n");//while(1){// 等待按鍵按下while (1) {KeyValue = XGpioPs_ReadPin(&GpioInst, PS_KEY0_GPIO_PIN);if (KeyValue == 0) { // 按鍵按下為低電平StartCount = XScuTimer_GetCounterValue(&TimerInst);printf("Key pressed, timing started.\n");break;}}// 等待按鍵釋放while (1) {KeyValue = XGpioPs_ReadPin(&GpioInst, PS_KEY0_GPIO_PIN);if (KeyValue == 1) { // 按鍵釋放為高電平EndCount = XScuTimer_GetCounterValue(&TimerInst);printf("Key released, timing stopped.\n");break;}}// 計算差值if (EndCount > StartCount) {printf("EndCount > StartCount.\n");CountDiff = (0xFFFFFFFF - EndCount) + StartCount + 1; // 注意:定時器會溢出}else {printf("EndCount < StartCount.\n");CountDiff = StartCount - EndCount; // 注意:定時器是遞減的}//printf("Key pressed for %lu clock cycles.\n", CountDiff);// 轉換為時間PressedTime = (float)CountDiff / TimerClkFreq;printf("Key pressed for %.3f seconds.\n", PressedTime);}//return 0;
}