是我同學寫的數據采集器代碼,其他的都沒有問題,就是最后一步的串口通信沒法完成,以下是他的代碼,我看了很久都沒有看到問題,求各位大神幫幫忙~~謝謝你們了!!
硬件用了兩塊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();
}
}
|