- 打卡等级:初来乍到
- 打卡总天数:1
- 最近打卡:2025-03-17 16:39:04
中级会员
- 积分
- 253
|
#include <STC8F2K08S2.H>
#include "intrins.h"
#define uchar unsigned char//宏定义无符号字符型
#define uint unsigned int //宏定义无符号整型
bit flagOnceTxd = 0; //单次发送完成标志,即发送完一个字节
bit cmdArrived = 0; //命令到达标志,即接收到上位机下发的命令
unsigned char cntRxd = 0;
unsigned char pdata bufRxd[40]; //串口接收缓冲区
unsigned char len;
xdata unsigned char buf[50];
sbit IN_1 = P1^7;
sbit IN_2 = P1^6;
sbit IN_3 = P1^5;
sbit IN_4 = P1^4;
sbit IN_5 = P1^3;
sbit IN_6 = P1^2;
sbit IN_7 = P0^3;
sbit IN_8 = P0^2;
sbit set_1 = P2^0;
sbit set_2 = P2^1;
sbit set_3 = P2^2;
sbit set_4 = P2^3;
sbit set_5 = P2^4;
sbit set_6 = P2^5;
sbit set_7 = P2^6;
sbit set_8 = P2^7;
sbit btv_1 = P3^2;
sbit btv_2 = P3^3;
bit kk=0,aj_1=0,aj_2=0,aj_3=0,aj_4=0,aj_5=0,aj_6=0,aj_7=0,aj_8=0;
bit biao_1=0,biao_2=0,biao_3=0,biao_4=0,biao_5=0,biao_6=0,biao_7=0,biao_8=0;
bit bb_1=0,bb_2=0,bb_3=0,bb_4=0;
uint ss=0x00,xx_1=0x00,xx_2=0x00,xx_3=0x00,xx_4=0x00,xx_5=0x00,xx_6=0x00,xx_7=0x00,xx_8=0x00,zz=0x00;
uchar dz_1=0x00,dz_2=0x00,dz_3=0x00,dz_4=0x00,dz_5=0x00,dz_6=0x00,dz_7=0x00,dz_8=0x00;
uchar l_1=0,h_1=0,hz=0x00,lz=0x00;
unsigned int GetCRC16(unsigned char *ptr, unsigned char len);
unsigned int crc;
unsigned char crch, crcl;
unsigned int T0RH=0,T0RL=0;
uchar i=0,cnt=0;
uchar ys=100;
uchar add1=0;
/********************************************************************
延时函数
*********************************************************************/
void delay(uchar t)
{
uchar i,j;
for(i=0;i<t;i++)
{
for(j=130;j>0;j--);
{ ;
}
}
}
void ConfigUART() //串口配置函数,baud为波特率
{
SCON = 0x50; //8位数据,可变波特率
S2CON = 0x50;
AUXR |= 0x01; //串口1选择定时器2为波特率发生器
AUXR |= 0x04; //定时器2时钟为Fosc,即1T
T2L = lz; //设定定时初值 默认9600
T2H = hz; //设定定时初值
AUXR |= 0x10; //启动定时器2
ES = 1; //使能串口中断
IE2 = ES2;
}
unsigned char UartRead(unsigned char *buf, unsigned char len) //串口数据读取函数,数据接收指针buf,读取数据长度len,返回值为实际读取到的数据长度
{
unsigned char i=0;
uchar bz=0;
if (len > cntRxd) //读取长度大于接收到的数据长度时,
{
len = cntRxd; //读取长度设置为实际接收到的数据长度
}
for (i=0; i<len; i++) //拷贝接收到的数据
{
*buf = bufRxd[ i];
buf++;
}
for(bz=i;bz>0;bz--)
{
bufRxd[bz] = 0;
}
cntRxd = 0; //清零接收计数器
return len; //返回实际读取长度
}
void UartWrite(unsigned char *buf, unsigned char len) //串口数据写入函数,即串口发送函数,待发送数据指针buf,数据长度len
{
while (len--) //发送数据
{
flagOnceTxd = 0;
SBUF = *buf;
S2BUF = *buf;
buf++;
while (!flagOnceTxd);
}
}
void UartDriver() //串口驱动函数,检测接收到的命令并执行相应动作
{
if (cmdArrived) //有命令到达时,读取处理该命令
{
cmdArrived = 0;
len = UartRead(buf, sizeof(buf)); //将接收到的命令读取到缓冲区中
if (buf[1] == ss) //核对地址以决定是否响应命令,本例本机地址为0x00
{
// crc = GetCRC16(buf, len-2); //计算CRC校验值
// crch = crc >> 8;
// crcl = crc & 0xFF;
// if ((buf[len-2] == crch) && (buf[len-1] == crcl)) //判断CRC校验是否正确
// {
switch (buf[2]) //按功能码执行操作
{
case 0x08: //查询输入状态
if ((buf[0] == 0xAA)&&(buf[5] == 0xBB)) //查询1号继电器以后的继电器状态
{
// if((buf[4] == 0x00)&&(buf[5] == 0x03))
// {
if(IN_1 == 0){xx_1 = 0x01;}else{xx_1 = 0;}//查询输入状态打开为1,关闭为0,没有的以0填充
if(IN_2 == 0){xx_2 = 0x02;}else{xx_2 = 0;}//查询输入状态打开为1,关闭为0,没有的以0填充
if(IN_3 == 0){xx_3 = 0x04;}else{xx_3 = 0;}//查询输入状态打开为1,关闭为0,没有的以0填充
if(IN_4 == 0){xx_4 = 0x08;}else{xx_4 = 0;}//查询输入状态打开为1,关闭为0,没有的以0填充
if(IN_5 == 0){xx_5 = 0x10;}else{xx_5 = 0;}//查询输入状态打开为1,关闭为0,没有的以0填充
if(IN_6 == 0){xx_6 = 0x20;}else{xx_6 = 0;}//查询输入状态打开为1,关闭为0,没有的以0填充
if(IN_7 == 0){xx_7 = 0x40;}else{xx_7 = 0;}//查询输入状态打开为1,关闭为0,没有的以0填充
if(IN_8 == 0){xx_8 = 0x80;}else{xx_8 = 0;}//查询输入状态打开为1,关闭为0,没有的以0填充
zz = ((xx_1)|(xx_2)|(xx_3)|(xx_4)|(xx_5)|(xx_6)|(xx_7)|(xx_8)); //输入状态
buf[0]=0xAA; //报头
buf[1]=ss; //地址码码
buf[2]=0x09; //功能码
buf[3]=0x00; //通道码
buf[4]=zz; //状态码
buf[5]=0xBB; //报尾
len=6;
} break;
}
UartWrite(buf, len);
}
}
}
void UartRxMonitor(unsigned char ms) //串口接收监控函数
{
static unsigned char cntbkp = 0;
static unsigned char idletmr = 0;
if (cntRxd > 0) //接收计数器大于零时,监控总线空闲时间
{
if (cntbkp != cntRxd) //接收计数器改变,即刚接收到数据时,清零空闲计时
{
cntbkp = cntRxd;
idletmr = 0;
}
else
{
if (idletmr < 6) //接收计数器未改变,即总线空闲时,累积空闲时间
{
idletmr += ms;
if (idletmr >= 6) //空闲时间超过4个字节传输时间即认为一帧命令接收完毕
{
cmdArrived = 1; //设置命令到达标志
}
}
}
}
else
{
cntbkp = 0;
}
}
void InterruptUART() interrupt 4 //UART中断服务函数
{
if (RI) //接收到字节
{
RI = 0; //手动清零接收中断标志位
if (cntRxd < sizeof(bufRxd)) //接收缓冲区尚未用完时,
{
bufRxd[cntRxd++] = SBUF; //保存接收字节,并递增计数器
// bufRxd[cntRxd++] = S2BUF;
}
}
if (TI) //字节发送完毕
{
TI = 0; //手动清零发送中断标志位
flagOnceTxd = 1; //设置单次发送完成标志
}
}
void InterruptUART2() interrupt 8 //UART中断服务函数
{
if( S2CON & 0x01 )
{
S2CON &= ~0x01;
if (cntRxd < sizeof(bufRxd)) //接收缓冲区尚未用完时,
{
bufRxd[cntRxd++] = S2BUF;
}
}
if( S2CON & 0x02 )
{
S2CON &= ~0x02;
flagOnceTxd = 1; //设置单次发送完成标志
}
}
void ConfigTimer0(unsigned int ms) //T0配置函数
{
unsigned long tmp; //临时变量
tmp = 11059200 / 12; //定时器计数频率
tmp = (tmp * ms) / 1000; //计算所需的计数值
tmp = 65536 - tmp; //计算定时器重载值
tmp = tmp + 33; //补偿中断响应延时造成的误差
T0RH = (unsigned char)(tmp>>8); //定时器重载值拆分为高低字节
T0RL = (unsigned char)tmp;
TMOD &= 0xF0; //清零T0的控制位
TMOD |= 0x01; //配置T0为模式1
TH0 = T0RH; //加载T0重载值
TL0 = T0RL;
ET0 = 1; //使能T0中断
TR0 = 1; //启动T0
}
void qmhs()//取码函数
{
if(IN_1 == 0){xx_1 = 0x01;}else{xx_1 = 0;}//查询输入状态打开为1,关闭为0,没有的以0填充
if(IN_2 == 0){xx_2 = 0x02;}else{xx_2 = 0;}//查询输入状态打开为1,关闭为0,没有的以0填充
if(IN_3 == 0){xx_3 = 0x04;}else{xx_3 = 0;}//查询输入状态打开为1,关闭为0,没有的以0填充
if(IN_4 == 0){xx_4 = 0x08;}else{xx_4 = 0;}//查询输入状态打开为1,关闭为0,没有的以0填充
if(IN_5 == 0){xx_5 = 0x10;}else{xx_5 = 0;}//查询输入状态打开为1,关闭为0,没有的以0填充
if(IN_6 == 0){xx_6 = 0x20;}else{xx_6 = 0;}//查询输入状态打开为1,关闭为0,没有的以0填充
if(IN_7 == 0){xx_7 = 0x40;}else{xx_7 = 0;}//查询输入状态打开为1,关闭为0,没有的以0填充
if(IN_8 == 0){xx_8 = 0x80;}else{xx_8 = 0;}//查询输入状态打开为1,关闭为0,没有的以0填充
zz = ((xx_1)|(xx_2)|(xx_3)|(xx_4)|(xx_5)|(xx_6)|(xx_7)|(xx_8)); //输入状态
}
void main ()
{
hz=0xFE;lz=0xE0; //9600
// hz=0xFB;lz=0x80; //2400
// hz=0xFD;lz=0xC0; //4800
// hz=0xFF;lz=0xE8; //115200
EA = 1; //开总中断
ConfigTimer0(1); //配置T0定时1ms
ConfigUART(); //配置波特率为9600
while(1)
{
if((btv_1 == 0)&&(btv_2 == 0)&&(bb_1 == 0)){hz=0xFF;lz=0xE8;bb_1=1;bb_2=0;bb_3=0;bb_4=0;ConfigUART();} //波特率设置两个拨码开关拨上去115200
if((btv_1 == 0)&&(btv_2 == 1)&&(bb_2 == 0)){hz=0xFF;lz=0xB8;bb_1=0;bb_2=1;bb_3=0;bb_4=0;ConfigUART();} //波特率设置38400
if((btv_1 == 1)&&(btv_2 == 0)&&(bb_3 == 0)){hz=0xFF;lz=0x70;bb_1=0;bb_2=0;bb_3=1;bb_4=0;ConfigUART();} //波特率设置19200
if((btv_1 == 1)&&(btv_2 == 1)&&(bb_4 == 0)){hz=0xFE;lz=0xE0;bb_1=0;bb_2=0;bb_3=0;bb_4=1;ConfigUART();} //波特率设置都不拨 9600
if(set_1==0){dz_1=0x01;kk=1;aj_1=1;}else{aj_1=0;dz_1=0x00;}//拨码开关拨上去后无法设置地址
if(set_2==0){dz_2=0x02;kk=1;aj_2=1;}else{aj_2=0;dz_2=0x00;}
if(set_3==0){dz_3=0x04;kk=1;aj_3=1;}else{aj_3=0;dz_3=0x00;}
if(set_4==0){dz_4=0x08;kk=1;aj_4=1;}else{aj_4=0;dz_4=0x00;}
if(set_5==0){dz_5=0x10;kk=1;aj_5=1;}else{aj_5=0;dz_5=0x00;}
if(set_6==0){dz_6=0x20;kk=1;aj_6=1;}else{aj_6=0;dz_6=0x00;}
if(set_7==0){dz_7=0x40;kk=1;aj_7=1;}else{aj_7=0;dz_7=0x00;}
if(set_8==0){dz_8=0x80;kk=1;aj_8=1;}else{aj_8=0;dz_8=0x00;}
ss=((dz_1)|(dz_2)|(dz_3)|(dz_4)|(dz_5)|(dz_6)|(dz_7)|(dz_8));//地址为 16进制所以地址为10时应对应16进制0A,11对应0B,
if((aj_1==0)&&(aj_2==0)&&(aj_3==0)&&(aj_4==0)&&(aj_5==0)&&(aj_6==0)&&(aj_7==0)&&(aj_8==0)){kk=0;}//kk设置地址标志位
if((IN_1==0)&&(biao_1==0)) //1号输入接通
{
delay(ys);if((IN_1==0)&&(biao_1==0))
{
biao_1=1;qmhs();
buf[0]=0xAA; //报头
buf[1]=ss; //地址码码
buf[2]=0x09; //功能码
buf[3]=0x00; //通道码
// buf[4]=0xff; //状态码
buf[4]=zz; //状态码
buf[5]=0xBB; //报尾
len=6;
// crc = GetCRC16(buf, len); //计算CRC校验值
// buf[len++] = crc >> 8; //CRC高字节
// buf[len++] = crc & 0xFF; //CRC低字节
UartWrite(buf, len);
}}
if((IN_1==1)&&(biao_1==1)) //1号输入断开
{
delay(ys);if((IN_1==1)&&(biao_1==1))
{
biao_1=0;qmhs();
buf[0]=0xAA; //报头
buf[1]=ss; //地址码码
buf[2]=0x09; //功能码
buf[3]=0x00; //通道码
// buf[4]=0xff; //状态码
buf[4]=zz; //状态码
buf[5]=0xBB; //报尾
len=6;
// crc = GetCRC16(buf, len); //计算CRC校验值
// buf[len++] = crc >> 8; //CRC高字节
// buf[len++] = crc & 0xFF; //CRC低字节
UartWrite(buf, len);
}}
// if(IN_1==1){biao_1=0;} //断开恢复标志位
if((IN_2==0)&&(biao_2==0)) //2号输入接通
{
delay(ys);if((IN_2==0)&&(biao_2==0))
{
biao_2=1;qmhs();
buf[0]=0xAA; //报头
buf[1]=ss; //地址码码
buf[2]=0x09; //功能码
buf[3]=0x00; //通道码
// buf[4]=0xff; //状态码
buf[4]=zz; //状态码
buf[5]=0xBB; //报尾
len=6;
UartWrite(buf, len);
}}
if((IN_2==1)&&(biao_2==1)) //2号输入断开
{
delay(ys);if((IN_2==1)&&(biao_2==1))
{
biao_2=0;qmhs();
buf[0]=0xAA; //报头
buf[1]=ss; //地址码码
buf[2]=0x09; //功能码
buf[3]=0x00; //通道码
// buf[4]=0xff; //状态码
buf[4]=zz; //状态码
buf[5]=0xBB; //报尾
len=6;
UartWrite(buf, len);
}}
if((IN_3==0)&&(biao_3==0)) //3号输入接通
{
delay(ys);if((IN_3==0)&&(biao_3==0))
{
biao_3=1;qmhs();
buf[0]=0xAA; //报头
buf[1]=ss; //地址码码
buf[2]=0x09; //功能码
buf[3]=0x00; //通道码
// buf[4]=0xff; //状态码
buf[4]=zz; //状态码
buf[5]=0xBB; //报尾
len=6;
UartWrite(buf, len);
}}
if((IN_3==1)&&(biao_3==1)) //3号输入断开
{
delay(ys);if((IN_3==1)&&(biao_3==1))
{
biao_3=0;qmhs();
buf[0]=0xAA; //报头
buf[1]=ss; //地址码码
buf[2]=0x09; //功能码
buf[3]=0x00; //通道码
// buf[4]=0xff; //状态码
buf[4]=zz; //状态码
buf[5]=0xBB; //报尾
len=6;
UartWrite(buf, len);
}}
if((IN_4==0)&&(biao_4==0)) //4号输入接通
{
delay(ys);if((IN_4==0)&&(biao_4==0))
{
biao_4=1;qmhs();
buf[0]=0xAA; //报头
buf[1]=ss; //地址码码
buf[2]=0x09; //功能码
buf[3]=0x00; //通道码
// buf[4]=0xff; //状态码
buf[4]=zz; //状态码
buf[5]=0xBB; //报尾
len=6;
UartWrite(buf, len);
}}
if((IN_4==1)&&(biao_4==1)) //4号输入断开
{
delay(ys);if((IN_4==1)&&(biao_4==1))
{
biao_4=0;qmhs();
buf[0]=0xAA; //报头
buf[1]=ss; //地址码码
buf[2]=0x09; //功能码
buf[3]=0x00; //通道码
// buf[4]=0xff; //状态码
buf[4]=zz; //状态码
buf[5]=0xBB; //报尾
len=6;
UartWrite(buf, len);
}}
if((IN_5==0)&&(biao_5==0)) //5号输入接通
{
delay(ys);if((IN_5==0)&&(biao_5==0))
{
biao_5=1;qmhs();
buf[0]=0xAA; //报头
buf[1]=ss; //地址码码
buf[2]=0x09; //功能码
buf[3]=0x00; //通道码
// buf[4]=0xff; //状态码
buf[4]=zz; //状态码
buf[5]=0xBB; //报尾
len=6;
UartWrite(buf, len);
}}
if((IN_5==1)&&(biao_5==1)) //5号输入断开
{
delay(ys);if((IN_5==1)&&(biao_5==1))
{
biao_5=0;qmhs();
buf[0]=0xAA; //报头
buf[1]=ss; //地址码码
buf[2]=0x09; //功能码
buf[3]=0x00; //通道码
// buf[4]=0xff; //状态码
buf[4]=zz; //状态码
buf[5]=0xBB; //报尾
len=6;
UartWrite(buf, len);
}}
if((IN_6==0)&&(biao_6==0)) //6号输入接通
{
delay(ys);if((IN_6==0)&&(biao_6==0))
{
biao_6=1;qmhs();
buf[0]=0xAA; //报头
buf[1]=ss; //地址码码
buf[2]=0x09; //功能码
buf[3]=0x00; //通道码
// buf[4]=0xff; //状态码
buf[4]=zz; //状态码
buf[5]=0xBB; //报尾
len=6;
UartWrite(buf, len);
}}
if((IN_6==1)&&(biao_6==1)) //6号输入断开
{
delay(ys);if((IN_6==1)&&(biao_6==1))
{
biao_6=0;qmhs();
buf[0]=0xAA; //报头
buf[1]=ss; //地址码码
buf[2]=0x09; //功能码
buf[3]=0x00; //通道码
// buf[4]=0xff; //状态码
buf[4]=zz; //状态码
buf[5]=0xBB; //报尾
len=6;
UartWrite(buf, len);
}}
if((IN_7==0)&&(biao_7==0)) //7号输入接通
{
delay(ys);if((IN_7==0)&&(biao_7==0))
{
biao_7=1;qmhs();
buf[0]=0xAA; //报头
buf[1]=ss; //地址码码
buf[2]=0x09; //功能码
buf[3]=0x00; //通道码
// buf[4]=0xff; //状态码
buf[4]=zz; //状态码
buf[5]=0xBB; //报尾
len=6;
UartWrite(buf, len);
}}
if((IN_7==1)&&(biao_7==1)) //7号输入断开
{
delay(ys);if((IN_7==1)&&(biao_7==1))
{
biao_7=0;qmhs();
buf[0]=0xAA; //报头
buf[1]=ss; //地址码码
buf[2]=0x09; //功能码
buf[3]=0x00; //通道码
// buf[4]=0xff; //状态码
buf[4]=zz; //状态码
buf[5]=0xBB; //报尾
len=6;
UartWrite(buf, len);
}}
if((IN_8==0)&&(biao_8==0)) //8号输入接通
{
delay(ys);if((IN_8==0)&&(biao_8==0))
{
biao_8=1;qmhs();
buf[0]=0xAA; //报头
buf[1]=ss; //地址码码
buf[2]=0x09; //功能码
buf[3]=0x00; //通道码
// buf[4]=0xff; //状态码
buf[4]=zz; //状态码
buf[5]=0xBB; //报尾
len=6;
UartWrite(buf, len);
}}
if((IN_8==1)&&(biao_8==1)) //8号输入断开
{
delay(ys);if((IN_8==1)&&(biao_8==1))
{
biao_8=0;qmhs();
buf[0]=0xAA; //报头
buf[1]=ss; //地址码码
buf[2]=0x09; //功能码
buf[3]=0x00; //通道码
// buf[4]=0xff; //状态码
buf[4]=zz; //状态码
buf[5]=0xBB; //报尾
len=6;
UartWrite(buf, len);
}}
UartDriver();
}
}
void InterruptTimer0() interrupt 1 //T0中断服务函数
{
TH0 = T0RH; //定时器重新加载重载值
TL0 = T0RL;
UartRxMonitor(1); //串口接收监控
}
|
|