【STM32学习】(22)STM32实现360度旋转编码器

360度 旋转编码器实物如下:

【STM32学习】(22)STM32实现360度旋转编码器_第1张图片

KY-040旋转编码器模块

 工作电压:5V

一圈脉冲数:20

旋转编码器可通过旋转可以计数正方向和反方向转动过程中输出脉冲的次数,旋转计数不像电位计,这种转动计数是没有限制的。配合旋转编码器上的按键,可以复位到初始状态,即从0开始计数。

 工作原理:增量编码器是一种将旋转位移转换为一连串数字脉冲信号的旋转式传感器。这些脉冲用来控制角位移。在Eltra编码器中角位移的转换采用了光电扫描原理。读数系统以由交替的透光窗口和不透光窗口构成的径向分度盘(码盘)的旋转为依据,同时被一个红外光源垂直照射,光把码盘的图像投射到接收器表面上。接收器覆盖着一层衍射光栅,它具有和码盘相同的窗口宽度。接收器的工作是感受光盘转动所产生的变化,然后将光变化转换成相应的电变化。再使低电平信号上升到较高电平,并产生没有任何干扰的方形脉冲,这就必须用电子电路来处理。读数系统通常采用差分方式,即将两个波形一样但相位差为180°的不同信号进行比较,以便提高输出信号的质量和稳定性。读数是再两个信号的差别基础上形成的,从而消除了干扰。

【STM32学习】(22)STM32实现360度旋转编码器_第2张图片

增量编码器给出两相方波,它们的相位差90°,通常称为A通道和B通道。其中一个通道给出与转速相关的信息,与此同时,通过两个通道信号进行顺序对比,得到旋转方向的信息。还有一个特殊信号称为Z或零通道,该通道给出编码器的绝对零位,此信号是一个方波与A通道方波的中心线重合。

【STM32学习】(22)STM32实现360度旋转编码器_第3张图片

 

现在实现检测这个增量编码器正转还是反转

我们这里用读取IO的方式来读取数据,来判断是正转还是反转。

单片机型号:STM32L052K8*

接线:CLK  接  PA0

            DT   接  PA1

            SW  接  PA2

int main(void)
{
  /* USER CODE BEGIN 1 */
	unsigned char dt;
	unsigned char clk,key;
  /* 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_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
	printf("\n\r****wantin****\n\r");
  /* USER CODE END 2 */

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

    /* USER CODE BEGIN 3 */
	  printf("\n\**************\n\r");
	  clk = HAL_GPIO_ReadPin(DT_GPIO_Port,DT_Pin);
	  dt = HAL_GPIO_ReadPin(DT_GPIO_Port,DT_Pin);
	  key = HAL_GPIO_ReadPin(SW_GPIO_Port,SW_Pin);
	  if(1 == clk)
	  {
		  printf("\n\clk == 1\n\r");
	  }
	  else
	  {
		  printf("\n\clk == 0\n\r");
	  }
	  if(1 == dt)
	  {
		  printf("\n\dt == 1\n\r");
	  }
	  else
	  {
		  printf("\n\dt == 0\n\r");
	  }
	  if(1 == key)
	  {
		  printf("\n\key == 1\n\r");
	  }
	  else
	  {
		  printf("\n\key == 0\n\r");
	  }
	  HAL_Delay(1000);
  }
  /* USER CODE END 3 */
}

 

实现效果来看,不理想:

【STM32学习】(22)STM32实现360度旋转编码器_第4张图片

不管你正转还是反转,CLK和DT这两个引脚的电平,都是成0、1交替,而且两个的电平一致,根本无法区分正转还是反转。

随后,将其插上电源,用示波器测试了一下这两个引脚产生的波形。效果如下:

采集中断0口,接的clk信号

正转的波形图:黄色的线为clk,蓝色的线为dt

下降沿触发,采集到的电平  都为低电平  clk = 0   dt = 0;

【STM32学习】(22)STM32实现360度旋转编码器_第5张图片

反转的波形图:黄色的线为clk,蓝色的线为dt

下降沿触发,采集到的电平  clk = 0   dt = 1;

【STM32学习】(22)STM32实现360度旋转编码器_第6张图片

通过波形可以看出,正反转是有波形区别的,如何实现正反转检测,可以使用中断的方式来实现。

采用下降沿触发方式来采集波形的变化。

int main(void)
{
  /* USER CODE BEGIN 1 */
	unsigned char dt;
	unsigned char clk,key;
  /* 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_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
	printf("\n\r****wantin****\n\r");
  /* USER CODE END 2 */

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

    /* USER CODE BEGIN 3 */
	  printf("\n\**************\n\r");
	  if(10 == spped_counter)
	  {
		  printf("\n\***正转***\n\r");
	  }
	  else
	  {
		  printf("\n\***反转***\n\r");
	  }
//	  clk = HAL_GPIO_ReadPin(DT_GPIO_Port,DT_Pin);
//	  dt = HAL_GPIO_ReadPin(DT_GPIO_Port,DT_Pin);
//	  key = HAL_GPIO_ReadPin(SW_GPIO_Port,SW_Pin);
//	  if(1 == clk)
//	  {
//		  printf("\n\clk == 1\n\r");
//	  }
//	  else
//	  {
//		  printf("\n\clk == 0\n\r");
//	  }
//	  if(1 == dt)
//	  {
//		  printf("\n\dt == 1\n\r");
//	  }
//	  else
//	  {
//		  printf("\n\dt == 0\n\r");
//	  }
//	  if(1 == key)
//	  {
//		  printf("\n\key == 1\n\r");
//	  }
//	  else
//	  {
//		  printf("\n\key == 0\n\r");
//	  }
	  HAL_Delay(1000);
  }
  /* USER CODE END 3 */
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)  //外部中断 回调函数
{
	if(GPIO_Pin == CLK_Pin) //检测到有变化就进来处理
	{
		if(HAL_GPIO_ReadPin(CLK_GPIO_Port,CLK_Pin) == HAL_GPIO_ReadPin(DT_GPIO_Port,DT_Pin))  //clk pb0 == dt pb1
		spped_counter=10;		//	表示 正转
		else
		spped_counter=100;		//	表示 反转
		
	}
}

 

 

效果如下:

【STM32学习】(22)STM32实现360度旋转编码器_第7张图片

 

 

 

你可能感兴趣的:(单片机c语言,STM32,增量编码器,外部中断)