找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3824|回复: 11
打印 上一主题 下一主题
收起左侧

单片机+MAX6675不能实时显示问题,已调试到崩溃了

[复制链接]
跳转到指定楼层
楼主
ID:592477 发表于 2019-9-1 23:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
20黑币
参考了网上的很多例程,温度能读取正常的,但无论怎样都不能实时刷新显示温度,重新打开电源或者使用独立按键按下就能读取更新一次温度????已经调试到崩溃了!

单片机源程序如下:
  1. #include<intrins.h>
  2. #include "reg51.h"                         //此文件中定义了单片机的一些特殊功能寄存器
  3. #include "oled.h"

  4. sbit SO=P1^1;                                 
  5. sbit SCK=P1^3;                        
  6. sbit CS=P1^2;
  7. sbit key = P3^3;
  8.                                 
  9. unsigned int MAX6675_Temp;
  10.                                        
  11. void delay(unsigned int i)
  12. {
  13.         while(i--);        
  14. }


  15. unsigned int Re_Convert() //热电偶数据读取,返回温度
  16. {
  17.         long int a=0x7ff8;
  18.         long int wendu=0,wendu_1;
  19.         float wendu_2;
  20.     unsigned int i;
  21.         CS=1;
  22.         SCK=0;
  23.         delay(200);
  24.         _nop_();
  25.         _nop_();
  26.         CS=0;
  27.         for(i=1;i<=16;i++)
  28.           {        wendu=wendu<<1;
  29.                 _nop_();
  30.                  SCK=1;
  31.                 if(SO==1){wendu=wendu|0x01;}
  32.                    else wendu=wendu|0x00;
  33.                 _nop_();
  34.                 _nop_();
  35.                 SCK=0;
  36.                 _nop_();
  37.                 _nop_();
  38.           }
  39.         wendu_1=wendu&a;
  40.         wendu_1=wendu_1>>3;
  41.         wendu_2=wendu_1*0.25;
  42.                
  43.         return wendu_2;                        //返回带两位小数的实际温度

  44. }

  45. void main()
  46. {        

  47.                 OLED_Init();                        //初始化OLED  
  48.                 OLED_Clear();
  49.                
  50.         while(1)
  51.         {
  52.                 if(key==0)
  53.                 {
  54.                         delay(1000);
  55.                         if(key==0)
  56.                                 {
  57.                                         while(key==0);
  58.                                         MAX6675_Temp=Re_Convert();
  59.                                 }
  60.                 }
  61.                
  62.                 OLED_ShowNum(103,6,MAX6675_Temp,3,16);
  63.         
  64.         }               
  65. }
复制代码

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:213173 发表于 2019-9-2 08:10 | 只看该作者
你把采样MAX6675_Temp=Re_Convert();放在按键程序中当然只有按一次键才能更新一次数据,这么可能实时更新?
回复

使用道具 举报

板凳
ID:425825 发表于 2019-9-2 08:11 | 只看该作者
如果能读取一次准确温度,问题还是出在程序上
回复

使用道具 举报

地板
ID:138097 发表于 2019-9-2 09:09 | 只看该作者
while(key==0);这是干什么,仿真看看,是不是卡死在这里了。。
回复

使用道具 举报

5#
ID:105206 发表于 2019-9-2 09:27 | 只看该作者
以上程序是按键按下弹起才能读温度。
void main()
{        
unsigned int i;
                OLED_Init();                        //初始化OLED  
                OLED_Clear();
               
        while(1)
        {
                if(key==0)
                {
                        delay(1000);
                        if(key==0)
                                {
                                        while(key==0);
                                       
                                }
                }
i++;if(i==500)
{
i=0;
MAX6675_Temp=Re_Convert();
}
               
                OLED_ShowNum(103,6,MAX6675_Temp,3,16);
        
        }               
}
回复

使用道具 举报

6#
ID:592477 发表于 2019-9-2 09:42 来自手机 | 只看该作者
whx.000 发表于 2019-9-2 09:09
while(key==0);这是干什么,仿真看看,是不是卡死在这里了。。

并没有卡死,同样是读取温度放在按键判断中,如果不加判断按键弹起的话,怎么按也不能更新温度
回复

使用道具 举报

7#
ID:592477 发表于 2019-9-2 11:04 | 只看该作者
jubaolun 发表于 2019-9-2 09:27
以上程序是按键按下弹起才能读温度。
void main()
{        

你这程序也不行啊,从代码上看,按下按键也没有执行读取温度的命令,不过我不断按下按键的时候,有时稍微长按一下,结果温度就偶尔有一次变化,否则一直都是“卡死”在之前变化的温度值上
回复

使用道具 举报

8#
ID:235200 发表于 2019-9-2 13:03 | 只看该作者
这样的程序问题,最好把电路也贴出来,看是按键的问题还是显示的问题,程序中判断(key==0)无电路不能判断你的程序,另外OLED_ShowNum(103,6,MAX6675_Temp,3,16)这处显示程序就更看不出来是否正确不正确了
回复

使用道具 举报

9#
ID:383215 发表于 2019-9-2 15:40 | 只看该作者
MAX6675早就调试出来,感觉没有任何压力,我就是参考下面的程序调试出来的:
#include <REGX52.H>
#include "intrins.h"                        //_nop_();延时函数用
#define uchar unsigned char
#define uint  unsigned int
sbit  SO  = P0^6;                                  //P3.6口与SO相连
sbit  SCK = P0^4;                                 //P3.4口与SCK相连
sbit  CS  = P0^5;                                  //P3.5口与CS相连
static uchar tempture[4];
static unsigned int MAX6675_Temp;
const uchar DevID = 1;                //本机设备ID
static uchar Flag_connect;
void DelayMs(unsigned int i);
unsigned int MAX6675_ReadReg(void)
{
        unsigned char i;   
        unsigned int dat;
        i   = 0;   
        dat = 0;  

        SCK = 0;   
        CS  = 0;
        _nop_();
        SCK = 1;
          
        for(i=0; i<16; i++)                //get D15-D0 from 6675  
        {      
                SCK = 0;
                _nop_();
                dat = dat<<1;
                  
                if( SO == 1 )   
                        dat = dat | 0x01;   

                SCK = 1;
                _nop_();           
        }
        CS = 1;  
          
        return dat;   
}  
/*
* 功  能:延时,若干毫秒
* 参  数:毫秒数
* 返回值:无
*/
void DelayMs(unsigned int i)        //一个延时函数,这个函数在11.0592M晶振下的延时时间大概为1ms
{
        unsigned int j,k;

        for(j=i; j>0; j--)
                for(k=114; k>0; k--);
}
/*
* 功  能:串口初始化
* 参  数:无
* 返回值:无
*/

void init_serialcomm( void )
{
        SCON = 0x50 ; //SCON: serail mode 1, 8-bit UART, enable ucvr
        TMOD |= 0x20 ; //TMOD: timer 1, mode 2, 8-bit reload
        PCON |= 0x80 ; //SMOD=1;
        TH1=0XF3;                                //计数器初始值设置,注意波特率是4800的
        TL1=0XF3;
        IE |= 0x90 ; //Enable Serial Interrupt
        TR1 = 1 ; // timer 1 run
        // TI=1;
//        ES=1;                                                //打开接收中断
//        EA=1;                                                //打开总中断
//        TR1=1;                                        //打开计数器
}
//向串口发送一个字符
void send_char_com( unsigned char ch)
{
        SBUF = ch;
        while (TI == 0 );
        TI = 0 ;
}
//向串口发送一个字符串,strlen为该字符串长度
void send_string_com( unsigned char *str, unsigned int strlen)
{
        unsigned int k= 0 ;
        do
        {
        send_char_com(*(str + k));
        k++;
        }
        while (k < strlen);
}

void display(uint temp)
{
        uchar *n;

        tempture[0]=(temp % 10000)/1000 | 0x30;
        tempture[1]=(temp % 1000)/100 | 0x30;
        tempture[2]=(temp % 100)/10 | 0x30;
        tempture[3]=temp % 10 | 0x30;       
        n= &tempture;
        send_string_com( n , 4 );
               
}
void main(void)
{
        unsigned int t=0,j=0;
        unsigned int Temp=0;
        unsigned int id=0;
       
        P0=0x00;
        init_serialcomm();                        // 串口初始化

        while(1)
        {               
                t = MAX6675_ReadReg();
               
                  Flag_connect = t & 0x04;                         //读出数据的D2位是热电偶掉线标志位,该位为1表示掉线,该位为0表示连接
                  Flag_connect = Flag_connect >> 2;         //MAX6675是否在线
               
                id = t & 0x02;
                id = id >> 1;

                if(Flag_connect==0)
                {
                        t = t<<1;                                                   //读出来的数据的D3~D14是温度值
                        t = t>>4;
                        MAX6675_Temp = t/4;                                //测得的温度单位是0.25,所以要乘以0.25(即除以4)才能得到以度为单位的温度值               
                        Temp = Temp + MAX6675_Temp;
                        j=j+1;
                        if(j==20)
                        {
                                Temp=Temp/20-32;
                                j=0;

                                send_string_com( "读取的温度值为:", 16);
                                display(Temp);
                                send_string_com( " ℃", 3); // ℃
                                Temp=0;
                                               
                                DelayMs(500);                                       
                        }
                }
                                               
                else       
                {
                        send_string_com( "热电偶未连接", 12);
                         DelayMs(500);
                }

        }
}

我调试成功之后读16位数据的程序是这个样子:
unsigned int MAX6675_ReadReg( void )
{
        unsigned char i;   
        unsigned int dat;
         
        i   = 0;   
        dat = 0;  

        sck = 0;   
        cs  = 0;
        _nop_( ) ;
       
        for(i=0; i<16; i++)                //get D15-D0 from 6675  
        {      
                sck = 1;
                _nop_( ) ;
                dat <<= 1 ;
                if ( so == 1 )
                {
                        dat |= 0x01 ;
                }
                sck = 0 ;
        }
        cs = 1;  
        return dat;   
}  

回复

使用道具 举报

10#
ID:606937 发表于 2019-9-3 16:02 | 只看该作者
不要按键一直读的话,6675早就被读死了,仔细看看间隔时间。
回复

使用道具 举报

11#
ID:564490 发表于 2019-10-11 14:58 | 只看该作者
两次读MAX6675的时间间隔大于300ms就可以了,手册上有具体的记不清了。
回复

使用道具 举报

12#
ID:700054 发表于 2022-3-10 20:54 | 只看该作者
w_xmai 发表于 2019-10-11 14:58
两次读MAX6675的时间间隔大于300ms就可以了,手册上有具体的记不清了。

感谢感谢,这个max6675读取要间隔读取呢,不然就卡死了,我说我调了半天都没出来
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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