OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 10720|回复: 7

K型热电偶采集的温度,经过MAX6675转换以后,用数码管不能实时显示温度值,什么原因了

[复制链接]

1

主题

1

帖子

0

精华

新手入门

积分
25
金钱
25
注册时间
2014-5-21
在线时间
0 小时
发表于 2014-5-21 11:37:26 | 显示全部楼层 |阅读模式
5金钱
#include <reg52.h>
#include<intrins.h> 
#include<string.h>
#include <stdio.h>
#include <math.h>
#define uchar unsigned char
#define uint unsigned int//位定义
//max6675
sbit SO=P1^0;
sbit SCK=P1^1;
sbit CS=P1^2;
//按键
sbit key1=P3^4;      //功能键
sbit key2=P3^5;      //+
sbit key3=P3^7;  //-
sbit BEEP=P2^3;       //蜂鸣器
//DAC0832
sbit CSDA=P3^2;
sbit 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};//数码管位选
sbit dula=P2^6; //数码管段选,锁存器控制信号
sbit 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();
  }
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2014-5-21 12:55:14 | 显示全部楼层
贴的代码比较长的,建议打包成附件发上来
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165369
金钱
165369
注册时间
2010-12-1
在线时间
2110 小时
发表于 2014-5-21 22:22:27 | 显示全部楼层
建议仿真找问题...
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

55

主题

1231

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2625
金钱
2625
注册时间
2014-2-13
在线时间
514 小时
发表于 2014-8-15 10:56:17 | 显示全部楼层
刚在网上搜索了一下,发现MAX6675蛮贵的,十来块一片
技术交流,Sell 中颖单片机,欢迎私信骚扰
回复

使用道具 举报

5

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
176
金钱
176
注册时间
2016-8-16
在线时间
77 小时
发表于 2016-8-17 10:57:01 | 显示全部楼层
有没有用STM32F407研究过啊,我现在正在做这方面的,能否讨论一下!
回复

使用道具 举报

9

主题

53

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
372
金钱
372
注册时间
2016-8-15
在线时间
55 小时
发表于 2016-8-17 22:08:36 | 显示全部楼层
不能实时?是指显示的刷新很慢吗还是一直不动,还是不能显示
不能显示的话估计超数码管的范围会不会
祝中国健儿奥运好成绩
回复

使用道具 举报

2

主题

47

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
291
金钱
291
注册时间
2016-6-18
在线时间
40 小时
发表于 2016-8-25 11:00:55 | 显示全部楼层
楼主,你的问题解决了吗??
我遇到你差不多的问题,,讨论下呗
回复

使用道具 举报

2

主题

32

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
226
金钱
226
注册时间
2016-4-21
在线时间
38 小时
发表于 2017-6-26 09:50:59 | 显示全部楼层
楼主解决了吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-1 14:54

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表