PIC16f877a单片机DS18b20源程序

发布者:明理厚德最新更新时间:2019-11-25 来源: 51hei关键字:PIC16f877a  单片机  DS18b20 手机看文章 扫描二维码
随时随地手机看文章

//调试总结:
//显著的问题是,写时序、读时序中,PIC MCU向总线写1是通过改方向为输入方向由上拉电阻拉高数据线实现的,而非在输出方向下输出1,与AVR不同
//某IO口8位未全使用时,对整个IO口读取进行位运算无效
//使用if(dat2&0xf8==0xf8)时,进错分支导致显示乱码仍未找到原因,用if(dat2>=240)代替正常


#include

#define uchar unsigned char

#define uint unsigned int

#define rs_h (PORTC|=0x01)

#define rs_l (PORTC&=0xfe)

#define rs_o (TRISC&=0xfe)

#define rw_h (PORTC|=0x02)

#define rw_l (PORTC&=0xfd)

#define rw_o (TRISC&=0xfd)

#define en_h (PORTC|=0x04) 

#define en_l (PORTC&=0xfb)

#define en_o (TRISC&=0xfb)

#define temp_h (PORTC|=0x08) 

#define temp_l (PORTC&=0xf7) 

#define temp_o (TRISC&=0xf7)

#define temp_i (TRISC|=0x08)

#define led_o (TRISC&=0xef)

#define led_l (PORTC&=0xef)

#define led_h (PORTC|=0x10)

#define LCD PORTB

uchar dat1,dat2;//保存读出的温度z

unsigned long int dat;

void delayms(uint x) //4M晶振下,延时1ms

{

        uint y,z;

        for(y=x;y>0;y--)

                for(z=110;z>0;z--);

}

void Ds18b20_reset(void)//DS18B20初始化

{

        uint count;

        uchar i,flag=1;

        temp_o;

        temp_l;

        for(count=60;count>0;count--);//延时480us

        temp_i;

        while(flag)

        {

                //temp=PORTC;//此例中,C口部分引脚未使用处于高阻态,对整个C口的读取无效,所以if(RC3)不能换成if(temp&0x08==0x08)

                if(RC3)//temp&0x08==0x08)

                        flag=1;

                else

                        flag=0;        

        }

        led_o;

        led_l;//开指示灯

        for(count=60;count>0;count--);//延时480us

}

void Ds18b20_write(uchar datt)//向DS18B20写一个字节

{

        uchar count;

        uchar i;

        temp_o;

        for(i=8;i>0;i--)

        {

                temp_o;

                temp_l;

                for(count=1;count>0;count--);

                //temp_h;//不能有此语句

                if(datt&0x01==0x01)

                        temp_i;

                else

                {        

                        temp_o;

                        temp_l;

                }

                for(count=23;count>0;count--);//延时60us

                temp_i;

                for(count=1;count>0;count--);

                datt>>=1;        

        }        

}

uchar Ds18b20_read(void) //从DS18B20读一个字节

{

        uchar i,datt;

        uchar count;

        for(i=8;i>0;i--)

        {

                datt>>=1;

                temp_o;

                temp_l;

                for(count=1;count>0;count--);

                temp_i;//改为输入方向时,上拉电阻把数据线拉高,释放总线,此语句必须有,参考datasheet的P15

                for(count=1;count>0;count--);

                if(RC3)//(PORTC&0x08==0x08)//换成(PORTC&0x08==0x08)后程序不正确

                        datt|=0x80;

                for(count=23;count>0;count--);//延时60us        

        }

        return datt;

}

void lcd_com(uchar com)//向LCD1602写命令

{

         rs_o;

        rw_o;

        en_o;

        TRISB=0x00;//配置RB为输出方向

        rs_l;        

        rw_l;

        LCD=com;

        delayms(1);

        en_h;

        delayms(1);        

        en_l;

        delayms(1);                

}

void lcd_dat(uchar dat)//向LCD1602写数据

{

         rs_o;

        rw_o;

        TRISB=0x00;//配置RB为输出方向

        en_o;

        rs_h;        

        rw_l;

        LCD=dat;

        delayms(1);

        en_h;

        delayms(1);

        en_l;

        delayms(1);        

}

void lcd_write(uchar c,uchar r,uchar dat)//向LCD1602指定行、指定列、写数据

{

        lcd_com(0x80+0x40*c+r);

        lcd_dat(dat);

        delayms(1);

}

void lcd_init(void)//LCD1602初始化,初始化后第一行显示temperature:,第二行显示.C

{

        lcd_com(0x38);

        lcd_com(0x0c);

        lcd_com(0x06);

        lcd_write(0,2,0x54);

        lcd_write(0,3,0x65);

        lcd_write(0,4,0x6d);

        lcd_write(0,5,0x70);

        lcd_write(0,6,0x65);

        lcd_write(0,7,0x72);

        lcd_write(0,8,0x61);

        lcd_write(0,9,0x74);

        lcd_write(0,10,0x75);

        lcd_write(0,11,0x72);

        lcd_write(0,12,0x65);

        lcd_write(0,13,0x3a);

        lcd_write(1,11,0xdf);

        lcd_write(1,12,0x43);

}

void show(void)//把温度值送LCD1602显示

{

        uchar flag;

        uchar t[4];

        uint temp;

        if(dat2>=240)//遗留问题,温度为25时读出dat1=144,dat2=1正确,但却进入if(dat2&0xf8==0xf8)分支导致显示乱码;

        {

                dat= (~(dat2*256+dat1)+1)*(0.0625*10);//取反加一,保留一位小数

                flag=1;

        }

        else

        {

                dat=(dat2*256+dat1)*(0.0625*10);

                flag=0;

        };

        temp=dat%10;

        t[0]=(0x30+temp);

        temp=dat%100;

        temp=temp/10;

        t[1]=(0x30+temp);

        temp=dat%1000;

        temp=temp/100;

        t[2]=(0x30+temp);

        temp=dat/1000;

        t[3]=(0x30+temp);

        if(flag==1)//负温度显示

        {

                lcd_write(1,10,t[0]);

                lcd_write(1,9,0xa5);

                lcd_write(1,8,t[1]);

                lcd_write(1,7,t[2]);

                lcd_write(1,6,t[3]);

                lcd_write(1,5,0x2d);

        }

        if(flag==0)//正温度显示

        {

                lcd_write(1,10,t[0]);

                lcd_write(1,9,0xa5);

                lcd_write(1,8,t[1]);

                lcd_write(1,7,t[2]);

                lcd_write(1,6,t[3]);

                lcd_write(1,5,0x20);//显示空格,刷掉负号

        }

}

void main(void)

{

        lcd_init();

        while(1)

        {

                Ds18b20_reset();

                Ds18b20_write(0xcc);

                Ds18b20_write(0x44);//发送温度转换命令

                delayms(1000);//延时1s,等待温度转换完成

                Ds18b20_reset();

                Ds18b20_write(0xcc);

                Ds18b20_write(0xbe);//发送读温度寄存器命令

                dat1=Ds18b20_read();

                dat2=Ds18b20_read();

                show();

                led_h;//关指示灯

[1] [2]
关键字:PIC16f877a  单片机  DS18b20 引用地址:PIC16f877a单片机DS18b20源程序

上一篇:PIC延时函数的分析
下一篇:PIC单片机C语言简记

推荐阅读最新更新时间:2024-11-21 20:12

Microchip推出全球首款采用28引脚封装的64 KB闪存16位单片机
PIC24FJ64GA004系列首创引脚映射功能,体现最佳设计灵活性 全球领先的单片机和模拟半导体供应商——Microchip Technology Inc.(美国微芯科技公司)近日宣布,其极具成本效益的PIC24F 16位单片机系列中又新增8款器件,将产品类型扩展至体积更小、成本更低的28和44引脚封装,并配备16至64 KB闪存程序存储器和高达8 KB的RAM。 和其他采用28引脚封装的16位单片机相比,全新PIC24FJ64GA002单片机可提供更大片上存储容量。整个PIC24FJ64GA004系列可让设计人员灵活运用所有片上外设,通过“外设引脚选择”引脚映射功能,把外设映射至所需的引脚。 为了更好地满足成本和有限空间
[新品]
FPGA与单片机实现数据RS232串口通信的设计
1 前言 现场可编程逻辑器件(FPGA)在高速采集系统中的应用越来越广,由于FPGA对采集到的数据的处理能力比较差,故需要将其采集到的数据送到其他CPU系统来实现数据的处理功能,这就使FPGA系统与其他CPU系统之间的数据通信提到日程上,得到人们的急切关注。本文介绍利用VHDL语言实现 FPGA与单片机的串口异步通信电路。 整个设计采用模块化的设计思想,可分为四个模块:FPGA数据发送模块,FPGA波特率发生控制模块,FPGA总体接口模块以及单片机数据接收模块。本文着重对FPGA数据发送模块实现进行说明。 2 FPGA数据发送模块的设计 根据RS232 异步串行通信来的帧格式,在FPGA发送模块中采用的每一帧格式为:1位开始位 8
[单片机]
FPGA与<font color='red'>单片机</font>实现数据RS232串口通信的设计
单片机中三极管的应用
三极管在数字电路里的开关特性,最常见的应用有 2 个:一个是控制应用,一个是驱动应用。所谓的控制就是如图 3-7 里边介绍的,我们可以通过单片机控制三极管的基极来间接控制后边的小灯的亮灭,用法大家基本熟悉了。还有一个控制就是进行不同电压之间的转换控制,比如我们的单片机是 5V 系统,它现在要跟一个 12V 的系统对接,如果 IO 直接接 12V电压就会烧坏单片机,所以我们加一个三极管,三极管的工作电压高于单片机的 IO 口电压,用 5V 的 IO 口来控制 12V 的电路,如图 3-8 所示。 图 3-8 三极管实现电压转换 图 3-8 中,当 IO 口输出高电平 5V 时,三极管导通,OUT 输出低电平 0V,当 IO 口输
[单片机]
<font color='red'>单片机</font>中三极管的应用
基于单片机的室内环境参数自控系统设计
本设计是对在单片机上开发的环境参数控制系统的研究设计,主要对温室内各个环境状态进行控制和实时测量数据。其中环境参数控制中,采用51单片机、DTH11、光强传感器、MQ-2气体传感器的硬件电路检测和显示实时数据,采用传感器与单片机相接再由硬件与软件电路组合来实现对加热电阻丝以及风扇开关的控制和超出规定的上下限温度的报警。 01 系统总体设计 大棚内整体的模块和元件主要有单片机,数据采集模块,A/D转换电路,调节模块等组成,单片机作为其核心芯片,同时作为各种参数的处理器和控制器,从而完成不同环境参数的控制和处理,并且将数据进行转换后交给主控芯片。 环境参数数据主要由温度传感器,湿度传感器,光照传感器,气体传感器,分别实时
[单片机]
基于<font color='red'>单片机</font>的室内环境参数自控系统设计
英飞凌表示首次成为车用MCU市场第一
根据TechInsights的最新报告显示,2023年全球汽车半导体市场增长16.5%,达到 692 亿美元。英飞凌整体市场份额增长了1个百分点,从2022年的近13%增至2023年的约14%,巩固了该公司作为汽车半导体市场全球领导者的地位。 英飞凌的半导体对于服务所有汽车关键应用至关重要,例如驾驶员辅助和安全系统、动力总成和电池管理、舒适性、信息娱乐和安全。 据TechInsights称,英飞凌在所有地区的市场份额均有所增加,在韩国和中国持续保持市场领先地位。 此外,英飞凌在日本汽车半导体市场也取得了显着的增长。欧洲市场英飞凌排名第二,北美则排名第三。 “我们非常自豪能够扩大我们作为领先汽车半导体供应商的地位。 这一巨大
[汽车电子]
单片机 C语言 编程风格
文件头说明 :源程序(如头文件.h文件、.inc文件、.def文件、编译说明文件.cfg等)头部应进行注释,注释必须列出:版权说明、版本号、生成日期、作者、内容、功能、与其它文件的关系、修改日志等,头文件的注释中还应有函数功能简要说明。 /************************************************************ 版权信息: 文件名: test.cpp 作者: 日期: 功能: 版本: 历史修改记录 作者 日期 版本 说明 ***************************************
[单片机]
基于单片机的EV动力蓄电池组电量计量系统的设计
引言 随着汽车工业的迅速发展,解决汽车尾气排放所带来的大气污染问题的较好方案是发展无空气污染的交通工具,电动汽车随之应运而生。以蓄电池作为动力源的电动汽车,无论从技术上还是经济上都是最可行的。 电动汽车用的动力蓄电池通常由多节单体电池串联或者并联构成,一般串联的单体电池数可达到十至几十个,单体电池电压一般是12V,总电压在100V以上,总容量在100Ah以上。本文所阐述的蓄电池性能检测系统在结构设计上可以根据需要增加或减少被检测电池的数量,具有较高的灵活性,单片机控制使精度可达1%,利用改进的开路电压法进行数据运算,进一步提高了精度。 由于铅酸蓄电池容量有限并具有腐蚀性,镍镉蓄电池中镉是有污染的重金属,而镍氢电池的容量、充放电特性
[单片机]
基于<font color='red'>单片机</font>的EV动力蓄电池组电量计量系统的设计
恩智浦发布LPC2900系列 扩展了32位ARM MCU产品线
三款基于ARM968E-S处理器的全新恩智浦微控制器扩展了业界最广泛的32位 ARM 微控制器产品线 荷兰埃因霍芬,2007年9月24日 ——恩智浦半导体(NXP Semiconductors)(由飞利浦创建的独立半导体公司)发布了LPC2900系列微控制器,进一步扩展了其ARM7? 和ARM9? 微控制器业界最广泛的生产线。恩智浦LPC2900基于广受欢迎的、高性能的ARM968E-S? 处理器,针对工业、医疗、发动机控制和汽车电子行业内的应用,为设计师提供一个具有高成本效益、灵活的、低功耗的解决方案。恩智浦此次工发布了三款ARM9 微控制器,分别为LPC2919、LPC2917和LPC2915,使其业界领先的基于ARM技术
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved