编码器的输出AB两相的波形如下图所示,其原理不赘述。
软件解码方案有两种
1.查表法
有波形可以知道,波形有四种状态组成:
当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 // 正转 {
上一篇:STM32-电源【ADC供电、VDDA、VSSA、VREF、VBAT等】
下一篇:片内外设、片上外设和片外外设的区别
推荐阅读最新更新时间:2024-11-11 11:33
推荐帖子
- 【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单片机