#include<reg52.h>
#include"DS18B20.h"
#include"lcd.h"//
#include"temp.h"
#define uchar unsigned char
#define uint unsigned int
#define MyAddr 0x01//定义地址
#define Start 0x40 //字头
#define End 0x0d //字尾
#define Read 0x00 //上位机读
#define Write 0x01//上位机写
uchar data dat[30]={1,2,3,4,5,6,7,8,0,0,25,0,2,3,4,0,0};//中间数据缓存
uchar xdata recbuf[22];//接收数据数组 最长为浮点数22个
uchar xdata sendbuf[10]={0x40,0x30,0x31,0x30,0x31,0,0,0,0,0x0d};//单片机发送 组态王读取速度
uchar xdata Answer[8]={0x40,0x30,0x31,0,0,0,0,0x0d};//下位机应答信息帧数组
uchar count=0;//接收字头字尾间数据个数
uchar flag=0;//单片机接收到字头标志
uchar send_temp;
uchar CNCHAR[6] = "摄氏度";//
void LcdDisplay(int);
void UsartConfiguration();
bit time_1s_ok;
bit time_2s_ok;
bit time_50ms_ok;
bit recok=0;//消息帧接收结束
bit startrec=0;//开始接受消息帧
sbit P0_0=P0^0;
int SV,SV3;
unsigned char t=0;
char control=0;
unsigned char flag_p=0,flag2=0;
sbit motor1=P3^6;
sbit motor2=P3^7;
sbit jiare=P0^0;
sbit ceshi=P0^5;
sbit BL=P1^5;
bit kaiguan=0;
char error=0,errorl=0,errorll=0;
uchar kp=3,ki=2,kd=1;
int mv,lmn=0;
int error_I; //存积分累加值
int i_lmn=0;
uchar fenli;
uchar dead=0;
//初始化
void serial_init()
{
SCON=0x50;// 方式1 波特率可变 8位 接受使能
TMOD=0x21;//定时器1 模式2 8 位自动重装 定时器0 16位定时器
TH1=0xfd;
TL1=0xfd;//波特率9600 11.0592MHz
TR1=1;
TL0=0x00;
TH0=0x4c;
TR0=1;
ET0=1;
PS=1; //串口中断优先级最高
EA=1;
ES=1;
SM2=1;//从机模式 接收到停止位后接收中断才置1
}
void dingshi() interrupt 1
{
uchar t;
uchar time2s;
TL0=0x00; //50MS
TH0=0x4c;
t++;
time_50ms_ok=1;
if(t==20)
{
t=0;
time_1s_ok=1;
}
if(time2s++==40)
{
time2s=0;
time_2s_ok=1;
}
}
//串行口接收中断
void recive() interrupt 4
{
uchar sbuf;
sbuf=SBUF;
recok=0;
if(!flag)
if(sbuf==Start) //检查接收的是否是字头
flag=1;
if(flag==1) //接收为字头
{
recbuf[count]=sbuf;
count++;
if(sbuf==End) //检查接收的为字尾
{
recok=1;
count=0;
flag=0;
}
}
RI=0;
}
//通过串行口发送数据
void uartsends(uchar buff[],uchar len)
{
uchar i;
for(i=0;i<len;i++)
{
SBUF=buff[i];
while(!TI);
TI=0;
}
}
//上位机标志 判断上位机发送来的指令是读/写 打包 字节 字 浮点数 本处均为字节
uchar read_write_flag()
{
uchar temp;
temp=recbuf[4]&0x01;
return temp;
}
//数据转换
uchar Dat_trans(uchar hight_v,uchar low_v)
{
uchar value,hight,low;//定义临时变量
if(hight_v>0x40)
hight=(hight_v-0x37)&0x0f;
else
hight=(hight_v-0x30)&0x0f;
if(low_v>0x40)
low=(low_v-0x37)&0x0f;
else
low=(low_v-0x30)&0x0f;
value=(hight<<4)+low;
return value;
}
//上位机写指令的应答
void write_inform(uchar dat)
{
uchar xordat;//异或值
uchar i,ctmp1,ctmp2;
Answer[3]=dat;Answer[4]=dat;
xordat=0;
for(i=1;i<3;i++)//i=1 2 3 4
{
xordat^=Answer[i];
}
send_temp=xordat;
ctmp1=(send_temp>>4)&0x0f;
ctmp2=send_temp&0x0f;
if(ctmp1>9)
Answer[5]=ctmp1+0x37;
else
Answer[5]=ctmp1+0x30;
if(ctmp2>9)
Answer[6]=ctmp2+0x37;
else
Answer[6]=ctmp2+0x30;
uartsends(Answer,8);
}
//上位机为读指令时的应答
void Read_byte1()
{
uchar ctmp1,ctmp2,xordat,i;
send_temp=dat[Dat_trans(recbuf[7],recbuf[8])]; //由地址寻址数据
ctmp1=(send_temp>>4)&0x0f;
ctmp2=send_temp&0x0f;
if(ctmp1>9)
sendbuf[5]=ctmp1+0x37;
else
sendbuf[5]=ctmp1+0x30;
if(ctmp2>9)
sendbuf[6]=ctmp2+0x37;
else
sendbuf[6]=ctmp2+0x30;
xordat=0;
for(i=1;i<7;i++)
{
xordat^=sendbuf[i];
}
send_temp=xordat;
ctmp1=(send_temp>>4)&0x0f;
ctmp2=send_temp&0x0f;
if(ctmp1>9)
sendbuf[7]=ctmp1+0x37;
else
sendbuf[7]=ctmp1+0x30;
if(ctmp2>9)
sendbuf[8]=ctmp2+0x37;
else
sendbuf[8]=ctmp2+0x30;
uartsends(sendbuf,10);
}
//j检验上位机CRC
bit check_CRC()
{
uchar xordat,i,ctmp1,ctmp2,temp;
if(read_write_flag()==Read)
{
temp=11;//读数据时需要异或的位时10位
}
if(read_write_flag()==Write)
{
temp=13;
}
xordat=0;
for(i=1;i<temp;i++)
xordat^=recbuf[i];
ctmp1=(xordat>>4)&0x0f;
ctmp2=xordat&0x0f;
if(ctmp1>9)
ctmp1=ctmp1+0x37;
else
ctmp1=ctmp1+0x30;
if(ctmp2>9)
ctmp2=ctmp2+0x37;
else
ctmp2=ctmp2+0x30;
if((ctmp1==recbuf[temp])&&(ctmp2==recbuf[temp+1]))
return 1;
else
return 0;
}
//上位机写字节
void Write_byte()
{
uchar temp;
temp=Dat_trans(recbuf[11],recbuf[12]); //数据
dat[Dat_trans(recbuf[7],recbuf[8])]=temp; //将此数据放到此地址中
write_inform('#');
}
void weizhi_PID() //位置式
{
errorll=errorl;
error=(SV*10-(wendu*10+display[0])+5)/10;
if(error>(0-dead)&&error<dead)
error=0;
error_I=(error+errorl)/2;
i_lmn+=error_I;
if(error>fenli||error<(0-fenli))
{
i_lmn =0;
}
mv=kp*error+ki*i_lmn+kd*(error-errorl);
lmn=mv;
errorl=error;
if(lmn>=100)lmn=100;
if(lmn<=-100)lmn=-100;
}
//显示部分
/*******************************************************************************
* 函数名 : LcdDisplay()
* 函数功能 : LCD显示读取到的温度
* 输入 : v
* 输出 : 无
*******************************************************************************/
void LcdDisplay(int temp) //lcd显示
{
unsigned char i, datas[] = {0, 0, 0, 0, 0}; //定义数组
float tp;
if(temp< 0) //当温度值为负数
{
LcdWriteCom(0x80); //写地址 80表示初始地址
SBUF='-';//将接收到的数据放入到发送寄存器
while(!TI); //等待发送数据完成
TI=0; //清除发送完成标志位
LcdWriteData('-'); //显示负
//因为读取的温度是实际温度的补码,所以减1,再取反求出原码
temp=temp-1;
temp=~temp;
tp=temp;
temp=tp*0.0625*100+0.5;
//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
//算由?.5,还是在小数点后面。
}
else
{
LcdWriteCom(0x80); //写地址 80表示初始地址
LcdWriteData('+'); //显示正
SBUF='+';//将接收到的数据放入到发送寄存器
while(!TI); //等待发送数据完成
TI=0; //清除发送完成标志位
tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
//如果温度是正的那么,那么正数的原码就是补码它本身
temp=tp*0.0625*100+0.5;
//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
//算加上0.5,还是在小数点后面。
}
datas[0] = temp / 10000;
datas[1] = temp % 10000 / 1000;
datas[2] = temp % 1000 / 100;
datas[3] = temp % 100 / 10;
datas[4] = temp % 10;
LcdWriteCom(0x82); //写地址 80表示初始地址
LcdWriteData('0'+datas[0]); //百位
SBUF = '0'+datas[0];//将接收到的数据放入到发送寄存器
while (!TI); //等待发送数据完成
TI = 0;
LcdWriteCom(0x83); //写地址 80表示初始地址
LcdWriteData('0'+datas[1]); //十位
SBUF = '0'+datas[1];//将接收到的数据放入到发送寄存器
while (!TI); //等待发送数据完成
TI = 0;
LcdWriteCom(0x84); //写地址 80表示初始地址
LcdWriteData('0'+datas[2]); //个位
SBUF = '0'+datas[2];//将接收到的数据放入到发送寄存器
while (!TI); //等待发送数据完成
TI = 0;
LcdWriteCom(0x85); //写地址 80表示初始地址
LcdWriteData('.'); //显示 ‘.’
SBUF = '.';//将接收到的数据放入到发送寄存器
while (!TI); //等待发送数据完成
TI = 0;
LcdWriteCom(0x86); //写地址 80表示初始地址
LcdWriteData('0'+datas[3]); //显示小数点
SBUF = '0'+datas[3];//将接收到的数据放入到发送寄存器
while (!TI); //等待发送数据完成
TI = 0;
LcdWriteCom(0x87); //写地址 80表示初始地址
LcdWriteData('0'+datas[4]); //显示小数点
SBUF = '0'+datas[4];//将接收到的数据放入到发送寄存器
while (!TI); //等待发送数据完成
TI = 0;
for(i=0; i<6; i++)
{
SBUF = CNCHAR[i];//将接收到的数据放入到发送寄存器
while (!TI); //等待发送数据完成
TI = 0;
}
51单片机ASCII与组态王通讯18B20检测温度.zip_OI7_组态 单片机_组态王_组态王 单片机_组态王与ASCII
版权申诉
5星 · 超过95%的资源 117 浏览量
2022-07-14
11:12:21
上传
评论 2
收藏 94KB ZIP 举报
小波思基
- 粉丝: 69
- 资源: 1万+
评论3