找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机+18b20程序无法显示温度

[复制链接]
回帖奖励 20 黑币 回复本帖可获得 20 黑币奖励! 每人限 1 次
跳转到指定楼层
楼主
怎么将18b20的温度显示到屏幕上 单片机用的stc15f2k602
//////////////////////////////////////////////////////////////////////////////////         
//本程序只供学习使用,未经作者许可,不得用于其它任何用途

//  文 件 名   : main.c
//  版 本 号   : v2.0
//  作    者   : HuangKai
//  生成日期   : 2014-0101
//  最近修改   :
//  功能描述   : OLED 4接口演示例程(51系列)
//              说明:
//              ----------------------------------------------------------------
//              GND    电源地
//              VCC  接5V或3.3v电源
//              D0   P1^0(SCL)
//              D1   P1^1(SDA)
//              RES  接P12
//              DC   接P13
//              CS   接P14               
//              ----------------------------------------------------------------
// 修改历史   :
// 日    期   :
//All rights reserved
//******************************************************************************/
#include "STC15Fxxx.H"//调用stc15f系列头文件,下载地址:  http://pan.baidu.com/s/1eRUbjLS
#include "oled.h"
#include "bmp.h"

#define ds18b20_io P20   //P2.0口作为数据读取接口
void  Delay3us();                                   //22.1184M晶振精确延时30微秒
void  Delay6us();                                   //22.1184M晶振精确延时30微秒
void  Delay24us();                              //22.1184M晶振精确延时40微秒
void  Delay30us();                              //22.1184M晶振精确延时40微秒
void  Delay300us();                             //22.1184M晶振精确延时40微秒
void  Delay600us();                             //22.1184M晶振精确延时30毫秒
void    Delay1000ms();                          //22.1184M晶振精确延时1000毫秒

bit  ds18b20_init();                                //初始化ds18b20
u8   ds18b20_read_one_char();               //从ds18b20读取一个字节
void ds18b20_write_one_char(u8 dat);//向ds18b20写入一个字节
void ds18b20_ready_read_temp();         //准备读取数据
u16  ds18b20_read_temp_val();               //读取数据,返回温度值,返回实际值的100倍,且万位为符号位,例:12556为-25.56度,2556为25.56度
u8 high,low;
//变量定义

u16 datas=12345;//测试用
float f_temp ;//温度数据
u16 d2,d1,d0,temp;//测试


int main(void)
         {
                        OLED_Init();                        //初始化OLED  
                        OLED_Clear();//清屏
                        ds18b20_io = 1;//18b20先高电平
                        OLED_DrawBMP(0,0,128,8,BMP1);
                        delay_ms(1000);
                        OLED_Clear();
                        while(1)
                        {
                        datas=ds18b20_read_temp_val();//
                        if(datas/10000 == 1)  //如果万位为1,则表示温度为负
                        f_temp=datas*0.0625;  //温度在寄存器中为12位 分辨率位0.0625°
                        datas=f_temp*10+0.5;  //精确到十分位,四舍五入
                        d2=datas/100;  //显示数据:十位
                        d1=datas%100/10;  //显示数据:个位
                        d0=datas%10;  //显示数据:十分位
                      Delay1000ms();
                        OLED_ShowCHinese(0,2,6);//当
                        OLED_ShowCHinese(16,2,7);//前
                        OLED_ShowCHinese(32,2,8);//温
                        OLED_ShowCHinese(48,2,9);//度
                        OLED_ShowNum(76,2,d2,1,16);
                        OLED_ShowNum(92,2,d1,1,16);
                        OLED_ShowNum(108,2,d0,1,16);
                        OLED_ShowCHinese(112,0,1);//满电
                        }
        }
        
        //ds18b20初始化
bit ds18b20_init()
{
    u8 init_success_tag=0;
    ds18b20_io=1;//拉高
    Delay6us();//6us
    ds18b20_io=0;//拉低
    Delay600us();//600us
    ds18b20_io=1;//拉高
    Delay30us();//30us
    init_success_tag=ds18b20_io;
    Delay600us();//600us
    return init_success_tag;
}

//读取一个字节
u8 ds18b20_read_one_char()
{
    u8 i=0;
    u8 dat=0;
    for(i=0;i<8;i++)
    {
        ds18b20_io=1;//拉高
        NOP1();
        ds18b20_io=0;//拉低
        dat>>=1;
        NOP1();
        ds18b20_io=1;//拉高
        Delay6us();//6us
        if(ds18b20_io==1)
            dat|=0x80;
        else
            dat|=0x00;
        Delay24us();//24us
    }
    return (dat);
}

//向传感器写入一个字节
void ds18b20_write_one_char(u8 dat)
{
    u8 i=0;
    for(i=0;i<8;i++)
    {
        ds18b20_io=1;//拉高
        NOP1();
        ds18b20_io=0;//拉低
        ds18b20_io=dat&0x01;
        Delay30us();//30us
        ds18b20_io=1;//拉高
        Delay3us();//3us
        dat>>=1;
    }
    Delay6us();
    Delay6us();//12us
}

//准备读取一个温度值
void ds18b20_ready_read_temp()
{
    ds18b20_init();                          //初始化
    ds18b20_write_one_char(0xcc);//忽略读序列号
    ds18b20_write_one_char(0x44);//启动温度转换
    Delay300us();                                   //300us,等待转换完毕
    ds18b20_init();                          //初始化
    ds18b20_write_one_char(0xcc);//忽略读序列号
    ds18b20_write_one_char(0xbe);//读取温度寄存器
}

//读取数据,返回温度值,返回实际值的100倍,且万位为符号位,例:12556
u16 ds18b20_read_temp_val()
{
    u16 temp_16_bit=0;
    u8  temp_L=0;
    u8  temp_H=0;
    ds18b20_ready_read_temp();
    temp_L=ds18b20_read_one_char();//读取温度低八位
    temp_H=ds18b20_read_one_char();//读取温度高八位
    if(temp_H>0x7f)
    {
        temp_L=~temp_L;                    //补码转换,取反加一
        temp_H=~temp_H+1;  
        temp_16_bit=100;
    }
    temp_16_bit=temp_16_bit+temp_H*16+temp_L/16;
    temp_16_bit=temp_16_bit*100;
    temp_16_bit=temp_16_bit+((temp_L&0x0f)*10/16)*10;
    temp_16_bit=temp_16_bit+(temp_L&0x0f)*100/16%10;
    return (u16)(temp_16_bit);
}

void Delay3us()     //@22.1184MHz
{
    unsigned char i;

    i = 14;
    while (--i);
}

void Delay6us()     //@22.1184MHz
{
    unsigned char i;

    _nop_();
    _nop_();
    _nop_();
    i = 30;
    while (--i);
}

void Delay24us()        //@22.1184MHz
{
    unsigned char i, j;

    _nop_();
    _nop_();
    _nop_();
    i = 1;
    j = 128;
    do
    {
        while (--j);
    } while (--i);
}

void Delay30us()        //@22.1184MHz
{
    unsigned char i, j;

    i = 1;
    j = 162;
    do
    {
        while (--j);
    } while (--i);
}

void Delay300us()       //@22.1184MHz
{
    unsigned char i, j;

    i = 7;
    j = 113;
    do
    {
        while (--j);
    } while (--i);
}

void Delay600us()       //@22.1184MHz
{
    unsigned char i, j;

    _nop_();
    _nop_();
    _nop_();
    i = 13;
    j = 229;
    do
    {
        while (--j);
    } while (--i);
}

void Delay1000ms()      //@22.1184MHz
{
    unsigned char i, j, k;

    _nop_();
    _nop_();
    i = 85;
    j = 12;
    k = 155;
    do
    {
        do
        {
            while (--k);
        } while (--j);
    } while (--i);
}         
        
        

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

使用道具 举报

沙发
ID:57657 发表于 2023-7-17 06:10 | 只看该作者
先用示波器或逻辑分析仪检测 Delay类 函数时间是否正确。
回复

使用道具 举报

板凳
ID:161164 发表于 2023-7-17 11:44 | 只看该作者

回复

使用道具 举报

地板
ID:190152 发表于 2023-7-17 12:40 来自手机 | 只看该作者
感谢各位已经解决了,18B20程序没有问题。是读取的16位温度数据到oled设置问题
回复

使用道具 举报

5#
ID:190152 发表于 2023-7-17 12:41 来自手机 | 只看该作者
npn 发表于 2023-7-17 06:10
先用示波器或逻辑分析仪检测 Delay类 函数时间是否正确。

原程序是18b20串口温度显示。正常没有问题。我想做一个温度计加了个显示屏改改代码
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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