请选择 进入手机版 | 继续访问电脑版

你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【新年开篇】我在兔年和“STM32G031G8的约会”之按键和旋转编码器开发

[复制链接]
EPTmachine 发布时间:2023-1-26 16:53
新年伊始,我从网上购买了一款开发板,这款开发板的核心板的处理器是STM32G031G8U6,
它是32位的Cortex M0+处理器,主频能达到64MHz,内存有8kB。核心板上MCU引脚和核心板引出脚的对应关系如图1。
图1 按键和编码器核心板侧接口
file:///C:/Users/EPT/AppData/Local/Temp/msohtmlclip1/01/clip_image001.png file:///C:/Users/EPT/AppData/Local/Temp/msohtmlclip1/01/clip_image002.png
开发板配套的底板提供了2个按键和一个旋转编码器,其硬件原理图如图2。
图2 按键和编码器底板板侧接口
file:///C:/Users/EPT/AppData/Local/Temp/msohtmlclip1/01/clip_image004.png
引脚关系表如表1所示
表1引脚关系表
  
元件引脚
  
接口引脚编号
MCU引脚
Encoder_A
2
PB0/ADC8 - Pin 14
Encoder_B
3
PB1/ADC9 - Pin 15
Encoder_S
5
PC6 - Pin 17
SW_S1
6
PA11 - Pin 18
SW_S2
7
PA12 - Pin 19
硬件原理介绍完了,实现按键和旋转编码开关输入检测的方法有轮询、GPIO的EXIT中断以及定时器的ADC捕获中断等解决方案。由于外部电路没有做硬件滤波消抖,需要做软件去抖,这里我选择了Systick定时器中断轮询的方式对输入信号进行去抖处理。在读取到电平后,软件开始计数,达到滤波要求的计数值后,更新软件内部相应的IO状态标志;
整体的软件设计如图所示:
按键在消抖之后,就可以根据按键得到状态进行相应的处理。
按键的软件设计,网上有很多模板,我选择了安富莱的按键设计框架,详情可以点击查看

+ s5 `& q/ c* t5 G; \! e. m5 U3 C
对旋转编码器,在消抖后,我选择按下列的处理逻辑进行方向判断和脉冲数计算:
当A信号上升沿时B信号为低电平,或当A信号下降沿时B信号为高电平,证明当前编码器为顺时针转动
当A信号上升沿时B信号为高电平,或当A信号下降沿时B信号为低电平,证明当前编码器为逆时针转动。
编码器信息更新主要分为滤波和编码器器技术计算。
核心代码如下:
/*对单个编码器的引脚进行滤波处理*/
static void bsp_DetectEncoder(uint8_t i)
{
   ENCODER_T *pEncoder;

. H+ ?1 _( Z5 q; I: d; s
   pEncoder=&s_tEncoder;

$ m& n3 g1 `' l" K
   if(EncoderPinActive(i))
    {
       if(pEncoder->FilterCountA<ENCODER_FILTER_TIME)
       {
           pEncoder->FilterCountA=KEY_FILTER_TIME;
       }
       else if(pEncoder->FilterCountA<2*ENCODER_FILTER_TIME)
       {
           pEncoder->FilterCountA++;
       }
       else
       {
           if(pEncoder->NowAState==0)
           {
               pEncoder->PreAState=pEncoder->NowAState;
                pEncoder->NowAState=1;
           }
           else
           {
               pEncoder->PreAState=pEncoder->NowAState;
           }
       }
    }
   else
    {
       if(pEncoder->FilterCountA>ENCODER_FILTER_TIME)
       {
           pEncoder->FilterCountA=ENCODER_FILTER_TIME;
       }
       else if(pEncoder->FilterCountA!=0)
       {
           pEncoder->FilterCountA--;
       }
       else
       {
            if(pEncoder->NowAState==1)
           {
               pEncoder->PreAState=pEncoder->NowAState;
                pEncoder->NowAState=0;
           }
           else
           {
               pEncoder->PreAState=pEncoder->NowAState;
           }
       }
    }
1 t7 C# B# E! g% N- k7 y4 f
   if(EncoderPinActive(i+1))
    {
       if(pEncoder->FilterCountB<ENCODER_FILTER_TIME)
       {
           pEncoder->FilterCountB=KEY_FILTER_TIME;
       }
       else if(pEncoder->FilterCountB<2*ENCODER_FILTER_TIME)
       {
           pEncoder->FilterCountB++;
       }
       else
       {
           if(pEncoder->BState==0)
           {
                pEncoder->BState=1;
           }
       }
    }
   else
    {
       if(pEncoder->FilterCountB>ENCODER_FILTER_TIME)
       {
           pEncoder->FilterCountB=ENCODER_FILTER_TIME;
       }
       else if(pEncoder->FilterCountB!=0)
       {
           pEncoder->FilterCountB--;
       }
       else
       {
           if(pEncoder->BState==1)
           {
                pEncoder->BState=0;
           }
       }
    }
- b; y* ~: i0 I' w1 S5 p
}

, m4 j* v4 O$ \& w% i. F
4 ?, @+ H7 j& a6 F' D9 Q
编码器相对脉冲数计算:
static void bsp_EncoderCalcPluse(uint8_t i)
{
   ENCODER_T *pEncoder;
/ b+ h+ Y7 d, H
   pEncoder=&s_tEncoder;
   if((pEncoder->NowAState^pEncoder->PreAState)==1)
    {
       if(pEncoder->PreAState==0)//上升沿
       {
           if(pEncoder->BState)
           {
               pEncoder->PluseCount-=pEncoder->PluseScale;
               printf("%d\r\n",pEncoder->PluseCount);
           }
           else
           {
               pEncoder->PluseCount+=pEncoder->PluseScale;
               printf("%d\r\n",pEncoder->PluseCount);
           }
       }
       else//下降沿
       {
           if(pEncoder->BState)
           {
               pEncoder->PluseCount+=pEncoder->PluseScale;
               printf("%d\r\n",pEncoder->PluseCount);
           }
           else
           {
               pEncoder->PluseCount-=pEncoder->PluseScale;
               printf("%d\r\n",pEncoder->PluseCount);
           }
       }
    }
}
首次发帖,不足之处请见谅

UP5K_EVA_SCH.pdf

下载

57.43 KB, 下载次数: 0

UP5KMCU.pdf

下载

111.42 KB, 下载次数: 0

miniscope_mcu.7z

下载

6.35 MB, 下载次数: 1

收藏 评论0 发布时间:2023-1-26 16:53

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版