📄 37.c
字号:
/*******************************************************************
**************重庆东电通信有限公司***************
文件名:SWS—3000加热软件(适用于双面加热)
版本:V3.5
编写:刘贤曙
创建日期:2006.10.7
2006.10.31调试OK
*******************************************************************/
#include<reg52.h>
#include<intrins.h>
#include<math.h>
#define uchar unsigned char
#define uint unsigned int
/********************以下是I2C通信定义******************/
uchar RCV_WD[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
uchar SEND_WD[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
#define SLVADR 0x40 //本机地址
union
{
uint I2c_STemperature;
uchar STemperature[2];
}byte;
#define TPL RCV_WD[0] //主机发来的目标温度低位--02h
#define TPH RCV_WD[1] //主机发来的目标温度高位--01h
#define FLOW RCV_WD[2] //主机发来的流量ml/min --03h
#define CWD RCV_WD[3] //主机发来的命令字- -00h
//#define RCV_WD[4] //保留
//#define RCV_WD[5] //保留
//#define RCV_WD[6] //保留
//#define RCV_WD[7] //保留
#define RTPL SEND_WD[0] //从机发送的适时温度低位--01h
#define RTPH SEND_WD[1] //从机发送的适时温度高位----00h
//#define SEND_WD[2] //保留
//#define SEND_WD[3] //保留
//#define SEND_WD[4] //保留
//#define SEND_WD[5] //保留
//#define SEND_WD[6] //保留
//#define SEND_WD[7] //保留
#define nop _nop_()
uchar reg_adr; //地址偏移量
sbit SDA = P3^5; //模拟I2C数据传送位
sbit SCL = P3^3; //模拟I2C时钟控制位
sbit K_INT = P3^4;
bit slv; //I2c数据控制状态标志位,0为发送,1为接收
bit DATOK_FLAG; //数据接收完标志
bit int1bz; //int1执行标志
/*******以下是AD转换定义************/
sbit AD7705_CLK = P1^3; //AD7705串行时钟
sbit AD7705_DIN = P1^4; //AD7705数据输入端
sbit AD7705_DOUT = P1^5; //AD7705数据输出端
sbit AD7705_DRDY = P3^2; //AD770准备好信号
sbit AD7705_REST = P1^2; //AD7705复位信号,低电平复位
sbit Door = P1^7; //AD结果和环境温度显示转换开关
/*********以下是环境温度采集及加热板温度采集定义*********/
sbit DQ = P1^6;
/**************以下是PID调节定义************/
uchar Kp; //PID调节比例系数
#define T_C 2 //采样周期
float error; //当前偏差
float last_error; //上一次偏差
float sum_error; //偏差累加和
float P_out,I_out,D_out,PWM_0; //比例项/积分项/微分项
float T_target=0.0; //目标温度
float T_real = 0.0; //当前温度
float PWM = 0; //输出量
float Ki = 0; //PID调节积分系数
float SV=0;
float Kd = 0;
#define Ti_H 50
#define Td_H 45 //PID调节微分系数
#define Ti_L 50 //积分时间常数
#define Td_L 45 //微分时间常数
uint TC_CNT = 0;
uchar TC_zhi=0; //采样周期计数器
uchar PWM_CNT= 0 ;
uchar Per = 0; //t:占空比计数器; per:输出百分比
sbit LED2 = P2^3; //加热状态?灯亮表示正在加热,灯灭表示停止加热
sbit LED3 = P2^4; //通信指示,灯亮表示正在通信
sbit PID_SW = P1^0; //加热控制执行
sbit sanre = P1^1; //散热风扇控制
bit PID_flag = 0; //PID运算允许标志
//bit sanre_flag;
bit First_flag=0;
bit End_flag=0;
bit DY_flag=0;
/**********微秒延时函数********/
void delay_US(uchar i)
{
while(i--);
}
/****************************************************
*函数原形: void Write_7705(uchar word)
*功能: 写AD7705
*参数: AD7705控制命令
*返回值:无
****************************************************/
void Write_7705(uchar Byte)
{
uchar i;
AD7705_CLK = 1;
for(i=8;i>0;i--)
{
if(Byte&0x80) AD7705_DIN = 1;
else AD7705_DIN = 0;
AD7705_CLK = 1;
nop;
AD7705_CLK = 0;
nop;
AD7705_CLK = 1;
Byte <<= 1;
}
AD7705_CLK = 1;
nop;
AD7705_DIN = 0;
}
/****************************************************
**函数原形:uint Read_7705()
**功能:读AD7705转换后数据
**参数:无
**返回值:转换结果
*****************************************************/
uint Read_7705(void)
{
uchar i,j,k=4;
uint AD_data=0x0000;
long int sum_data=0;
for(j=0;j<8;j++)
{
Write_7705(0x38);
AD7705_CLK=1;
while(AD7705_DRDY==1)
{ delay_US(100);
k-- ;
if(!k) break;
}
for(i=16;i>0;i--)
{
AD_data=AD_data<<1;
AD7705_CLK=0;
nop;
AD7705_DOUT=1;
if(AD7705_DOUT) AD_data|=0x0001;
else AD_data|=0x0000;
AD7705_CLK=1;
}
AD7705_CLK=1;
nop;
AD7705_DIN=1;
sum_data+=AD_data;
AD_data=0x0000;
}
AD_data=sum_data>>3;
return(AD_data);
}
/*******************************************************
**函数原形: void Init_7705(void)
**功能:初始化AD7705,设置为20HZ更新率、双极性、自校准、增益128
**参数:无
**返回值:无
*********************************************************/
void Init_7705(void) //初始化7705
{
uchar i;
AD7705_CLK=1;
nop;
AD7705_DIN=1;
for (i=0;i<40;i++) // AD7705复位
{
AD7705_CLK=0;
nop;
AD7705_CLK=1;
}
Write_7705(0x20); //写通信寄存器设置通道1 选择下一个操作是写时钟寄存器
Write_7705(0x04); //写时钟寄存器设置更新速率为20Hz
Write_7705(0x10); //通道1 ,下一个写设置寄存器
Write_7705(0x7a); //写设置寄存器,设置成双极性、增益为128、自校准
}
/********************************************************
**
**环境温度采集
**
**
********************************************************/
Init_DS18B20(void)
{
uchar x = 0;
DQ = 1; //DQ复位
delay_US(8);
DQ = 0; //拉低
delay_US(80); //延时 480us
DQ = 1; //拉高总线
delay_US(14); //稍延时后 如果DQ=0则初始化成功 DQ=1则初始化失败
x = DQ;
delay_US(20);
}
/*******************************************************
**函数原形:Read_byte(void )
**函数功能:读18B20一个字节
**参数:无
**返回值:读出的数据
********************************************************/
Read_byte(void )
{
uchar i = 0,dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat >>= 1;
DQ = 1; // 给脉冲信号
if(DQ)
dat |= 0x80;
delay_US(4);
}
return(dat);
}
/*******************************************************
**函数原形:void Write_byte(uchar dat)
**函数字功能:向DS18B20写入命令
**参数:命令数据
**返回值:无
********************************************************/
void Write_byte(uchar dat)
{
uchar i = 0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay_US(5);
DQ = 1;
dat >>= 1;
}
}
/*******************************************************
**函数原形:uint Read_Temp_surr(void)
**函数功能:读取DS18B20数据并计算出温度
**参数:无
**返回值:温度
********************************************************/
uint Read_Temp_surr(void)
{
uchar th=0,tl=0;
uint temp=0;
EA=0; //禁T0中断
Init_DS18B20();
Write_byte(0xCC); // 跳过读序号列号的操作
Write_byte(0x44); // 启动温度转换
Init_DS18B20();
Write_byte(0xCC); //跳过读序号列号的操作
Write_byte(0xBE); //读取温度寄存器
tl=Read_byte(); //低字节
th=Read_byte(); //高字节
EA=1;
temp=(uint)((th*256+tl)/16.0*10);
return temp;
}
/***************************************
定时器初始化
****************************************/
void T_Init()
{
TMOD = 0xe1 ; //定时器工作方式:定时器1外控、计数方式2,定时器0、方式1
IE = 0x0a ; //开外中断INT0
PT1 = 1 ; //定时器1中断优先
TH1 = 0x0ff ;
TL1 = 0x0ff ;
TH0 = 0xd8; //定时初值10MS
TL0 = 0xef;
nop;
EA = 1 ; //总中断开放
TR1 = 1 ; //启动T1
}
/*****************************************************
**函数原形
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -