C语言大林算法,大林算法控制器PID电阻炉温度控制室温的C程序如何实现? 求帮助...

#include

#include

#include

#include

#define CIRCLE 100

#define uchar unsigned char

#define uint   unsigned int;

struct PID {

unsigned int SetPoint; // 设定目标 Desired Value

unsigned int Proportion; // 比例常数 Proportional Const

unsigned int Integral; // 积分常数 Integral Const

unsigned int Derivative; // 微分常数 Derivative Const

unsigned int LastError; // Error[-1]

unsigned int PrevError; // Error[-2]

unsigned int SumError; // Sums of Errors

};

struct PID spid; // PID Control Structure

unsigned int rout; // PID Response (Output)

unsigned int rin; // PID Feedback (Input)

typedef unsigned char BYTE;

typedef unsigned int WORD;

typedef bit BOOL ;

sbit key1=P3^2;   //定义按键位置

sbit key2=P3^3;

sbit rs = P1^0;

sbit rw = P1^1;

sbit ep = P1^2;

sbit pwm=P1^5; //PWM输出端设置为P1.5输出

sbit DQ=P1^3;//ds18b20 信号引脚即DQ

sfr dataled=0x80;//显示数据端口 即P2口为段选码输入口

uchar temp;//温度变量

unsigned char set_temper=30;

unsigned char high_time;

unsigned int s;

uchar flag_get,count,num,counter; //温度读取标志位、中断次数变量t0中断次数以读取温度值, t1中断次数以控制周期和PWM的占空比

char const table[]={100,80,70,60,50,40,30,20,0};//高电平时间查表

uchar

code

tab[]={0x28,0xEB,0x32,0xA2,0xE1,0xA4,0x24,0xEA,0x20,0xA0,0x60,0x25,0x3C,0x23,0x34,

0x74,0xF7,0xFF};//,0x88,0x83,0xC6,0xA1,0x86,0x8E};//共阳led显示段码115段码表

uchar  shi,ge,danwei,dang,dang_dis;  // 定义温度十位、个位、摄氏度单位、及档位变量名称,及显示档位的查表变量

void delay1(uchar MS);// 延时函数

unsigned char ReadTemperature(void);//读温度子函数

void Init_DS18B20(void);// DS18B20初始化

unsigned char ReadOneChar(void);//读字节子函数

void WriteOneChar(unsigned char dat);//写字节子函数

void delay(unsigned int i);//延时

//void del(unsigned int);

void drive_moto();//由P1低四位输出控制信号

void initial();

unsigned int TempBuffer[5];

BYTE code dis1[] = {"Temperature:"};

BYTE code dis2[] = {"Set_Temper:"};

BYTE code dis3[] = {"0123456789"};

BYTE code dis4[] = 0xdf;

BYTE code dis5[] = {"C"};

//

void init();

void delay2(BYTE ms)

{

BYTE i;

while(ms--)

{

for(i = 0; i< 250; i++)

{

_nop_();

_nop_();

_nop_();

_nop_();

}

}

}

BOOL lcd_bz()

{       // 测试LCD忙碌状态

BOOL result;

rs = 0;

rw = 1;

ep = 1;

_nop_();

_nop_();

_nop_();

_nop_();

result = (BOOL)(P0 & 0x80);

ep = 0;

return result;

}

void lcd_wcmd(BYTE cmd)

{       // 写入指令数据到LCD

while(lcd_bz());

rs = 0;

rw = 0;

ep = 0;

_nop_();

_nop_();

P0 = cmd;

_nop_();

_nop_();

_nop_();

_nop_();

ep = 1;

_nop_();

_nop_();

_nop_();

_nop_();

ep = 0;

}

void lcd_pos(BYTE pos)

{       //设定显示位置

lcd_wcmd(pos | 0x80);

}

void lcd_wdat(BYTE dat)

{       //写入字符显示数据到LCD

while(lcd_bz());

rs = 1;

rw = 0;

ep = 0;

P0 = dat;

_nop_();

_nop_();

_nop_();

_nop_();

ep = 1;

_nop_();

_nop_();

_nop_();

_nop_();

ep = 0;

}

void lcd_init()

{       //LCD初始化设定

lcd_wcmd(0x38);   //

delay2(1);

lcd_wcmd(0x0c);   //

delay2(1);

lcd_wcmd(0x06);   //

delay2(1);

lcd_wcmd(0x01);   //清除LCD的显示内容

delay2(1);

}

void initial()

{

EA=1;

TMOD=0x11;//定时器设置皆工作在16定时计数器模式

TH0=0xef;//T0赋初值

TL0=0xf0;

TH1=(65536-1000)/256;//T1赋初值

TL1=(65536-1000)%256;

ET1=1;

ET0=1;

TR0=1;

TR1=1;

P2=0xff;

count=0;

counter=0;//pwm占空比控制变量

//IP=0x08; //T1优先级高于T0 ,后来证明此语句是多余的因为当加入此句后反/而PWM调速和温度检测都变得有点不稳定

}

void delay(unsigned int i)//延时函数

{

while(i--);

}

//18b20初始化函数检测总线上是否有从属器件DS的存在若存在则通讯成功

void Init_DS18B20(void)

{

unsigned char x=0;

DQ = 1;    //DQ复位

delay(8);  //稍做延时

DQ = 0;    //单片机将DQ拉低

delay(80); //延时 大于 480us

DQ = 1;    //拉高总线

delay(10);

x=DQ;      //稍做延时后 如果x=0则初始化成功 x=1则初始化失败因为DQ复位成功的回答信号即存在信号是低电平

delay(5);

}

//读一个字节ROM

unsigned char ReadOneChar(void)

{

unsigned char i=0;

unsigned char dat = 0;

for (i=8;i>0;i--)

{

DQ = 0; // 给脉冲信号

dat>>=1;

DQ = 1; // 给脉冲信号

if(DQ)

dat|=0x80;//

delay(5);

}

return(dat);

}

//写一个字节

void WriteOneChar(unsigned char dat)

{

unsigned char i=0;

for (i=8; i>0; i--)

{

DQ = 0;

DQ = dat&0x01;

delay(5);

DQ = 1;

dat>>=1;

}

delay(5);

}

//读取温度

unsigned char ReadTemperature(void)

{

unsigned char a=0;

unsigned char b=0;

unsigned char t=0;

Init_DS18B20();// 复位

WriteOneChar(0xCC); // 跳过读序号列号的操作

WriteOneChar(0x44); // 启动温度转换

delay(100);

Init_DS18B20();  //每次操作前都要进行复位

WriteOneChar(0xCC); //跳过读序号列号的操作

WriteOneChar(0xBE); //读取温度寄存器等共可读9个寄存器 前两个就是温度

a=ReadOneChar();

b=ReadOneChar();

s=(unsigned int)(a&0x0f);

b<<=4;//取高字节的第四位因为高四位为符号位1111为负0000为正

b+=(a&0xf0)>>4;//忽略小数位取a的高四位与b的相加就是此时所测得到整数温度值

t=b;

return(t);//返回温度值给这个函数

}

void printf()

{

BYTE i;

delay2(10);

lcd_pos(0x00);    // 设置显示位置为第一行的第5个字符

i = 0;

while(dis1[i] != '\0')

{

lcd_wdat(dis1[i]);

i++;

}

lcd_pos(0x40);   // 设置显示位置为第二行第二个字符

i = 0;

while(dis2[i] != '\0')

{

lcd_wdat(dis2[i]); // 显示字符

i++;

}

TempBuffer[0]=temp/10;  //十位

TempBuffer[1]=temp%10;  //个位

lcd_pos(0x0c);

lcd_wdat(dis3[TempBuffer[0]]); //测试温度十位

lcd_pos(0x0d);

lcd_wdat(dis3[TempBuffer[1]]); //测试温度个位

lcd_pos(0x0e);

lcd_wdat(dis4[0]);

lcd_pos(0x0f);

lcd_wdat(dis5[0]);

TempBuffer[2]=set_temper/10;  //十位

TempBuffer[3]=set_temper%10;  //个位

lcd_pos(0x4c);

lcd_wdat(dis3[TempBuffer[2]]); //设置温度十位

lcd_pos(0x4d);

lcd_wdat(dis3[TempBuffer[3]]); //设置温度个位

lcd_pos(0x4e);

lcd_wdat(dis4[0]);

lcd_pos(0x4f);

lcd_wdat(dis5[0]);

}

void keyscan()

{

if(key1==0)

{

delay(200);

if(key1==0)

{

set_temper++;

}

}

if(key2==0)

{

delay(200);

if(key2==0)

{

set_temper--;

}

}

}

void tim(void) interrupt 1 using 1//中断用于数码管扫描和温度检测间隔

{

// TH0=0xef;//定时器重装值

// TL0=0xf0;

// num++;

// if (num==100)

// {

//  num=0;

//  flag_get=1;//标志位有效

// }

}

void into(void) interrupt 3 //T1定时中断服务程序

{

TH1=(65536-1000)/256;//初值重装

TL1=(65536-1000)%256;

counter++;

if(counter>CIRCLE)

{

counter=0;限定周期为T=100X0.01ms=10ms

}

if(counter<=high_time)//取得查表参数以调节pwm的占空比

pwm=1;//PWM高电平

else

pwm=0;

}

void compare_temper()

{

// unsigned char i;

if(set_temper>temp)

{

if(set_temper-temp>=10)

{

high_time=100;

}

else

{

//   for(i=0;i<10;i++)

//   {

//    rin = s; // Read Input

//    rout = PIDCalc ( &spid,rin ); // Perform PID Interation

//   }

if (set_temper-temp==9)

high_time=90;

if (set_temper-temp==8)

high_time=80;

if (set_temper-temp==7)

high_time=70;

if (set_temper-temp==6)

high_time=60;

if (set_temper-temp==5)

high_time=50;

if (set_temper-temp==4)

high_time=40;

if (set_temper-temp==3)

high_time=30;

if (set_temper-temp==2)

high_time=20;

if (set_temper-temp==1)

high_time=10;

}

}

else if(set_temper

{

//  if(temp-set_temper>0)

//  {

high_time=0;

//  }

}

}

main()

{

initial();// 初始化个变量及定时器的初值开中断等

lcd_init();    // 初始化LCD

while(1)

{

compare_temper();

printf();

temp=ReadTemperature();

keyscan();

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值