打印
[菜农助学交流]

【第四批】入门笔记第三帖—LCD +18b20

[复制链接]
2230|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zxcscm|  楼主 | 2012-2-2 22:42 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
说到DS18B20,开始玩单片机时接触的第一个外围器件就是它了,虽不能说精通其操作,但对其流程也早已了然于心了。既然助学板上有DS18B20,肯定要拿来把玩了。
不说太多废话,只说说俺在调试时遇到的困惑
I/O模拟单总线访问DS18B20,最关键的就是时序了。对于51单片机好办,因为知道指令的执行周期,所以可以用软件延时做到精确的控制,但在ARM上指令不再有固定的执行周期,也就无法估算软件延时的时间了。
俺先把一起自己用过的51程序移植过来,改了端口和延时,花了很长时间也没成功,
找来网友“烈火狂龙”的程序,移植过来仍然不行,很纳闷,又找来网友“lixiaoxu2meng”的程序,这次干脆直接拷贝,不做任何改动,下载后能读出温度了!
比较俺前后的程序,发现俺的程序操作流程和lixiaoxu2meng的几乎一模一样,可俺自个写的程序就是读不出温度,作为菜鸟,只能暂时作罢,纠结下去也没有意义。这次只是把以前学的整合一下。
若有精力一定要研究研究李老师是如何用uart操作ds18b20


言归正传,简单介绍下程序功能:开机LCD显示“菜农助学板 祝愿园地 越来越红火” 按下K1显示温度,按下K2显示18B20的内部ID,长按K1显示欢迎界面,长按K2显示“新春快乐”


ds18b20程序:

/***************************************************/
/*     参照lixiaoxu2meng\烈火狂龙的程序修改而成    */
/*     移值于其它MCU时,注意修改端口和延时函数    */
/*     2012.02.02-01(调试通过)               zxcscm*/
/***************************************************/

#include "ds1.h"
//extern unsigned int value;
unsigned int temp_value;
extern unsigned char DS18B20_sign_flag=0;
/*************************************************************************************
** Function name:       ds1820reset
** Descriptions:        DS18B20初始化
** input parameters:    none
** output parameters:   none
** Returned value:      none
*************************************************************************************/
void ds1820reset()
{  
    /*step1:首先主机产生RESET脉冲*/
    DQ_OUTPUT;     //将DQ引脚设置为输出
    CLR_DQ;      //DQ引脚输出低电平(即拉低至少为480us)
    delay_ds18b20(300);   //精确延时  大于480us
    SET_DQ;      //DQ引脚输出高电平(即释放数据线)
   /*step2:等待15~60us后 DS18B20将把数据线拉低60~240us 以作为应答*/
    DQ_INPUT;     //将DQ引脚设置为输入
    while(DQ_STATE);    //如果没有应答也一直等待(注意在while里可加上超时处理 以免通信出错 而造成死机)
    while(!DQ_STATE);   //应答后等待(注意在while里可加上超时处理 以免通信出错 而造成死机)
    /*step3:释放数据线,并延时480us(因为等待与应答必须大于480us才算整个初始化完成)*/      
    SET_DQ;      //DQ引脚输出高电平(即释放数据线)
    delay_ds18b20(300);   //为了保证初始化完成 在延时480us   
}   
/*************************************************************************************
** Function name:       ds1820rd
** Descriptions:        DS18B20 读数据
** input parameters:    none
** output parameters:   none
** Returned value:      none
*************************************************************************************/
unsigned char ds1820rd()//读数据
{
    unsigned char i=0;
    unsigned char dat = 0;
    for (i=8;i>0;i--)
    {
        DQ_OUTPUT;//将DQ引脚设置为输出
        CLR_DQ;//DQ引脚输出低电平(即拉低)
        delay_ds18b20(2);
        dat>>=1;
        SET_DQ;//DQ引脚输出高电平
        DQ_INPUT;//将DQ引脚设置为输入   
        delay_ds18b20(2);
        if(DQ_STATE)
        dat|=0x80;
        delay_ds18b20(40);//大于60us
    }
    DQ_OUTPUT;     
    SET_DQ; //放数据线
    return(dat);
}
/*************************************************************************************
** Function name:       ds1820rd
** Descriptions:        DS18B20 写数据
** input parameters:    none
** output parameters:   none
** Returned value:      none
*************************************************************************************/
void ds1820wr(unsigned char wdata)//写数据
{
    unsigned char i=0;
    for (i=8; i>0; i--)
    {
        DQ_OUTPUT;    //将DQ引脚设置为输出
        CLR_DQ;    //DQ引脚输出低电平(小于15us )
        delay_ds18b20(2);  //延时小于15us
        if(wdata&0x01) SET_DQ; //DQ引脚输出高电平
        else  CLR_DQ;   //DQ引脚输出低电平     
        delay_ds18b20(40);  //延时大于60us
        SET_DQ;    //DQ引脚输出高电平
        wdata>>=1;
    }
}
extern void GetRom_DS18B20(unsigned char *p)
{
    unsigned char i;
    ds1820reset();
    //if(Reset_DS18B20()==0xff)
    {
        ds1820wr(0x33);
        for(i=8;i>0;i--)
        {
            *p++=ds1820rd(); //由低位到高位读
        }
    }
}
/*extern void ReadRom_DS18B20(unsigned char rom[8])
{
unsigned char i;
if(Reset_DS18B20()==0xff)
    {
        WriteByte_DS18B20(ds18b20_ReadRom);
        for(i=8;i>0;i--)
        {
            rom[i-1]=ReadByte_DS18B20();
        }
    }
}
************************************************************************************
** Function name:       read_temp
** Descriptions:       读取温度值并将读到的温度进行处理
** input parameters:    none
** output parameters:   none
** Returned value:      none
*************************************************************************************/
extern unsigned int read_temp()//读取温度值并转换
{
    unsigned char a,b;
    temp_value = 0;
    ds1820reset();   
    ds1820wr(0xcc);//跳过读序列号
    ds1820wr(0x44);//启动温度转换
    ds1820reset();   
    ds1820wr(0xcc);//跳过读序列号
    ds1820wr(0xbe);//读取温度
    a=ds1820rd();
    b=ds1820rd();
    temp_value=b;
    temp_value<<=8;
    temp_value=temp_value|a;
    if(temp_value<0x0fff)   //如果为正数
    DS18B20_sign_flag=0;
    else                 //如果为负数
    {
        temp_value=~temp_value+1;
     DS18B20_sign_flag=1;
    }
    temp_value=temp_value*(0.625);//温度值扩大10倍,精确到1位小数
    return(temp_value);
}
/*************************************************************************************
** Function name:       delay_ms
** Descriptions:        1ms(晶振为12MHZ)延时子程序
** input parameters:    count
** output parameters:   无
** Returned value:      无
*************************************************************************************/
void delay_ms(unsigned int count)
{
    unsigned int i,j;
for(i=count;i>0;i--)
    for(j=2395;j>0;j--);
}
/*************************************************************************************
** Function name:       delay_ms
** Descriptions:        大约40us(晶振为12MHZ)延时子程序
** input parameters:    count
** output parameters:   无
** Returned value:      无
*************************************************************************************/
void delay_ds18b20(unsigned int count)
{
    unsigned int i,j;
for(i=count;i>0;i--)
   for(j=2;j>0;j--);
}



其他程序感兴趣的请见工程包 04-DS18B20_LCD.rar (827.08 KB)


开机画面:



按下K1显示温度:

按下K2显示ID:



长按K2:









相关帖子

沙发
yulri| | 2012-2-9 10:58 | 只看该作者
好东西!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

628

帖子

1

粉丝