复制代码
#include "user.h"
#include "oled.h"
char rx_buf[128];
extern DMA_HandleTypeDef hdma_usart1_rx;
// Global variables
// TIM3 捕获溢出全局变量
uint32_t rise_time1 = 0; // 第一个上升沿时间
uint32_t fall_time = 0; // 下降沿时间
uint32_t rise_time2 = 0; // 第二个上升沿时间
uint32_t rise_time1_overflow = 0; // 第一个上升沿时的溢出次数
uint32_t fall_time_overflow = 0; // 下降沿时的溢出次数
uint32_t rise_time2_overflow = 0; // 第二个上升沿时的溢出次数
uint8_t capture_cnt = 0; // 捕获阶段计数
uint8_t capture_flag = 0; // 捕获完成标志
float pwm_frequency = 0; // 最终计算的PWM频率
float pwm_duty = 0; // 最终计算的占空比
extern volatile uint32_t tim3_overflow_count; // 声明在 stm32f1xx_it.c 中的溢出计数
void app(void){
//OLED
OLED_Init();
OLED_Clear();
OLED_Refresh();
//UART
HAL_UARTEx_ReceiveToIdle_DMA(&huart1,(uint8_t*)rx_buf,128);
__HAL_DMA_DISABLE_IT(&hdma_usart1_rx,DMA_IT_HT);
// 确保初始极性为上升沿
__HAL_TIM_SET_CAPTUREPOLARITY(&htim3, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);
//TIM2 start
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
//TIM3 IC start
HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_1);
while(1){
if (capture_flag)
{
print("Freq: %.2f Hz, Duty: %.2f%%\r\n", pwm_frequency, pwm_duty);
capture_flag = 0;
}
}
}
//uart Idle DMA
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size){
if(huart == &huart1){
print("Received: %s",rx_buf);
memset(rx_buf,0,128);
HAL_UARTEx_ReceiveToIdle_DMA(&huart1,(uint8_t*)rx_buf,128);
__HAL_DMA_DISABLE_IT(&hdma_usart1_rx,DMA_IT_HT);
}
}
//TIM2->PWM->TIM3
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim){
if (htim->Instance == TIM3 && htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
{
if (capture_cnt == 0)
{
// 第一个上升沿
rise_time1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
rise_time1_overflow = tim3_overflow_count; // 记录溢出次数
__HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_FALLING);
capture_cnt = 1;
}
else if (capture_cnt == 1)
{
// 下降沿
fall_time = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
fall_time_overflow = tim3_overflow_count; // 记录溢出次数
__HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);
capture_cnt = 2;
}
else if (capture_cnt == 2)
{
// 第二个上升沿
rise_time2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
rise_time2_overflow = tim3_overflow_count; // 记录溢出次数
uint32_t high_time_total;
uint32_t period_total;
// 计算高电平时间 (考虑溢出)
if (fall_time_overflow == rise_time1_overflow) {
high_time_total = fall_time - rise_time1;
} else {
high_time_total = (fall_time_overflow - rise_time1_overflow) * (0xFFFF + 1) + fall_time - rise_time1;
}
// 计算周期 (考虑溢出)
if (rise_time2_overflow == rise_time1_overflow) {
period_total = rise_time2 - rise_time1;
} else {
period_total = (rise_time2_overflow - rise_time1_overflow) * (0xFFFF + 1) + rise_time2 - rise_time1;
}
// 重置溢出计数器,确保下一次测量从0开始
tim3_overflow_count = 0;
if (period_total > 0)
{
pwm_frequency = 1000000.0f / (float)period_total; // TIM3 频率为 1MHz (1us/tick)
pwm_duty = ((float)high_time_total * 100.0f) / (float)period_total;
capture_flag = 1;
}
capture_cnt = 0;
}
}
}
void print(const char *format, ...){
char buf[128];
va_list args;
va_start(args,format);
vsnprintf(buf,128-1,format,args);
va_end(args);
HAL_UART_Transmit(&huart1,(uint8_t*)buf,strlen(buf),1000);
}