新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 單片機驅動數碼管電路的制做

        單片機驅動數碼管電路的制做

        作者: 時間:2016-11-22 來源:網絡 收藏
        把七或八只發光二極管組合在一個模件上組成了個8字和小數點,用以顯示數字。為了減少管腳,把各個發光管的其中同一個極接在一起作為共用點,因此就產生了共陽極和共陰極數碼之說。共陽管就是把各個發光管的正極接在一起,而共陰管就剛好相反。見下圖:

        本文引用地址:http://www.104case.com/article/201611/319671.htm
        大部分的邏輯IC的吸收電流要強于輸出電流。因此,大家都愛使用共陰極的數碼管,因為可選的IC多些。很可惜,我的這組數碼管是共陽的,因此公共端我打算用三級管來驅動。最常用的S9012,首先我得計劃好電路方式,就采用最常用的動態掃描顯示。先搭建最簡電路,調試出需采用元件的參數。


        先不接上圖的R2和74HC244,將數碼管一個段直接接地。調節R1,測得S9012基極電流為0.21mA時集電極也就是數碼管上已有40mA,說明放大倍數足夠了。這時接上R2和74HC244,調節R2使數碼管電流控制在15mA,這樣當8個段一起點亮時三極管上得通過120mA的電流。而基極上需要0.63mA,為了減小三極管的負荷應使三極管過飽和,,調節R1使基極電流為2mA,此時測得集電極和漏極之間的電壓約0.1V。好!此時R1為2K。R2為240歐姆。


        接下來就是確定電路。電路的接口與AT89S51間有三組接口:段碼、位碼和電源。為了讓AT89S51獨立出來這三級接口都采用插針做接口,用排線自由連接到AT89S51的P1-P3口,電源用短路帽連接,完成后的板子見下圖





        然后就是寫程序。先寫個查詢方式的吧!
        //六位管碼管在以0.3秒的間隔在閃爍,這是采用查詢方式的,比較占CUP資源

        # include
        typedef unsigned char uchar;
        uchar code bit_num[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};//位碼值表:0,1,2,3,4,5
        uchar code meg_val[]={0x03,0x9f,0x25,0x0d,0x99,0x49};//段碼值表:0,1,2,3,4,5
        uchar code hello[]={0x03,0xe3,0xe3,0x61,0x91,0xff}; //HELLO
        uchar code beybey[]={0x89,0x61,0xc1,0x89,0x61,0xc1};//beybey
        uchar code ab6789[]={0xc1,0x11,0x09,0x01,0x1f,0x41};//ab6789
        void delay(int n);
        void main(void)
        {
        uchar i,m;
        P2=0xff; //先將段碼關閉
        P3=0xff; //將位碼關閉
        delay(20);//等待一會
        while(1)
        {
        for (m=30;m>0;m--) //顯示30次約0.3秒
        {
        for(i=0;i<=5;i++)
        {
        P2=0xff;
        P3=bit_num[i]; //輸出位碼到P3口
        P2=ab6789[i]; //輸出段碼到P2口
        delay(5);
        }
        }
        P2=0xff; //關閉段碼
        P3=0xff; //關閉位碼
        delay(1000); //等待0.3秒
        }
        }
        void delay(int n) //子程序
        {
        int j;
        uchar k;
        for(j=0;j
        {
        for(k=255;k>0;k--);
        }
        }
        ======================================
        當我插把程序寫入片子,插上電運行時,是亂碼。你猜怎么回事?
        原來那個P2口方向是反的,您注意過沒有,在AT89S51管腳排列上,P0--P1和P3都是上方為PX_0。而唯獨P2口管腳排列是下方為P2_0。方向則好是反的。既然反了,我就把段碼表重寫一下。再試,一切正常。
        在這里我說一下段碼的排列,好多人問數碼管段碼是如何排列的,我也在網上查了,好像沒有什么標準的排法,隨自己的接法而定,這也是導致為什么在網上下載的一些數碼管程序在自己的板子上不能正常顯示的原因。就普遍而言我最上面的那張圖示的標法最多,在上面程序里原打算也是P2_0對應段碼a(也就是上面的橫)。一直到P2_7對應段為h(就是小數點)。結果哪知道P2口剛好是反的。這樣一來也就是倒過來了,P2_0對應段h(小數點了)。例如我原先定義的數碼管顯示“2”段碼為10100100B的,一接反了就不再是“2”了。而要想再顯示“2”那就把段碼的高低位倒過來。改為00100101B就OK了。

        下面再寫個用中斷來顯示的:
        //這是采用中斷方式的,也是帶閃爍的。

        # include
        typedef unsigned char uchar;
        uchar code bit_num[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};//位碼:0,1,2,3,4,5
        uchar code meg_val[]={0x49,0x99,0x0d,0x25,0x9f,0x03};//段碼:0,1,2,3,4,5
        uchar i,aa; //定義全局變量
        bit fg; //定義一個亮起和熄滅標志
        void timer0(void) interrupt 1 using 1 //中斷程序
        {
        if (fg) //當fg為1時點亮6位數碼管
        { P2=0xff;
        if (i>=6)
        {
        i=0;
        }
        else
        {
        P3=bit_num[i]; //輸出位碼到P3口
        P2=meg_val[i]; //輸出段碼到P2口
        i++;
        }
        }
        else //當fg為0時熄滅數碼管
        {
        if(aa==0)
        {
        P3=0xff;
        P2=0xff;
        }
        }
        aa++;
        if (aa>=254) //當aa值累加至254時fg標志翻轉。
        {
        fg=~fg;
        aa=0;
        }
        TH0=0xf8; //重裝定時器初值,2ms,值為65536-2000
        TL0=0x30;
        }

        void main(void)
        {
        P2=0xff; //先將段碼關閉
        P3=0xff; //將位碼關閉
        TMOD=0x01;//設置T0為模式1
        TH0=0xf8; //裝入計數初值高位
        TL0=0x30; //裝入計數初值低位
        EA=1; //總充許
        ET0=1; //T0充許
        fg=1; //將亮、滅標志設置為亮
        TR0=1; //啟動中斷
        while(1);
        }
        OK!



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 长子县| 资溪县| 惠来县| 柏乡县| 太谷县| 兴安盟| 隆子县| 昌乐县| 揭西县| 台东县| 香港| 崇阳县| 金沙县| 乌审旗| 唐海县| 张家港市| 宣恩县| 长沙县| 济宁市| 龙井市| 巢湖市| 夏津县| 萍乡市| 海安县| 木里| 宁明县| 枣强县| 称多县| 隆安县| 长泰县| 紫阳县| 新干县| 榕江县| 淮阳县| 柞水县| 孙吴县| 潮州市| 华池县| 晋中市| 山西省| 肇东市|