在嵌入式設計中,微控制器中存在沒有足夠的I/O引腳的可能性。這可能是由于任何原因造成的,可能是您的應用程序需要多個 LED,或者您想使用多個 7 段顯示器,但您的微控制器中沒有所需的 I/O 引腳。這里有一個完美的組件,移位寄存器。移位寄存器接受串行數據并提供并行輸出。它只需要3 個引腳即可與您的微控制器連接,您將從中獲得超過 8 個輸出引腳。其中一個流行的移位寄存器是74HC595。它具有8位存儲寄存器和8位移位寄存器。
您將向移位寄存器提供串行數據,該數據將被鎖存于存儲寄存器上,然后存儲寄存器將控制 8 個輸出。如果您想要更多輸出,只需添加另一個移位寄存器。通過級聯兩個移位寄存器,您將獲得額外的 8 個輸出,總共 16 位輸出。
移位寄存器 74HC595:
這是根據數據表的74HC595的引腳圖-
HC595 有 16 針;如果我們看到數據表,我們將了解引腳功能-
QA至QH,從引腳號1到7和15用作移位寄存器的8位輸出,其中引腳14用于接收串行數據。還有關于如何使用其他引腳和利用移位寄存器的其他功能的真值表。
當我們編寫用于連接74HC595的代碼時,我們將應用此真值表來獲取所需的輸出。
所需組件:
PIC16F877A
2個33pF陶瓷盤式電容器
20兆赫晶體
4.7k 電阻
8顆發光二極管
1k 電阻器 -1 個(如果需要每個 LED 上的單獨電阻器,則需要 8 個 1k 電阻器)
74HC595 集成電路
5V墻上適配器
PIC 編程環境
面包板和電線
電路圖:
在電路圖中,我們連接了串行數據引腳;時鐘和選通(鎖存)引腳分別位于微控制器的RB0,RB1和RB2引腳上。在這里,我們使用一個電阻器用于8個LED。根據真值表,我們通過將74HC595的引腳13接地來啟用輸出。QH引腳保持打開狀態,因為我們不會用它級聯另一個74HC595。我們通過將移位寄存器的引腳10與VCC連接來禁用清除輸入標志。
晶體振蕩器連接在微控制器的 OSC 引腳上。PIC16F877A 沒有任何內部振蕩器。在本項目中,我們將使用移位注冊表從 Q0 到 Q7逐個點亮 lead。
我們在面包板中構建了電路-
代碼說明:
文末給出了使用移位寄存器控制LED的完整代碼。與往常一樣,我們需要在PIC微控制器中設置配置位。
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3/PGM pin has PGM function; low-voltage programming enabled)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
之后,我們聲明了延遲所需的晶體頻率和74HC595的引腳聲明。
#include
/*
Hardware related definition
*/
#define _XTAL_FREQ 20000000 //Crystal Frequency, used in delay
#define DATA_595 PORTBbits.RB0
#define STROBE_595 PORTBbits.RB1
#define CLK_595 PORTBbits.RB2
接下來我們聲明了 system_init() 函數來初始化引腳方向。
void system_init(void){
TRISB = 0x00;
}
我們使用兩種不同的函數創建了時鐘脈沖和鎖存脈沖
/*
*This function will enable the Clock.
*/
void clock(void){
CLK_595 = 1;
__delay_us(500);
CLK_595 = 0;
__delay_us(500);
}
和
/*
*This function will strobe and enable the output trigger.
*/
void strobe(void){
STROBE_595 = 1;
__delay_us(500);
STROBE_595 = 0;
}
在這兩個函數之后,我們聲明了data_submit(無符號 int data)函數以向74HC595提交串行數據。
void data_submit(unsigned int data){
for (int i=0 ; i<8 ; i++){
DATA_595 = (data >> i) & 0x01;
clock();
}
strobe(); // Data finally submitted
}
在此函數中,我們接受 8 位數據并使用兩個按位運算符左移和AND運算符發送每個位。我們首先逐個移動數據,并使用帶有 0x01 的 AND 運算符找出確切的位是 0 還是 1。每個數據都由時鐘脈沖存儲,最終數據輸出使用鎖存器或選通脈沖完成。在此過程中,數據輸出將首先是MSB(最高有效位)。
在主函數中,我們提交了二進制文件,并逐個將輸出引腳調高。
system_init(); // System getting ready
while(1){
data_submit(0b00000000);
__delay_ms(200);
data_submit(0b10000000);
__delay_ms(200);
data_submit(0b01000000);
__delay_ms(200);
data_submit(0b00100000);
__delay_ms(200);
data_submit(0b00010000);
__delay_ms(200);
data_submit(0b00001000);
__delay_ms(200);
data_submit(0b00000100);
__delay_ms(200);
data_submit(0b00000010);
__delay_ms(200);
data_submit(0b00000001);
__delay_ms(200);
data_submit(0xFF);
__delay_ms(200);
}
return;
}
這就是移位寄存器可用于在任何微控制器中獲得更多空閑I/O引腳以連接更多傳感器的方式。
-
微控制器
+關注
關注
48文章
7627瀏覽量
151768 -
傳感器
+關注
關注
2552文章
51320瀏覽量
755330 -
移位寄存器
+關注
關注
3文章
259瀏覽量
22307 -
i/o
+關注
關注
0文章
33瀏覽量
4600
發布評論請先 登錄
相關推薦
評論