2
`上位机往串口发送一个(温度)浮点数;
单片机接收到浮点数之后 把温度信号转化成PT100对应次温度下的电阻 然后乘以0.152Ma的电流 转化成一个电压信号
单片机再控制DA芯片 AD5542输出一个电压给仪器。
单片机C51程序如下:
/* ********************************
上位机需要往串口发送一个温度数据
******************************** */
#include
#include
#define uchar unsigned char
***it D_cs=P0^0;//片选信号
***it D_sclk=P0^1;//时钟信号
***it D_in=P0^2;//数据输入端
float DAT;//表示从串口读取的数据
***it dula=P2^6;
***it wela=P2^7;
uchar tt;
int dat1,num;
float vol;
float res;//温度所对应的热电阻值
//以下是编码表的定义
float code Temp2Res_table[]={
100.00,100.39,100.78,101.17,101.56,101.95,
102.34,102.73,103.12,103.51,103.90,104.29,
104.68,105.07,105.46,105.85,106.24,106.63,
107.02,107.40,107.79,108.18,108.57,108.96,
109.35,109.73,110.12,110.51,110.90,111.29,
111.67,112.06,112.45,112.83,113.22,113.61,
114.00,114.38,114.77,115.15,115.54,115.93,
116.31,116.70,117.08,117.47,117.86,118.24,
118.63,119.01,119.40,119.78,120.17,120.55,
120.94,121.32,121.71,122.09,122.47,122.86,
123.24,123.63,124.01,124.39,124.78,125.16,
125.54,125.93,126.31,126.69,127.08,127.46,
127.84,128.22,128.61,128.99,129.37,129.75,
130.13,130.52,130.90,131.28,131.66,132.04}; //0度到83度的PT100分度表
void short_delay();
void init();
int AsciiToNumerical(char hexnum);//Ascii到数值的转换 //没错
uchar SerialReadOneByte(); //没错
float SerialReadTempreture();
float date_process(float DD);//对从串口读取的温度数据进行取整4舍5入
void DAC_16bit_oper(int date);//跳变沿数据读走
int vol_to_NumerialNumber(float voltage); //电压转化为16进制数往DAC传输
void delay(uchar t);
void main()
{
// int dat1,num;
// float vol;
// float res;//温度所对应的热电阻值
init();
while(1)
{
/* REN=1;
DAT=SerialReadTempreture();
REN=0;
DAT=date_process(DAT);//4舍5入
dat1=(int)DAT;//把DAT强制转化成int型数据
res=Temp2Res_table[dat1];//某温度对应的电阻值
vol=res*(0.152);//单位mv
num=vol_to_NumerialNumber(vol);
DAC_16bit_oper(num);//完成一次向AD5542写数据的操作
*/
}
}
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
tt++;
if(tt==4)
{
tt=0;
REN=1;
DAT=SerialReadTempreture();
REN=0;
DAT=date_process(DAT);//4舍5入 //已经修改
dat1=(int)DAT;//把DAT强制转化成int型数据 //没错
res=Temp2Res_table[dat1];//某温度对应的电阻值 //没错
vol=res*(0.152);//单位mv //没错
num=vol_to_NumerialNumber(vol); //没错
// num=788;
DAC_16bit_oper(num);//完成一次向AD5542写数据的操作 //没错
}
}
void short_delay()
{
uchar i;
for(i=20;i>0;i--)
;
}
void delay(uchar t)
{
int x,y;
for(x=t;x>0;x--)
for(y=110;y>0;y--);
}
void init()
{
//T1初始化波特率发生波特率为9600 晶振频率为11.0592M
TMOD=0x21; //定时器1工作与方式2 定时器0工作与方式1
TH1=0xFD;
TL1=0xFD;
TR1=1;
//串口初始化串口工作在方式1
REN=1;
SM0=0;
SM1=1;
//定时器0装初值 54ms进入一次中断
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
/*dula wela TX-1C开发板专用其他器件这两条语句删除*/
dula=0;
wela=0;
}
int AsciiToNumerical(uchar hexnum)//Ascii到数值的转换
{
int NumericalValue;
switch (hexnum)
{
case 0x30:
NumericalValue=0;break;
case 0x31:
NumericalValue=1;break;
case 0x32:
NumericalValue=2;break;
case 0x33:
NumericalValue=3;break;
case 0x34:
NumericalValue=4;break;
case 0x35:
NumericalValue=5;break;
case 0x36:
NumericalValue=6;break;
case 0x37:
NumericalValue=7;break;
case 0x38:
NumericalValue=8;break;
case 0x39:
NumericalValue=9;break;
default:
NumericalValue=10;break;
}
return NumericalValue;
}
uchar SerialReadOneByte()
{
uchar OneByte;
while(!RI);
RI=0;
OneByte=SBUF;
return OneByte;
}
float SerialReadTempreture()
{
uchar FirstByteDate,SecondByteDate,date1,date2,date3;
/* FirstByteDate为串口读到的第一个字符ASCII码,date1,2,3为串口连续得读到0和.之后读到的3个字节 */
float ge,shi,xiaoshu,tempreture;
FirstByteDate=SerialReadOneByte();
SecondByteDate=SerialReadOneByte();
while((FirstByteDate!=0x30)||(SecondByteDate!=0x2e))
{
FirstByteDate=SerialReadOneByte();
SecondByteDate=SerialReadOneByte();
}
date1=SerialReadOneByte();//读取有效数据第一个字节
date2=SerialReadOneByte();//读取有效数据第二个字节
date3=SerialReadOneByte();//读取有效数据第三个字节
shi=AsciiToNumerical(date1);
ge=AsciiToNumerical(date2);
xiaoshu=AsciiToNumerical(date3);
tempreture=((shi*100)+(ge*10)+xiaoshu)/10.0;
while(tempreture>83.0)
{
FirstByteDate=SerialReadOneByte();
SecondByteDate=SerialReadOneByte();
while((FirstByteDate!=0x30)||(SecondByteDate!=0x2e))
{
FirstByteDate=SerialReadOneByte();
SecondByteDate=SerialReadOneByte();
}
date1=SerialReadOneByte();//读取有效数据第一个字节
date2=SerialReadOneByte();//读取有效数据第二个字节
date3=SerialReadOneByte();//读取有效数据第三个字节
shi=AsciiToNumerical(date1);
ge=AsciiToNumerical(date2);
xiaoshu=AsciiToNumerical(date3);
tempreture=((shi*100)+(ge*10)+xiaoshu)/10.0;
}
return tempreture;
}
float date_process(float DD)//对从串口读取的温度数据进行取整4舍5入
{
float z,x;//z 代表DAT整数部分,x代表DAT小数部分
z=floor(DD);//floor 表示向下取整
x=DD-z;
if(x>0.5)
{
z++;
}
else
{
;
}
return z;
}
void DAC_16bit_oper(int date)//跳变沿数据读走 0~65536
{
uchar i;
bit b;
D_cs=0;//CS片选
short_delay(); /* 51单片机的速度short_delay 可以不写*/
D_cs=1;
D_sclk=0;
short_delay();
D_sclk=1;
short_delay();
D_cs=0;
D_sclk=0;
for(i=16;i>0;i--)
{
D_sclk=0; //时钟信号
b=(date&0x8000)>>15;
D_in=b; //数据输入端
short_delay();
D_sclk=1;
short_delay();
D_sclk=0;
date=(date<<1);
}
D_cs=1;
delay(5);
}
int vol_to_NumerialNumber(float voltage) //电压转化为16进制数往DAC传输
{
float num1,zhen,xiao;
num1=voltage/0.038147; // 2500mv/65536=0.03814697265625mv
zhen=floor(num1);
xiao=num1-zhen; //
if(xiao>=0.5)
{
zhen++;
}
else
{
zhen=zhen;
}
return zhen;
}
不足之处 请各位不吝赐教
发帖不易请版主。。。。。。。。
`
|
评分
-
参与人数 1 | 威望 +3 |
+3 |
积分 +3 |
收起
理由
|
电子眼
| + 3 |
+ 3 |
+ 3 |
资源分享达人,加分鼓励! |
查看全部评分
|