⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 37.c

📁 采用单片机控制
💻 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 + -