【STM32】增量型旋钮编码器
1.增量型旋钮编码器原理
该编码器有A,B两相,当顺时针旋转时
 
 B相会提前A相90度(匀速转的时候),也就是A相上升沿时,B相对应高电平,计数器会+1,A相下降沿时,B相为低电平时,计数器也会+1;
 当逆时针转时
 
 B相会落后A相90度(匀速转的时候),也就是A相上升沿时,B相对应低电平,计数器会-1,A相下降沿时,B相为高电平时,计数器也会-1;
 编码器旋转一圈,会有20个脉冲信号,360°分20,一个脉冲是18°。
 而单片机有他的编码器模式,只需要将编码器的A,B相接入TI1,TI2。
2.配置实现编码器调节灯亮度以及屏幕上进度条的进度

 根据原理图可知编码器的A,B相分别对应的是PA8,PA9口。
 
 
 而PA8,PA9分别对应着定时器1的通道1和通道2
 
 
 将PB_15设置为输入模式,使用编码器按键来切换灯的颜色
 
 这三个口分别是定时器3的通道1,2,3
 
 i2c配置要使用显示屏
 
 代码:
int count=0;
char message[50]="";
int main(void)
{
 
  
  OLED_Init();
  HAL_TIM_Encoder_Start(&htim1,TIM_CHANNEL_ALL);//开启定时器1的编码器
  HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);//先开启定时器3的通道1,蓝灯
 
  while (1)
  {
	  count=__HAL_TIM_GET_COUNTER(&htim1);
	  if(count>60000)//逆时针
	  {
		  count=0;
		  __HAL_TIM_SET_COUNTER(&htim1,0);
	  }
	  else if(count>100)//顺时针
	  {
		  count=100;//count也要作为灯的占空比0~100
		  __HAL_TIM_SET_COUNTER(&htim1,100);
	  }
	  __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,count);//只是改变蓝灯占空比
       OLED_NewFrame();
       sprintf(message,"count:%d",count);
       OLED_PrintString(10,10,message, &font16x16, OLED_COLOR_NORMAL);
       OLED_DrawRectangle(10,30, 100,10,OLED_COLOR_NORMAL);//绘制进度条外边框(宽102,高10)
       OLED_DrawFilledRectangle(10,30 ,count, 10, OLED_COLOR_NORMAL);//进度条,宽随count变化0~100
	   OLED_ShowFrame();
 
  }
 
}
旋转编码器1
根据视频我们发现有两个问题
 1.每次扭动,count+2,或-2
 2.顺时针是减,逆时针是+。
 因为对上下边沿都敏感,A相的一个脉冲会计数两次,我们采用2分频即可
 
 对于顺时针还是逆时针,我们需要将A相或B相任意一个反相即可
 
旋转编码器2
然后需要加旋转编码器的按键来切换三个灯,每次按下按钮,需要停止对应定时器通道下的PWM,开启另一个,在此之前,我们需要将PB15配置上拉模式,要不然,按钮不好识别
 
int count=0;
char message[50]="";
uint32_t chan[3]={TIM_CHANNEL_1,TIM_CHANNEL_2,TIM_CHANNEL_3};
int ins=0;
int main(void)
{
  
  OLED_Init();
  HAL_TIM_Encoder_Start(&htim1,TIM_CHANNEL_ALL);//开启定时器1的编码器
  HAL_TIM_PWM_Start(&htim3,chan[ins]);//先开启定时器3的通道1,蓝灯
 
  while (1)
  {
	  count=__HAL_TIM_GET_COUNTER(&htim1);
	  if(count>60000)//逆时针
	  {
		  count=0;
		  __HAL_TIM_SET_COUNTER(&htim1,0);
	  }
	  else if(count>100)//顺时针
	  {
		  count=100;//count也要作为灯的占空比0~100
		  __HAL_TIM_SET_COUNTER(&htim1,100);
	  }
	  
	   if(HAL_GPIO_ReadPin(Key_GPIO_Port,Key_Pin)==GPIO_PIN_RESET)
	   {
		   HAL_Delay(10);
		   if(HAL_GPIO_ReadPin(Key_GPIO_Port,Key_Pin)==GPIO_PIN_RESET)
		   {
			   
			   HAL_TIM_PWM_Stop(&htim3,chan[ins]);//关闭当前通道的PWM
			   ins=(ins+1)%3;//通道下标
			   HAL_TIM_PWM_Start(&htim3,chan[ins]);//打开下一个通道的PWM
			   while(HAL_GPIO_ReadPin(Key_GPIO_Port,Key_Pin)==GPIO_PIN_RESET);
			   
			   
		   }
		   
		   
		   
		   
	   }
	  
	  
	  
	  
	  
	  
	  
         
	  __HAL_TIM_SET_COMPARE(&htim3,chan[index],count);
       OLED_NewFrame();
       sprintf(message,"count:%d",count);
       OLED_PrintString(10,10,message, &font16x16, OLED_COLOR_NORMAL);
       OLED_DrawRectangle(10,30, 100,10,OLED_COLOR_NORMAL);//绘制进度条外边框(宽102,高10)
       OLED_DrawFilledRectangle(10,30 ,count, 10, OLED_COLOR_NORMAL);//进度条,宽随count变化0~100
	   OLED_ShowFrame();
  }
 
}
旋转编码器3
