|
单片机源程序:
- #include<REG51.H>
- #include<math.h>
- #include<INTRINS.H>
- #include<string.h>
- #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显示段码115段码表
- 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<temp)
- {
- // if(temp-set_temper>0)
- // {
- high_time=0;
- // }
- }
- }
- main()
- {
- initial();// 初始化个变量及定时器的初值开中断等
- lcd_init(); // 初始化LCD
- while(1)
- {
- compare_temper();
- printf();
- temp=ReadTemperature();
- keyscan();
- }
- }
复制代码
所有资料打包下载:
炉温控制系统.rar
(382.23 KB, 下载次数: 262)
|
评分
-
查看全部评分
|