车速转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 车速,中间停车三次

 

posted @   妖岭  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 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)连接千寻
点击右上角即可分享
微信分享提示