cumtnj

    1. DS18B20 测温程序完全解读 10/10247 单片机 2008-04-11
      上个程序俺用数码管显示温度,这次就贴个用LCD1602显示的吧,呵呵…… lcd1602硬件连接:        /*---------------------------------------------------------------------------------------------------- TC1602A(16*2)模拟口线接线方式 连接线图:          ---------------------------------------------------        |LCM-----51   | LCM-----51   | LCM------51      |        -------------------------------------------------------------------        |D0-----P0.0 | D4-----P0.4 | RW------接地 (只能写) |        |D1-----P0.1 | D5-----P0.5 | RS-------P3.5           |        |D2-----P0.2 | D6-----P0.6 | E---------P3.4            |        |D3-----P0.3 | D7-----P0.7 | VLCD接1K电阻到GND|        --------------------------------------------------- ---------------- [注:AT89c52使用11.0592M晶振] ---------------------------------------------------------------------------------------------------------*/ DS18B20的硬件连接:        这个没有变,和上一个程序一样 程序如下:    #include  "reg52.h" #include  "intrins.h" #define uchar unsigned char #define uint unsigned int sbit DS=P2^2; sbit dula=P2^6; sbit wela=P2^7; sbit LCD1602_E=P3^4; sbit LCD1602_RS=P3^5; uchar flag; uint temp; uchar tflag;       //温度正负标志位 uint tvalue;         //呵呵 刚开始又犯了那个错误,就是tvalue的类型要声明为int型 uchar data disdata[5]; uchar table1[]="temperature:";      //lcd第一行要显示的字符 uchar table2[]="            ";      //lcd第二行初始化时使用 /*********************************************** LCD1602 的操作 ***********************************************/ void delay(uint x)    //延时子函数 {     uint a,b;     for(a=x;a>0;a--)       for(b=10;b>0;b--); } /*--------------------------------------------- 写指令,看着时序图编写就可以了 ------------------------------------------------  */ void lcd_write_cmd(uchar cmd) {    P0=cmd;    LCD1602_RS=0;    LCD1602_E=0;    delay(10);    LCD1602_E=1;    delay(10);    LCD1602_E=0; } /*----------------------------------- 读指令,同样要看着时序图写 -------------------------------------*/ void lcd_write_data(uchar data1) {    P0=data1;    LCD1602_RS=1;    LCD1602_E=0;    delay(10);    LCD1602_E=1;    delay(10);    LCD1602_E=0; } /*----------------------------------- lcd1602 的初始化设置 -------------------------------------*/ void init_lcd1602(void) {     dula=0;     wela=0;     lcd_write_cmd(0x38);     delay(20);     lcd_write_cmd(0x0e);     delay(20);     lcd_write_cmd(0x06);     delay(20);     lcd_write_cmd(0x01);     delay(20); } /*----------------------------------- 初始化lcd1602的显示时用到的显示函数 -------------------------------------*/ void display(unsigned char *p) {     while(*p!='\0')     {         lcd_write_data(*p);         p++;         delay(20);     } } /*----------------------------------- 初始化lcd1602的显示 -------------------------------------*/ void  init_lcd_display(void) {   init_lcd1602();   lcd_write_cmd(0x80); //设定第一行显示初始地址   delay(20);   display(table1);   lcd_write_cmd(0xc0); //设定第而行显示的初地址   delay(20);   display(table2); } /*********************************************** DS18B20 的操作 ***********************************************/ /*----------------------------------- 延时函数 -------------------------------------*/ void TempDelay (uchar us) {    while(us--); } /*ds18b20 的初始化*/ void ds_reset(void) {    DS=1;    _nop_();        //1us    DS=0;    TempDelay(80);  //当总线停留在低电平超过480us,总线上所以器件都将被复位,这里延时约530us                    //总线停留在低电平超过480μs,总线上的所有器件都将被复位。    _nop_();    DS=1;           //产生复位脉冲后,微处理器释放总线,让总线处于空闲状态,原因查18b20中文资料    TempDelay(5);  //释放总线后,以便从机18b20通过拉低总线来指示其是否在线,                   //存在检测高电平时间:15~60us, 所以延时44us,进行1-wire presence detect(单线存在检测)    _nop_();    _nop_();    _nop_();   if(DS==0)       flag=1;       //detect 18b20 success    else       flag=0;       //detect 18b20 fail   TempDelay(20);    //存在检测低电平时间:60~240us,所以延时约140us    _nop_();    _nop_();    DS=1;          //再次拉高总线,让总线处于空闲状态 /**/ } /*----------------------------------------------------------- 读/写时间隙:             DS1820 的数据读写是通过时间隙处理             位和命令字来确认信息交换。 -------------------------------------------------------------*/ bit  ds_read_bit(void)    //读一位 {    bit dat;    DS=0;          //单片机(微处理器)将总线拉低   _nop_();       //读时隙起始于微处理器将总线拉低至少1us    DS=1;          //拉低总线后接着释放总线,让从机18b20能够接管总线,输出有效数据    _nop_();    _nop_();          //小延时一下,读取18b20上的数据 ,因为从ds18b20上输出的数据在读"时间隙"下降沿出现15us内有效    dat=DS;           //主机读从机18b20输出的数据,这些数据在读时隙的下降沿出现15us内有效    TempDelay(10);    //所有读"时间隙"必须60~120us,这里77us    return(dat);     //返回有效数据 } uchar ds_read_byte(void ) //读一字节 {     uchar value,i,j;     value=0;          //一定别忘了给初值     for(i=0;i1;     if(onebit)      //写 1     {       DS=0;       _nop_();          _nop_();      //看时序图,至少延时1us,才产生写"时间隙"         DS=1;       //写时间隙开始后的15μs内允许数据线拉到高电平      TempDelay(5);  //所有写时间隙必须最少持续60us     }     else         //写 0     {       DS=0;      TempDelay(8);    //主机要生成一个写0 时间隙,必须把数据线拉到低电平并保持至少60μs,这里64us      DS=1;       _nop_();      _nop_();     }   } } /*-------------------------------------------------------------------------------------- 进行温度转换:              先初始化              然后跳过ROM:跳过64位ROM地址,直接向ds18B20发温度转换命令,适合单片工作              发送温度转换命令 ----------------------------------------------------------------------------------------*/ void tem_change() {   ds_reset();   delay(1);              //约2ms   ds_write_byte(0xcc);   ds_write_byte(0x44); } /*---------------------------------------- 获得温度:                ------------------------------------------*/ uint get_temperature() {   float wendu;   uchar a,b;   ds_reset();   delay(1);              //约2ms   ds_write_byte(0xcc);   ds_write_byte(0xbe);   a=ds_read_byte();   b=ds_read_byte();   temp=b;   temp

最近访客

< 1/1 >

统计信息

已有50人来访过

  • 芯积分:--
  • 好友:--
  • 主题:2
  • 回复:1

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言