久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4709|回復: 2
收起左側

MLX90614為啥不能返回數據?以下是我使用的程序以及實用的單片機板

[復制鏈接]
ID:583286 發表于 2019-8-7 10:18 | 顯示全部樓層 |閱讀模式
//-------------------------------------------------------------------------
//存在的問題:數碼管無法顯示,無法接收到傳感器的數據。

//-------------------------------------------------------------------------
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define Nack_number 10
#define LCD P0
//**************端口定義**************************************************
uchar flag;            //LCD控制線接口
sbit RS=P2^6;             //RS 端
sbit RW=P2^5;          // 讀寫端
sbit LCDE=P2^7;        //使能端
           //mlx90614 端口定義
sbit SCK=P3^7;        // 時鐘線
sbit SDA=P3^6;         // 數據線


sbit DPY1 = P2^2;                      //溫度顯示第 1 個數碼管段選
sbit DPY2 = P2^3;                      //溫度顯示第 2 個數碼管段選
sbit DPY3 = P2^4;                      //溫度顯示第 3 個數碼管段選

sbit row1 = P1^7;                           //矩陣鍵盤第 1 列
sbit row2 = P1^6;                           //矩陣鍵盤第 2 列
sbit row3 = P1^5;                           //矩陣鍵盤第 3 列
sbit cow1 = P1^3;                           //矩陣鍵盤第 1 行  
sbit cow2 = P1^2;                           //矩陣鍵盤第 2 行
sbit cow3 = P1^1;                           //矩陣鍵盤第 3 行
//************數據定義****************************************************
bdata uchar flag1;       //可位尋址數據
sbit bit_out=flag1^7;
sbit bit_in=flag1^0;
uchar tempH,tempL,err;

void CALTEMP(uint TEMP);
void ReadKey(void);
void initInt();
void delay1(uint z);
void show();
uchar key_num;
uchar mah[5];

/********數碼管碼值定義*******************************************************/
uchar code LED01[]={           //LED顯示代碼,0-9 共陽  不帶小數點的   
0xC0,0xF9,0xA4,0xB0,
0x99,0x92,0x82,0xF8,
0x80,0x90};

uchar code LED02[]={           //LED顯示代碼,0-9 共陽  帶小數點的   
0x40,0x79,0x24,0x30,
0x19,0x12,0x02,0x78,
0x00,0x10};
/**********全局變量定義******************************************************/
bit b20ms,b100ms;   //定時標志位
uchar c20ms,c100ms;     //定時毫秒數

//**************************  LCD1602  ***********************************
//向 LCD 寫入命令或數據*****************************************************
#define LCD_COMMAND   0         //命令
#define LCD_DATA   1         // 數據
#define LCD_CLEAR_SCREEN 0x01        // 清屏
#define LCD_HOMING    0x02        // 光標返回原點
//設置顯示模式******* 0x08+   *********************************************
#define LCD_SHOW   0x04      //顯示開
#define LCD_HIDE   0x00      //顯示關
#define LCD_CURSOR   0x02    //顯示光標
#define LCD_NO_CURSOR  0x00      //無光標
#define LCD_FLASH   0x01      //光標閃動
#define LCD_NO_FLASH  0x00      //光標不閃動
//設置輸入模式********** 0x04+ ********************************************
#define LCD_AC_UP   0x02       //光標右移 AC+
#define LCD_AC_DOWN   0x00        //默認 光標左移 AC-
#define LCD_MOVE   0x01        //畫面可平移
#define LCD_NO_MOVE   0x00        //默認 畫面不移動

//**************************  mlx90614  ***********************************
//command mode  命令模式
#define RamAccess 0x00     // 對 RAM 操作
#define EepomAccess 0x20     // 對 EEPRAM 操作
#define Mode  0x60     //進入命令模式
#define ExitMode 0x61     //退出命令模式
#define ReadFlag 0xf0     //讀標志
#define EnterSleep 0xff     //進入睡眠模式
//ram address read only RAM 地址(只讀)
#define AbmientTempAddr  0x03   //周圍溫度
#define IR1Addr    0x04
#define IR2Addr    0x05
#define LineAbmientTempAddr 0x06     //環境溫度
/*0x0000 0x4074  16500  0.01/單元
     -40    125*/
#define LineObj1TempAddr 0x07   //目標溫度,紅外溫度
/*0x27ad-0x7fff  0x3559 22610 0.02/單元
  -70.01-382.19  0.01   452.2*/
#define LineObj2TempAddr 0x08
//eepom address  EEPROM 地址
#define TObjMaxAddr  0x00    //測量范圍上限設定
#define TObjMinAddr  0x01    //測量范圍下限設定
#define PWMCtrlAddr  0x02    //PWM 設定
#define TaRangeAddr  0x03    //環境溫度設定
#define KeAddr   0x04    //頻率修正系數
#define ConfigAddr  0x05    //配置寄存器
#define SMbusAddr  0x0e    //器件地址設定
#define Reserverd1Addr 0x0f    //保留
#define Reserverd2Addr 0x19    // 保留
#define ID1Addr   0x1c    //ID 地址 1
#define ID2Addr   0x1d    //ID 地址 2
#define ID3Addr   0x1e    //ID 地址 3
#define ID4Addr   0x1f    //ID 地址 4

//************函數聲明*****************************************************
void start();         //MLX90614 發起始位子程序
void stop();         //MLX90614 發結束位子程序
uchar ReadByte(void);       //MLX90614接收字節子程序
void send_bit(void);       //MLX90614 發送位子程序
void SendByte(uchar number);     //MLX90614 接收字節子程序
void read_bit(void);       //MLX90614 接收位子程序
void delay(uint N);       //延時程序
uint readtemp(void);       //讀溫度數據
void init1602(void);       //LCD 初始化子程序
void busy(void);        //LCD 判斷忙子程序
void cmd_wrt(uchar cmd);      //LCD 寫命令子程序
void dat_wrt(uchar dat);      //LCD 寫數據子程序
void display(uint Tem);      //顯示子程序
void Print(uchar *str);      //字符串顯示程序

//*************主函數*******************************************
void main()
{
uint Tem;        //溫度變量
    initInt();
SCK=1;
SDA=1;
delay(4);
SCK=0;
delay(1000);
SCK=1;
init1602();        // 初始化 LCD
while(1)
{
        while(b100ms)    //每 100ms 掃描一次鍵盤
        {
         b100ms=0;
      ReadKey();
        }  

        if(key_num==1)              //按下 1 鍵時,進行數碼管顯示
        {
         Tem=readtemp();
         CALTEMP(Tem);
         show();
        }

        if(key_num!=1)      //液晶屏顯示
        {
  Tem=readtemp();      //讀取溫度
  cmd_wrt(0x01);      // 清屏
  Print("  Temperature:    ");  //顯示字符串  Temperature: 且換行
  display(Tem);      //顯示溫度
  Print(" ^C");     //顯示攝氏度
  delay(100000);      //延時再讀取溫度顯示
        }
}
}
//------------------字符串顯示程序--------------------------
void Print(uchar *str)      //字符串顯示程序
{
while(*str!='\0')      //直到字符串結束
{
  dat_wrt(*str);      // 轉成 ASCII 碼   
  str++;        //指向下一個字符
}
}

//--------------輸入轉換并顯示(用于 LCD1602)--------------------
void display(uint Tem)
{
uint T,a,b;
T=Tem*2;
if(T>=27315)       //溫度為正
{
  T=T-27315;       //
  a=T/100;       //溫度整數
  b=T-a*100;       //溫度小數
  if(a>=100)       //溫度超過 100 度
  {
   dat_wrt(0x30+a/100);   //顯示溫度百位
   dat_wrt(0x30+a%100/10);   //顯示溫度十位
   dat_wrt(0x30+a%10);    //顯示溫度個位
  }
  else if(a>=10)      //溫度超過 10 度
  {
   dat_wrt(0x30+a%100/10);   //顯示溫度十位
   dat_wrt(0x30+a%10);    //顯示溫度個位
  }
  else        //溫度不超過 10 度
  {
   dat_wrt(0x30+a);    //顯示溫度個位
  }
  dat_wrt(0x2e);      //顯示小數點
  if(b>=10)       //溫度小數點后第 1 位數不等于 0
  {
  dat_wrt(0x30+b/10);     //顯示溫度小數點后第 1 位數
  dat_wrt(0x30+b%10);     //顯示溫度小數點后第 2 位數
  }
  else        //溫度小數點后第 1 位數等于 0
  {
   dat_wrt(0x30);     //顯示溫度小數點后第 1 位數 0
   dat_wrt(0x30+b);    //顯示溫度小數點后第 2 位數
  }
}
else         //溫度為負
{
  T=27315-T;
  a=T/100;
  b=T-a*100;
  dat_wrt(0x2d);      //顯示負號
  if(a>=10)       //溫度低于負 10 度
  {
   dat_wrt(0x30+a/10);    //顯示溫度十位
   dat_wrt(0x30+a%10);    //顯示溫度個位
  }
  else        //溫度高于負 10 度
  {
   dat_wrt(0x30+a);    //顯示溫度個位
  }
  dat_wrt(0x2e);      //顯示小數點
  if(b>=10)       //溫度小數點后第 1 位數不等于 0
  {
   dat_wrt(0x30+b/10);    //顯示溫度小數點后第 1 位數
   dat_wrt(0x30+b%10);    //顯示溫度小數點后第 2 位數
  }
  else        //溫度小數點后第 1 位數等于 0
  {
   dat_wrt(0x30);     //顯示溫度小數點后第 1 位數 0
   dat_wrt(0x30+b);    //顯示溫度小數點后第 2 位數
  }
}
}
//--------------------根據十六進制計算溫度------------------------------
void CALTEMP(uint TEMP)
{
      uint T;
      uint a,b;
      uchar A4,A5,A6,A7,A8;
      T=TEMP*2;
      if(T>=27315)
            {
               T=T-27315;
               a=T/100;
               b=T-a*100;
               if(a>=100)
                   {
                      A4=a/100;
                      a=a%100;
                      A5=a/10;
                      a=a%10;
                      A6=a;
                    }
               else if(a>=10)
                    {
                      A4=0;
                      A5=a/10;
                      a=a%10;
                      A6=a;
                    }
               else  
                    {
                      A4=0;
                      A5=0;
                      A6=a;
                    }
               if(b>=10)
                    {
                      A7=b/10;
                      b=b%10;
                      A8=b;
                    }
                else
                    {
                      A7=0;
                      A8=b;
                    }
             }
         else
               {
                  T=27315-T;
                  a=T/100;
                  b=T-a*100;
                  A4=9;
                  if(a>=10)
                      {
                         A5=a/10;
                         a=a%10;
                         A6=a;
                      }
                  else  
                      {
                         A5=0;
                         A6=a;
                      }
                  if(b>=10)
                      {
                         A7=b/10;
                         b=b%10;
                         A8=b;
                      }
                  else
                      {
                         A7=0;
                         A8=b;
                      }
                }
             mah[4]=A4;
             mah[3]=A5;
             mah[2]=A6;
             mah[1]=A7;
             mah[0]=A8;
}
//------------------------------
void start(void)       //開始條件是 SCK=1 時,SDA 由 1 到 0
{
SCK=0;
delay(4);
SDA=1;
delay(4);
SCK=1;
delay(4);
SDA=0;
delay(4);
SCK=0;
delay(4);
}
//------------------------------
void stop(void)        //停止條件是 SCK=1 時,SDA 由 0 到 1
{
SCK=0;
delay(4);
SDA=0;
delay(4);
SCK=1;
delay(4);
SDA=1;
delay(4);
}
//---------發送一個字節---------
void SendByte(uchar number)
{
uchar i,n,dat;
n=Nack_number;       //可以重發次數
    Send_again:
dat=number;
for(i=0;i<8;i++)       //8 位依次發送
{
  if(dat&0x80)         //取最高位
  {
   bit_out=1;         // 發 1
  }
  else
  {
   bit_out=0;         // 發 0
  }   
  send_bit();          //發送一個位
  dat=dat<<1;          //左移一位
}  
read_bit();          //接收 1 位 應答信號
if(bit_in==1)           //無應答時重發
{
  stop();
  if(n!=0)
  {
   n--;          //可以重發 Nack_number=10 次
   goto Repeat;     // 重發
  }
  else
  {
   goto exit;      // 退出
  }   
}
else
{
  goto exit;
}   
Repeat:
start();        //重新開始
goto Send_again;      // 重發
exit: ;         // 退出
}
//-----------發送一個位---------
void send_bit(void)
{
if(bit_out==1)
{
  SDA=1;          // 發 1
}  
else
{
  SDA=0;          // 發 0
}
_nop_();
SCK=1;           // 上升沿
delay(4);delay(4);
SCK=0;
delay(4);delay(4);
}
//----------接收一個字節--------
uchar ReadByte(void)
{
uchar i,dat;
dat=0;         // 初值為 0
for(i=0;i<8;i++)
{
  dat=dat<<1;       // 左移
  read_bit();       //接收一位
  if(bit_in==1)
  {
   dat=dat+1;      // 為 1 時對應位加 1
  }   
}
SDA=0;         //發送應答信號 0
send_bit();
return dat;        //帶回接收數據
}
//----------接收一個位----------
void read_bit(void)
{
SDA=1;         //數據端先置 1
bit_in=1;
SCK=1;         // 上升沿
delay(4);delay(4);
bit_in=SDA;        // 讀數據
_nop_();
SCK=0;
delay(4);delay(4);
}


//------------------------------
uint readtemp(void)
{
SCK=0;
start();         //開始條件
SendByte(0x00);       //發送從地址 00
SendByte(0x07);       //發送命令
start();         //開始條件
SendByte(0x01);       //讀從地址 00
bit_out=0;
tempL=ReadByte();      //讀數據低字節
bit_out=0;
tempH=ReadByte();      //讀數據高字節
bit_out=1;
err=ReadByte();       //讀錯誤信息碼
stop();         //停止條件
return(tempH*256+tempL);
}
//******************LCD 顯示子函數***********************
void init1602(void)       //初始化 LCD
{
cmd_wrt(0x01);       // 清屏
cmd_wrt(0x0c);       //開顯示,不顯示光標,不閃爍
cmd_wrt(0x06);       //完成一個字符碼傳送后,光標左移,顯 示不發生移位
cmd_wrt(0x38);       //16 ×2 顯示,5×7 點陣,8 位數據接口
}
void busy(void)        //LCD忙標志判斷
{
flag=0x80;        // 賦初值 高位為 1 禁止
while(flag&0x80)      //讀寫操作使能位禁止時等待 繼續檢測
{
  LCD=0xff;
  RS=0;         //指向地址計數器
  RW=1;         // 讀
  LCDE=1;        //信號下降沿有效
  flag=LCD;       //讀狀態位 高位為狀態
  LCDE=0;
}
}
void cmd_wrt(uchar cmd)      //寫命令子函數
{
LCDE=0;
busy();         //檢測 讀寫操作使能嗎
LCD=cmd;         // 命令
RS=0;          //指向命令計數器
RW=0;          // 寫
LCDE=1;         //高電平有效
LCDE=0;
}
void dat_wrt(uchar dat)      //寫數據子函數
{
busy();         //檢測 讀寫操作使能嗎
LCDE=0;
if(flag==16)
{   
  RS=0;        //指向指令寄存器   
  RW=0;         // 寫
  LCD=0XC0;       //指向第二行
  LCDE=1;        //高電平有效
  LCDE=0;
}  
RS=1;         //指向數據寄存器
RW=0;          // 寫
LCD=dat;         // 寫數據
LCDE=1;         //高電平有效
LCDE=0;
}
//------------延時--------------
void delay(uint n)
{
uint j;
for(j=0;j<n;j++)
{
  _nop_();
}
}

//------------定時器初始化函數----------------
void initInt()
{
TMOD = 0x10;       // 定時器 1 方式 1
TH1=(65536-1000)/256;     //定時器 1 設置 1ms 定時
TL1=(65536-1000)%256;
    EA=1;                              //開總中斷                          
ET1 = 1;                          //開定時器 T1 中斷   
TR1 = 1;                             //啟動定時器 T1
}

//------------定時器中斷處理函數-------------------
void timer1handle() interrupt 3   //定時器 3 1ms 中斷
{
TH1=(65536-1000)/256;
TL1=(65536-1000)%256;
c20ms++;
c100ms++;
if(c20ms >= 20)    //20ms 計時器
    {
        c20ms = 0;      
        b20ms = 1;
    }
if(c100ms >= 50)    //100ms 計時器
    {
        c100ms = 0;      
        b100ms = 1;
    }
}

//--------------------------溫度顯示函數------------------------
void show()     
{      
DPY1=0;  
LCD=LED01[mah[4]];           //轉換 8 位數顯示,不帶小數點的
delay1(2);
LCD=0xFF;
DPY1=1;

DPY2=0;  
LCD=LED02[mah[3]];            //轉換 8 位數顯示,帶小數點的  
delay1(2);
LCD=0xFF;  

DPY1=0;  
LCD=LED01[mah[2]];            //轉換 8 位數顯示,不帶小數點的
delay1(2);
LCD=0xFF;

DPY3=0;
DPY2=1;
DPY1=1;  
LCD=LED01[mah[1]];            //轉換 8 位數顯示,不帶小數點的
delay1(2);
LCD=0xFF;
DPY1=0;

LCD=LED01[mah[0]];            //轉換 8 位數顯示,不帶小數點的
delay1(2);
LCD=0xFF;
DPY3=1;
DPY1=1;  
}


void ReadKey(void)
{
    row1=0;           //矩陣鍵盤第 1 列,將第一列拉低,掃描是否有按鍵按下,第一列按鍵包 括:1,4,7
    row2=1;           //矩陣鍵盤第 2 列
    row3=1;           //矩陣鍵盤第 3 列
    cow1=1;           //矩陣鍵盤第 1 行  
    cow2=1;           //矩陣鍵盤第 2 行
    cow3=1;           //矩陣鍵盤第 3 行
_nop_();          //延時函數
if(!(cow1&cow2&cow3)) //如果有鍵按下,就返回,且判斷是那個鍵值,否則繼續掃描下 一列
{
if(cow1==0)
key_num=1;
    if(cow2==0)
key_num=4;
if(cow3==0)
key_num=7;
return;
}

    row1=1;           //矩陣鍵盤第 1 列,將第一列拉低,掃描是否有按鍵按下,第一列按鍵包 括:2,5,8
    row2=0;           //矩陣鍵盤第 2 列
    row3=1;           //矩陣鍵盤第 3 列
    cow1=1;           //矩陣鍵盤第 1 行  
    cow2=1;           //矩陣鍵盤第 2 行
    cow3=1;           //矩陣鍵盤第 3 行
_nop_();          //延時函數
if(!(cow1&cow2&cow3)) //如果有鍵按下,就返回,且判斷是那個鍵值,否則繼續掃描下 一列
{
if(cow1==0)
key_num=2;
    if(cow2==0)
key_num=5;
if(cow3==0)
key_num=8;
return;
}

row1=1;           //矩陣鍵盤第 1 列,將第一列拉低,掃描是否有按鍵按下,第一列按鍵包 括:3,6
    row2=1;           //矩陣鍵盤第 2 列
    row3=0;           //矩陣鍵盤第 3 列
    cow1=1;           //矩陣鍵盤第 1 行  
    cow2=1;           //矩陣鍵盤第 2 行
_nop_();          //延時函數
if(!(cow1&cow2)) //如果有鍵按下,就返回,且判斷是那個鍵值,否則繼續掃描下一列
{
if(cow1==0)
key_num=3;
    if(cow2==0)
key_num=6;
return;
}
}
//--------------數碼管顯示延時函數-----------------------------------------------------
void delay1(uint z)
{
  uint x,y;
  for(x=z;x>0;x--)
  for(y=110;y>0;y--);
}

我使用的傳感器

我使用的傳感器
IMG_20190807_101536.jpg

HC6800-ES V2.0.pdf

404.98 KB, 下載次數: 22

使用的開發板原理圖

Datasheet-MLX90614-中文-數據手冊-rev008.pdf

1.52 MB, 下載次數: 27

傳感器中文手冊

回復

使用道具 舉報

ID:703871 發表于 2020-3-7 16:33 | 顯示全部樓層
最后怎么解決的?
回復

使用道具 舉報

ID:583286 發表于 2020-3-15 11:20 | 顯示全部樓層
cwgyyj 發表于 2020-3-7 16:33
最后怎么解決的?

我使用的單片機里面使用了定時器中斷,導致時鐘無法運行,這個溫度用到了時鐘有沖突!你可以換別的型號能滿足這些中斷要求的單片機
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: a免费在线| www.日韩高清 | 久久亚洲国产精品 | 美女福利网站 | 男女免费在线观看视频 | 欧美一区二区三区在线观看 | 欧美日韩1区 | 国产98色在线 | 日韩 | www.久 | 中文字幕在线三区 | 久久精品福利 | 911精品国产 | 91精品久久久久久久99 | 亚洲网站在线观看 | 日韩视频一级 | 亚洲国产精品99久久久久久久久 | 蜜桃免费一区二区三区 | 久久中文视频 | 亚洲免费精品 | 欧美极品少妇xxxxⅹ免费视频 | 亚洲免费视频播放 | 国产一区二区三区亚洲 | 国产欧美一区二区三区免费 | 免费一区二区三区在线视频 | 成人欧美一区二区三区在线观看 | 婷婷91| 黄色一级视频 | 九九精品在线 | www.男人天堂.com | 国产精品久久久久久亚洲调教 | 精品国产99| 黄视频网站免费观看 | 国产成人精品免费视频大全最热 | 中文字幕二区 | 一区在线视频 | 日本高清在线一区 | 97视频在线免费 | 美女视频一区二区三区 | 婷婷国产一区二区三区 | 国产区精品视频 | 免费观看一区二区三区毛片 |