完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
#include
#include #include #include #include #define uchar unsigned char #define uint unsigned int//位定义 //max6675 ***it SO=P1^0; ***it SCK=P1^1; ***it CS=P1^2; //按键 ***it key1=P3^4; //功能键 ***it key2=P3^5; //+ ***it key3=P3^7; //- ***it BEEP=P2^3; //蜂鸣器 //DAC0832 ***it CSDA=P3^2; ***it wr=P3^6; int shang=1250; //上限报警温度,默认值为1250 int SetPoint=1200; //设定目标 int wendu,k1; uchar qian=0,bai=0,shi=0,ge=0,xiao=0; float Kp,Ki,Kd; uchar tab1[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴极数码管赋值 0,1,2,3,4,5,6,7,8,9 uchar code tab[]={0x7e,0x7d,0x7b,0x77};//数码管位选 ***it dula=P2^6; //数码管段选,锁存器控制信号 ***it wela=P2^7;//数码管位选,锁存器控制信号 uint Re_Convert(); //热电偶数据读取,返回温度 int ek=0; int ek1=0; //第K-1采样时的偏差值,Error[-1] int ek2=0; //第K-2采样时的偏差值,Error[-2] float LastOutput=0; //上次PID输出 float Output=0; //PID的输出 uchar high_time,low_time,count=0;//占空比调节参数 //---------------------------延时子程序---------------------------// void delay_50ms(uint m) { uchar x,y; for(x=m;x>0;x--) for(y=50;y>0;y--) ; } /*********** MAX6675函数***********/ uint Re_Convert() //热电偶数据读取,返回温度 { uchar i; unsigned long Temp_2; Temp_2=0; CS=1; //片选段 SCK=0; //sck串行时钟输入 delay_50ms(5); CS=0; //片选段,低电平选通 for(i=0;i<16;i++)//16位数据读取 { Temp_2=Temp_2<<1;//向左移一位 SCK=1;// 上升 if(SO==1)//so串行数据输出 { Temp_2=Temp_2|0x01; } else Temp_2=Temp_2|0x00; SCK=0; } Temp_2=Temp_2<<1;//向左移一位,取0-14位 Temp_2=Temp_2>>4;//向右移4位,取3-14位 Temp_2=Temp_2*1024/4096;//变换为温度值,后边Temp_2是你采集到的数据,temp是转换成实际温度的数据,可以直接送到显示部分显示,精度0.25 return Temp_2; } //*************温度显示程序*******************// void Disp_temp1(uint temp)//温度显示 { ge=temp%10; //取个数位数字 temp=temp/10; shi=temp%10;//取十位数字 temp=temp/10; bai=temp%10;//取百位数字 qian=temp/10;//取千位数字 0=0Xff;//关掉数码管的位选信号。阻止数码管受到P0口信号的影响。 delay_50ms(10); wela=1; delay_50ms(10); wela=0; dula=0; 0=tab1[qian]; //送数字到段码端口,显示数字 dula=1; //高电平,打开段选锁存器 dula=0; //低电平,锁存段选 wela=0; 0=tab[0]; //数码管位选 wela=1;//打开位选选存器 wela=0; //锁存位选 delay_50ms(10); P0=0Xff;//关掉数码管的位选信号。阻止数码管受到P0口信号的影响。 delay_50ms(10); wela=1; delay_50ms(10); wela=0; dula=0; P0=tab1[bai];//送数字到段码端口 dula=1; dula=0; wela=0; P0=tab[1]; //数码管位选 wela=1; wela=0; delay_50ms(10); P0=0Xff;//关掉数码管的位选信号。阻止数码管受到P0口信号的影响。 delay_50ms(10); wela=1; delay_50ms(10); wela=0; dula=0; P0=tab1[shi]; //送数字到段码端口 dula=1; dula=0; wela=0; P0=tab[2]; //数码管位选 wela=1; wela=0; delay_50ms(10); 0=0Xff;//关掉数码管的位选信号。阻止数码管受到P0口信号的影响。 delay_50ms(10); wela=1; delay_50ms(10); wela=0; dula=0; 0=tab1[ge]; //送数字到段码端口 dula=1; dula=0; wela=0; 0=tab[3]; //数码管位选 wela=1; wela=0; delay_50ms(10); } //*************PID显示程序*******************// void Disp_temp2(float t)//PID显示 { uchar temp=t*10; xiao=temp%10; //取小数位数字 temp=temp/10; ge=temp%10; //取个数位数字 temp=temp/10; shi=temp%10;//取十位数字 temp=temp/10; bai=temp%10;//取百位数字 P0=0Xff;//关掉数码管的位选信号。阻止数码管受到P0口信号的影响。 delay_50ms(10); wela=1; delay_50ms(10); wela=0; dula=0; 0=tab1[bai];//送数字到段码端口 dula=1; dula=0; wela=0; 0=tab[0]; //数码管位选 wela=1; wela=0; delay_50ms(10); 0=0Xff;//关掉数码管的位选信号。阻止数码管受到P0口信号的影响。 delay_50ms(10); wela=1; delay_50ms(10); wela=0; dula=0; P0=tab1[shi]; //送数字到段码端口 dula=1; dula=0; wela=0; 0=tab[1]; //数码管位选 wela=1; wela=0; delay_50ms(10); P0=0Xff;//关掉数码管的位选信号。阻止数码管受到P0口信号的影响。 delay_50ms(10); wela=1; delay_50ms(10); wela=0; dula=0; P0=tab1[ge]|0x80; //送数字到段码端口 dula=1; dula=0; wela=0; P0=tab[2]; //数码管位选 wela=1; wela=0; delay_50ms(10); P0=0Xff;//关掉数码管的位选信号。阻止数码管受到P0口信号的影响。 delay_50ms(10); wela=1; delay_50ms(10); wela=0; dula=0; P0=tab1[xiao]; //送数字到段码端口 dula=1; dula=0; wela=0; P0=tab[3]; //数码管位选 wela=1; wela=0; delay_50ms(10); P0=0Xff;//关掉数码管的位选信号。阻止数码管受到P0口信号的影响。 delay_50ms(10); wela=1; delay_50ms(10); wela=0; dula=0; } //*************PID运算程序*******************// PID() { float P,D,iIncpid; ek=SetPoint-wendu; if(ek<=2) { iIncpid=0; } P=ek-ek1; //增量计算 D=ek-2*ek1+ek2; if(ek<=5) //判断积分分离 iIncpid=Kp*P+Ki*ek+Kd*D; else {iIncpid=Kp*P+Kd*D;} //积分分离,去掉积分 Output=LastOutput+iIncpid; if(Output>=1300) Output=1300; if(Output<=0) Output=0; ek2=ek1; //存储误差,用于下次计算 ek1=ek; LastOutput=Output; return (Output); } //*************报警子程序*******************// void AlARM()//蜂鸣器间断 {if(wendu>shang) { int f; for(f=100;f>0;f--) { BEEP=0; delay_50ms(10); } } } void compare_temper() { uint temper=wendu; if(SetPoint>temper) //是否设置的温度大于实际温度 { if(SetPoint-temper>100) //设置的温度比实际的温度是否是大于100度 { high_time=100; //如果是,则全速加热 low_time=0; } else //如果是在100度范围内,则运行PID计算 { PID(); if (high_time<=100) high_time=(uchar)(Output/4); //? else high_time=100; low_time= (100-high_time); } } else if(SetPoint<=temper) { high_time=0; low_time=100; } } // // void serve_T0() interrupt 1 //{ //TH0=(65536-50000)/256; //初值 //TL0=(65536-50000)%256; // //if(++count<=(high_time)) //Output=1; //else if(count<=100) //{ //Output=0; //} //else //count=0; //TH0=0xf0; //TL0=0x60; //} //*******功率放大子程序*******// void timer0() interrupt 1 { int a; CSDA=0; WR=0; P0=0Xc0; //输出正脉冲 TR0=0; //关T0记数 for(a=100;a>0;a--); //脉冲宽度由延时确定 P0=0X00; } void int0() interrupt 0 //外部中断 { TH0=0X30;//T0初值确定晶闸管导通角 TL0=0X31; TR0=1;//允许T0记数 } //*******按键子程序*******// void keyset() { k1++; Disp_temp2(Kp); delay_50ms(50); while(k1<7) { if(k1==1) { Disp_temp2(Kp); if(key1==0) delay_50ms(10); if(key1==0) {k1++; Disp_temp2(Kp); delay_50ms(1); while(!key1); } if(key2==0) delay_50ms(10); if(key2==0) { Kp=Kp+0.1; Disp_temp2(Kp); delay_50ms(1); while(!key2); } if(key3==0) delay_50ms(10); if(key3==0) { Kp=Kp-0.1; Disp_temp2(Kp); delay_50ms(1); while(!key3); } } if(k1==2) { Disp_temp2(Kp); if(key1==0) delay_50ms(10); if(key1==0) {k1++; Disp_temp2(Kp); delay_50ms(1); while(!key1); } if(key2==0) delay_50ms(10); if(key2==0) { Kp=Kp+0.1; Disp_temp2(Kp); delay_50ms(1); while(!key2); } if(key3==0) delay_50ms(10); if(key3==0) { Kp=Kp-0.1; Disp_temp2(Kp); delay_50ms(1); while(!key3); } } if(k1==3) { Disp_temp2(Ki); if(key1==0) delay_50ms(10); if(key1==0) {k1++; Disp_temp2(Ki); delay_50ms(1); while(!key1); } if(key2==0) delay_50ms(10); if(key2==0) { Ki=Ki+0.1; Disp_temp2(Ki); delay_50ms(1); while(!key2); } if(key3==0) delay_50ms(10); if(key3==0) { Ki=Ki-0.1; Disp_temp2(Ki); delay_50ms(1); while(!key3); } } if(k1==4) { Disp_temp2(Kd); if(key1==0) delay_50ms(10); if(key1==0) {k1++; Disp_temp2(Kd); delay_50ms(6); while(!key1); } if(key2==0) delay_50ms(10); if(key2==0) { Kd=Kd+0.1; Disp_temp2(Kd); delay_50ms(1); while(!key2); } if(key3==0) delay_50ms(10); if(key3==0) { Kd=Kd-0.1; Disp_temp2(Kd); delay_50ms(1); while(!key3); } } if(k1==5) { Disp_temp2(Output); if(key1==0) {k1++; Disp_temp2(Output); delay_50ms(6); while(!key1); } } if(k1==6) { Disp_temp1(shang); if(key1==0) delay_50ms(10); if(key1==0) {k1++; Disp_temp1(shang); delay_50ms(6); while(!key1); } if(key2==0) delay_50ms(10); if(key2==0) { shang=shang+10; Disp_temp1(shang); delay_50ms(1); while(!key2); } if(key3==0) delay_50ms(10); if(key3==0) { shang=shang-10; Disp_temp1(shang); delay_50ms(10); while(!key3); } } } delay_50ms(1); if(k1>6) k1=0; } void init_sys() //系统初始化 { IT0=1; EX0=1; ET0=1; EA=1; TMOD=1; CSDA=0; wr=0; P0=0Xc0; } //*************主程序*******************// void main() { Kp=1.2; Ki=3.4; Kd=5.6; init_sys(); delay_50ms(1); while(1) { wendu=Re_Convert();// 热电偶数据读取,返回温度 compare_temper(); Disp_temp1(wendu); if(key1==0) { keyset(); } PID(); Alarm(); } } |
|
相关推荐
1 条评论
6个回答
|
|
刚在网上搜索了一下,发现MAX6675蛮贵的,十来块一片
|
|
|
|
有没有用STM32F407研究过啊,我现在正在做这方面的,能否讨论一下!
|
|
|
|
|
|
|
|
|
|
|
|
楼主解决了吗?
|
|
|
|
只有小组成员才能发言,加入小组>>
3278 浏览 9 评论
2956 浏览 16 评论
3456 浏览 1 评论
8988 浏览 16 评论
4050 浏览 18 评论
1103浏览 3评论
570浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
568浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2301浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1857浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 15:07 , Processed in 1.502975 second(s), Total 110, Slave 82 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号