用STC12C5A60S2做一个多机通信系统,主从机之间无法通讯,我检查过硬件线路没有问题,程序也检查了好几遍,自认为没有什么逻辑错误,可就是不能通信,请各位大神帮忙看看我的程序有什么错误
功能:主机通过按键输入一个0~200的数,再给各个从机发送(这里取25),从机收到后发一些数据给主机,主机在液晶上显示
主机程序
#include<STC12C5A60S2.H>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define RS_CLR RS=0
#define RS_SET RS=1
#define RW_CLR RW=0
#define RW_SET RW=1
#define EN_CLR EN=0
#define EN_SET EN=1
sbit RS = P2^4; //定义端口
sbit RW = P2^5;
sbit EN = P2^6;
#define DataPort P0
#define KeyPort P1
uchar sendsbuf[4]=0;
uchar resbuf[4]=0;
float idata cj_data0[6];
char cj_data1[6];
uchar addr[6]={0x00,0x01,0x02,0x03,0x04,0x05};
float I;
uchar num,h,num1,num12,num13,jj,iii;
int e,d;
uchar code dofly_code[]={'0','1','2','3','4','5','6','7','8','9',' '};
/*------------------------------------------------
uS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
长度如下 T=tx2+5 uS
------------------------------------------------*/
void DelayUs2x(unsigned char ttt)
{
while(--ttt);
}
/*------------------------------------------------
mS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char Ms)
{
while(Ms--)
{
//大致延时1mS
DelayUs2x(245);
DelayUs2x(245);
}
}
/*------------------------------------------------
写入命令函数
------------------------------------------------*/
void LCD_Write_Com(unsigned char com)
{
// while(LCD_Check_Busy()); //忙则等待
DelayMs(5);
RS_CLR;
RW_CLR;
EN_SET;
DataPort= com;
_nop_();
EN_CLR;
}
/*------------------------------------------------
写入数据函数
------------------------------------------------*/
void LCD_Write_Data(unsigned char Data)
{
//while(LCD_Check_Busy()); //忙则等待
DelayMs(5);
RS_SET;
RW_CLR;
EN_SET;
DataPort= Data;
_nop_();
EN_CLR;
}
/*------------------------------------------------
清屏函数
------------------------------------------------*/
void LCD_Clear(void)
{
LCD_Write_Com(0x01);
DelayMs(5);
}
/*------------------------------------------------
写入字符串函数
------------------------------------------------
void LCD_Write_String(unsigned char x2,unsigned char y2,unsigned char *s)
{
if (y2 == 0)
{
LCD_Write_Com(0x80 + x2); //表示第一行
}
else
{
LCD_Write_Com(0xC0 + x2); //表示第二行
}
while (*s)
{
LCD_Write_Data( *s);
s++;
}
}*/
/*------------------------------------------------
写入字符函数
------------------------------------------------*/
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
{
if (y == 0)
{
LCD_Write_Com(0x80 + x);
}
else
{
LCD_Write_Com(0xC0 + x);
}
LCD_Write_Data( Data);
}
/*------------------------------------------------
初始化函数
------------------------------------------------*/
void LCD_Init(void)
{
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
LCD_Write_Com(0x08);
LCD_Write_Com(0x01);
LCD_Write_Com(0x06);
DelayMs(5);
LCD_Write_Com(0x0C);
}
void serialport_init()
{
PCON=0;
SCON=0xf8;
AUXR=0x15;
IPH=0x10;
IP=0x10;
BRT=0xfd;
EA=1;
ES=1;
}
/*------------------------------------------------
设定二个自定义字符,LCD1602中自定义字符的地址为0x00--0x07,
即可定义8个字符
这里我们设定把一个自定义字符放在0x00位置(000),
另一个放在0x01位子(001)
------------------------------------------------*/
void Lcd_User_Chr(void)
{ //第一个自定义字符
LCD_Write_Com(0x40); //"01 000 000" 第1行地址 (D7D6为地址设定命令形式D5D4D3为字符存放位置(0--7),D2D1D0为字符行地址(0--7))
LCD_Write_Data(0x00); //"XXX 11111" 第1行数据(D7D6D5为XXX,表示为任意数(一般用000),D4D3D2D1D0为字符行数据(1-点亮,0-熄灭)
LCD_Write_Com(0x41); //"01 000 001" 第2行地址
LCD_Write_Data(0x04); //"XXX 10001" 第2行数据
LCD_Write_Com(0x42); //"01 000 010" 第3行地址
LCD_Write_Data(0x0e); //"XXX 10101" 第3行数据
LCD_Write_Com(0x43); //"01 000 011" 第4行地址
LCD_Write_Data(0x0e); //"XXX 10001" 第4行数据
LCD_Write_Com(0x44); //"01 000 100" 第5行地址
LCD_Write_Data(0x0e); //"XXX 11111" 第5行数据
LCD_Write_Com(0x45); //"01 000 101" 第6行地址
LCD_Write_Data(0x1f); //"XXX 01010" 第6行数据
LCD_Write_Com(0x46); //"01 000 110" 第7行地址
LCD_Write_Data(0x04); //"XXX 11111" 第7行数据
LCD_Write_Com(0x47); //"01 000 111" 第8行地址
LCD_Write_Data(0x00); //"XXX 00000" 第8行数据
//第二个自定义字符
LCD_Write_Com(0x48); //"01 001 000" 第1行地址
LCD_Write_Data(0x03); //"XXX 00001" 第1行数据
LCD_Write_Com(0x49); //"01 001 001" 第2行地址
LCD_Write_Data(0x03); //"XXX 11011" 第2行数据
LCD_Write_Com(0x4a); //"01 001 010" 第3行地址
LCD_Write_Data(0x00); //"XXX 11101" 第3行数据
LCD_Write_Com(0x4b); //"01 001 011" 第4行地址
LCD_Write_Data(0x00); //"XXX 11001" 第4行数据
LCD_Write_Com(0x4c); //"01 001 100" 第5行地址
LCD_Write_Data(0x00); //"XXX 11101" 第5行数据
LCD_Write_Com(0x4d); //"01 001 101" 第6行地址
LCD_Write_Data(0x00); //"XXX 11011" 第6行数据
LCD_Write_Com(0x4e); //"01 001 110" 第7行地址
LCD_Write_Data(0x00); //"XXX 00001" 第7行数据
LCD_Write_Com(0x4f); //"01 001 111" 第8行地址
LCD_Write_Data(0x00); //"XXX 00000" 第8行数据
}
/*------------------------------------------------
键盘函数
------------------------------------------------*/
uchar KeyScan() //键盘扫描函数,使用行列反转扫描法
{
uchar cord_h,cord_l;//行列值中间变量
KeyPort=0x0f; //行线输出全为0
cord_h=KeyPort&0x0f; //读入列线值
if(cord_h!=0x0f) //先检测有无按键按下
{
DelayMs(15); //去抖
if((KeyPort&0x0f)!=0x0f)
{
cord_h=KeyPort&0x0f; //读入列线值
KeyPort=cord_h|0xf0; //输出当前列线值
cord_l=KeyPort&0xf0; //读入行线值
while((KeyPort&0xf0)!=0xf0);//等待松开并输出
return(cord_h+cord_l);//键盘最后组合码值
}
}return(0xff); //返回该值
}
/*------------------------------------------------
按键值处理函数,返回扫键值
------------------------------------------------*/
uchar KeyPro()
{
switch(KeyScan())
{
case 0x7e:return 0;break;//0 按下相应的键显示相对应的码值
case 0x7d:return 1;break;//1
case 0x7b:return 2;break;//2
case 0x77:return 3;break;//3
case 0xbe:return 4;break;//4
case 0xbd:return 5;break;//5
case 0xbb:return 6;break;//6
//case 0xb7:return 20;break;//7
case 0xde:return 7;break;//8
case 0xdd:return 8;break;//9
case 0xdb:return 9;break;//a
case 0xd7:return 10;break;//退格键
case 0xb7:num1=20;return 20;break;//确定键
case 0xee:num13=1;num12=0;iii=0;return 21;break;//显示启动键
case 0xed:num12=1;num13=0;jj=0;return 22;break;//翻页键
//case 0xeb:return 14;break;//e
//case 0xe7:return 15;break;//f
default:return 0xff;break;
}
}
uint yuqizhi(uint o)
{
uint r=0,p=0,q=0,iii;
if(o!=r&&iii==0)
{
r=o;
e=o*100;
++iii;
}
if(o!=p&&iii==1)
{
p=o;
e=e+p*10;
++iii;
}
if(o!=q&&iii==2)
{
q=o;
e=e+q;
}
iii=0;
return e;
}
void senddata(uint g)
{
uchar m=0,n=0,l=0;
l=g/100;
m=g/10%10;
n=g%10;
LCD_Write_Char(12,0,dofly_code[l]);
LCD_Write_Char(13,0,dofly_code[m]);
LCD_Write_Char(14,0,dofly_code[n]);
}
void senddata1(float t)
{
uchar n=0,l=0,m=0,o=0;
if(t>=1)
l=1;
else
l=0;
n=(uint)(t*10)%10;
m=(uint)(t*100)%10;
o=(uint)(t*1000)%10;
LCD_Write_Char(3,1,dofly_code[l]);
LCD_Write_Char(5,1,dofly_code[n]);
LCD_Write_Char(6,1,dofly_code[m]);
LCD_Write_Char(7,1,dofly_code[o]);
}
void senddata2(float t)
{
uint n=0,l=0,m=0;
l=(uint)(t);
n=(uint)(t*10)%10;
m=(uint)(t*100)%10;
if(t==cj_data0[0])
{
LCD_Write_Char(11,0,dofly_code[l]);
LCD_Write_Char(13,0,dofly_code[n]);
LCD_Write_Char(14,0,dofly_code[m]);
}
if(t==cj_data0[1])
{
LCD_Write_Char(11,1,dofly_code[l]);
LCD_Write_Char(13,1,dofly_code[n]);
LCD_Write_Char(14,1,dofly_code[m]);
}
}
senddata3(uchar g)
{
uchar m=0,n=0,l=0;
l=g/100;
m=g/10%10;
n=g%10;
if(g==cj_data1[0])
{
LCD_Write_Char(3,0,dofly_code[l]);
LCD_Write_Char(4,0,dofly_code[n]);
LCD_Write_Char(5,0,dofly_code[m]);
}
if(g==cj_data1[1])
{
LCD_Write_Char(3,1,dofly_code[l]);
LCD_Write_Char(4,1,dofly_code[n]);
LCD_Write_Char(5,1,dofly_code[m]);
}
}
void error()
{
SBUF=0xff;
while(TI!=1);
TI=0;
}
uchar SerialPort_deal(uchar addr,uchar command)
{
uchar sb=0,p=0,j=0,ad=0,q=0;
while(1)
{
SBUF=addr;
if(TI==1)
TI=0;
if(RI==1)
RI=0;
if(RB8==1)
ad=SBUF;
if(ad!=addr)
error();
else
{
TB8=0;
SBUF=command;
if(TI==1)
TI=0;
if(RI==1)
{
RI=0;
sb=SBUF;//接受从机传来的状态信号
}
if((sb&0x08)==0x00)
{
TB8=1;
error();
}
else
{
if(command==0x01)
{
if((sb&0x01)==0x01)
{
do
{
p=0;
for(j=0;j<3;j++)
{
SBUF=sendsbuf[j];
p+=sendsbuf[j];
if(TI==1)
TI=0;
}
SBUF=p;
if(TI==1)
TI=0;
if(RI==1)
RI=0;
}while(SBUF!=0);
TB8=1;
return(0);
}
else
{
if((sb&0x02)==0x02)
{
while(1)
{
p=0;
for(j=0;j<3;j++)
{
while(RI!=1)
RI=0;
resbuf[j]=SBUF;
p+=resbuf[j];
}
if(RI==1)
{
RI=0;
q=SBUF;
}
if(q==p)
{
SBUF=0x00;
if(TI==1)
TI=0;
break;
}
else
error();
}
TB8=1;
return(0);
}
}
}
}
}
}
}
void main()
{
uchar j;
e=25;
d=25;
I=(2.617-2.597)/0.185;
LCD_Init();
_nop_();
serialport_init();
DelayMs(5);
LCD_Clear();
Lcd_User_Chr();
DelayMs(1);
LCD_Write_Com(0x0F);//光标开,光标闪烁开 ;
while(1)
{
num=KeyPro();
DelayUs2x(10);
if((num!=0xff&&(num!=20&&num13==1))&&(num!=21&&num!=22))
{
if(num!=10)
{
LCD_Write_Char(4+h,0,dofly_code[num]);//依次显示输入字符
h++;
if(h==3)
h=0;
DelayMs(2);
yuqizhi(num);
}
else
{
LCD_Write_Char(6-h,0,dofly_code[num]);//依次显示输入字符
h++;
if(h==3)
h=0;
}
}
DelayMs(2);
if(num1==20)
{
if(e>200)
e=200;
sendsbuf[0]=e/100;
sendsbuf[1]=e/10%10;
sendsbuf[2]=e%10;
for(j=0;j<1;j++)
SerialPort_deal(addr[j],0x01);
DelayMs(2);
for(j=0;j<1;j++)
{
SerialPort_deal(addr[j],0x02);//要求接收反馈数据
DelayMs(1);
cj_data0[j]=resbuf[0]+(float)(resbuf[1]/10)+(float)(resbuf[2]/100)+(float)(resbuf[3]/1000);
}
_nop_();
for(j=0;j<1;j++)
{
SerialPort_deal(addr[j],0x02);//要求接收反馈数据
DelayMs(1);
cj_data1[j]=resbuf[0]*100+resbuf[1]*10+resbuf[2];
}
if(cj_data0[0]!=(I/2) || cj_data0[1]!=(I/2))
{
sendsbuf[0]=(uint)(I);
sendsbuf[1]=(uint)(I*10)%10;
sendsbuf[2]=(uint)(I*100)%10;
sendsbuf[3]=(uint)(I*1000)%10;
for(j=0;j<1;j++)
SerialPort_deal(addr[j],0x01);
}
}
if(num13==1)
{
if(iii==0)
{
LCD_Clear();
Lcd_User_Chr();
iii++;
}
LCD_Write_Char(0,0,'V');
LCD_Write_Char(1,0,'e');
LCD_Write_Char(2,0,'q');
LCD_Write_Char(3,0,':');
LCD_Write_Char(7,0,'v');
LCD_Write_Char(9,0,'V');
LCD_Write_Char(10,0,'o');
LCD_Write_Char(11,0,':');
LCD_Write_Char(15,0,'v');
LCD_Write_Char(0,1,'I');
LCD_Write_Char(1,1,'L');
LCD_Write_Char(2,1,':');
LCD_Write_Char(8,1,'A');
LCD_Write_Char(4,1,0x2e);
senddata(d);
senddata1(I);
}
if(num12==1)
{
if(jj==0)
{
LCD_Clear();
Lcd_User_Chr();
jj++;
}
LCD_Write_Char(0,0,'V');
LCD_Write_Char(1,0,'1');
LCD_Write_Char(2,0,':');
LCD_Write_Char(6,0,'v');
LCD_Write_Char(0,1,'V');
LCD_Write_Char(1,1,'2');
LCD_Write_Char(2,1,':');
LCD_Write_Char(6,1,'v');
LCD_Write_Char(8,0,'I');
LCD_Write_Char(9,0,'1');
LCD_Write_Char(10,0,':');
LCD_Write_Char(12,0,0x2e);
LCD_Write_Char(15,0,'A');
LCD_Write_Char(8,1,'I');
LCD_Write_Char(9,1,'2');
LCD_Write_Char(10,1,':');
LCD_Write_Char(12,1,0x2e);
LCD_Write_Char(15,1,'A');
senddata2(cj_data0[0]);
senddata3(cj_data1[0]);
senddata2(cj_data0[1]);
senddata3(cj_data1[1]);
}
}
}
从机程序
#define uint unsigned int
#define uchar unsigned char
#define SLAVE 0x01
uchar idata sendsbuf[4]=0;
uchar idata resbuf[4]=0;
bit tready;
bit rready;
bit readend;
bit sendend;
float num2,I;
uchar num1;
int d;
void serialport_init()
{
tready=0;
rready=0;
readend=0;
sendend=0;
PCON=0;
SCON=0xf0;
AUXR=0x15;
IPH=0x10;
IP=0x10;
BRT=0xfd;
EA=1;
ES=1;
}
/*--------------------------
接收函数
---------------------------*/
void sre()
{
uchar p=0,j=0,q;
rready=0;
while(1)
{
p=0;
for(j=0;j<3;j++)
{
if(RI==1)
RI=0;
resbuf[j]=SBUF;
p+=resbuf[j];
}
if(RI==1)
{
RI=0;
q=SBUF;
}
if(q==p)
{
SBUF=0x00;//校验和相同,表示接收完全,发0停止
if(TI==1)
TI=0;
break;
}
else
{
SBUF=0xff;//校验和不同,数据有丢失,发0xff重收
if(TI==1)
TI=0;
}
}
if(resbuf[3]==0)
num1=resbuf[0]*100+resbuf[1]*10+resbuf[2];
else
num2=resbuf[0]+(float)(resbuf[1]/10)+(float)(resbuf[2]/100)+(float)(resbuf[3]/1000);
SM2=1;
ES=1;
readend=1;
}
/*--------------------------
发送函数
---------------------------*/
void str()
{
uchar p=0,j=0;
tready=0;
do
{
p=0;
for(j=0;j<3;j++)
{
SBUF=sendsbuf[j];
p+=sendsbuf[j];
if(TI==0)
TI=0;
}
SBUF=p;
if(TI==1)
TI=0;
if(RI==1)
RI=0;
}while(SBUF!=0);
SM2=1;
ES=1;
sendend=1;
}
/*----------------------------------------
主函数
-------------------------------------------*/
void main()
{
serialport_init();
while(1)
{
rready=1;
if(num1<=200&&num1!=0)
{
d=25;
I=0.187;
}
if(readend==1)
{
sendsbuf[0]=(uint)(I);
sendsbuf[1]=(uint)(I*10)%10;
sendsbuf[2]=(uint)(I*100)%10;
sendsbuf[3]=(uint)(I*1000)%10;
readend=0;
if(sendend==1)
{
sendend=0;
sendsbuf[0]=d/100;
sendsbuf[1]=d/10%10;
sendsbuf[2]=d%10;
tready=1;
}
tready=1;
}
}
}
/*--------------------------
串口通信中断处理
---------------------------*/
void URAT1_Routine() interrupt 4
{
uchar sb=0,ad=0;
RI=0;
ES=0;
if(RB8==1)
{
ad=SBUF;
if(ad!=SLAVE)
{
ES=1;
goto reti;
}
SM2=0;
SBUF=SLAVE;
if(TI==1)
TI=0;
if(RI==1)
RI=0;
if(RB8==1)
{
SM2=1;
ES=1;
goto reti;
}
}
if(RI==1)
{
RI=0;
sb=SBUF;
}
if(sb==0x01)
{
if(rready==1)
{
SBUF=0x01;
RB8=0;
}
else
{
SBUF=0x00;
RB8=0;
}
if(TI==1)
TI=0;
if(RI==1)
RI=0;
if(RB8==1)
{
SM2=1;
ES=1;
goto reti;
}
sre();
}
else
{
if(sb==0x02)
{
if(tready==1)
{
SBUF=0x02;
RB8=0;
}
else
{
SBUF=0x00;
RB8=0;
}
if(TI==1)
TI=0;
if(RI==1)
RI=0;
if(RB8==1)
{
SM2=1;
ES=1;
goto reti;
}
str();
}
else
{
SBUF=0x08;
if(TI==1)
TI=0;
SM2=1;
ES=1;
}
}
reti:;
}
|