7.2-定时器之计算脉冲宽度实验
- 电脑硬件
- 2025-09-21 23:03:01

文章目录 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; }7.2-定时器之计算脉冲宽度实验由讯客互联电脑硬件栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“7.2-定时器之计算脉冲宽度实验”