这个是个绝对式的编码器,是被动接受式的,也就是说只有发送读命令后才能读取当前编码器的角度。重点:程序写好了,但是编码器转了,显示器不显示角度值,是为什么?懂得可否给个想法
取命令在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;
}
} |