您的当前位置:首页正文

STM32学习总结4---编码器旋钮式增量编码器

2022-07-11 来源:易榕旅网
STM32学习总结4---编码器旋钮式增量编码器

  这个我实在⽹上找了好久找了⼀个可⽤的程序,⼤部分,你搜索编码器程序出来的都是电机的相关程序,⽽我要的是旋钮式的,PEC11-4020F-S0018型号的编码器。

  这个代码写得挺完善的,就是没有写主函数,因此调⽤问题上,还是费了好些神才弄出来,关键它⾥⾯的⼀些定义,我很久没有些程序,都不清楚了,如:

typedef struct tagspin{

    RotateStatus rotatestatus; // 旋转状态    KeyStatus keystatus; // 按键状态}struspin;

  我知道struct为结构体,但是typedef就真的忘了,百度⼀下,就清楚了。在主函数⾥只需

struspin left_spin;struspin right_spin;

在调⽤函数void Init_Spin_Status(struspin *left_spin, struspin *right_spin)和void Read_Spin(struspin *left_spin, struspin *right_spin)时,就⼜忘了*left_spin这是指针的,因此:Init_Spin_Status( &left_spin , &right_spin ); 要添加&Read_Spin(&left_spin, &right_spin);

修改相关配置,在主函数加⼏句调⽤,便可以运⾏了,不过⾄今还有⼏个问题:1、⽬前程序的执⾏是旋转编码器两次才有加1或减1;

2、PEC11-4020F-S0018码编器,⼀圈有30个定位,实物⾃⼰转出来数的。资料⾥0018 = 18 Pulses per 360 ° Rotation 我的理解是⼀圈18个脉冲,⼀圈有30个定位18个脉冲,那⼀个定位应该有⼏个脉冲呢?再研究下程序,怎么会转两个定位加1操作⼀次;3、我⽤的循环扫描的⽅式,编码器有按键功能,当只有扫描编码器不显⽰数码管时,按键的程序是要亮灯,可是实际就是闪⼀下没有,不过当我在主程序⾥加上数码管的显⽰,按键的灯就可以⼀直亮着了;

4、在主函数的while⾥我⼜添加了另外四个独⽴按键的扫描,按键和编码器都可以正常运⾏,有个问题就是每次按键时,数码管的会闪⼀下,就好像按键时停⽌了⼀下数码管的显⽰,很明显,⾁眼能观察到。

上⾯⼏个问题的部分分析:(2015.11.21)

1、这个是程序的问题,在每次出来的波⽤三个点去判断即可;

2、当时的资料和实物不符,所有有这个问题,应该是每次旋转⼀个定位就出⼀个波,A相和B想分别⼀个波;

主要的部分程序:

// 初始化左右旋转编码器的状态

void Init_Spin_Status(struspin *left_spin, struspin *right_spin){

l  eft_spin->rotatestatus = SPIN_NO_ROTATE;  left_spin->keystatus = KEY_NO_PRESSED;  right_spin->rotatestatus = SPIN_NO_ROTATE;  right_spin->keystatus = KEY_NO_PRESSED; }

////////////////////////////////////////////////////////////// 读取 2 旋转编码器的状态

static LEVEL last_leftspinkey_level= H, last_rightspinkey_level= H; // 保存的上⼀次按键的电平情况

static SpinABstatus last_leftspinABst=SPIN_AB_ST3, last_rightspinABst=SPIN_AB_ST3; // 保存的上⼀次AB引脚的电平情况void Read_Spin(struspin *left_spin, struspin *right_spin){

  LEVEL now_leftspinkey_level, now_rightspinkey_level;  LEVEL now_leftspinA_level, now_leftspinB_level;  LEVEL now_rightspinA_level, now_rightspinB_level;  SpinABstatus now_leftspinABst, now_rightspinABst;

  // 先读取旋转编码器的各引脚的电平值

  if( READ_SPIN_L_KEY() ) { now_leftspinkey_level = H; } // 读取左侧旋转编码器的按键电平值  else { now_leftspinkey_level = L; }

  if( READ_SPIN_R_KEY() ) { now_rightspinkey_level = H; } // 读取右侧旋转编码器的按键电平值  else { now_rightspinkey_level = L; }

  if( READ_SPIN_L_A() ) { now_leftspinA_level = H; } // 读取左侧旋转编码器的 A 信号电平值  else { now_leftspinA_level = L; }

  if( READ_SPIN_L_B() ) { now_leftspinB_level = H; } // 读取左侧旋转编码器的 B 信号电平值  else { now_leftspinB_level = L; }

  if( READ_SPIN_R_A() ) { now_rightspinA_level = H; } // 读取右侧旋转编码器的 A 信号电平值  else { now_rightspinA_level = L; }

  if( READ_SPIN_R_B() ) { now_rightspinB_level = H; } // 读取右侧旋转编码器的 B 信号电平值  else { now_rightspinB_level = L; }

  // 根据 左侧旋转编码器的按键 前后 两次的电平值, 确定按键状态

  if( (last_leftspinkey_level == H) && (now_leftspinkey_level == L) ) { left_spin->keystatus = KEY_JUST_PRESSED; }   else if((last_leftspinkey_level == H) && (now_leftspinkey_level == H) ) { left_spin->keystatus = KEY_NO_PRESSED; }   else if((last_leftspinkey_level == L) && (now_leftspinkey_level == H) ) { left_spin->keystatus = KEY_JUST_POPUP; }   else { left_spin->keystatus = KEY_ALREADY_PRESSED; }

  // 根据 右侧旋转编码器的按键 前后 两次的电平值, 确定按键状态

  if( (last_rightspinkey_level == H) && (now_rightspinkey_level == L) ) { right_spin->keystatus = KEY_JUST_PRESSED; }   else if((last_rightspinkey_level == H) && (now_rightspinkey_level == H) ) { right_spin->keystatus = KEY_NO_PRESSED; }   else if((last_rightspinkey_level == L) && (now_rightspinkey_level == H) ) { right_spin->keystatus = KEY_JUST_POPUP; }   else { right_spin->keystatus = KEY_ALREADY_PRESSED; }

  // 根据 左侧旋转编码器的 A B 的电平值, 确定 AB 状态

  if( (now_leftspinA_level == H) && (now_leftspinB_level == H) ) { now_leftspinABst = SPIN_AB_ST3; } // A=1 B=1;   else if((now_leftspinA_level == H) && (now_leftspinB_level == L) ) { now_leftspinABst = SPIN_AB_ST2; } // A=1 B=0;  else if((now_leftspinA_level == L) && (now_leftspinB_level == L) ) { now_leftspinABst = SPIN_AB_ST0; } // A=0 B=0;  else { now_leftspinABst = SPIN_AB_ST1; } // A=0 B=1;

  // 根据 右侧旋转编码器的 A B 的电平值, 确定 AB 状态

  if( (now_rightspinA_level == H) && (now_rightspinB_level == H) ) { now_rightspinABst = SPIN_AB_ST3; } // A=1 B=1;   else if((now_rightspinA_level == H) && (now_rightspinB_level == L) ) { now_rightspinABst = SPIN_AB_ST2; } // A=1 B=0;  else if((now_rightspinA_level == L) && (now_rightspinB_level == L) ) { now_rightspinABst = SPIN_AB_ST0; } // A=0 B=0;  else { now_rightspinABst = SPIN_AB_ST1; } // A=0 B=1;

  // 再根据 左侧旋转编码器 前后两次 AB信号线的状态, 确定是左旋还是右旋

  if( (last_leftspinABst == SPIN_AB_ST3) && (now_leftspinABst == SPIN_AB_ST2)){ left_spin->rotatestatus =SPIN_UNTICLOCKWISE; }

  else if ((last_leftspinABst == SPIN_AB_ST3) && (now_leftspinABst == SPIN_AB_ST1)){ left_spin->rotatestatus =SPIN_CLOCKWISE; }

  else { left_spin->rotatestatus = SPIN_NO_ROTATE; }

// 再根据 右侧旋转编码器 前后两次 AB信号线的状态, 确定是左旋还是右旋

if( (last_rightspinABst== SPIN_AB_ST3) && (now_rightspinABst== SPIN_AB_ST2)){ right_spin->rotatestatus =SPIN_UNTICLOCKWISE;}

else if ((last_rightspinABst== SPIN_AB_ST3) && (now_rightspinABst== SPIN_AB_ST1)){ right_spin->rotatestatus =SPIN_CLOCKWISE; }

else { right_spin->rotatestatus = SPIN_NO_ROTATE; }

last_leftspinkey_level = now_leftspinkey_level; // 保存当前状态,作为下次状态的依据last_rightspinkey_level = now_rightspinkey_level; last_leftspinABst = now_leftspinABst;last_rightspinABst = now_rightspinABst;}

// 右⾯旋转编码器,⽤户⾃⼰的代码

void Process_Right_Spin( struspin *rightspin){

  if(rightspin->keystatus == KEY_JUST_PRESSED) // 旋转编码器的按键刚按下的处理程序,⽤户⾃⼰填⼊  {

    LED5=!LED5;

  }

  else if(rightspin->rotatestatus == SPIN_CLOCKWISE) // 旋转编码器顺时针旋转的处理程序,⽤户⾃⼰填⼊  {

    right_NUM++;   }

  else if(rightspin->rotatestatus == SPIN_UNTICLOCKWISE) // 旋转编码器反时针旋转的处理程序,⽤户⾃⼰填⼊  {

    right_NUM--;  } }

///////////////////////////////////////////////////////////// 左⾯的旋转编码器 ///////////////

//#define RCC_LEFT_SPIN RCC_APB2Periph_GPIOC // 左⾯的旋转编码器使⽤的GPIOE时钟//#define GPIO_SPIN_L_PORT GPIOC // 左⾯的旋转编码器驱动引脚所在的端⼝#define SPIN_L_KEY_PIN GPIO_Pin_9 // 左⾯的旋转编码器 按键 引脚号#define pinSPINleftKEY PIN9

#define SPIN_L_A_PIN GPIO_Pin_7 // 左⾯的旋转编码器 A 引脚号#define pinSPINleftA PIN7

#define SPIN_L_B_PIN GPIO_Pin_8 // 左⾯的旋转编码器 B 引脚号#define pinSPINleftB PIN8

#define READ_SPIN_L_KEY() PCin(pinSPINleftKEY) // PC9

#define READ_SPIN_L_A() PCin(pinSPINleftA) // PC7 读⼊ A 引脚的电平#define READ_SPIN_L_B() PCin(pinSPINleftB) // PC8 读⼊ B 引脚的电平///////////////////////////////////////////////////typedef enum{

  KEY_NO_PRESSED = 0,  KEY_JUST_PRESSED ,

  KEY_ALREADY_PRESSED ,  KEY_JUST_POPUP ,}KeyStatus;typedef enum{

  L = 0, // 低电平  H , // ⾼电平}LEVEL;

typedef enum{

  SPIN_NO_ROTATE = 0, // ⽆旋转  SPIN_CLOCKWISE , // 顺时针旋转

  SPIN_UNTICLOCKWISE , // 反时针旋转}RotateStatus;

typedef struct tagspin{

  RotateStatus rotatestatus; // 旋转状态  KeyStatus keystatus; // 按键状态}struspin;

typedef enum{

  SPIN_AB_ST0 = 0, // A=0 B=0;  SPIN_AB_ST1 , // A=0 B=1;  SPIN_AB_ST2 , // A=1 B=0;  SPIN_AB_ST3 , // A=1 B=1;

}SpinABstatus; // 旋转编码器信号线 A B 的电平

Init_Spin_Status( &left_spin , &right_spin );

left_NUM=0;right_NUM=0;LED5=0;while(1){

  Read_Spin(&left_spin, &right_spin);  Process_LEFT_Spin(&left_spin);  Process_Right_Spin( &right_spin);   display(0,left_NUM);  display(1,right_NUM); }

因篇幅问题不能全部显示,请点此查看更多更全内容