codeblocks 51單片機學習(二)74HC595模塊實現點陣屏

  • 引言:

74HC595是一個實現串行轉並行功能的芯片,這也是我們51單片機學習接觸到的第一個通過控制時序線完成數據輸入輸出的芯片,這樣的芯片在以後會遇到很多,像是完成數據存儲的EEPROM需要用到的I2C協議,還有完成計時功能的時鐘DS1302,他們在與主機進行交互時必然需要數據的輸入和讀取,所以我們在輸入讀取時就需要控制幾根由引腳控制的總線,通過控制這些總線的電平變化,我們就可以完成數據輸入和讀取。這些都是我自己的理解,有錯誤的地方希望可以得到指正。

在此之前我先講一下在學習這些模塊中需要理解的一些知識:

  1. 總線:一般的我們會有幾根時鐘線,其中一根數據時鐘線負責暫時存放一位數據,一根輸入時鐘線能將數據時鐘線的數據發送到寄存器,另一根總線控制整個過程。當然每個芯片都有不同,像是DS18B20溫度傳感器只有一根線就能完成所有操作,I2C只有兩根線,而SPI則有4根線,但是總體來說一定包含了以上3個功能,或是將它們的功能分開成多根線,或是將它們功能合併從而減少線的數量。
  2. 上升沿/下降沿:上升沿即是一根線由低電平轉變爲高電平的的過程,而下降沿就是高電平轉變爲低電平的過程。在上升沿或者下降沿的過程中就可以完成數據輸入或讀取的操作,具體視芯片的協議時序而定。

然後74HC595這個芯片是怎樣工作的呢,是怎樣做到將一串數據並行同時輸出的呢。下圖是74HC595數據手冊上給出的時序圖,也就是在程序設計中,根據這個時序圖我們就可以實現該芯片的功能。
首先,RCK相當於控制整個過程,在程序中先將RCK置爲低電平,待數據存儲完成後置爲高電平完成上升沿將寄存器內的數據發送出去。SER用於暫時存儲一位數據,CLK在每次下降沿會將SER數據存儲在寄存器中。不過不知爲何,這個時序圖有點難看懂,主要思路是這樣的吧,去參考代碼的話更好理解吧。
在這裏插入圖片描述

接下來讓我們分析一下點陣屏的原理,首先我們51單片機開發板上的點陣屏是一個8X8的一個點陣屏,點亮點陣屏的方法和led燈原理是一樣的,led燈就是發光二極管嘛,當一個燈正極一邊處於高電平狀態負極一邊處於低電平狀態時,該燈會有電流通過,led燈就會發光,所以去看看原理圖,控制led燈的端口是不是都是控制二極管的負極?所以在程序中,我們給一個引腳設置爲0,該led燈就會發光。而點陣屏無非就是燈的數量多了一些,所以這裏用到一個很神奇的控制方式:用P0端口與74HC595共同控制點陣屏。

  • 控制方式:
    P0端口和74HC595共同控制,分別是列方向控制和行方向控制。P0端口控制負極,從正方向看,P0端口是在行方向控制的,也就是說給P0端口的一個引腳賦值爲0,那它對應的那一列是可以亮的,最低位在每行右方,最高位在每行左方。而74HC595控制正極,而且是縱向控制,給74HC595發送的數據中,賦值爲1的對應的那一行是可以亮的,最低位在每列上方,最高位在每列下方。所以要使點陣屏的一個燈亮,需要在P0端口設置那一列的電平爲低,在74HC595中設置那一行的電平爲高。
  • PS:可以利用字模提取軟件提取一個含有8個元素的數組,通過在快速地將每一列顯示,形成一個字。
/*74HC595*/

#include <8051.h>
#define _nop_() __asm nop__endasm
#define CLK P3_5
#define SCK P3_6
#define SER P3_4
typedef unsigned char u8;
u8 b1[]={0xBE,0xAB,0xBE,0xAB,0x3F,0xF6,0xB3,0xBE};
u8 h1[]={0x45,0x2A,0x51,0x9D,0xF7,0x38,0x24,0x32};
u8 w1[]={0x89,0x7F,0x29,0x00,0x2A,0xFF,0x2A,0x60};
u8 k[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};

void _74HC595(u8 dat);
void delay10ms(void);   //誤差 0us


void main(void)
{
    while(1)
    {
        for(u8 i=0;i<8;i++)//逐列將該列並行數據輸入,也就是一列一列顯示,但是刷新的夠快就是全部顯示了
        {
            P0=k[i];//控制一行,將該行某一個點置爲低電平,該列可以亮
            _74HC595(h1[i]);//控制一列,將該列某一個點置爲高電平,該列可以亮
            //通過對P0端口和74HC595共同作用,P0取低電平,並行數據取高電平,對應的燈就亮
            _74HC595(0x00);//消影
        }
    }

}
/*完成數據串行轉並行的過程
其實就是將一串數據逐位存放
到寄存器中,然後一次性輸出
即爲並行輸出。
*/
void _74HC595(u8 dat)
{
    u8 i=0,j=0;
    SER=0;//串行數據輸入線,用來存放數據
    RCK=0;//串行寄存器時鐘線,進行上升沿,即由低電平到高電平的過程,將所有數據並行輸出。
    for(i=0;i<8;i++)
    {
        SER=dat>>7;
        dat <<= 1;
        CLK=1;//串行輸入時鐘,進行下降沿即可將SER中存放的數據存放到寄存器中
        j++;
        j++;
        CLK=0;//下降沿
    }
    RCK=1;//進行上升沿,將8位數據輸出
}

void delay10ms(void)   //誤差 0us
{
    unsigned char a,b,c;
    for(c=1;c>0;c--)
        for(b=38;b>0;b--)
            for(a=130;a>0;a--);
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章