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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2194|回復: 2
打印 上一主題 下一主題
收起左側

單片機程序功能:檢測DS18B20并顯示數碼管上;求大神解答

[復制鏈接]
跳轉到指定樓層
樓主
500黑幣
程序功能:檢車DS18B20并顯示數碼管上;晶振12hz

#include<STC8.h>
#include<intrins.h>
#define uchar unsigned char
#define uint  unsigned int
#define FOSC  12000000L
sbit w0=P1^0;
sbit w1=P1^1;
sbit w2=P1^2;
sbit w3=P1^3;
sbit w4=P1^4;
sbit w5=P1^5;
sbit w6=P1^6;
sbit w7=P1^7;
sbit w8=P5^4;
sbit w9=P5^5;
sbit s1=P2^1;
sbit s2=P2^2;
sbit s3=P2^3;
sbit s4=P2^4;
sbit s5=P2^0;
sbit l1=P4^0;
sbit l2=P4^1;
sbit l3=P4^2;//led
sbit l4=P4^3;//led
sbit l5=P4^4;
sbit  DQ=P2^5;//ds18b20
signed char m;         //溫度全局變量
unsigned char tempL=0;  //全局變量
unsigned char tempH=0;
unsigned int sdata;  //車輛到的溫度的整數部分
unsigned char xiaoshu1; //小數第一位
unsigned char xiaoshu2; //小數第二位
unsigned char xiaoshu;  //兩位小數
bit  fg=1;              //溫度正負標志
uchar code SM[]={
0x3f,0x06,0x5d,0x4f,
0x66,0x6b,0x7b,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void nb(uint z)   //??
{
uint x,y;
     x=z;
for(x;x>0;x--)
   for(y=110;y>0;y--);
}
void xs(uint tt)//顯示函數
{
uint nn;
uchar ge , shi;
    nn=tt;
    ge=nn%10;
    shi=tt/10%10;
    w6=0;
    P3=SM[shi];
    nb(10);
    w6=1;
    w7=0;
    P3=SM[ge];
    nb(10);
    w7=1;
}
void delay(unsigned char i)
{
     while(i--);
   
}
void delay1ms(int n)
{
  unsigned int i;
  for(i=124*n;i>0;i--);  //延時124*8+10=1002us
}
/*****&sup3;初始化DS18B20*****/
void Init_DS18B20(void)
{
unsigned char x=0;
DQ=1; //DQ置高
delay(8); //稍延遲
DQ=0; //發送復位脈沖
delay(100); //延時(>480us)
DQ=1; //拉高數據線
delay(5); //等待(15~60us)
x=DQ; //用來判斷DQ的值初始化有沒有成功;存在x=0;否者x=1;
delay(20);
if(x==0)//成功led3亮
{
  l3=0;
}
if(x)//失敗led4亮
{
  l4=0;
}//  問題led4常亮;感覺初始化失敗求大神解答


}
/*****讀一個字節*****/
ReadOneChar(void)  //住數據線先充高位拉低1us
{
unsigned char i=0; //每個走起最短持續時間60us,各個走起必須有1us以上的恢復;
unsigned char dat=0;
for (i=8;i>0;i--) //8位
{
  DQ=1;
  delay(1);
  DQ=0;
  dat>>=1;     //數據移位子
  DQ=1;
  if(DQ)
  dat|=0x80;     //得讀取數據線得到一個狀態
  delay(4);
} return(dat);
}
/*****寫一個字節*****/
void WriteOneChar(unsigned char dat)
{
unsigned char i=0; //數據線高拉低,產生寫起始信號。15us之內將數據寫的位數送到數據線上
for(i=8;i>0;i--) //
{
  DQ=0; //另一個寫周期之前要有1us高電平
  DQ=dat&0x01;  //按低位發送數據
  delay(5);
  DQ=1;
  dat>>=1;
}
delay(4);
}
/*****讀取溫度*****/
void ReadTemperature(void)
{
Init_DS18B20(); //初始化
WriteOneChar(0xcc); //跳過序列號
WriteOneChar(0x44); //啟動溫度轉換
delay(125); //轉換延時
Init_DS18B20();初始化
WriteOneChar(0xcc); //跳過讀序號
WriteOneChar(0xbe); //讀溫度寄存器
tempL=ReadOneChar(); //溫度高位
tempH=ReadOneChar(); //溫度低位

if(tempH>0x7f)      //最高位為1溫度為負
{
   tempL=~tempL;         //補碼轉換,取反加一
   tempH=~tempH+1;      
   fg=0;      //讀取溫度為負是fg=0
}
sdata = tempL/16+tempH*16;      //整數部分
xiaoshu1 = (tempL&0x0f)*10/16; //小數第一位
xiaoshu2 = (tempL&0x0f)*100/16%10;//小數第二位
xiaoshu=xiaoshu1*10+xiaoshu2; //小數兩位
}
\
void main()
{   
unsigned int i;
while(1)
{
  ReadTemperature(); //讀取溫度
  for(i=0;i<20;i++)
  {
   xs(sdata);    //顯示溫度
  }
}
}


最佳答案

查看完整內容

stc8的單片機速度快,你的復位延時肯定短了,最好買個邏輯分析儀看一下,淘寶上20幾塊錢的就夠了。
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:382826 發表于 2019-3-5 00:37 | 只看該作者
stc8的單片機速度快,你的復位延時肯定短了,最好買個邏輯分析儀看一下,淘寶上20幾塊錢的就夠了。
回復

使用道具 舉報

板凳
ID:164602 發表于 2019-3-5 08:01 | 只看該作者
STC8沒用過,不知道程序中應該做哪些設置。不過STC89C52做過的,功能正常,程序給你參考
主程序:/*******************************************************************************
* 實驗名                           :溫度顯示實驗
* 使用的IO             :
* 實驗效果       :數碼管顯示溫度
*        注意                                         :
*******************************************************************************/

#include<reg51.h>
#include"temp.h"

//數碼管IO
#define DIG        P0
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

unsigned char code DIG_CODE[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char Num=0;
unsigned int disp[8]={0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f};

void LcdDisplay(int);
void Timer0Configuration();

/*******************************************************************************
* 函數名         : main
* 函數功能                   : 主函數
* 輸入           : 無
* 輸出                  : 無
*******************************************************************************/

void main()
{
    Timer0Configuration();
        while(1)
        {
                LcdDisplay(Ds18b20ReadTemp());
        }
}

/*******************************************************************************
* 函數名         : LcdDisplay()
* 函數功能                   : LCD顯示讀取到的溫度
* 輸入           : v
* 輸出                  : 無
*******************************************************************************/

void LcdDisplay(int temp)          //lcd顯示
{

          unsigned char datas[] = {0, 0, 0, 0, 0}; //定義數組
        float tp;  
        if(temp< 0)                                //當溫度值為負數
          {
        disp[2] = 0x40;
                //因為讀取的溫度是實際溫度的補碼,所以減1,再取反求出原碼
                temp=temp-1;
                temp=~temp;
                tp=temp;
                temp=tp*0.0625*100+0.5;       
                //留兩個小數點就*100,+0.5是四舍五入,因為C語言浮點數轉換為整型的時候把小數點
                //后面的數自動去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進1了,小于0.5的就
                //算加上.5,還是在小數點后面。

          }
        else
          {       
        disp[2] = 0;               
                tp=temp;//因為數據處理有小數點所以將溫度賦給一個浮點型變量
                //如果溫度是正的那么,那么正數的原碼就是補碼它本身
                temp=tp*0.0625*100+0.5;       
                //留兩個小數點就*100,+0.5是四舍五入,因為C語言浮點數轉換為整型的時候把小數點
                //后面的數自動去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進1了,小于0.5的就
                //算加上0.5,還是在小數點后面。
        }
    disp[0] = 0;
    disp[1] = 0;
    disp[3] = DIG_CODE[temp / 10000];
        disp[4] = DIG_CODE[temp % 10000 / 1000];
        disp[5] = DIG_CODE[temp % 1000 / 100] | 0x80;
        disp[6] = DIG_CODE[temp % 100 / 10];
        disp[7] = DIG_CODE[temp % 10];

}

/*******************************************************************************
* 函數名         : Timer0Configuration()
* 函數功能                   : 設置計時器
* 輸入           : 無
* 輸出                  : 無
*******************************************************************************/

void Timer0Configuration()
{
        TMOD=0X02;//選擇為定時器模式,工作方式2,僅用TRX打開啟動。

        TH0=0X9C;        //給定時器賦初值,定時100us
        TL0=0X9C;       
        ET0=1;//打開定時器0中斷允許
        EA=1;//打開總中斷
        TR0=1;//打開定時器               
}

/*******************************************************************************
* 函數名         : DigDisplay() interrupt 1
* 函數功能                   : 中斷數碼管顯示
* 輸入           : 無
* 輸出                  : 無
*******************************************************************************/

void DigDisplay() interrupt 1
{
//定時器在工作方式二會自動重裝初,所以不用在賦值。
//        TH0=0X9c;//給定時器賦初值,定時1ms
//        TL0=0X00;               
        DIG=0; //消隱
        switch(Num)         //位選,選擇點亮的數碼管,
        {
                case(7):
                        LSA=0;LSB=0;LSC=0; break;
                case(6):
                        LSA=1;LSB=0;LSC=0; break;
                case(5):
                        LSA=0;LSB=1;LSC=0; break;
                case(4):
                        LSA=1;LSB=1;LSC=0; break;
                case(3):
                        LSA=0;LSB=0;LSC=1; break;
                case(2):
                        LSA=1;LSB=0;LSC=1; break;
                case(1):
                        LSA=0;LSB=1;LSC=1; break;
                case(0):
                        LSA=1;LSB=1;LSC=1; break;       
        }
        DIG=disp[Num]; //段選,選擇顯示的數字。
        Num++;
        if(Num>7)
                Num=0;
}


18B20驅動程序temp.c:
#include"temp.h"
/*******************************************************************************
* 函數名         : Delay1ms
* 函數功能                   : 延時函數
* 輸入           : 無
* 輸出                  : 無
*******************************************************************************/

void Delay1ms(unsigned int y)
{
        unsigned int x;
        for(y;y>0;y--)
                for(x=110;x>0;x--);
}
/*******************************************************************************
* 函數名         : Ds18b20Init
* 函數功能                   : 初始化
* 輸入           : 無
* 輸出                  : 初始化成功返回1,失敗返回0
*******************************************************************************/

unsigned char Ds18b20Init()
{
        unsigned int i;
    EA = 0;
        DSPORT=0;                         //將總線拉低480us~960us
        i=70;       
        while(i--);//延時642us
        DSPORT=1;                        //然后拉高總線,如果DS18B20做出反應會將在15us~60us后總線拉低
        i=0;
    EA = 1;
        while(DSPORT)        //等待DS18B20拉低總線
        {
                i++;
                if(i>5000)//等待>5MS
                        return 0;//初始化失敗       
        }
        return 1;//初始化成功
}

/*******************************************************************************
* 函數名         : Ds18b20WriteByte
* 函數功能                   : 向18B20寫入一個字節
* 輸入           : com
* 輸出                  : 無
*******************************************************************************/

void Ds18b20WriteByte(unsigned char dat)
{
        unsigned int i,j;
    EA = 0;
        for(j=0;j<8;j++)
        {
                DSPORT=0;                        //每寫入一位數據之前先把總線拉低1us
                i++;
                DSPORT=dat&0x01; //然后寫入一個數據,從最低位開始
                i=6;
                while(i--); //延時68us,持續時間最少60us
                DSPORT=1;        //然后釋放總線,至少1us給總線恢復時間才能接著寫入第二個數值
                dat>>=1;
        }
    EA = 1;
}
/*******************************************************************************
* 函數名         : Ds18b20ReadByte
* 函數功能                   : 讀取一個字節
* 輸入           : com
* 輸出                  : 無
*******************************************************************************/


unsigned char Ds18b20ReadByte()
{
        unsigned char byte,bi;
        unsigned int i,j;
    EA = 0;       
        for(j=8;j>0;j--)
        {
                DSPORT=0;//先將總線拉低1us
                i++;
                DSPORT=1;//然后釋放總線
                i++;
                i++;//延時6us等待數據穩定
                bi=DSPORT;         //讀取數據,從最低位開始讀取
                /*將byte左移一位,然后與上右移7位后的bi,注意移動之后移掉那位補0。*/
                byte=(byte>>1)|(bi<<7);                                                  
                i=4;                //讀取完之后等待48us再接著讀取下一個數
                while(i--);
        }
    EA = 1;                               
        return byte;
}
/*******************************************************************************
* 函數名         : Ds18b20ChangTemp
* 函數功能                   : 讓18b20開始轉換溫度
* 輸入           : com
* 輸出                  : 無
*******************************************************************************/

void  Ds18b20ChangTemp()
{
        Ds18b20Init();
        Delay1ms(1);
        Ds18b20WriteByte(0xcc);                //跳過ROM操作命令                 
        Ds18b20WriteByte(0x44);            //溫度轉換命令
//        Delay1ms(100);        //等待轉換成功,而如果你是一直刷著的話,就不用這個延時了

}
/*******************************************************************************
* 函數名         : Ds18b20ReadTempCom
* 函數功能                   : 發送讀取溫度命令
* 輸入           : com
* 輸出                  : 無
*******************************************************************************/

void  Ds18b20ReadTempCom()
{       

        Ds18b20Init();
        Delay1ms(1);
        Ds18b20WriteByte(0xcc);         //跳過ROM操作命令
        Ds18b20WriteByte(0xbe);         //發送讀取溫度命令
}
/*******************************************************************************
* 函數名         : Ds18b20ReadTemp
* 函數功能                   : 讀取溫度
* 輸入           : com
* 輸出                  : 無
*******************************************************************************/

int Ds18b20ReadTemp()
{
        int temp=0;
        unsigned char tmh,tml;
        Ds18b20ChangTemp();                                 //先寫入轉換命令
        Ds18b20ReadTempCom();                        //然后等待轉換完后發送讀取溫度命令
        tml=Ds18b20ReadByte();                //讀取溫度值共16位,先讀低字節
        tmh=Ds18b20ReadByte();                //再讀高字節
        temp=tmh;
        temp<<=8;
        temp|=tml;
        return temp;
}

18B20頭文件temp.h:

#ifndef __TEMP_H_
#define __TEMP_H_

#include<reg51.h>

sbit DSPORT=P3^7;

void Delay1ms(unsigned int );
unsigned char Ds18b20Init();
void Ds18b20WriteByte(unsigned char com);
unsigned char Ds18b20ReadByte();
void  Ds18b20ChangTemp();
void  Ds18b20ReadTempCom();
int Ds18b20ReadTemp();

#endif


對應的電路圖:







回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产一区 在线视频 | 一道本不卡 | 国产一区二区三区精品久久久 | 国产精品欧美一区喷水 | 色黄网站 | 欧美激情在线播放 | 草逼网站| 久色视频在线观看 | 韩国精品在线 | 一区二区日韩 | 99精品在线观看 | 亚洲精品一区二区三区中文字幕 | 草久久| 亚洲一区高清 | 日韩中文一区 | 成人激情视频免费观看 | 日韩精品免费在线观看 | 久久一区二区av | 欧美激情精品久久久久久变态 | 日韩亚洲欧美综合 | 国产精品久久网 | 日韩a| 国产亚洲一区二区三区 | 欧美日韩精品一区 | 国产免费看 | 日韩中文在线 | 伊人网在线综合 | 在线高清免费观看视频 | 91精品一区 | 久久久69| 亚洲成人a v| 国产精品成人久久久久a级 久久蜜桃av一区二区天堂 | 欧美一二三 | 天天操人人干 | tube国产| 黄色精品视频网站 | 一级特黄色毛片 | 可以免费看的毛片 | 91在线免费视频 | 亚洲欧美成人 | 国产一区二区三区视频在线观看 |