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

📄 1624.c

📁 利用I2C总线实现数字式测温
💻 C
字号:
/*==================================
/*PID Program for TEC*/
/*Ou Yaodong,2008-12-20*/
/*==================================*/

#include <reg51.h>
#include <string.h>
#include <stdio.h>
#include <absacc.h>
#include <math.h>
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int

struct PID
{
  double SetPoint;          /* 设定目标 Desired value */
  double Proportion;        /* 比例常数 Proportional Const */
  double Integral;          /* 积分常数 Integral Const */
  double Derivative;        /* 微分常数 Derivative Const */
  double LastError;         /* 偏差 Error[-1] */
  double PrevError;         /* 偏差 Error[-2] */
  double SumError;          /* 偏差总和 Sums of Errors */
};
struct PID *m;


sbit SDA=P1^1;
sbit SCL=P1^2;
sbit SHDN=P1^3;
sbit CS=P1^4;
sbit GREED=P1^6;
sbit RED=P1^7;

bit timeflag=0;
bit u;
double rOut;      /* PID Response (Output) */
double rIn;       /* PID Feedback (Input) */


void delay(void);
void init_timer(void);
void delay10ms(void);
void delay1s(void) ;
void startBit(void);
void stopBit(void);
void sACK(void);
void mACK(void);
void NOmACK(void);
void writeByte(unsigned char Dat);
uchar readData(void);
void Start_Temperature_T(void);
void stopConvert(void) ;
uint readTem(void) ;
void setup1624(void) ;
uchar readR(uchar addr);
double ds1624(void);
double PIDCalc(struct PID *pp, double rIn );
void PIDInit (struct PID *pp);
void tlv5618(double rOut);


/*=================================================================
PID计算部分
==================================================================*/
double PIDCalc(struct PID *pp, double rIn )
{
  double dError,Error;
  Error = pp->SetPoint - rIn;               /* 偏差 */
  pp->SumError += Error;                      /* 积分 */
  dError = pp->LastError - pp->PrevError;      /* 当前微分 */
  pp->PrevError = pp->LastError;
  pp->LastError = Error;
  return (pp->Proportion * Error              /* 比例项 */
         + pp->Integral * pp->SumError         /* 积分项 */
         + pp->Derivative * dError);          /* 微分项 */
}

/*===================================================================
Initialize PID Structure
===================================================================*/
void PIDInit (struct PID *pp)
{
  pp->SetPoint=0;
  pp->Proportion=0;
  pp->Integral=0;
  pp->Derivative=0;
  pp->SumError=0;
  pp->PrevError=0;
  pp->LastError=0;
}

/*=================================================================
                            设置定时器
==================================================================*/
void delay(void)
{
  _nop_();_nop_();_nop_();_nop_();
}

void timer1() interrupt 3 using 1
{
  uchar time;
  uchar period = 20;                         /* 需中断20次为时间一秒--定时1秒 */
  TH1 =(65536-46080)/256;                    /* 根据每隔50ms中断一次,设定时器的初值 */
  TL1 =(65536-46080)%256;
  ++time;
  if (time == period)                        /* 中断20次后,即1秒后 */
   {

     time = 0 ;
     timeflag=1;
     TR1=0;
   }
}

void init_timer(void)
{
  TMOD=0x11;              /* 定时器0和定时器1都工作在方式1,即十六位定时器 */
  EA = 1;                 /* 开CPU中断 */
  ET1 = 1;                /* 开定时器1的中断 */
}

void delay10ms(void)      /* 采用定时器0控制10ms */
{
  TH0=(65536-9216)/256;   /* 装载初值,定时10MS,晶振:11.0592MHZ */
  TL0=(65536-9216)%256;
  TR0=1;                  /* 启动定时器0 */
  do{RED=0;}while(!TF0);        /* 查询等待TF0置位,则10ms到 */
  TF0=0;                  /* TF0由软件置0 */
  TR0=0;
  RED=0;
}

void delay1s(void)        /* 采用定时器1控制1s */
{
  TH1=(65536-46080)/256;   /* 装载初值,定时50ms,晶振:11.0592MHZ,20次50ms实现1s定时 */
  TL1=(65536-46080)%256;
  TR1=1;                   /* 启动定时器1 */
  timeflag=0;
}


/*=================================================================
               从DS1624数字温度传感器读取的温度值
==================================================================*/

void startBit(void)         /* 写START BIT */
{
  SDA=1;
  SCL=1;   delay();
  SDA=0;   delay();
  SCL=0;   delay();
}

void sACK(void)       /* DS1624 generates acknowledge bit */
{
  SDA=1;             /* 单片机读时要先写1 */
  delay();
  SCL=1;
  u=SDA;
  while(u==1)
  {
    u=SDA;
  }
  SCL=1;
  SCL=0;
  delay();
}

void mACK(void)      /* Bus Master generates acknowledge bit */
{
  SDA=0;   delay();
  SCL=1;   delay();
  SCL=0;   delay();
}

void NOmACK(void)    /* Bus Master send “NO KWOWLEDGE”bit */
{
  SDA=1;   delay();
  SCL=1;   delay();
  SCL=0;   delay();
}

void stopBit(void)          /* 写STOP BIT */
{
  SDA=0;
  SCL=1;   delay();
  SDA=1;   delay();
  SCL=0;   delay();
}

void writeByte(unsigned char Dat)
{
  uchar i;
  uchar temp1,temp2;
  temp1=Dat;
  for(i=0; i<8; i++)
        {
            temp2=temp1&0x80;   /* temp2为最高位 */
            if(temp2==0x80)
                SDA=1;
            else
                SDA=0;
            SCL=1;   delay();
            SCL=0;
            temp1<<=1;          /* 左移一位,输入下一个数 */
        }
}

uchar readData(void)
{
  uchar i,temp1=0,temp2=0;
  for(i=0;i<8;i++)
    {
       SDA=1;                    /* 单片机读时要先写1 */
       delay();
       SCL=1;
       temp1=SDA;
       temp2=temp2+(temp1<<(7-i));
       SCL=0;
       delay();
    }
  return temp2;
}

void stopConvert(void)      /* Command protocol for Stop Convert T */
{
  startBit();
  writeByte(0x90);
  sACK();
  writeByte(0x22);
  sACK();
  stopBit();
}

void Start_Temperature_T(void)      /* Command protocol for Start Convert T */
{                                   /* 启动温度转换,大约1S转换完一次 */
  startBit();
  writeByte(0x90);
  sACK();
  writeByte(0xEE);
  sACK();
  stopBit();
}

void setup1624(void)      /* Command protocol for configuration register */
{
  startBit();             /* 是对EEPROM的访问,需延时10ms */
  writeByte(0x90);
  sACK();
  writeByte(0xAC);
  sACK();
  writeByte(0x00);        /* 一次转换模式 */
  sACK();
  stopBit();
}

uint readTem(void)           /* Command protocol for reading the Temperature */
{
  uint Dat,DatH,DatL;
  startBit();
  writeByte(0x90);
  sACK();
  writeByte(0xAA);
  sACK();
  startBit();
  writeByte(0x91);
  mACK();
  DatH=readData();
  mACK();
  DatL=readData();
  NOmACK();
  stopBit();
  Dat=(DatH<<8)+DatL;
  return Dat;
}

uchar readR(uchar addr)                /* 读寄存器 */
{
  uchar temp;
  startBit();
  writeByte(0x90);
  sACK();
  writeByte(addr);
  sACK();
  startBit();
  writeByte(0x91);                     /* 向AD7747写入Slave address,0x91表示读操作 */
  mACK();
  temp=readData();
  NOmACK();
  stopBit();
  return temp;
}

void main(void)
{
  double R;
  uchar a;
  init_timer();
  setup1624();
  delay10ms();              /* 写EEPROM时要延时10MS */
  a=readR(0xAC);
  Start_Temperature_T();
  delay1s();
  while(!timeflag);
  R=(readTem()>>3)*0.03125;
  stopConvert();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -