PIC单片机 旋转编码器鉴相问题

[复制链接]
 楼主| 发表于 2013-6-17 16:24 | 显示全部楼层 |阅读模式
本人新手,想知道PIC单片与旋转编码器连接工作的鉴相程序怎么写?求大神们指点
发表于 2013-6-17 17:35 | 显示全部楼层
原理和以前机械鼠标类似,两路信号A,B, 在A上升沿时,采样B,B为高或低表示正反转。
 楼主| 发表于 2013-6-19 09:19 | 显示全部楼层
apple 发表于 2013-6-17 17:35
原理和以前机械鼠标类似,两路信号A,B, 在A上升沿时,采样B,B为高或低表示正反转。 ...

我尝试过用TMR0的T0CKI做输入,结果采集到的脉冲根本就飞的不着边了...
麻烦你能把你的程序给我看下吗?谢啦
 楼主| 发表于 2013-6-19 09:20 | 显示全部楼层
是这个问题太简单了么?????

没人多少人浏览.................
发表于 2013-7-1 23:07 来自手机 | 显示全部楼层
用D触发器很简单
发表于 2013-7-2 07:06 | 显示全部楼层
除非成本要求非常苛刻,个人不建议直接接编码器,主要问题是响应速度受限。你至少得评估一下每圈输出多少个脉冲,以及最大转速,看看单片机能否可靠响应。

可以用硬件电路将两路脉冲转换成实现一路脉冲,一路方向,再进单片机,这样难度小很多。或者直接上硬件计数器,或者带编码器计数的芯片,如个别单片机和DSP。
发表于 2013-7-2 11:48 | 显示全部楼层
用定时中断,在中断里判断上升或者下降沿。
 楼主| 发表于 2013-7-6 11:21 | 显示全部楼层
gonggu8181 发表于 2013-7-1 23:07
用D触发器很简单

我现在用的是D触发器,但是出现个问题,在旋转的时候如果卡在上升沿或下降沿的时候,T0中断会一直响应,计数器就一直加...这个问题要怎么解决?
 楼主| 发表于 2013-7-6 11:21 | 显示全部楼层
wangch_sh 发表于 2013-7-2 11:48
用定时中断,在中断里判断上升或者下降沿。

麻烦能给个程序么?参考一下:lol
 楼主| 发表于 2013-7-6 11:23 | 显示全部楼层
dqyubsh 发表于 2013-7-2 07:06
除非成本要求非常苛刻,个人不建议直接接编码器,主要问题是响应速度受限。你至少得评估一下每圈输出多少个 ...

你说的硬件是不是用D触发器做鉴相?然后用单片机计脉冲 ?我现在就是这么做的,但是遇到了问题,在旋转的时候如果卡在上升沿或下降沿的时候,T0中断会一直响应,计数器就一直加...这个问题要怎么解决?
发表于 2013-7-7 11:14 | 显示全部楼层
lx911gt 发表于 2013-7-6 11:21
麻烦能给个程序么?参考一下

TO计时,T1计数。你用应该是脉冲直接控制T0使能吧?
发表于 2013-7-7 11:16 | 显示全部楼层
lx911gt 发表于 2013-7-6 11:21
麻烦能给个程序么?参考一下


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
发表于 2013-7-7 11:17 | 显示全部楼层
lx911gt 发表于 2013-7-6 11:21
麻烦能给个程序么?参考一下
  1. #include<STC12C2052AD.h>
  2. #include<intrins.h>         
  3. #include<string.h>
  4. #include<math.h>
  5. #include<stdio.h>
  6. #include<stdlib.h>
  7. #include<absacc.h>                     
  8. #define   uchar  unsigned char                               
  9. #define   ulong  unsigned long
  10. #define   uint   unsigned int                       
  11. #define _Nop() _nop_()         /*定义空指令*/
  12. void sendbyte(uchar byte);
  13. void Disp();

  14. //显示部分
  15. sbit CLK=P1^0;                //定义A串行数据输入端   
  16. sbit DAT=P3^7;                //定义A控制端                 
  17.                                                          
  18. sbit vol=P1^1;                        //
  19. sbit crt=P1^2;          

  20. uchar i=0;
  21. bit flag=0;
  22. uchar count;         //计数
  23. ulong pinlv=0,pin=0;   //频率——频率缓存  
  24. uchar temp[4]=0;          //数据缓存
  25. uchar DispBuf[4]=0;            //4位数据显示

  26. uchar dis_code[10]={
  27.                       0x03,  //"0"
  28.                 0x9F,  //"1"
  29.                 0x25,  //"2"
  30.                 0x0D,  //"3"
  31.                 0x99,  //"4"
  32.                 0x49,  //"5"
  33.                 0x41,  //"6"
  34.                 0x1F,  //"7"
  35.                 0x01,  //"8"
  36.                 0x09   //"9"
  37. };

  38. //延时
  39. void delay_50ms(unsigned int t)
  40. {
  41. unsigned int j;   
  42. for(;t>0;t--)
  43.    for(j=6245;j>0;j--)
  44. {;}
  45. }       
  46. void sendbyte(uchar byte)
  47. {   
  48.                 uchar num,c;
  49.                 num=dis_code[byte];
  50.                 for(c=0;c<8;c++)
  51.                 {
  52.                         CLK=0;
  53.                         DAT=num&0x01;
  54.                         CLK=1;
  55.                         num>>=1;   
  56.                 }          
  57. }

  58. void time0(void) interrupt 1   //定时器0溢出中断模式2可重装载
  59. {
  60.         TR0=0;                        //定时器0暂停  
  61.         count++;   
  62.         TL0 = 0xB0;                //设置定时初值
  63.         TH0 = 0x3C;                //设置定时初值
  64.         if(count==1)
  65.         {
  66.                 Disp();//        LED2=!LED2;
  67.                 if(vol==0)
  68.                 {
  69.                         delay_50ms(10);
  70.                         if(vol==0)
  71.                         {
  72.                                 crt=0;
  73.                         }           
  74.                 }
  75.                 else crt=1;   
  76.         }                                         
  77.         if(count==20)
  78.         {       
  79.                 TR1=0;          //T1计数停止
  80.                 count=0;
  81.                 TR1=0;                        //定时器1停止计数
  82.                 pinlv=TH1*256+TL1;           //计算频率值
  83.                 pin=pinlv;                                             
  84.                 TH1=0;                                           //计数清零
  85.                 TL1=0;
  86.                 TR1=1;                                        //开始计数          
  87.          }  
  88.         TR0=1;
  89. }
  90. void Disp()
  91. {                                                                           
  92.         pin=pin*0.06;// (pin/1000)*60 1000线            
  93.         temp[3]=pin/1000%10;            //千位
  94.         temp[2]=pin/100%10;                //百位
  95.         temp[1]=pin%100/10;         //十位
  96.         temp[0]=pin%10;             //个位                  
  97. //        if(temp[4]>=1)
  98. //        {
  99. //                sendbyte(temp[1]);
  100. //                sendbyte(temp[2]);
  101. //                sendbyte(temp[3]);
  102. //                sendbyte(temp[4]);
  103. //        }
  104. //        else  
  105.         sendbyte(temp[0]);
  106.         sendbyte(temp[1]);
  107.         sendbyte(temp[2]);
  108.         sendbyte(temp[3]);                          
  109. }
  110. void init()        //定时器0,1初始化
  111. {
  112.                                                                           
  113.         EA=0;                          //关主中断
  114.         TMOD=0x51;                  //方式寄存器,T0定时,T1计数功能
  115.         TH0=0x3c;                                  //0x3c 定时50ms
  116.         TL0=0xb0;                                   //0xb0
  117.         TH1=0;
  118.         TL1=0;
  119.         ET0=ET1=1;      //T0允许中?       
  120.         EA=1;           //开主中断
  121.         TR1=1;          //T1计数
  122.         TR0=1;              //T0定                 
  123. }  
  124. int main()
  125. {                                                                                                            
  126.         init();            
  127.         while(1);          
  128. }

发表于 2013-7-7 11:19 | 显示全部楼层
误差1/1000左右,晶振20M最好,单片机STC12/STC15系列的都可以。
 楼主| 发表于 2013-7-8 12:19 | 显示全部楼层
gonggu8181 发表于 2013-7-7 11:19
误差1/1000左右,晶振20M最好,单片机STC12/STC15系列的都可以。

3Q~~~~
发表于 2017-3-18 09:00 | 显示全部楼层
路过,现在要用PIC18F4431来写编码器,求解
您需要登录后才可以回帖 登录 | 注册

本版积分规则

16

主题

62

帖子

0

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