是我同学写的数据采集器代码,其他的都没有问题,就是最后一步的串口通信没法完成,以下是他的代码,我看了很久都没有看到问题,求各位大神帮帮忙~~谢谢你们了!!
硬件用了两块ATMEL 89C51,采集端有一块ADC0809,晶振11.0592MHz,硬件没有问题。。。
控制室代码:
#include <reg51.h>
#include <intrins.h>
char eflag=0; //报错显示 1:不改变show【】0:刷新数据
int counter=0; //1秒显示计数
int ecount=0; //错误闪烁计数
char t = 0; //串口接收数据序号
char ct =3; //显示数据位数序号
unsigned char x = 0; //数码显示数据序号
char cond=0; //状态{0巡回显示,1,2,键盘值,3按键处理}
char show[4]={0}; //当前显示数据
unsigned char ch[8]={10,20,30,40,50,60,70,80}; //数据存储空间
char en[4]={0x80,0x40,0x20,0x10};//位选使能
char seg[12]={0xf6,0xf5,0xf3,0xee,0xed,0xeb,0xde,0xdd,0xdb,0xbe,0xbd,0xbb}; //0~9 ,确定,巡回
char dseg[10]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09}; //数码显示
//************************************延时函数*************
void delay() //10ms
{
int i,j;
for(i=0;i<36;i++)
for(j=0;j<256;j++);
}
//**********************************扫键判断****************
//***************\\范围0~11 ************
//***************\\0~9数字键,10确定键,11巡回键 *********
int keyscan()
{
unsigned char k,k_temp;
int i=0;
P1=0xf8; //需修改
k=P1;
if(k!=0xf8)
{
delay();
k_temp=P1;
if(k==k_temp)
{
k=0xfe; //当P^1低判断哪两个联通
do
{
P1=k;
if(k!=P1)
{
for(i=0;i<12;i++)
{
if(P1==seg)
{
while(P1==seg); //消耗长按
return i;
}
}
}
k=_crol_(k,1); //循环左移
}while(k!=0xf7);
}
}
return;
}
//**********************显示*********************************
//******* P2脚位选使能 *************
//******* P0脚段选使能 *************
//******* 显示状态{0:巡回显示,1,2:键盘值,3:按键已处理}*
void display()
{
if(eflag) //错误闪烁代码
{
ecount++;
if(ecount<40)
{
P2=0x00;
}
else
{
P2=en[ct];
P0=dseg[show[ct]];
}
if(ecount==80)
ecount=0;
}
else if((cond==0)||(cond==3))
{
P2=en[ct];
P0=dseg[show[ct]];
}
else if((cond==1)||(cond==2))
{
if(ct>(3-cond))
{
P2=en[ct];
P0=dseg[show[ct]];
}
else
{
P2=0x00;
}
}
ct--;
if(ct<0)
ct=3;
}
//****************************指定序号数据显示**********
void led_xunhui()
{
show[0]=0;
show[1]=x+1;
show[2]=(ch[x])/10;
show[3]=(ch[x])%10;
}
//*******************************附属keyjudge**********
//************************ 判断,结果出错 ******
void led_kj_error()
{
show[0]=8;
show[1]=8;
show[2]=8;
show[3]=8;
cond=3;
eflag=1;
}
//*******************************附属keyjudge**********
//************************ 判断,结果正确 **********
void led_kj_right()
{
x=show[3]-1;
led_xunhui(); //数码显示
cond=3; //显示对号数据
}
//************************按键选择判断函数***************************
//************* 输入正确则改变显示数组show【】=指定工号+数据 *****
//************* 输入错误则改变显示数组show【】=“8888” **********
//************* 按下巡回键返回“循环显示”中 **************
void keyjudge(int temp)
{
if(temp==11) //按下巡回键
{
x=0; //显示数据序号
cond=0; //显示状态(巡回)
counter=0; //计数清零
led_xunhui();
eflag=0; //巡回显示
}
else if(temp>=0&&temp<=9) //按下数字键
{
if(cond==0||(cond==3)) //首次输入和报错
{
show[3]=temp; //右边第一位
cond=1;
eflag=0;
}
else if(cond==1) //按下第二数
{
show[2]=show[3];
show[3]=temp;
cond=2;
}
else if(cond==2) //按下第三数,报错
{
led_kj_error();
}
}
else if(temp==10) //按下确定键
{ if(cond==0)
{
eflag=0;
}
if(cond==1)
{
if(show[3]>=9||show[3]==0) //判断是否大于有效采样个数且不为零
{
led_kj_error();
}
else if(show[3]>0)
{
led_kj_right();
}
}
else if(cond==2)
{
if(show[3]+10*show[2]>8)
{
led_kj_error();
}
else if(show[3]>0)
{
led_kj_right();
}
}
}
}
//*********************************改变显示序号************************
//************************ 到4秒时:改变show【】内容 实现循环显示 *****
//************************ 若处于单值监控(cond==3&&eflag==0): ********
//************************ 刷新当前工号内容 **********
//************************ 处于报错状态(cond==3&&eflag==0):则不改变***
//*********************************************************************
void timer_0() interrupt 1
{
char tm;
TH0=(65536-3600)/256;
TL0=(65536-3600)%256;
display(); //显示
counter++;
if(counter==256) //1秒改变显示内容
{
//*********************串行通信********************
//*********************1秒一次*********************
SBUF=x;
if(TI)
{
REN=1;
TI=0;
}
for(tm=0;tm<10;tm++);
if(RI)
{
RI=0;
REN=0;
ch[x]=SBUF;
}
//**************数据接收完毕**************************
counter=0;
if(cond==0) //判断是键盘显示
{
led_xunhui();
x++;
if(x==8)
x=0;
}
else if(cond==3)
{
if(eflag==0)
led_xunhui();
}
}
}
//****************定时中断初始化****************************
void inti_time()
{
//TMOD=0X01;
TH0=(65536-3600)/256;
TL0=(65536-3600)%256;
EA=1;
ET0=1;
TR0=1; //启动定时器1
}
//***********串口初始化*******
void uart_into()
{
SCON=0X50;
//TMOD=0X20;
TH1 =0XFD;
TR1 =1;//启动定时器2
REN=0;
}
void uart()interrupt 4
{
if(RI)
{
ch[t]=SBUF;
RI=0;
}
t++;
if(t==8)
t=0;
}
void main()
{
char temp,i;
TMOD=0x21;
inti_time();
uart_into();
while(1)
{
temp=keyscan();
keyjudge(temp);
for(i=0;i<3;i++)
delay();
}
}
采集端代码:
#include <reg51.h>
int counter;
int D[8]={0};//数据存储
sbit da=P1^1;
sbit db=P1^2;
sbit dc=P1^3;
sbit EOC=P1^4;
sbit ST=P1^5;
sbit OE=P1^6;
void delay() //10ms
{
int i,j;
for(i=0;i<36;i++)
for(j=0;j<256;j++);
}
void timer_0() interrupt 1 //每秒送数据
{
char temp=0;
TH0=(65536-3600)/256;
TL0=(65536-3600)%256;
counter++;
if(counter==256)
{
SCON=0X50;
TMOD=0X20;
TH1=0XFD; //9600bit/s
TR1=1;//启动定时器
counter=0;
if(TI)
{
TI=0;
REN=1;
}
if(RI)
{
RI=0;
temp=SBUF;
SBUF=D[temp];
REN=0;
}
}
}
void judget(int t)
{
switch(t)
{
case 0:{dc=0;db=0;da=0;OE=0;break;}
case 1:{dc=0;db=0;da=1;OE=0;break;}
case 2:{dc=0;db=1;da=0;OE=0;break;}
case 3:{dc=0;db=1;da=1;OE=0;break;}
case 4:{dc=1;db=0;da=0;OE=0;break;}
case 5:{dc=1;db=0;da=1;OE=0;break;}
case 6:{dc=1;db=1;da=0;OE=0;break;}
case 7:{dc=1;db=1;da=1;OE=0;break;}
}
}
void main()
{
int t=0,tp;
TMOD=0x21;
TH0=(65536-3600)/256;
TL0=(65536-3600)%256;
TR0=1;
ET0=1;
EA=1;
while(1)
{
judget(t);
ST=0;
ST=1;
ST=0;
while(EOC==0);
OE=1;
tp=P2;
D[t]=tp*99/256;
t++;
if(t==8)
t=0;
OE=0;
delay();
}
}
|