简介
通过TIM5_CH1捕获上升沿电平, 两个上升沿的计数值计算频率;
电路原理图
连接图
将 PC7 与 PA0使用跳线进行连接
其他知识
APIs
/* Blocking mode: Polling */
HAL_StatusTypeDef HAL_TIM_IC_Start(TIM_HandleTypeDef *htim, uint32_t Channel); // 堵塞捕获开启
HAL_StatusTypeDef HAL_TIM_IC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); // 堵塞捕获停止
/* Non-Blocking mode: Interrupt */
HAL_StatusTypeDef HAL_TIM_IC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); // 中断捕获开启
HAL_StatusTypeDef HAL_TIM_IC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); // 中断捕获停止
/* Non-Blocking mode: DMA */
HAL_StatusTypeDef HAL_TIM_IC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length); //DMA捕获开启
HAL_StatusTypeDef HAL_TIM_IC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); // DMA捕获停止
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim); // 捕获时中断回调函数
实现步骤
创建项目
参考 普中STM32-PZ6806L开发板(HAL库函数实现-PWM呼吸灯), 使用同一个GPIO口PC7产生PWM,然后PA0引脚进行捕获
初始化PA0为TIM5_CH1
添加用户代码
main.c
float frequency = 0;
int is_first_captured = 0;
uint32_t ic_val1 = 0, ic_val2 = 0;
uint32_t difference = 0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if ( htim->Instance == TIM5 )
{
if ( htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1 )
{
if (0 == is_first_captured)
{
ic_val1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); // 获取第一个上升沿计数值
is_first_captured = 1;
}
else
{
ic_val2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); // 获取第二个上升沿计数值
/* 计算完整脉冲计数值 */
if (ic_val2 > ic_val1)
{
difference = ic_val2-ic_val1;
}
else if (ic_val2 < ic_val1)
{
difference = (0xffff - ic_val1) + ic_val2;
}
float refClock = 1000000; // System Clock/Prescale = (72000000)/(72);
frequency = refClock/difference; // 计算频率
__HAL_TIM_SET_COUNTER(htim, 0); //reset the counter
is_first_captured = 0;
}
}
}
}
int main()
{
...
printf("Very Welcome!\r\n");
__HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_2, 250);
HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_2); // 启动PWM输出
while (1)
{
HAL_Delay(2000);
printf ("frequency : %f\r\n", frequency);
}
...
}
共赏
刚好之前的呼吸灯设置的就是2KHz, 采集到的也是2000
参考
普中STM32-PZ6806L开发板(HAL库函数实现-批量操作GPIO引脚实现跑马灯)