找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6370|回复: 6
打印 上一主题 下一主题
收起左侧

求旋转编码器c程序

[复制链接]
跳转到指定楼层
楼主
ID:143803 发表于 2017-1-20 17:32 来自手机 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
功能:顺时针转动数值增大,逆时针转动数值减小
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:162621 发表于 2017-1-21 11:12 | 只看该作者
在百度云游
回复

使用道具 举报

板凳
ID:149451 发表于 2017-1-21 14:04 | 只看该作者
编码器涵盖很多种类,不知你具体要求的哪种?我也曾折腾过一段时间EC11型的,给你个从网上找来的,参考吧(在我板上能运行)
//通过编码开关(旋转编码器)控制数码管的加减一
#include<AT89X52.H>
#define uchar unsigned char
#define uint  unsigned int
#define cycle       1           //定义动作周期,编码器旋转多少格有效
#define NULL       0          //定义编码器不动作时的还回值
#define E_RIGHT     0x0e        //定义右旋转还回值
#define E_LEFT      0x0f        //定义左旋转还回值
/*=====数码管位及按键定义=====*/
sbit dula=P2^0;  //数码管段选,锁存器控制信号
sbit wela=P2^1;  //数码管位选,锁存器控制信号
sbit PINA   =   P1^0;  //定义IO
sbit PINB   =   P1^1;
uchar WheelNow,WheelOld,RightCount,LeftCount;
/*=====0-9=====A-G=====*/
uchar a[16]={0x3f,0x06,0x5b,0x4f,0x66,
   0x6d,0x7d,0x07,0x7f,0x6f,0x00};
   //数码管显示编码
unsigned sled_bit_table[]={0x5f,0x6f,0x77,0x7b,0x7d,0x7e,0xff};
       /*定义点亮的数码管与数组的关系*/
/*=====四个数码管显示数据存放处=====*/
uchar one,two,three,four;
uint wc=0;
/*=====函数定义=====*/
void delay(uint x);
void display(void);
//void key();
void led_analyze(uint i);
/*====延时函数=====*/
void delay(uint x)
{
  uint i;
  for(i=0;i<x;i++);
}
/*====显示函数=====*/
void display(void)
{
//送段码
dula=0;  
P0 =a[one];
dula=1;
dula=0;
//数码管位选
wela=0;
P0=sled_bit_table[0]; //开显示  
wela=1;
wela=0;
delay(200);    //调用键盘扫描
wela=0;
P0=sled_bit_table[6];  
wela=1;
wela=0;  //关显示
dula=0;
P0=a[two];
dula=1;
dula=0;
//数码管位选
wela=0;
P0=sled_bit_table[1]; //开显示  
wela=1;
wela=0;
delay(200);    //调用键盘扫描
wela=0;
P0=sled_bit_table[6];  
wela=1;
wela=0;  //关显示
dula=0;
P0=a[three];
dula=1;
dula=0;
//数码管位选
wela=0;
P0=sled_bit_table[2]; //开显示  
wela=1;
wela=0;
delay(200);    //调用键盘扫描
wela=0;
P0=sled_bit_table[6];  
wela=1;
wela=0;  //关显示
dula=0;
P0=a[four];
dula=1;
dula=0;
//数码管位选
wela=0;
P0=sled_bit_table[3]; //开显示  
wela=1;
wela=0;
delay(200);    //调用键盘扫描
wela=0;
P0=sled_bit_table[6];  
wela=1;
wela=0;  //关显示  
}
/*====分解显示数据=====*/
void led_analyze(uint i)
{
    i=i%10000;
four=i/1000;  // 千位
    three=(i/100)%10; // 百位
    two=(i%100)/10;  // 十位
    one=(i%100)%10;  // 个位
}
//=================================================
uchar WheelRight()
{
    LeftCount=0;
    RightCount++;
    if (RightCount>=cycle)
{
  RightCount=0;
  return(E_RIGHT);
    }  
else
return(NULL);
}
//=====================================================
uchar WheelLeft()
{
    RightCount=0;
    LeftCount++;
    if (LeftCount>=cycle)
{
        LeftCount=0;
        return(E_LEFT);
    }
else
return(NULL);
}
//=================================================================
uchar EncoderProcess()
{
    uchar keytmp;  
    PINA = 1;
    PINB = 1;
    WheelNow=WheelNow<<1;
    if (PINA==1) WheelNow=WheelNow+1;  // 读 PINA
    WheelNow=WheelNow<<1;
    if (PINB==1) WheelNow=WheelNow+1;  // 读 PINB
    WheelNow=WheelNow & 0x03;   // 将 WheelNow 的 2 - 7 位清零,保留 0 - 1 两个位的状态.
    if (WheelNow==0x00) return(NULL); //当  PINA 和 PINB 都为低电平时退出,低电平区不做处理
    keytmp=WheelNow;
    keytmp ^=WheelOld; // 判断新读的数据同旧数据
    if (keytmp==0) return(NULL); // 新读的数据同旧数据一样时退出.   
    if (WheelOld==0x01 && WheelNow==0x02)
{ // 是左旋转否
        WheelOld=WheelNow;
        return(WheelLeft()); //左旋转
    }
    else
if (WheelOld==0x02 && WheelNow==0x01)
{ // 是右旋转否
        WheelOld=WheelNow;
        return(WheelRight()); //右旋转
    }
    WheelOld=WheelNow; // 保存当前值
    return(NULL); // 当  PINA 和 PINB 都为高电平时表示编码器没有动作,退出
}
//==========================================================================
void inc()
{   
   wc++;
   if(wc>9999) wc=0;//如果WG大于9999则将它清零
    led_analyze(wc);
} // 在此处设置断点看 num 加的变化
//====================================================================
void dec()
{
    wc--;
    if(wc>9999) wc=9999;
     led_analyze(wc);
} // 在此处设置断点看 num 减的变化
//===========================================================================
void main()
{
    while (1)
{
        switch(EncoderProcess())
  {
            case E_RIGHT:  inc(); break;
            case E_LEFT:   dec(); break;
        }
display();
    }
}

评分

参与人数 1黑币 +5 收起 理由
1281431189a + 5 很给力!

查看全部评分

回复

使用道具 举报

地板
ID:137676 发表于 2017-2-2 19:19 | 只看该作者

void main(void)
{
        EA=1;
        IT0 = 1;        // 外部中断0下降沿中断
        EX0 = 1;        // 外部中断0允许
        PX0=1;
        while(1)
        {
                ;//加入你要显示的函数,调用
        }
}
void INT0_int (void) interrupt 0
{
        if(x_flag)//x_flag 编码器A,INT0 编码器B
        {
                if(INT1==0)        x_step++,x_fx=0;//x_fx 方向标志
                else                x_step--,x_fx=1;
                if(x_step<0)        x_step=4294967296-x_step,x_fx=0;//x_step定义为long x_step;
                else                x_step=x_step,x_fx=1;
        }
}
回复

使用道具 举报

5#
ID:231343 发表于 2017-9-7 10:18 | 只看该作者
w1179benp 发表于 2017-1-21 14:04
编码器涵盖很多种类,不知你具体要求的哪种?我也曾折腾过一段时间EC11型的,给你个从网上找来的,参考吧( ...

这个里面WheelOld好像是一直为0吧,没有哪个地方可以改变它的值,是吗?
回复

使用道具 举报

6#
ID:105269 发表于 2017-9-7 12:07 | 只看该作者
给你提供个思路吧。一般的编码器输出,会有两个。一个是顺时针的脉冲,一个是逆时针的脉冲。可以分别检测这两种脉冲来判断。
回复

使用道具 举报

7#
ID:1064915 发表于 2023-6-26 11:47 | 只看该作者
在顺时针和逆时针方向不同点是:两个波形的滞后或超前不同。
   编程原理:
   1、可以将A输出到单片机的电平变化检测口,B口为普通I/O口,2个口都设置为输入口。
   2、设置A为上升沿或下降沿触发。开启电平变化检测中断。
   3、在中断程序中,产生中断后,根据B口的电平高低不同,判断是顺时针,还是逆时针。
   4、顺时针和逆时针的B口电平是不同的。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表