车速转ODO PWM实现(假设检测方为上升沿触发GPIO中断)
1. 配置
2. 启动PWM
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); //启动PWM输出
// 修改PWM参数
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1, 90); //占空比值等于 Couner Period 低电平占比100%(CH Polarity配置为LOW)
3. 动态调整频率,接收CAN车速消息改变 Pulsefreq_Hz(ODO频率)= 车速*(ODO:车速(km/h) = 8:1)
计算分频值
分频值 = (uint32_t)round(800000.0/Pulsefreq_Hz) // TIM时钟频率(72MHz)/ (Couner Period (89)+1)= 800000
设置分频值和占空比
__HAL_TIM_SET_PRESCALER(&htim1, (uint32_t)round(800000.0/Pulsefreq_Hz));
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1, 2); //设置占空比(高电平)(90-2)/90
上升沿触发:高电平占比越大,可检测频率越高;
下降沿触发:低电平占比越大,可检测频率越高。
int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_CAN_Init(); MX_TIM1_Init(); MX_USART2_UART_Init(); MX_TIM2_Init(); /* USER CODE BEGIN 2 */ hcan.Instance->IER |= (1U<<1); //Enable FIFO message pending interrupt HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); // 修改PWM参数 __HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1, 90); __HAL_TIM_ENABLE(&htim2); //Enable TIM2 /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ for(;;) { if(1 == ReceiveSpeed) { if(Pulsefreq_Hz) { __HAL_TIM_SET_PRESCALER(&htim1, (uint32_t)round(800000.0/Pulsefreq_Hz)); __HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1, 2); } else __HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1, 90); ReceiveSpeed=0; Pulsefreq_Valid = 0; printf("odo_freq:%d\r\n", Pulsefreq_Hz); } else if(Pulsefreq_Valid>2) { Pulsefreq_Valid = 0; __HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1, 90); printf("odo_freq:%d, No Receive From CAN\r\n", 0); LED1(1);LED2(1); HAL_Delay(500); LED1(0);LED2(0); HAL_Delay(500); } GetKey(); // Test // if(Pulsefreq_Hz) // { // __HAL_TIM_SET_PRESCALER(&htim1, (uint32_t)round(800000.0/Pulsefreq_Hz)); // __HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1, 45); // printf("odo_freq:%lu\r\n", Pulsefreq_Hz); // printf("prescaler:%lu, %lf\r\n", (uint32_t)round(800000.0/Pulsefreq_Hz),800000.0/Pulsefreq_Hz); // } // else // { // __HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1, 90); // printf("odo_freq:%lu\r\n", Pulsefreq_Hz); // printf("prescaler:%lu, %lf\r\n", 0,0); // // } // Pulsefreq_Hz += 8; // if(Pulsefreq_Hz>3000) Pulsefreq_Hz = 0; // HAL_Delay(5000); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }
100Hz 车速,中间停车三次
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
2023-12-05 Keil(C/C++混编)printf问题
2023-12-05 Ntrip协议
2023-12-05 SIM800C模块(2G)连接千寻