<strike id="um4h1"></strike>
<legend id="um4h1"><pre id="um4h1"><dl id="um4h1"></dl></pre></legend>
<th id="um4h1"><track id="um4h1"></track></th>
  • <dd id="um4h1"></dd><nav id="um4h1"><sub id="um4h1"></sub></nav>
    <rp id="um4h1"></rp>

    <dd id="um4h1"></dd>
    1. <th id="um4h1"></th>
       找回密碼
       馬上注冊

      QQ登錄

      只需一步,快速開始

      搜索

      [ 單片機 ] 純手工制作顯示溫度的時鐘

      2013-10-6 09:11| 發布者: lamp | 查看: 11139

      一、.先發下制作完成的成品

      手機拍的不是很清楚,但LCD上能看到顯示的時間和溫度值。

      因為國慶忙,還沒來加上設置按鍵和鬧鐘功能,后續一定補上!見諒!

      二、開始制作了

      材料清單:

      1.萬能電路板一塊

      2.ATmega16單片機一塊

      3.40DIP插座一塊

      4.1602LCD液晶顯示屏一塊

      5.ds1820溫度傳感器一只

      6.4.7K電阻一只

      7.7.3728Mhz晶振一只

      8.27P電容兩只

      9.排插和排坐若干

      10.USB下載線

      以上材料淘寶都可以買到,大概40元左右。

      三、我設計的原理圖

       

      ds1820引腳圖(用TO-92封裝的)

      LCD1602 引腳圖

      四、按圖紙手工焊接,大家動手能力這么強,具體過程我就不寫了。

      五、程序編寫(注:不懂得話可以直接跳過看下面的第六項)

      軟件使用ICCAVR軟件,網上搜下很容易下載。

      下面是我寫的程序:

      #include

      #include

      #include "delay.h"

      #include "1602.h"

      unsigned long int j=0;

      unsigned int s,t,h;

      unsigned char display[9]={0,0,0,0,0,0,0,0,0};//顯示數據


      typedef unsigned char  uint8; /* 定義可移植的無符號8位整數關鍵字    */

      typedef signed   char  int8; /* 定義可移植的有符號8位整數關鍵字    */

      typedef unsigned int   uint16; /* 定義可移植的無符號16位整數關鍵字   */

      typedef signed   int   int16; /* 定義可移植的有符號16位整數關鍵字   */

      typedef unsigned long  uint32; /* 定義可移植的無符號32位整數關鍵字   */

      typedef signed   long  int32; /* 定義可移植的有符號32位整數關鍵字   */


      extern unsigned char wmh,wml;           //全局變量

      extern unsigned char count,count1;

      #define CLR_DIR_1WIRE DDRD&=~BIT(4)     //只要修改這里的參數就可以了!呵呵! 

      #define SET_DIR_1WIRE DDRD|=BIT(4)      //里面什么都不用該! 

      #define CLR_OP_1WIRE PORTD&=~BIT(4) 

      #define SET_OP_1WIRE PORTD|=BIT(4)       

      #define CHECK_IP_1WIRE (PIND & 0x10)    //檢測 pD4


      void init_1820(void);


      void write_1820(unsigned char x);  


      unsigned char read_1820(void);


      /*************************************************

      ** 讀取溫度值

      ** 更改全局變量 wmh,wml; 溫度的高低位

      *************************************************/

      extern void gettemp(void);


      unsigned char count,count1,flag; //flag溫度為負標志,count為實際溫度

      void init_1820(void)  

      {  

          SET_DIR_1WIRE;      //設置PC2 為輸出 

          SET_OP_1WIRE;   

          CLR_OP_1WIRE;  

          delay_nus(480);    //480us以上  

          SET_OP_1WIRE;  

          CLR_DIR_1WIRE;  

          delay_nus(20);     //15~60us  

          while(CHECK_IP_1WIRE);  

          SET_DIR_1WIRE;  

          SET_OP_1WIRE;  

          delay_nus(140);   //60~240us  

      }  

      void write_1820(unsigned char x)  

      {     

           unsigned char m;  

          for(m=0;m<8;m++)  

          {  

             CLR_OP_1WIRE;  

             if(x&(1<

             SET_OP_1WIRE;  

             else  

             {CLR_OP_1WIRE;}  

             delay_nus(40);   //15~60us  

             SET_OP_1WIRE;  

          }  

           SET_OP_1WIRE;  

      }  

      unsigned char read_1820(void)  

      {      

          unsigned char temp,k,n;  

          temp=0;  

          for(n=0;n<8;n++)  

          {

            CLR_OP_1WIRE;  

            SET_OP_1WIRE;  

            CLR_DIR_1WIRE;  

            k=(CHECK_IP_1WIRE);    //讀數據,從低位開始  

            if(k)  

            temp|=(1<

            else  

            temp&=~(1<

            delay_nus(50); //60~120us      

            SET_DIR_1WIRE;  

          }  

         return (temp);  

      }   


      void gettemp(void)         //讀取溫度值 

      {  

           unsigned char temh,teml,wm0,wm1,wm2,wm3;  

           init_1820();        //復位18b20  

           write_1820(0xcc);   // 發出轉換命令  

           write_1820(0x44); 

           delay_nms(800);     //不延時也好使,不知道怎么回事! 

           init_1820();  

           write_1820(0xcc);  //發出讀命令  

           write_1820(0xbe);  

           teml=read_1820();  //讀數據  

           temh=read_1820();  

           wm0=teml>>4;       //只要高8位的低四位和低8位的高四位,溫度范圍0~99啦! 

           wm1=temh<<4;

      j=(temh*256+teml)*5; //計算具體溫度   

           display[1]=j/100%10+0x30;

          display[2]=j/10%10+0x30;

          display[3]=j%10+0x30;

      LCD_write_char(5,1,display[1]); 

      LCD_write_char(6,1,display[2]);  

      LCD_write_char(7,1,'.'); 

      LCD_write_char(8,1,display[3]); 

      LCD_write_char(9,1,'C');

       

      }


      //TIMER1 initialize - prescale:1024

      // WGM: 0) Normal, TOP=0xFFFF

      // desired value: 1Sec

      // actual value:  1.000Sec (0.0%)

      void timer1_init(void)

      {

       TCCR1B = 0x00; //stop

       TCNT1H = 0xE3; //setup

       TCNT1L = 0xE1;

       OCR1AH = 0x1C;

       OCR1AL = 0x1F;

       OCR1BH = 0x1C;

       OCR1BL = 0x1F;

       ICR1H  = 0x1C;

       ICR1L  = 0x1F;

       TCCR1A = 0x00;

       TCCR1B = 0x05; //start Timer

      }


      void init_devices(void)

      {

       //stop errant interrupts until set up

       CLI(); //disable all interrupts

       timer1_init();


       MCUCR = 0x00;

       GICR  = 0x00;

       TIMSK = 0x1C; //timer interrupt sources

       SEI(); //re-enable interrupts

       //all peripherals are now initialized

      }


      #pragma interrupt_handler timer1_ovf_isr:9

      void timer1_ovf_isr(void)

      {

       //TIMER1 has overflowed

       TCNT1H = 0xE3; //reload counter high value

       TCNT1L = 0xE1; //reload counter low value

       if(s++ == 59)

           {s=0;

         if(t++ == 59)

       {t=0;

        if(h++ == 24)

          {h=1;

          }

       }

           }

      }


      void dis(void)

      display[4]=s/10+0x30;  

      display[5]=s%10+0x30;

      display[6]=t/10+0x30;  

      display[7]=t%10+0x30;

      display[8]=h/10+0x30;  

      display[9]=h%10+0x30;

      LCD_write_char(10,0,display[5]); 

      LCD_write_char(9,0,display[4]); 

      LCD_write_char(8,0,':'); 

      LCD_write_char(7,0,display[7]); 

      LCD_write_char(6,0,display[6]);

      LCD_write_char(5,0,':'); 

      LCD_write_char(4,0,display[9]); 

      LCD_write_char(3,0,display[8]);

      delay_nms(50);

      }


      void main(void)

      {h=24;

       t=59;

       s=55;

       init_devices();

       LCD_init(); 

       delay_nms(50);

       while(1)

       {      

             gettemp();

        dis();

             delay_nms(500);

       }

      經過ICCAVR編譯后生成的 hex 就是我們下載到單片機需要的文件。

       六.下載 time.hex 到單片機

      1.先下載 time.hex 文件

      2.把USB下載線插在ISP接口上。

      3.運行 AVR_fighter 軟件(買USB下載線送的配套軟件

      按圖紅圈先選擇 ATMEGA16,再設置好熔絲位,最后點擊寫入。

      4.

      點擊 裝FLASH 按鈕選擇 time.hex 文件后,點擊 編程。

      幾秒后你就會看到液晶顯示出時間和溫度值,因為因為國慶忙,還沒來加上設置按鍵和鬧鐘功能,后續加下,見諒!

      不過聰明的你一定看出來了,只要提前設定好 s,t,h(時、分、秒)編譯后下載,時鐘就能按你的要求工作了。

      最后,祝大家節日 geekfans 快樂!

      收藏 邀請
      上一篇:單片機萬年歷 下一篇:arduino小車
      已有10人參與

      會員評論

      • 引用 秋天楓葉林 2014-3-21 15:25
        呵呵,學習,學習,若自己動手就不用了,淘寶上22元搞定,外觀好的,自己動手制作價格都不止這么多錢啦
      • 引用 顏靖峰 2013-11-17 20:15
        嘻嘻看看我做的吧
      • 引用 睡神耗子 2013-10-12 10:21
        個人認為花費有點高……
        顯示溫度,用段碼液晶的顯示,省電還便宜……
        單片機用個便宜的就可以……
        估計節省下。不過15塊錢。
      • 引用 lamp 2013-10-8 20:57
        758425775: 呵呵,挺好的。值得推廣
        謝謝支持。!
      • 引用 758425775 2013-10-7 17:43
        呵呵,挺好的。值得推廣
      • 引用 lamp 2013-10-7 08:04
        Robbie: 個人認為綠屏好土,還是藍屏的好,就是沒背光看不見,有點費電
        手上沒有藍屏的,只好用綠屏的了,不過你的提議很好,后續我加上感應功能,有人屏就亮。
      • 引用 lamp 2013-10-7 07:56
        zjk995063909: 這是16位的單片機嗎?
        是AVR8位單片機
      • 引用 Robbie 2013-10-6 20:45
        個人認為綠屏好土,還是藍屏的好,就是沒背光看不見,有點費電
      • 引用 小小飛貓 2013-10-6 15:29
        個人認為A比1602D好用。。。。。
      • 引用 zjk995063909 2013-10-6 11:47
        這是16位的單片機嗎?

      查看全部評論>>

      推薦閱讀

      QQ|極客迷網 ( ICP09011854

      44030602000010

      © 2009-2016 All Rights Reserved

      GMT+8, 2022-4-16 06:06 , Processed in 0.103724 second(s), 17 queries , Gzip On, Memcache On.