STM32-编码器的软件解码

发布者:数据探险家最新更新时间:2022-04-21 来源: eefocus关键字:STM32  编码器  软件解码 手机看文章 扫描二维码
随时随地手机看文章

编码器的输出AB两相的波形如下图所示,其原理不赘述。

软件解码方案有两种


1.查表法

有波形可以知道,波形有四种状态组成:

image.png

当AB相波形经历00—10—11—01的状态就表示一个正向步进。反之则表示反向步进。


读引脚电平的代码就不贴上了,只贴波形处理代码:


#define FILTER_MAX      3       // 电平滤波次数

 

//AB电平状态表

const unsigned char TrueTabA[4] = {1,0,0,1} ;

const unsigned char TrueTabB[4] = {1,1,0,0} ;

 

typedef struct 

{

    unsigned char AVal;         // A电平

    unsigned char BVal;         // B电平  

    unsigned char PreAVal;      // 前次A电平

    unsigned char PreBVal;      // 前次B电平  

    unsigned char CmpNum;       // 滤波次数

 

    unsigned char Index;        // 真值表中位置  (这是什么鬼?)

    unsigned char CWW ;         // 方向  1-正向  0-反向

 

    unsigned char Initbut;         // 上电后初始化标志

    signed short PNum;        // 累计脉冲数 

    signed short PrePNum;     // 前次累计脉冲数

 

    GPIO_TypeDef port;          // 

    unsigned short pin;         //

 

}T_TubeButInfo;

 

// 获取在真值表中的位置

static unsigned char GetIndex(unsigned char tbindex)  //当AB不同电平的时候返回相应的值

{

    if(TubeButInfo[tbindex].AVal)  

    {

        if(TubeButInfo[tbindex].BVal) return 0 ;//A高B高

        return 3 ;  //A高 B低

    }

    else

    {

        if(TubeButInfo[tbindex].BVal) return 1 ;//A低B高

        return 2 ;         //A低 B低

    }

}

 

// 计算脉冲个数

// asf : 1表示累加  0-累减

static void SetPNum(unsigned char tbindex, unsigned char asf)

{   //1表示正向转     0表示反向转

    if((asf != 0) & (TubeButInfo[tbindex].PNum < 8000))   //防止溢出

{

TubeButInfo[tbindex].PNum++;

}

    else if((asf == 0) & (TubeButInfo[tbindex].PNum > -8000))

{

TubeButInfo[tbindex].PNum--;

}

}

 

void ProcessTubeButton(void)     //按键数据处理

{

    unsigned int i ;

    unsigned char index ;

    for(i=0; i    {

        if( (TubeButInfo[i].PreAVal == TubeButInfo[i].AVal) && (TubeButInfo[i].PreBVal == TubeButInfo[i].BVal) )  //A B 电平都没有发生变化

        {

            TubeButInfo[i].CmpNum = TubeButInfo[i].CmpNum + 1 ;

            if( TubeButInfo[i].CmpNum >= FILTER_MAX )//滤波,等稳定下来

            {

                TubeButInfo[i].CmpNum = 0 ;

                index = GetIndex(i) ;// 返回值:  A高B高0    A高B低3    A低B高1   A低B低2         即对应查表TrueTabA/B的状态

                if( TubeButInfo[i].Initbut == 1)  //开机刷新

                {

                    TubeButInfo[i].Index = index ;

                    TubeButInfo[i].Initbut = 0 ;

                }

                else

                {

                    if( TubeButInfo[i].Index == index)  // 旋钮没动

                    {

return;

}

                    if( TubeButInfo[i].CWW == 1)        // 当前为正转状态

                    {

if( TubeButInfo[i].Index == 3)  //前状态A高B低

                        {

                            if(index == 0)  // 3到0  为正转

                            {

                                SetPNum(i,1);

                            }

                            else                  // 3到其他(只能是3到2),为反转

                            {

                                SetPNum(i,0) ;

                                TubeButInfo[i].CWW = 0 ;

                            }

                        }

                        else

                        {

                            if( (TubeButInfo[i].Index + 1) == index)  // 为正转

                            {

                                SetPNum(i,1);

                            }

                            else                                    // 为反转

                            {

                                SetPNum(i,0) ;

                                TubeButInfo[i].CWW = 0;                                

                            }

                        }

                        TubeButInfo[i].Index = index;

                    }

                    else                                      // 当前为反转状态

                    {

                        if( TubeButInfo[i].Index == 0 )

                        {

                            if(index == 3)      // 0到3 为反转

                            {

                                SetPNum(i,0) ;                                                            

                            }

                            else                // 0到其他 为正转

                            {

                                SetPNum(i,1) ;

                                TubeButInfo[i].CWW = 1 ;         

                            }

                        }

                        else

                        {

                            if( (TubeButInfo[i].Index - 1)== index)  // 为反转

                            {

                                SetPNum(i,0);                              

                            }

                            else                                     // 正转   

                            {

[1] [2]
关键字:STM32  编码器  软件解码 引用地址:STM32-编码器的软件解码

上一篇:STM32-电源【ADC供电、VDDA、VSSA、VREF、VBAT等】
下一篇:片内外设、片上外设和片外外设的区别

推荐阅读最新更新时间:2024-11-11 11:33

STM32 定时器(二)——定时器产生不同频率的PWM
STM32产生PWM是非常的方便的,要需要简单的设置定时器,即刻产生!当然,简单的设置对于新手来产,也是麻烦的,主要包括: (1)使能定时器时钟:RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); (2)定义相应的GPIO: GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //下拉接地,检测输入的高电平 GPIO_InitStructure.GPIO_
[单片机]
stm32串口通信程序之UART2(TTL)
一、硬件连接 二、串口助手设置: 三、keil下编程 1.要添加的工程文件 二要编写的user文件 1.main.c #include printf.h int main() { printf_init(); printf( \luoyiran is a nice boy\n ); printf( xixi\n ); printf( serial communications is so mystical and interesting!\n ); printf( keep striving!\n ); } 2.printf
[单片机]
<font color='red'>stm32</font>串口通信程序之UART2(TTL)
stm32程序中的assert_param()的说明
子程序都有assert_param(....),如下:这句到底有什么用呢???把它删了应该可以的吗?? void TIM1_TimeBaseInit(u16 TIM1_Prescaler, TIM1_CounterMode_TypeDef TIM1_CounterMode, u16 TIM1_Period, u8 TIM1_RepetitionCounter) { assert_param(IS_TIM1_COUNTER_MODE_OK(TIM1_CounterMode)); ...... } 答: 这是断言,可以删掉,只在编译的时候防
[单片机]
如何理解STM32引脚中的GPIO,AFIO时钟分配策略和管脚复用
适用COTEX-M3系列的MCU也有两三年的时间了,一直用的是ST的产品,由于开发紧张,时间紧迫,整个过程不求甚解,只要东西能够做出来,也就不关心到底是怎么回事。最近刚好有点时间,在整理之前的软件设计时发现了一些疑惑: 使用过STM32系列产品的开发人员都知道,在该款芯片上凡是要使用某一个功能,必须给该功能分配相应的时钟,如何来分配这个时钟资源就成了一个问题:举个具体的例子,以STM32F103X8为例,假设需要使用PA9进行串口正常输出,时钟应该如何配置??数据手册管脚定义如下: 参考给出的时钟分配策略是这样: RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Per
[单片机]
如何理解<font color='red'>STM32</font>引脚中的GPIO,AFIO时钟分配策略和管脚复用
stm32 精确个数高速脉冲输出
/**************************** **TIM2的通道1使用单脉冲模式 **TIM3使用门控模式用来输出PWM ** ****************************/ //TIM2per:重装值 //Compare1:比较捕获1的预装载值 void Motor_Init(u16 TIM2per, u16 TIM3per, u16 TIM3Compare1) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_OCInitTypeDef TIM_OCInitStruct; GPIO_InitTypeDef GPIO_InitStruct;
[单片机]
STM32信息安全—密码学基本原理(中)
本文的主要内容包括: 哈希函数 完整性和安全性 消息验证 常用算法 Hash/哈希/散列/摘要 函数 哈希函数的功能:对任意输入可以产生固定长度的摘要值 哈希函数的特点:输入的任何改变,都会导致摘要值变化;单向性;低碰撞性 常用哈希函数 消息的“狭义完整性”和“广义完整性” 哈希函数,仅能保证消息的狭义完整性 要保证数据确实是Alice发送的,需要消息认证机制 消息认证 哈希和对称加解密技术的结合之一:HMAC 前提:双方事先约好一个共享密钥 哈希和对称加解密技术的结合之二:AES-GCM AES counter模式+特殊的哈希 输出结果:加密后消息,该消息的认证码标
[单片机]
<font color='red'>STM32</font>信息安全—密码学基本原理(中)
STM32_CorTex-M3位带操作的理解
STM32支持了位带操作(bit_band),有两个区中实现了位带。其中一个是SRAM 区的最低1MB 范围,第二个则是片内外设 区的最低1MB 范围。这两个区中的地址除了可以像普通的RAM 一样使用外,它们还都有自己的“位带别名区”,位带别名区 把每个比特膨胀成一个32 位的字。 每个比特膨胀成一个32 位的字,就是把 1M 扩展为 32M , 于是;RAM地址 0X200000000(一个字节)扩展到8个32 位的字,它们是:(STM32中的SRAM依然是8位的,所以RAM中任一地址对应一个字节内容) 0X220000000 ,0X220000004,0X220000008,0X22000000C,0X2200
[单片机]
STM32_CorTex-M3位带操作的理解
STM32 | STM32的复用时钟何时开启?
STM32的AFIO时钟真的是在开启引脚复用功能的时候开启吗?其实并不是~ 什么是复用? 我们知道,STM32有很多外设,这些外设的外部引脚都是与GPIO共用的。我们可以通过软件来配置引脚作为GPIO引脚还是作为外设引脚。当引脚配置为外设引脚时就叫做复用。如串口默认复用的引脚为: PA9、PA10引脚可配置为普通IO,也可配置为串口引脚(PA9为TX,PA10为RX)。 例子:串口1为例 关于外设的配置可查阅:《STM32参考手册》关于通用和复用功能I/O(GPIO和AFIO) 的章节,如串口引脚配置如下: 最近看到一份代码(基于STM32F103ZET6)的串口配置如下: 看到这里开启了AFIO时钟,让我疑惑
[单片机]
<font color='red'>STM32</font> | <font color='red'>STM32</font>的复用时钟何时开启?

推荐帖子

【STM32H7S78-DK】 六 可设置时钟及代码分析
【STM32H7S78-DK】六可设置时钟及代码分析【STM32H7S78-DK】一开箱贴【STM32H7S78-DK】二touchgxf环境搭建和基本测试【STM32H7S78-DK】三touchgxf和stm32cubeide和led按键测试【STM32H7S78-DK】四下载失败问题及解决、计数器实现及分析【STM32H7S78-DK】五乱序键盘实现及分析之后一、打开to
damiaa stm32/stm8
【得捷Follow me第3期】远程无线开灯提醒器
必做任务1:使用MicroPython系统esptool是乐鑫的官方刷机程序,可以从baidu上下载到,下载完成后,通过以下命令来清空当前flash内的内容,其中COMx是开发板对应的串口号。pythonesptool.py-pCOMx -b460800--beforedefault_reset --chipesp32c3 erase_flash随后去micropython官网下载ESP32_GENERIC_C3
eew_dy9f48 DigiKey得捷技术专区
请教下,购买WARP无线电研究平台有哪些公司做这个?可与我联系
你好!请问WARP的无线电研究平台,这个要购买去哪里买?可否告知下,如果知道请与我联系18822859896请教下,购买WARP无线电研究平台有哪些公司做这个?可与我联系
weizhijingwei RF/无线
mos管并联的驱动电阻如何配置,开启电压如何确定?
mos管并联可以增大电流能力,并联MOS管需要注意mos管的哪些特性,比如开通关断延迟时间,开启电压?下面的连接正确吗?mos管并联的驱动电阻如何配置,开启电压如何确定?实际上,每个MOS管获得的信号都是两个电阻对drive信号分压,幅度只有drive信号的一半。考虑到MOS管输入电容,MOS管开启和关断都会变得比较缓慢。实际应用中,往往去掉R5R6R8(开路),R4R7R9的值也比1千欧要小得多,通常用数十欧,不应超过1百欧。MOS管并联的原则也是参数的一
kal9623287 电源技术
UCOS在小模式下的移植程序
UCOS在小模式下的移植程序UCOS在小模式下的移植程序
lorant 实时操作系统RTOS
单片机控制,74hc595驱动显示20个4位数码管显示!问题求助。。。。
51单片机控制74hc595驱动20个4位数码管显示不同数据!!!5959该怎么级联,能是程序简单控制显示又能达到要求(用最少的IO口资源和最少的74hc595)...单片机控制,74hc595驱动显示20个4位数码管显示!问题求助。。。。
pengdaizhong 51单片机
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved