打印
[51单片机]

51单片机,连接485转TTL模块,模块连接绝对式编码器( 产生的是rs485信号)

[复制链接]
960|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wzy96321|  楼主 | 2017-1-5 20:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这个是个绝对式的编码器,是被动接受式的,也就是说只有发送读命令后才能读取当前编码器的角度。重点:程序写好了,但是编码器转了,显示器不显示角度值,是为什么?懂得可否给个想法
取命令在Rxdcom数组里面,还有显示器部分是没问题的,我测试过。所以问题可能是发送命令跟接受数据哪里
#include<reg52.h>                                                        
#include<intrins.h>
#include<stdlib.h>
#define uint unsigned int
#define uchar unsigned char
//lcd 引脚 ,P0口用于给lcd传递数据跟命令
sbit lcden = P2^2;
sbit lcdpsb = P2^4;                  //串并行方式控制
sbit lcdrw = P2^5;
sbit lcdrs = P2^6;
//编码器读命令
uchar code Rxd_com[] = {0x01,0x03,0x00,0x00,0x00,0x01,0x84,0x0A};  //编码器的读命令字

uchar code tabwind[] = {"风速:"};
uchar code tabweight[] = {"吊重:"};
uchar code tabangle[] = {"转角:"};
uchar code tabwind1[] = {"级"};
uchar code tabweight1[] = {"kg"};
uchar code tabangle1[] = {"度"};                  

uint flag=0;
uchar temp[8];
uchar txdate[8];

//延时函数
void delayms(uint xms)
{
  uint i, j;
  for(i = xms;i > 0;i--)
    for(j = 110;j > 0;j--);
}
//lcd写命令
void write_com(uchar com)
{
  lcdrs = 0;
  lcdrw = 0;
  lcden = 0;
  P0 = com;
  delayms(5);
  lcden = 1;
  delayms(5);
  lcden = 0;
}
//lcd写数据
void write_dat(uchar dat)
{
   lcdrs = 1;
   lcdrw = 0;
   lcden = 0;
   P0 = dat;
   delayms(5);
   lcden = 1;
   delayms(5);
   lcden = 0;
}
//lcd显示位置
void lcd_pos(uchar x,uchar y)
{
   uchar pos;
   if(x == 0)
     x = 0x80;
   else if(x == 1)
     x = 0x90;
   else if(x == 2)
     x = 0x88;
   else if(x == 3)
     x = 0x98;
   pos = x + y;
   write_com(pos);
}
//初始化lcd
void lcd_init()
{
  lcdpsb = 1;              //并行方式
  write_com(0x30);         //基本指令
  delayms(5);
  write_com(0x0c);         //开显示,关光标
  delayms(5);
  write_com(0x01);         //清屏
  delayms(5);
}

//串口初始化函数
void USART_Init(void)
{
        TMOD = 0x20;       //将定时器1设置为方式2,8位自动重装模式
        SCON = 0x50;      //串口控制寄存器,使串口工作在方式1,并且接受使能
        PCON = 0x00;      //该寄存器第一位为串口波特率倍速控制位,这里不倍速
        TH1 = 0xfd;       //11.0592M晶振,波特率9600
        TL1 = 0xfd;
        TR1 = 1;          //开启定时器1
        ES = 1;           //开启串口中断
        EA = 1;           //开启总中断
}
//lcd显示器不改变量
void display1()
{
  uchar i;
  //lcd显示不变量
  lcd_pos(0,0);    //lcd第一行第一个地址
  i = 0;
  while(tabwind[i] != 0)
  {
     write_dat(tabwind[i]);
         i++;
  }
  lcd_pos(0,0x05);             //风速单位显示地址
  i = 0;
  while(tabwind1[i] != 0)
  {
     write_dat(tabwind1[i]);
         i++;
  }

  lcd_pos(1,0);        //lcd第二行第一个地址
  i = 0;
  while(tabweight[i] != 0)
  {
     write_dat(tabweight[i]);
         i++;
  }
  lcd_pos(1,0x05);             //吊重显示位置
  i = 0;
  while(tabweight1[i] != 0)
  {
     write_dat(tabweight1[i]);
         i++;
  }                                          

  lcd_pos(2,0);        //lcd第三行第一个地址
  i = 0;
  while(tabangle[i] != 0)
  {
     write_dat(tabangle[i]);
         i++;
  }
  lcd_pos(2,0x05);             //转角显示位置
  i = 0;
  while(tabangle1[i] != 0)
  {
     write_dat(tabangle1[i]);
         i++;
  }
}
//发送字节函数
void Send_Dat(uchar dat)
{        
        SBUF = dat;
        while(TI==0);
        TI=0;
}
//字符串发送
void SendString(unsigned char *p)
{
   while(*p)
   {
          Send_Dat(*p);
           p++;
   }
}
/*//16进制转化为10进制
int oxtoten(char s)
{
  int i,m,temp=0,n;
  m=strlen(s);//十六进制是按字符串传进来的,所以要获得他的长度
  for(i=0;i<m;i++)
  {
     if(s[i]>='A'&&s[i]<='F')//十六进制还要判断他是不是在A-F或者a-f之间a=10。。
     n=s[i]-'A'+10;
     else if(s[i]>='a'&&s[i]<='f')
     n=s[i]-'a'+10;
     else n=s[i]-'0';
     temp=temp*16+n;
  }
  return temp;
} */
//主函数
void main()
{
   uchar a1[3];
   uint i;
   USART_Init();
   lcd_init();               
   display1();                    //显示lcd不变量
   delayms(5);

  /* for(i=0;i<8;i--)                                           //编码器必须先发送数据才能发送,此段为一开始的发送读命令
   {
          Send_Dat(Rxd_com[i]);
          while(!TI);
          TI = 0;
   }  */        
   while(1)
   {                                                                           
         
          if(flag == 1)
          {
             ES = 0;                                     //关串口中断为了接受数据
             SendString(Rxd_com);           //读命令
                 while(!TI);
                 TI = 0;
          }
          ES = 1;
          flag = 0;           

          //转角数据显示位置         
          lcd_pos(2,0x03);
         // a1[0] = 3 + 0x30; 用于测试数据
        //  write_dat(a1[0]);                     
          a1[0] = txdate[7] + 0x30;
          a1[1] = txdate[8] + 0x30;
          a1[2] = txdate[9] + 0x30;
          a1[3] = txdate[10] + 0x30;
          for(i = 0;i < 4;i++)
          {
            write_dat(a1[i]);  
          }                  
                  
   }
}

void USART_INTR() interrupt 4        //串口中断
{
    uchar temp;
        uint j = 0;
        if(RI == 1)
        {
                RI = 0;
                temp = SBUF;
                if(temp != '\0')
                {
                  txdate[j] = temp;
                  j++;
                }               
                flag = 1;
        }
}

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

13

帖子

0

粉丝