【stm32简单外设篇】- 测速传感器模块(光电)

一、适用场景

适用场景:车轮/轴转速测量、里程计(里程计算路程)、风速/流量脉冲采集、马达 RPM 测量、测速表盘、测速触发与检测教学。

二、器材清单

测速传感器(光电开关模块)×1

编码盘×1

小车轮子×1

STM32 开发板(3.3V MCU)×1

若干杜邦线(公/母)×1组

稳定电源:5V/3.3V(最好是5v)

三、工作原理(要点)

原理:传感器在目标穿孔经过检测点时产生电平跳变(脉冲)。把脉冲的频率或脉冲间隔测量出来,按脉冲每转数与轮胎周长换算为线速度。

四、接线示意

GND→ GND

VCC→ 5V/3.3V电源

标准库

DO→ PC3

HAL库

DO→ PA3

五、示例代码

标准库

cpp 复制代码
#include "stm32f10x.h"
#include "stdio.h"
#include "bsp_SysTick.h"
#include "adc_time.h"
#include "breathing.h"
#include "bsp_usart.h"


int cnt;
char oledshow[20] = {0};
void TIM4_Init()
{
	NVIC_InitTypeDef nvic;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);

	TIM_DeInit(TIM4);
	TIM_TimeBaseInitStructure.TIM_Period = (1000000-1);							
	TIM_TimeBaseInitStructure.TIM_Prescaler = (72-1);							
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;					
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;	
	TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);
	
	TIM_ClearFlag(TIM4,TIM_FLAG_Update);
	TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	nvic.NVIC_IRQChannel=TIM4_IRQn;
	nvic.NVIC_IRQChannelPreemptionPriority=0;
	nvic.NVIC_IRQChannelSubPriority=0;
	nvic.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&nvic);
	
	TIM_Cmd(TIM4,ENABLE);

}

void Exit_Init()
{
	NVIC_InitTypeDef nvic;
	GPIO_InitTypeDef  PC;
	EXTI_InitTypeDef exti;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);

	PC.GPIO_Pin = GPIO_Pin_3;	 
	PC.GPIO_Mode = GPIO_Mode_IPU; 
	PC.GPIO_Speed =	GPIO_Speed_50MHz;	 
	GPIO_Init(GPIOC, &PC);	   
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource3);
	exti.EXTI_Line = EXTI_Line3;
	exti.EXTI_Mode = EXTI_Mode_Interrupt;
	exti.EXTI_Trigger = EXTI_Trigger_Falling;
	exti.EXTI_LineCmd = ENABLE;
	EXTI_Init(&exti);

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	nvic.NVIC_IRQChannel=EXTI3_IRQn;
	nvic.NVIC_IRQChannelPreemptionPriority=1;
	nvic.NVIC_IRQChannelSubPriority=1;
	nvic.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&nvic);
}

int main()
{
	SysTick_Init();
	Exit_Init();
	TIM4_Init();
	USART_Config();
	while(1)
	{
	}
//	return 0;
}

void TIM4_IRQHandler()
{
	if(TIM_GetITStatus(TIM4,TIM_IT_Update)!=RESET)
	{
		sprintf((char *)oledshow,"speed:%d\n",cnt);
		Usart_SendString(USART1,oledshow);
		cnt=0;
//		Usart_SendString(USART1,"speed:0\n");
		TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
	}
}

void EXTI3_IRQHandler()
{
	if(EXTI_GetITStatus(EXTI_Line3)!=RESET)
	{	
		
		if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_3) == 0)
		{	
			cnt++;
//			sprintf((char *)oledshow,"speed:%d\n",cnt);
//		  Usart_SendString(USART1,oledshow);
		}
	}
	EXTI_ClearITPendingBit(EXTI_Line3);
}

HAL库

cpp 复制代码
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_TIM4_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
	HAL_TIM_Base_Start_IT(&htim4);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief TIM4 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM4_Init(void)
{

  /* USER CODE BEGIN TIM4_Init 0 */

  /* USER CODE END TIM4_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  /* USER CODE BEGIN TIM4_Init 1 */

  /* USER CODE END TIM4_Init 1 */
  htim4.Instance = TIM4;
  htim4.Init.Prescaler = 7199;
  htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim4.Init.Period = 9999;
  htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM4_Init 2 */

  /* USER CODE END TIM4_Init 2 */

}

/**
  * @brief USART1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART1_UART_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */

  /* USER CODE END USART1_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin : PA3 */
  GPIO_InitStruct.Pin = GPIO_PIN_3;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /* EXTI interrupt init*/
  HAL_NVIC_SetPriority(EXTI3_IRQn, 1, 0);
  HAL_NVIC_EnableIRQ(EXTI3_IRQn);

/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if (GPIO_Pin == GPIO_PIN_3)
  {
    uint32_t now = HAL_GetTick();           // 毫秒滴答
    if (now - _last_exti_tick < 10) return; // <50ms 内当抖动,忽略
    _last_exti_tick = now;

    cnt++;
    sprintf((char *)show, "speed:%d\r\n", cnt);
		HAL_UART_Transmit(&huart1,show,strlen(show),HAL_MAX_DELAY);
  }
}


void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == TIM4) // 判断是否是 TIM4
    {
      cnt=0;
			HAL_UART_Transmit(&huart1,"speed:0\r\n",strlen("speed:0\r\n"),HAL_MAX_DELAY);
    }
}

六、讲解视频

https://www.bilibili.com/video/BV16JzyBREGS/?spm_id_from=333.1387.search.video_card.click&vd_source=f7dfe1b14f260b9cc3a146d2dbfd0719

https://www.bilibili.com/video/BV16EzyBxED5/?spm_id_from=333.1387.search.video_card.click&vd_source=f7dfe1b14f260b9cc3a146d2dbfd0719

https://www.bilibili.com/video/BV11uzyBaEnV/?spm_id_from=333.1387.search.video_card.click&vd_source=f7dfe1b14f260b9cc3a146d2dbfd0719

相关推荐
hateregiste1 小时前
嵌入式软件开发中常见知识点问答集锦!
c语言·单片机·嵌入式软件
电化学仪器白超1 小时前
EC20CEHDLG-128-SNNS调试记录
python·单片机·嵌入式硬件·自动化
极客小张1 小时前
基于STM32的智能水质监测与远程预警系统设计与实现
c语言·python·stm32·单片机·嵌入式硬件·物联网
2501_918126912 小时前
stm32最级别的烧录解锁是什么?
stm32·单片机·嵌入式硬件·学习·个人开发
Once_day2 小时前
GCC编译(7)链接脚本LinkerScripts
c语言·c++·编译和链接·程序员自我修养
qq_241585612 小时前
jump_to_app
单片机·嵌入式硬件
你好,奋斗者!2 小时前
74HC595芯片原理及代码示例
嵌入式硬件·软件·电路设计
小刘爱玩单片机2 小时前
【stm32简单外设篇】- KY-025 干簧管(磁控)模块
c语言·stm32·单片机·嵌入式硬件
forAllforMe2 小时前
STM32的分散加载问题--使用场合
stm32·单片机·嵌入式硬件