#include "W78E354.H" #define COUNT 4 //定义接收缓冲区的大小// #define uchar unsigned char /*数据采集部分管脚定义*/ sbit RO=P2^0;//格雷码输入// sbit RED=P2^1;//允许格雷码输入,低电平有效// sbit DE=P2^2;//时钟输出允许,高电平有效// sbit CLOCK=P2^3;//时钟输出// /*串口输出部分管脚定义*/ sbit RE_DE=P1^4;//485控制引脚// sbit Key_3=P0^4; sbit Key_4=P0^5; sbit ALARM=P0^3; /*7219管脚定义*/ sbit LOAD = P0^2; //MAX7219 Load-Data Input: sbit DIN = P0^0; //MAX7219 Serial-Data Input: sbit CLK = P0^1; //MAX7219 Serial-Clock Input: uchar bstop=0;/*结束泵工作的标志*/ uchar fstop=0;/*结束阀工作的标志*/ uchar key=0; uchar key1=0;/*7219寄存器的标志设置*/ uchar idata displ[COUNT]={3,6,8};/*定义发送缓冲区*/ void COM_inter(void);/*声明函数变量*/ void manage_key1(void); void manage_key2(void); void Timer_ini(void); void judge_key(void); void collect(void); main() { CLOCK=1; RED=0;/*接收器允许*/ DE=1;/*发送器允许*/ Key_3=0;/*泵,阀初始化*/ Key_4=0; RE_DE=0;/*485准备接收*/ Timer_ini(); while(1) { collect(); judge_key(); } }
void Timer_ini(void) //定时器的初始化// { TMOD=0x20;/*定时器0工作于方式2,定时器1工作于方式2, 0010 0010*/ TH1=0xb7;//实现数据传输率9600// TL1=0xb7; SCON=0x50;//选择串口工作方式1,打开接收允许// PCON=0x00;//波特率倍增设置// TR1=1;//启动定时器T1// ES=1;EA=1;//允许串口中断// }
//-------------------------------------------------------- //函数名称:COM_send();串口发送函数 //函数功能:把数据缓冲区的4位数据发送出去 //-------------------------------------------------------- void COM_send(void) { uchar point; for(point=0;point<COUNT;point++) //连续发送4位数据,将数据发送到缓冲口// { SBUF=displ[point];//发送数据// while(TI!=1); TI=0; } ES=1; } //----------------------------------------------- //函数名称:manage_key3() //函数功能:按键3处理子程序 //----------------------------------------------- void manage_key3(void) { bstop++; if(bstop<=1) { Key_3=1;/*使外部泵开始工作*/ } else { Key_3=0;/*结束泵工作*/ bstop=0;/*标注清零*/ }
} //----------------------------------------------- //函数名称:manage_key4() //函数功能:按键4处理子程序 //----------------------------------------------- void manage_key4(void) { fstop++;/**/ if(fstop<=1) { Key_4=1;/*使外部阀开始工作*/ } else { Key_4=0;/*结束外部阀开始工作*/ fstop=0;/*标注清零*/ } }
//-------------------------------------------------------- //函数名称:com_interrup()串口接收中断处理函数 //函数功能:接收包括起始位0xFE,地址位和终止位0xEF在内的10bit数据到数据缓冲区 // ,地址不匹配,则接收到的是无效数字,不写到接收缓冲区 //-------------------------------------------------------- void COM_inter(void) interrupt 4 using 1//串口处理函数// { uchar a;/*串口标志*/ RI=0; RE_DE=0; a=SBUF; switch(a) { case 0x01:ES=0;RI=0;manage_key1();ES=1;break; case 0x02:ES=0;RI=0;manage_key2();ES=1;break; case 0x03:ES=0;RI=0;manage_key3();ES=1;break;/*调用函数实现泵的控制*/ case 0x04:ES=0;RI=0;manage_key4();ES=1;break;/*调用函数实现阀的控制*/ default:RE_DE=1;RI=0;TI=0; ES=0;COM_send();break;/*使485处于发送状态,发送数据*/ } } /****************************************** 发送一个字节的子程序: 上升沿发送数据, MSB first ******************************************/ void Write_Max7219_byte(unsigned char temp) { unsigned char i; for (i=0; i<8; i++) { CLK = 0; DIN = (bit)(temp&0x80); temp <<=1; CLK = 1; } } /********************************************************** 向寄存器中写入一个数据 先写地址,后写数据 load 上升沿锁存数据 **********************************************************/ void Write_Max7219(unsigned char address,unsigned char dat) { LOAD = 0; Write_Max7219_byte(address); Write_Max7219_byte(dat); LOAD = 1; } //----------------------------------------------- //函数名称:manage_key1() //函数功能:按键1处理子程序 //----------------------------------------------- void manage_key1(void) { key1++;/*进行寄存器的标志设置*/ key++; switch(key1) { case 1:Write_Max7219(1, 0x80);break;//选择最低位寄存器,准备进行调节// case 2:Write_Max7219(2, 0);break;//选择次低位寄存器,进行调节// case 3:Write_Max7219(3, 0);break;//选择次中间寄存器,进行调节// case 4:Write_Max7219(4, 0);break;//选择最高位寄存器,进行调节// default:key1=0;break; } } //----------------------------------------------- //函数名称:manage_key2() //函数功能:按键2处理子程序,对显示的数据进行增1调节 //----------------------------------------------- void manage_key2(void) { switch(key) { case 1:{displ[0]++;Write_Max7219(1,(displ[0]|0x80));if((displ[0]|0x80)==0x8A)displ[0]=(0|0x80);}break;//依次对显示进行增量调节 case 2:{displ[1]++;Write_Max7219(2,displ[1]);if(displ[1]==10)displ[1]=0;}break; case 3:{displ[2]++;Write_Max7219(3,displ[2]);if(displ[2]==10)displ[2]=0;}break; case 4:{displ[3]++;Write_Max7219(4,displ[3]);if(displ[3]==10)displ[3]=0;key=0;}break; default:key=0;break; } } /*延时子程序,延时时间为(16×N+24微秒)*/ void delay(unsigned int N) { int i; for(i=0;i<N;i++); } //----键值判断--------------------------
//--------------------------------------------------- void judge_key(void) {uchar Key_value=0; Key_value=P1&0x0f; switch(Key_value) { case 0x0E:delay(30000); if(Key_value==(P1&0x0f)) { manage_key1();break; } else break; case 0x0D:delay(30000); if(Key_value==(P1&0x0f)) { manage_key2();break; } else break; case 0x0B:delay(30000); if(Key_value==(P1&0x0f)) { manage_key3();break; } else break; case 0x07:delay(30000); if(Key_value==(P1&0x0f)) { manage_key4();break; } else break; default: break; } } void collect(void) { uchar Gdata[25]; uchar Bdata[25]; uchar i,j,k,l=0; unsigned long Tran=0; for(i=0;i<25;i++) { CLOCK=0; CLOCK=1; Gdata=RO; } i=0; Bdata[0]=Gdata[0];/*将首位赋给二进制首位*/ for(j=1;j<=24;j++) { if(Gdata[j]==0)/*若格雷码为0,二进制与前一位相同*/ Bdata[j]=Bdata[j-1]; else/*若格雷码为1,二进制与前一位相反*/ {if(l==0) {l++; if(Bdata[j-1]==1) {Bdata[j]=Bdata[j-1]-1;} else {Bdata[j]=Bdata[j-1]+1;} } else { if(Bdata[j-1]==1) {Bdata[j]=Bdata[j-1]-1;} else {Bdata[j]=Bdata[j-1]+1;} l=0;} } } for(k=0;k<=20;k++);/*延时*/ for(i=0;i<25;i++)/*将转换的二进制存入长整形变量*/ { Tran^=Bdata; Tran=Tran<<1; } displ[0]=(Tran/62111);//二进制转换成显示的工程算法,Diaply0显示的是最高位,// displ[1]=(Tran%62111)/6211;//此值赋给次高位// displ[2]=((Tran%62111)%6211)/621; displ[3]=(((Tran%62111)%6211)%621)/62; if((displ[0]==9)&&(displ[1]==9))/*出错控制*/ {ALARM=0;} } 程序在单独运行键盘显示时 能用;单独测试串口时 能够给单片机写入数据,上传的数据看不到 我以为是数据格式的问题,但是将两个程序放在一起的时候,就不好用了 请教这是为什么啊 ?多谢大家 |