7.2 - 定时器之计算脉冲宽度实验
文章目录
- 1 实验任务
- 2 系统框图
- 3 硬件设计
- 4 软件设计
- 4.1 注意事项
- 4.2 工程源码
1 实验任务
本实验任务是通过CPU私有定时器来计算按键按下的时间长短。
2 系统框图
参见7.1。
3 硬件设计
参见7.1。
4 软件设计
4.1 注意事项
- 无。
4.2 工程源码
/***************************** Include Files ********************************/#include<stdio.h>#include"xparameters.h"#include"xgpiops.h"#include"xscutimer.h"/************************** Constant Definitions ****************************/#defineGPIOPS_DEVICE_IDXPAR_XGPIOPS_0_DEVICE_ID// GPIOPS设备ID#defineTIMER_DEVICE_IDXPAR_XSCUTIMER_0_DEVICE_ID// TIMER设备ID#defineMIO_KEY050// KEY0对应的MIO引脚号#defineTIMER_LOAD_VALUE0xFFFFFFFFU// Timer加载值(最大值, 约12.9秒)#defineTIMER_CLOCK_FREQ(XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ/2)// Timer时钟频率(CPU时钟的一半)/**************************** Type Definitions ******************************//***************** Macros (Inline Functions) Definitions ********************//************************** Function Prototypes *****************************/staticintGpioPsInit(XGpioPs*GpioPsInstPtr,u16 DeviceId);staticintTimerInit(XScuTimer*TimerInstPtr,u16 DeviceId);/************************** Variable Definitions ****************************/staticXGpioPs GpioPsInst;// GpioPs驱动实例staticXScuTimer TimerInst;// Timer驱动实例/************************** Function Definitions ****************************//* * @brief GpioPs初始化函数 - 配置KEY引脚为输入 * @param GpioPsInstPtr: GpioPs驱动实例指针 * @param DeviceId: GpioPs设备ID * @return 成功返回XST_SUCCESS,失败返回对应错误码 */staticintGpioPsInit(XGpioPs*GpioPsInstPtr,u16 DeviceId){// 校验GpioPs驱动实例指针是否为空if(NULL==GpioPsInstPtr){returnXST_INVALID_PARAM;}// 校验GpioPs设备ID是否有效if(DeviceId!=GPIOPS_DEVICE_ID){returnXST_INVALID_PARAM;}//intStatus;// GpioPs配置指针XGpioPs_Config*GpioPsConfigPtr;// 获取GpioPs设备配置信息GpioPsConfigPtr=XGpioPs_LookupConfig(DeviceId);if(NULL==GpioPsConfigPtr){returnXST_FAILURE;}// 根据配置信息初始化GpioPs驱动实例Status=XGpioPs_CfgInitialize(GpioPsInstPtr,GpioPsConfigPtr,GpioPsConfigPtr->BaseAddr);if(Status!=XST_SUCCESS){returnStatus;}// 设置MIO_KEY0引脚方向为输入XGpioPs_SetDirectionPin(GpioPsInstPtr,MIO_KEY0,0);// 初始化成功returnXST_SUCCESS;}/* * @brief Timer初始化函数 - 配置为单次计数模式, 不使用中断 * @param TimerInstPtr: Timer驱动实例指针 * @param DeviceId: Timer设备ID * @return 成功返回XST_SUCCESS,失败返回对应错误码 */staticintTimerInit(XScuTimer*TimerInstPtr,u16 DeviceId){// 校验Timer驱动实例指针是否为空if(NULL==TimerInstPtr){returnXST_INVALID_PARAM;}// 校验Timer设备ID是否有效if(DeviceId!=TIMER_DEVICE_ID){returnXST_INVALID_PARAM;}//intStatus;// Timer配置指针XScuTimer_Config*TimerConfigPtr;// 获取Timer设备配置信息TimerConfigPtr=XScuTimer_LookupConfig(DeviceId);if(NULL==TimerConfigPtr){returnXST_FAILURE;}// 根据配置信息初始化Timer驱动实例Status=XScuTimer_CfgInitialize(TimerInstPtr,TimerConfigPtr,TimerConfigPtr->BaseAddr);if(Status!=XST_SUCCESS){returnStatus;}// Timer自检Status=XScuTimer_SelfTest(TimerInstPtr);if(Status!=XST_SUCCESS){returnStatus;}// 停止TimerXScuTimer_Stop(TimerInstPtr);// 加载Timer计数值(最大值)XScuTimer_LoadTimer(TimerInstPtr,TIMER_LOAD_VALUE);// 禁用Timer自动重载模式(单次计数, 计到0停止)XScuTimer_DisableAutoReload(TimerInstPtr);// 禁用Timer中断XScuTimer_DisableInterrupt(TimerInstPtr);// 初始化成功returnXST_SUCCESS;}/* * @brief 主函数 - 通过轮询检测按键按下时长, 使用Timer计时并打印结果 */intmain(void){//intStatus;// 当前按键状态u32 key_current;// 上一次按键状态 - 初始值为1(松开)u32 key_previous=1;// Timer当前计数值u32 timer_value;// 按键按下时长(秒)floatpress_duration;// 初始化GpioPsStatus=GpioPsInit(&GpioPsInst,GPIOPS_DEVICE_ID);if(Status!=XST_SUCCESS){printf("GpioPs init failed, error code: %d\n",Status);returnStatus;}// 初始化TimerStatus=TimerInit(&TimerInst,TIMER_DEVICE_ID);if(Status!=XST_SUCCESS){printf("Timer init failed, error code: %d\n",Status);returnStatus;}// 打印提示信息printf("Timer Key Press Test: Measure button press duration\n");// 主循环 - 轮询检测按键边沿, 测量按下时长while(1){// 读取当前按键状态key_current=XGpioPs_ReadPin(&GpioPsInst,MIO_KEY0);// 检测下降沿: 按键从松开变为按下if(key_previous==1&&key_current==0){// 重载Timer计数值XScuTimer_LoadTimer(&TimerInst,TIMER_LOAD_VALUE);// 启动Timer开始计时XScuTimer_Start(&TimerInst);}// 检测上升沿: 按键从按下变为松开if(key_previous==0&&key_current==1){// 停止Timer计时XScuTimer_Stop(&TimerInst);// 读取Timer当前计数值timer_value=XScuTimer_GetCounterValue(&TimerInst);// 计算按键按下时长 = (加载值 - 当前计数值) / Timer时钟频率press_duration=(float)(TIMER_LOAD_VALUE-timer_value)/(float)TIMER_CLOCK_FREQ;// 打印按键按下时长printf("Key pressed for %.3f seconds\n",press_duration);}// 更新上一次按键状态key_previous=key_current;}// 程序正常退出returnXST_SUCCESS;}