<acronym id="xonnx"></acronym>
      <td id="xonnx"></td>
    1. <pre id="xonnx"></pre>

      1. 專注電子技術學習與研究
        當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

        時鐘及溫度用74hc164+74ls145數碼管顯示單片機程序

        作者:huqin   來源:本站原創   點擊數:  更新時間:2014年03月15日   【字體:

        下面是實物圖:



        電路圖很簡單我就不畫了 數碼管用74hc164串行轉并行芯片+74ls145這2個芯片驅動一個負責段選一個負責位選,具體看程序頂部的引腳定義.完整的keil工程文件下載地址: http://www.thefapper.com/f/164smg.rar   下面是程序源碼.

        #include<reg52.h>
        #include <intrins.h>
        #define uchar unsigned char
        #define uint unsigned int
        sbit iicclk=P1^0;////總線存儲時鐘引腳定義
        sbit iicdat=P1^1;////總線存儲數據引腳定義
        sbit hc164dat=P1^2;//段顯串行數據引腳定義
        sbit hc164clk=P1^3;//段顯串行時鐘引腳定義
        /*sbit hc164clr=P1^4;*///段顯芯片清零引腳,低電平時,全部輸出引腳清零,即低電平
        sbit ls145p0=P1^5;///位選譯碼芯片P0
        sbit ls145p1=P1^6;///位選譯碼芯片P1
        sbit ls145p2=P1^7;///位選譯碼芯片P2
        sbit ls145p3=P3^7;///位選譯碼芯片P2,用于在74HC164移入數據時P0~P3全置高,關閉所有數碼管
        sbit DS1820DQ=P0^0;
        sbit ADD=P0^4;///////加一
        sbit MINUS=P0^5;/////減一
        sbit ENTER=P0^6;/////確定
        sbit SET=P0^7;///////設定鍵
        uchar code tabledu[]={0xed,0x21,0x8f,0xab,0x63,0xea,0xee,0xa1,0xef,0xeb,0x0};//垃圾顯示板0~~9段顯數據
        uchar code tablewe[]={0x0,0x20,0x40,0x60,0x80,0xa0,0xc0,0xe0,0x10};//位選編碼,P2口高八位產生編碼值,0x10為關閉所有位選
        char dateshu[8];
        uchar tim,sec,ming,mins,hourg,hours,min,hour,setflag,seta,dqflag,temperl,temperh,dat;
        void delay1ms(uint x)//0.5毫秒延時函數
         {
          uint y,z;
           for(y=x;y>0;y--)
            for(z=60;z>0;z--);
         }
        void delayns()
         {
          _nop_();
          _nop_();
         
         }
        void delay10us(uchar z)//z為3是定時10微秒
        {
          while(z)
          z--;
        }
        void DelayX0us(uchar n)
        {
            while (n--)
            {
                _nop_();
                _nop_();
            }
        }
        void dqrsr()//1820初始化函數
            {
           
                 dqflag=0;
                 DS1820DQ=1;
                 delayns();
                 DS1820DQ=0;
                 DelayX0us(48);//時序延時500US
                 DS1820DQ=1;
                 delay10us(6);//時序延時20us
                  if(DS1820DQ==0)dqflag=1;
                 DelayX0us(42);
               
           
            }
        void dqwrite(uchar a)
           {
             uchar i;
            dqflag=0;
            DS1820DQ=1; //to釋放總線
            delayns();//時序延時
           
             for(i=8;i>0;i--)//寫一個字節的數據
              {
               DS1820DQ=0;//總線置低
               _nop_();
               _nop_();
              
               a=a>>1;//右移時,逸出位保存到CY中
               DS1820DQ=CY;//發送送據
               DelayX0us(6);//延時70us
               DS1820DQ=1; //to釋放總線
                      
              }
           }
        uchar dqread(void)//1820讀函數
           {
            uchar i;
            DS1820DQ=1; //to釋放總線
           
            delayns();//時序延時
                for(i=0;i<8;i++)
              {
               dat>>=1;
               DS1820DQ=0;
               _nop_();
               _nop_();
               DS1820DQ=1;       
               delayns();
              
               if(DS1820DQ)dat|=0x80; //如果讀回的數據為1則作與處理移入DAT變量
              
               DelayX0us(6);//延時70us
              }
           
            return dat;
           
           }
        void write164(uchar x)
           {
             uchar y;
             hc164clk=0;//時鐘置低
             _nop_();
             _nop_();
               for(y=0;y<8;y++)
                {
            hc164dat=(x&0x80);
            delayns();
            hc164clk=1;
            delayns();
            hc164clk=0;
            delayns();
            x<<=1;
             }
          
           }
        void init()
         {
          P0=0xff;//輸入接口P0全置一,讓按鍵讀回輸入信息
          P2=tablewe[8];//關閉所有數碼管的位選
          hc164clk=0;//時鐘置低,以產生上升沿移入數據
          IE=0X82;  //EA=1開總中斷ET0=1定時器零中斷允許
          TCON=0X10;//TR0=1定時零中斷啟動
          TMOD=0X01;//M1M0=01 T0 工作方式1,16位定時器
          TH0=(65636-50000)/256;
          TL0=(65636-50000)%256;//50ms定時初值
          DS1820DQ=1;
         
         }
        void iicstart()//暫未使用
         {
         
         }
        void iicstop()//暫未使用
         {
         
         }
        void display(uchar a,uchar b,uchar c,uchar d,uchar e,uchar f,uchar g,uchar h)//顯示函數
           {
            P2=tablewe[8];
            write164(tabledu[a]);
            P2=tablewe[0];
            delay1ms(2);
            
            P2=tablewe[8];
            write164(tabledu[b]);
            P2=tablewe[1];
            delay1ms(2);
            P2=tablewe[8];
            write164(tabledu[c]);
            P2=tablewe[2];
            delay1ms(2);
            P2=tablewe[8];
            write164(tabledu[d]);
            P2=tablewe[3];
            delay1ms(2);
            P2=tablewe[8];
            write164(tabledu[e]);
            P2=tablewe[4];
            delay1ms(2);
            P2=tablewe[8];
            write164(tabledu[f]);
            P2=tablewe[5];
            delay1ms(2);
            P2=tablewe[8];
            write164(tabledu[g]);
            P2=tablewe[6];
            delay1ms(2);
            P2=tablewe[8];
            write164(tabledu[h]);
            P2=tablewe[7];
            delay1ms(2);
           }
        void timer()//24小時時間計算函數
           {
            
            if(sec>59)
             {
             
             
              sec=0;
              min++;
                 if(min>59)
                {
                 min=0;
                 hour++;
                  if(hour>23)
                 {
                   hour=0;
                 }
                }
             
             }
           dateshu[0]=sec%10;
           dateshu[1]=sec/10;
           dateshu[2]=min%10;
           dateshu[3]=min/10;
           dateshu[4]=hour%10;
           dateshu[5]=hour/10;
           
          
           }
        void key()//設定程序入口
           {
               if(SET==0)
                {
                 setflag=1;
                }
            
            
          
          
           }
        void keyshu()//設定鍵函數
           {
           
            bit b,d,e;
            b=MINUS;d=ADD;//變量B,D,E分別讀回P0。4~P0。6的狀態。分別為加一,減一,確認鍵
            e=ENTER;
            if(b==0)//減一按鍵按下
             {
              dateshu[seta]--;
               if(dateshu[seta]<0)dateshu[seta]=9;//減到零時自動循環回九
               b=MINUS;//再讀回鍵值,做松手查檢測
              while(b==0){b=MINUS;display(dateshu[0],dateshu[1],10,seta+1,dateshu[2],dateshu[3],dateshu[4],dateshu[5]);}//松手檢測
             
             }
            else if(d==0)//加一按鍵按下
             {
              dateshu[seta]++;
               if(dateshu[seta]>9)dateshu[seta]=0;//加到九時自動循環回零
               d=ADD;//做松手檢測
              while(d==0){d=ADD;display(dateshu[0],dateshu[1],10,seta+1,dateshu[2],dateshu[3],dateshu[4],dateshu[5]);}//松手檢測
            
             }
               else if(e==0)//確認鍵按下
             {
              seta++;
              e=ENTER;
              while(e==0){e=ENTER;display(dateshu[0],dateshu[1],10,seta+1,dateshu[2],dateshu[3],dateshu[4],dateshu[5]);}
              if(seta>5)//如果六位數值已設定完畢,測退出設定狀態
        {
         seta=0;sec=0;setflag=0;
         sec=dateshu[1]*10+dateshu[0];//分別將設定好的值,賦給時秒變量,設定生效
         min=dateshu[3]*10+dateshu[2];//分別將設定好的值,賦給分變量,設定生效
         hour=dateshu[5]*10+dateshu[4];//分別將設定好的值,賦給時變量,設定生效
         
        }
             }
           
        }  
        void main()

         {
           init();//各外圍元件及CPU初始化
           delay10us(150);//進入大循環時的延時
           while(1)
         
             {
             
               key();//檢測功能鍵有無按下
                  if(setflag==0)//如果設定功能未進入,則顯示實時時鐘
                 {
                timer();//時間運算函數
                display(dateshu[0],dateshu[1],10,10,dateshu[2],dateshu[3],dateshu[4],dateshu[5]);//顯示實時時鐘
                 }
               else//如果進入了功能設定函數
                 {
                keyshu();//讀取鍵值
                display(dateshu[0],dateshu[1],10,seta+1,dateshu[2],dateshu[3],dateshu[4],dateshu[5]);//顯示實時設定
                 }
                if((dateshu[0]==3)&&(dateshu[1]%2==0))//每隔十秒溫度讀取顯示一次
                 {uchar i;//顯示延時用
                  dqrsr();//初始化
                   if(dqflag==1)//檢測存在脈沖
                    {
                    
                     dqwrite(0xcc);//跳過ROM操作
                    
                     dqwrite(0x44);//開始溫度轉換
                     while(!DS1820DQ);//延時等待溫度轉換完畢
                      dqrsr();//初始化
                       if(dqflag==1)
                         {
                          uchar temper;//溫度變量
                          dqwrite(0xcc);//跳過ROM操作
                          dqwrite(0xbe);//讀取數據指令
                         
                          temperl=dqread();//讀取低字節溫度值
                          temperh=dqread();//讀取高字節溫度值
                          temperl=temperl>>4;//移去低四位的溫度值
                          temperh=temperh<<4;//移去讀回的符號號
                          temper=temperl+temperh;//將處理后的高字節溫度和低字節溫度值相加
                    for(i=250;i>0;i--)display(temper%10,temper/10,temper/100,10,10,10,10,10);//延時顯示實時溫度
                                          

                         }
                    }   
         
           
                 }
             }
         
         
         
         
         
         
         
         
         }
        void time0(void) interrupt 1
          {
         
           TH0=(65536-50000)/256;
           TL0=(65536-50000)%256;//定時器零重賦初值
            tim++;
             if(tim==20)
               {
                tim=0;//tim==20時,為50MS*20=1S
                sec++;
               }
         
          }

         


        關閉窗口

        相關文章

        欧美性色欧美精品视频,99热这里只有精品mp4,日韩高清亚洲日韩精品一区二区,2020国自产拍精品高潮