复刻江协旋钮控制模块

复刻江协旋钮控制模块

1、初始化硬件

OLED初始化

  • 这里就不展开细讲了,可以看我之前的帖子

复刻江协激光触发器

旋钮初始化

  • 使能外部中断
    img
  • 模式改为上拉
    img
  • 根据旋钮接口接上线

2、操作代码

(1) 初始化输出

  • 定义全局变量count,并初始化值为0,表示旋钮的相对位置
/* USER CODE BEGIN 0 */
int32_t count = 0;
/* USER CODE END 0 */
  • 在第一行,顶格位置显示字符串count:
	OLED_ShowString(1, 1, "count:");
  /* USER CODE END 2 */
  • 在循环体内输出相对位置的值

注意:OLED_ShowNum()函数不支持输出负数,所以需要额外步骤来进行判断

  /* USER CODE BEGIN WHILE */
  while (1)
  {
    //判断正负性
		if(count >= 0){//如果为非负数,加'+'
			OLED_ShowChar(2, 1, '+');
			OLED_ShowNum(2, 2, count, 10);
		}
		else{//如果为复数,加'-'并对相对位置的值取反
			OLED_ShowChar(2, 1, '-');
			OLED_ShowNum(2, 2, -count, 10);
		}
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

(2) 消抖

  • 由于旋钮在触发任意端后,会产生一个相反方向的信号,所以需要进行消抖

I 设置标识位

  • stm32f1xx_it.c中设置表示状态旋钮的变量FlagFalse表示在空闲状态,true表示旋钮某端已被触发
bool Flag = false;
/* USER CODE END PV */
  • stm32f1xx_it.c中定义以下函数
/** @brief 翻转标识位
 *
*/
void FlagToggle(void){
	Flag = !Flag;
}
/** @brief 判断旋钮状态
 *
 *	@retval bool
*/
bool ReturnFlag(void){
	return Flag;
}
/* USER CODE END 1 */
  • 在主循环内加上询问"是否空闲"的步骤,若处于"触发状态",则延时0.1s,再翻转Flag的值
  while (1)
  {
		if(ReturnFlag()){
			HAL_Delay(99);
			FlagToggle();
		}

(3) 处理中断

  • stm32f1xx_it.c的对用中断处理函数中添加以下内容
/******************************************************************************/
/* STM32F1xx 外设中断处理函数                                                  */
/* 在此处添加已使用外设的中断处理                                               */
/* 关于可用的外设中断名称,                                                     */
/* 请参考启动文件 (startup_stm32f1xx.s).                                       */
/******************************************************************************/

/**
  * @brief 该函数处理 EXTI Line1 中断
  */
void EXTI1_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI1_IRQn 0 */
  //判断中断源是否为PinA
	if(__HAL_GPIO_EXTI_GET_FLAG(PinA_Pin)){
		//判断此时旋钮是否处于"空闲状态"
		if(Flag == false){
			FlagToggle();//将旋钮改为"触发状态"
			Counter++;
		}		
	}
		
  /* USER CODE END EXTI1_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(PinA_Pin);
  /* USER CODE BEGIN EXTI1_IRQn 1 */

  /* USER CODE END EXTI1_IRQn 1 */
}

/**
  * @brief 该函数处理 EXTI Line2 中断
  */
void EXTI2_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI2_IRQn 0 */
  //判断中断源是否为PinB
	if(__HAL_GPIO_EXTI_GET_FLAG(PinB_Pin)){
		//判断此时旋钮是否处于"空闲状态"
		if(Flag == false){
			FlagToggle();//将旋钮改为"触发状态"
			Counter--;
		}		
	}
  /* USER CODE END EXTI2_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(PinB_Pin);
  /* USER CODE BEGIN EXTI2_IRQn 1 */

  /* USER CODE END EXTI2_IRQn 1 */
}

3、实验效果

  • 向右拧旋钮后,相对位置增加
    img
  • 向左拧旋钮后,相对位置减小
    img

4、流程图

主程序部分

img

中断部分

  • EXTI Line1
    img
  • EXTI Line2
    img
posted @ 2025-09-29 19:39  奶龙大王  阅读(27)  评论(0)    收藏  举报