📄 1624.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 + -