/*********************执行通讯协议解析************************/
command();
/*********************执行通讯协议解析 end************************/
/*********************tft显示屏 显示************************/
myGLCD.setColor(0, 255, 0);
myGLCD.setBackColor(0, 0, 0);
myGLCD.setFont(SevenSegNumFont);
myGLCD.print("0123456789", CENTER, 20,0); //Print函数参数,显示字符串,位置xy,角度
/*********************tft显示屏 换行显示 使用ASC编码每行显示5个字符************************/
if(bufferBytes>5){
//Serial.println(data);
dataA=data.substring(0,15);
//Serial.println(dataA);
dataB=data.substring(15,30);
//Serial.println(dataB);
myGLCD.print(dataA, 0, 80);
myGLCD.print(dataB, 0, 140);
}
else {
myGLCD.print(data, 0, 80,0);
}
/*********************tft显示屏 换行显示 end************************/
/*********************tft显示屏 换行显示 使用ASC编码每行显示10个字符************************/
myGLCD.setFont(BigFont);
for(int i=0;i<7;i++){ //将指令按照字节单位循环读取并赋值给字符数组Receive_Data
Senddata+=Send_Data[i];
Senddata+=' ';
delay(2);
}
if(bufferBytes>12){
myGLCD.print(Senddata.substring(0,30), 0, 210);
myGLCD.print(Senddata.substring(30,60), 0, 230);
}
else {
myGLCD.print(Senddata, 0, 210);
}
/*********************tft显示屏 换行显示 end************************/
myGLCD.print("TotalNum=", 0, 260);
myGLCD.print(a, 150, 260);
for(int j=0; j<2; j++){ //提取串口每个位得字
data2+=Receive_Data[j];
data2+=' ';
}
myGLCD.print(data2, 0, 280,0);
/*********************tft显示屏 显示 end************************/
}
while(Serial.read() >= 0) { //用空操作来清除缓存区中的所有数据
}
delay(200);
}
char* itostr(char *str,int i)
{
sprintf(str,"%d",i);//%x 显示成16进制 %d十进制 %o八进制
return str;
}
void command(void)
{
//缺少对收到指令的校验,通过对指令的校验,可以识别出不符合指令格式的输入指令,减少bug
uint crc_end,legg;
switch (Receive_Data[1]) {
case 0x01:
//int echo1[7] = {0x01,0x01,0x02,0x00,0x00,0xB9,0xFC};
// 位状态读取指令
Send_Data[0]=Receive_Data[0]; //站号
Send_Data[1]=Receive_Data[1]; //功能码
Send_Data[2]=0x02; //功能码0x02代表位状态显示元件
Send_Data[3]=check_Bitout(0); //低位状态,即LED开关情况
Send_Data[4]=check_Bitout(0); //高位状态
Send_Data[5]=0xB9; //校验低位 模运算,求的是余数
Send_Data[6]=0xFC; //校验高位 除运算,求的是商
send_word(Send_Data,7);
break;
case 0x03:
// 字状态读取指令
begin_address=Receive_Data[2]<<8|Receive_Data[3];
address_leg=Receive_Data[4]<<8 | Receive_Data[5]; //总寄存器长度
//hi_type=0;
Send_Data[0]=0x0C;//Receive_Data[0]; //站号
Send_Data[1]=0x01;//Receive_Data[1]; //功能码
legg=(uint)address_leg*2; //字节数
Send_Data[2]=0x02;//address_leg*2; //字节数
for(time=0;time<legg;time++) //发送相应字节
{
if(!(time%2)) //字高位为0
Send_Data[time+3] =0x00;//disp[time/2+begin_address]/256; //字高字节
else
Send_Data[time+3] =0x00;//disp[time/2+begin_address]%256; //字低字节
}
//crc_end=crc16(Send_buf,legg+3); //校验
Send_Data[legg+3]=0x94;//crc_end%256; //校验低位
Send_Data[legg+4]=0x3D;//crc_end/256; //校验高位
send_word(Send_Data,legg+5); //返回屏
break;
case 0x05:
begin_address=Receive_Data[3];
if(Receive_Data[4]==0xff){ //当为强制打开时,可以通过配置Receive_Data[2],增加到16个继电器位控制
switch(begin_address){ //对应的地址
case 0x00: digitalWrite(PD0, HIGH); break; //相应的LED点亮,记录下相应的P0位状态
case 0x01: digitalWrite(PD1, HIGH); break;
case 0x02: digitalWrite(PD2, HIGH); break;
case 0x03: digitalWrite(PD3, HIGH); break;
case 0x04: digitalWrite(PD4, HIGH); break;
case 0x05: digitalWrite(PD5, HIGH); break;
case 0x06: digitalWrite(PD6, HIGH); break;
case 0x07: digitalWrite(PD7, HIGH); break;
}
}
else //当强制为OFF时
{
// flag_led=0;
switch(begin_address){
case 0x00: digitalWrite(PD0, LOW); break; //相应的LED熄灭,记录下相应的P0位状态
case 0x01: digitalWrite(PD1, LOW); break;
case 0x02: digitalWrite(PD2, LOW); break;
case 0x03: digitalWrite(PD3, LOW); break;
case 0x04: digitalWrite(PD4, LOW); break;
case 0x05: digitalWrite(PD5, LOW); break;
case 0x06: digitalWrite(PD6, LOW); break;
case 0x07: digitalWrite(PD7, LOW); break;
}
}
Send_Data[0]=Receive_Data[0]; //站号
Send_Data[1]=Receive_Data[1]; //功能码
Send_Data[2]=Receive_Data[2]; //起始高位
Send_Data[3]=Receive_Data[3]; //起始低位
Send_Data[4]=Receive_Data[4]; //返回状态
Send_Data[5]=Receive_Data[5]; //返回状态
//crc_end=crc16(Send_buf,6); //校验
Send_Data[6]=Receive_Data[6];//crc_end%256; //校验低位
Send_Data[7]=Receive_Data[7];//crc_end/256; //校验高位
send_word(Send_Data,8); //发送返回屏
break;
case 0x06:
// do something
digitalWrite(PD0, LOW);
digitalWrite(PD7, LOW);
break;
default:
// do something
Serial.print("no OUTPUT");
}
}
//////////数码管显示函数,最多显示五位数,数值仅限于0-9,该函数根据实际情况选择使用////////////////
void Display(uint Num)
{
uint i;
for (i=0;i<5; i++)
{
//P2 = 0; //清除显示,防止数字重影
//P0 = DuanMa[Num%10]; //显示最低一位数
delay(10);
//P2 = 0x80>>i; //显示第一位数时点亮第一个数码管,第二位时点亮第二个数码管,以此类推。
Num = Num/10; //将变量除以10处理将显示下一位数
delay(1);
}
}
/**************************数码管显示相关,DuanMa是显示0-9*****************************/
uchar DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9
/**********************检查位状态函数,并返回int数值类型***********************/
/*************************hl表示查询低位1或者高位2**默认返回0******************/
int check_Bitout(int hl)
{
char hi_type,low_type;
switch (hl) {
case 1:
// do something
low_type=digitalRead(PD0);
low_type=low_type | digitalRead(PD1)<<1;
low_type=low_type | digitalRead(PD2)<<2;
low_type=low_type | digitalRead(PD3)<<3;
low_type=low_type | digitalRead(PD4)<<4;
low_type=low_type | digitalRead(PD5)<<5;
low_type=low_type | digitalRead(PD6)<<6;
low_type=low_type | digitalRead(PD7)<<7;
return low_type;
break;
case 2:
// do something
hi_type=digitalRead(PC0);
hi_type=hi_type | digitalRead(PC1)<<1;
hi_type=hi_type | digitalRead(PC2)<<2;
hi_type=hi_type | digitalRead(PC3)<<3;
hi_type=hi_type | digitalRead(PC4)<<4;
hi_type=hi_type | digitalRead(PC5)<<5;
hi_type=hi_type | digitalRead(PC6)<<6;
hi_type=hi_type | digitalRead(PC7)<<7;
return hi_type;
break;
default:
// do something
return 0;
}
}
/**********************发送函数***********************/
/***********发送字符串或者一连串的字节数据************/
/****mydata表示要发送的字符串数组,num表示数组长度****/
void send_word(uchar *mydata,uchar num)
{
int i;
for(i=0;i<num;i++)
{
Serial.write(*(mydata+i));
}
//count=0;
} |