帮我写一个基于51的pid温度控制系统的程序,采用ds18b20作为温度传感器,数码管显示,通过按键设置期望的温度,按键有三个,第一个按下会使期望的温度+1,第二个按下会使期望的温度-1,第三个按下会设置当前的期望温度。使用LM32测温电路,将LM32的输出经过OP07放大连接到单片机的一个I/O口上作为实际温度对应的电压值
时间: 2024-03-23 13:39:01 浏览: 53
好的,我会为您编写一个基于51的PID温度控制系统的程序。但是,在编写代码之前,需要明确以下几个问题:
1. PID控制器参数的确定:在PID控制器中,需要确定比例系数、积分时间和微分时间,这需要根据实际的温度控制对象进行调整。请告诉我您需要控制的温度范围和控制精度,以便我能够为您确定PID控制器参数。
2. 数码管型号的确定:不同型号的数码管显示方式和控制方式可能不同,因此需要明确您所使用的数码管型号。
3. 按键的接口方式:您需要告诉我您所使用的按键的接口方式,是矩阵按键、单独按键还是其他方式。
4. 单片机型号的确定:您需要告诉我您所使用的单片机型号,以便我能够编写相应的程序。
根据您提供的信息,我可以为您提供一份基本的程序框架。请参考以下代码:
```c
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit DSPORT = P2^0; // DS18B20数据线
sbit DS1820RST = P2^1; // DS18B20复位线
// 数码管段选码
uchar code segTable[] = {
0x3f, // 0
0x06, // 1
// ...
};
// 数码管位选码
uchar code posTable[] = {
0xfe, // 第1位
0xfd, // 第2位
// ...
};
// 温度控制器参数
float Kp = 0.0; // 比例系数
float Ti = 0.0; // 积分时间
float Td = 0.0; // 微分时间
// 期望温度
int setTemp = 0;
// 实际温度
float realTemp = 0.0;
// PID控制器变量
float err = 0.0; // 误差
float errSum = 0.0; // 误差积分
float errDiff = 0.0; // 误差微分
float lastErr = 0.0; // 上一次误差
// 数码管显示变量
uchar dispBuff[4] = {0}; // 显示缓冲区
uchar dispPos = 0; // 显示位置
// DS18B20读写一个字节
uchar DS18B20ReadByte()
{
uchar i, dat = 0;
for (i = 0; i < 8; i++) {
dat >>= 1;
DSPORT = 0;
_nop_();
_nop_();
DSPORT = 1;
_nop_();
_nop_();
if (DSPORT) dat |= 0x80;
}
return dat;
}
// DS18B20写一个字节
void DS18B20WriteByte(uchar dat)
{
uchar i;
for (i = 0; i < 8; i++) {
DSPORT = 0;
_nop_();
_nop_();
if (dat & 0x01) DSPORT = 1;
_nop_();
_nop_();
DSPORT = 1;
dat >>= 1;
}
}
// DS18B20初始化
uchar DS18B20Init()
{
uchar i;
DS1820RST = 1;
DSPORT = 1;
_nop_();
_nop_();
if (!DSPORT) return 0;
DS1820RST = 0;
_nop_();
_nop_();
DS1820RST = 1;
_nop_();
_nop_();
if (!DSPORT) return 0;
return 1;
}
// DS18B20读取温度
float DS18B20ReadTemp()
{
uchar TL, TH;
float temp;
DS18B20Init();
DS18B20WriteByte(0xcc);
DS18B20WriteByte(0x44);
_nop_();
_nop_();
DS18B20Init();
DS18B20WriteByte(0xcc);
DS18B20WriteByte(0xbe);
TL = DS18B20ReadByte();
TH = DS18B20ReadByte();
temp = TH;
temp *= 256;
temp += TL;
if (temp > 32768) {
temp = ~temp + 1;
temp *= -1;
}
temp *= 0.0625;
return temp;
}
// 将温度转换为显示数据
void Temp2Disp(float temp)
{
uchar i;
int data = (int)(temp * 10);
for (i = 0; i < 4; i++) {
if (data == 0 && i > 1) break;
dispBuff[i] = segTable[data % 10];
data /= 10;
}
}
// 显示下一个数码管
void DispNext()
{
dispPos++;
if (dispPos >= 4) dispPos = 0;
P0 = 0xff;
P1 = posTable[dispPos];
P0 = dispBuff[dispPos];
}
// 处理按键事件
void KeyProc()
{
if (!P3_0) {
setTemp++;
if (setTemp > 100) setTemp = 100;
}
if (!P3_1) {
setTemp--;
if (setTemp < 0) setTemp = 0;
}
if (!P3_2) {
realTemp = DS18B20ReadTemp();
}
}
// PID控制器
void PIDControl()
{
float output;
err = setTemp - realTemp;
errSum += err;
errDiff = err - lastErr;
output = Kp * err + Kp / Ti * errSum + Kp * Td * errDiff;
lastErr = err;
// 控制输出
}
// 主函数
void main()
{
// 初始化
while (1) {
// 读取温度
realTemp = DS18B20ReadTemp();
// 处理按键事件
KeyProc();
// PID控制器
PIDControl();
// 显示温度
Temp2Disp(realTemp);
DispNext();
// 延时
}
}
```
以上代码只是一个基本的框架,具体的实现需要根据您的实际需求进行调整。请注意,以上代码仅供参考,具体实现可能还需要进行调试和优化。
阅读全文