74hc165引腳圖及功能程序


74HC165:并行輸入串行輸出移位寄存器詳解
在數(shù)字電子領(lǐng)域,并行輸入串行輸出(PISO)移位寄存器是一種至關(guān)重要的器件,它能夠?qū)⒍鄠€(gè)并行輸入的數(shù)據(jù)位轉(zhuǎn)換為串行數(shù)據(jù)流,從而有效減少微控制器或其他邏輯器件所需的I/O引腳數(shù)量。其中,74HC165是CMOS系列中一款非常常用的8位PISO移位寄存器,以其高速度、低功耗和可靠性,在各種數(shù)據(jù)采集、傳感器接口和I/O擴(kuò)展應(yīng)用中占據(jù)著重要地位。
本章節(jié)將深入探討74HC165的引腳圖、各項(xiàng)功能、工作原理、時(shí)序分析,并提供基于常見(jiàn)微控制器(如Arduino和STM32)的編程示例,旨在幫助讀者全面理解和掌握74HC165的應(yīng)用。
1. 74HC165 概述與特點(diǎn)
74HC165是一款高速CMOS器件,屬于74HC(High-speed CMOS)系列。它繼承了CMOS器件低功耗的優(yōu)點(diǎn),同時(shí)擁有接近LSTTL(Low-power Schottky TTL)器件的速度。其核心功能是將8路并行輸入的數(shù)據(jù)同時(shí)載入內(nèi)部寄存器,然后通過(guò)一個(gè)時(shí)鐘脈沖,以串行方式一位一位地將數(shù)據(jù)移出。這種并行轉(zhuǎn)串行的能力使其成為擴(kuò)展微控制器輸入端口的理想選擇。
主要特點(diǎn)包括:
8位并行輸入: 可以同時(shí)接收8位數(shù)據(jù)。
串行輸出: 數(shù)據(jù)以串行方式逐位輸出。
異步并行載入: 允許在任何時(shí)鐘周期內(nèi)載入并行數(shù)據(jù),由PL(并行載入)引腳控制。
同步串行移位: 數(shù)據(jù)的移位與時(shí)鐘脈沖同步。
高噪聲抗擾性: CMOS特性使其對(duì)噪聲具有較強(qiáng)的抵抗能力。
寬工作電壓范圍: 通常為2V至6V,適用于多種電源環(huán)境。
寬溫度范圍: 適用于工業(yè)和商業(yè)應(yīng)用。
這些特性使得74HC165在按鈕陣列掃描、鍵盤(pán)接口、傳感器數(shù)據(jù)采集、多路開(kāi)關(guān)狀態(tài)監(jiān)測(cè)以及任何需要將大量并行輸入轉(zhuǎn)換為串行數(shù)據(jù)以節(jié)省I/O資源的場(chǎng)景中表現(xiàn)出色。
2. 74HC165 引腳圖及功能詳解
理解74HC165的引腳功能是正確使用它的前提。74HC165通常采用16引腳DIP(雙列直插式封裝)或SOIC(小外形集成電路封裝)等形式。
(注:此處應(yīng)為74HC165的引腳圖,由于我無(wú)法直接生成圖片,請(qǐng)您自行查找對(duì)應(yīng)的74HC165數(shù)據(jù)手冊(cè)以獲取準(zhǔn)確的引腳圖。)
以下是74HC165各引腳的詳細(xì)功能說(shuō)明:
2.1. 電源引腳
VCC (Pin 16): 電源正極輸入。通常連接到+5V或+3.3V電源。
GND (Pin 8): 接地引腳。連接到電源的負(fù)極或電路的公共地。
2.2. 并行輸入引腳
D0 - D7 (Pin 15, 14, 13, 12, 11, 10, 9, 7): 這八個(gè)引腳是8位并行數(shù)據(jù)的輸入端。當(dāng) PL(并行載入) 引腳為低電平(L)時(shí),數(shù)據(jù)會(huì)從這些引腳加載到內(nèi)部寄存器中。它們通常連接到傳感器、開(kāi)關(guān)、按鈕或其他需要讀取狀態(tài)的數(shù)字信號(hào)源。
2.3. 控制引腳
PL (Parallel Load) / SH/LD (Shift/Load) (Pin 1): 并行載入使能引腳。
低電平(L): 激活并行載入功能。當(dāng)此引腳為低電平,且時(shí)鐘(CP)處于上升沿時(shí),D0-D7引腳上的并行數(shù)據(jù)將被加載到內(nèi)部寄存器中。在某些數(shù)據(jù)手冊(cè)中,此引腳可能標(biāo)記為 overlineSH/LD,表示低電平時(shí)是載入(Load),高電平時(shí)是移位(Shift)。
高電平(H): 禁止并行載入,允許移位操作。 這個(gè)引腳是控制74HC165工作模式的關(guān)鍵,無(wú)論是讀取并行數(shù)據(jù)還是進(jìn)行串行移位,都需要正確設(shè)置它。
CP (Clock Pulse) (Pin 2): 時(shí)鐘輸入引腳。這是移位寄存器的主時(shí)鐘信號(hào)。
上升沿: 在移位模式下(PL為高電平),Q7(串行輸出)上的數(shù)據(jù)會(huì)移動(dòng)到Q6,Q6移動(dòng)到Q5,以此類(lèi)推,同時(shí)D7(并行輸入)上的數(shù)據(jù)移入Q0。
下降沿: 通常對(duì)數(shù)據(jù)移位沒(méi)有影響,但在某些應(yīng)用中可能會(huì)被用于特定的同步。 時(shí)鐘信號(hào)的穩(wěn)定性直接影響數(shù)據(jù)傳輸?shù)目煽啃浴?/span>
CE (Clock Enable) / CLK_INH (Clock Inhibit) (Pin 15): 時(shí)鐘使能/時(shí)鐘禁止引腳。
低電平(L): 允許時(shí)鐘(CP)信號(hào)通過(guò),移位寄存器正常工作。
高電平(H): 禁止時(shí)鐘信號(hào)通過(guò),即使CP引腳有脈沖,移位寄存器也不會(huì)發(fā)生移位。 這個(gè)引腳可以用來(lái)暫停數(shù)據(jù)移位,或者在多個(gè)移位寄存器級(jí)聯(lián)時(shí),對(duì)特定的芯片進(jìn)行時(shí)鐘控制。這個(gè)引腳與CP引腳共同控制移位操作的時(shí)序。
2.4. 串行輸出引腳
Q7 (Pin 6): 串行數(shù)據(jù)輸出引腳。這是移位寄存器的數(shù)據(jù)出口,每次時(shí)鐘脈沖(CP上升沿)后,最先被加載到內(nèi)部寄存器的數(shù)據(jù)位會(huì)從這里移出。通常連接到微控制器的GPIO引腳,用于接收串行數(shù)據(jù)。
overlineQ7 (Pin 5): Q7的互補(bǔ)輸出引腳。其邏輯狀態(tài)與Q7相反。這個(gè)引腳在某些應(yīng)用中可能有用,例如當(dāng)需要反向數(shù)據(jù)或作為輔助信號(hào)時(shí)。
3. 74HC165 工作原理
74HC165的工作原理可以分為兩個(gè)主要階段:并行數(shù)據(jù)載入和串行數(shù)據(jù)移位。
3.1. 并行數(shù)據(jù)載入
當(dāng) PL(并行載入) 引腳被拉低(邏輯L)時(shí),74HC165進(jìn)入并行載入模式。此時(shí),無(wú)論時(shí)鐘(CP)引腳處于何種狀態(tài),D0到D7引腳上的瞬時(shí)邏輯電平會(huì)被立即捕獲并加載到內(nèi)部的8個(gè)D觸發(fā)器中。這個(gè)過(guò)程是異步的,這意味著數(shù)據(jù)的載入不受時(shí)鐘邊沿的嚴(yán)格控制,只要PL為低,數(shù)據(jù)就會(huì)被載入。
重要提示: 為了確保數(shù)據(jù)的正確載入,在PL引腳從高電平變?yōu)榈碗娖?,并維持低電平的整個(gè)期間,D0-D7上的數(shù)據(jù)必須保持穩(wěn)定。一旦PL被拉高,數(shù)據(jù)就被鎖存,并且移位操作開(kāi)始。
3.2. 串行數(shù)據(jù)移位
當(dāng) PL 引腳被拉高(邏輯H)時(shí),74HC165進(jìn)入串行移位模式。此時(shí),移位寄存器開(kāi)始響應(yīng) CP(時(shí)鐘) 引腳的上升沿。
每當(dāng)CP引腳檢測(cè)到一個(gè)上升沿,內(nèi)部寄存器中的數(shù)據(jù)就會(huì)向右(從Q0到Q7方向)移動(dòng)一位。這意味著:
D7引腳上的當(dāng)前數(shù)據(jù)(如果CP_INH為低電平且PL為高電平)將移入Q0寄存器。
Q0寄存器中的數(shù)據(jù)移到Q1。
Q1寄存器中的數(shù)據(jù)移到Q2。
...
Q6寄存器中的數(shù)據(jù)移到Q7。
Q7寄存器中的數(shù)據(jù)將通過(guò)Q7引腳輸出。
CE(時(shí)鐘使能) 引腳在移位過(guò)程中扮演著重要的角色。如果CE為高電平,即使CP引腳有上升沿,移位操作也會(huì)被阻止,內(nèi)部寄存器的數(shù)據(jù)狀態(tài)保持不變。只有當(dāng)CE為低電平,并且PL為高電平,CP的上升沿才能觸發(fā)數(shù)據(jù)移位。
通過(guò)連續(xù)提供8個(gè)時(shí)鐘脈沖,可以依次從Q7引腳讀取完整的8位并行數(shù)據(jù)。第一個(gè)移出的位是D7處的數(shù)據(jù)(在載入時(shí))。
工作流程總結(jié):
將 PL 拉低,將并行數(shù)據(jù)(D0-D7)載入到74HC165的內(nèi)部寄存器中。
將 PL 拉高,使74HC165進(jìn)入移位模式。
確保 CE 保持低電平,允許時(shí)鐘通過(guò)。
發(fā)送一個(gè)時(shí)鐘脈沖(CP引腳產(chǎn)生一個(gè)上升沿),第一個(gè)數(shù)據(jù)位(即最初加載的D7位)會(huì)出現(xiàn)在 Q7 引腳上。
讀取 Q7 引腳上的數(shù)據(jù)。
重復(fù)步驟4和5,發(fā)送7個(gè)額外的時(shí)鐘脈沖,每次讀取一個(gè)數(shù)據(jù)位,直到所有8位數(shù)據(jù)都被讀取完畢。
4. 時(shí)序分析
理解74HC165的時(shí)序圖對(duì)于確保數(shù)據(jù)傳輸?shù)恼_性至關(guān)重要。時(shí)序圖描述了不同信號(hào)之間的時(shí)間關(guān)系,例如數(shù)據(jù)建立時(shí)間、保持時(shí)間、傳播延遲等。
4.1. 關(guān)鍵時(shí)序參數(shù)
t_su (Setup Time): 建立時(shí)間。指數(shù)據(jù)在時(shí)鐘有效沿到來(lái)之前,輸入數(shù)據(jù)必須保持穩(wěn)定的最短時(shí)間。例如,在PL引腳從低電平跳變?yōu)楦唠娖街?,并行?shù)據(jù)D0-D7必須穩(wěn)定下來(lái)。
t_h (Hold Time): 保持時(shí)間。指數(shù)據(jù)在時(shí)鐘有效沿到來(lái)之后,輸入數(shù)據(jù)必須保持穩(wěn)定的最短時(shí)間。
t_pd (Propagation Delay): 傳播延遲。指信號(hào)從輸入端(如CP或PL)到輸出端(如Q7)所需的時(shí)間。
4.2. 并行載入時(shí)序
當(dāng) PL 從高到低電平跳變時(shí),開(kāi)始并行載入。D0-D7上的數(shù)據(jù)必須在此之前穩(wěn)定,并在PL變?yōu)楦唠娖街蟊3忠欢螘r(shí)間。CP 的狀態(tài)在并行載入期間不重要。
4.3. 串行移位時(shí)序
當(dāng) PL 為高電平且 CE 為低電平時(shí),CP 的上升沿觸發(fā)數(shù)據(jù)移位。在CP上升沿到達(dá)之前,輸入到D7的數(shù)據(jù)(如果是級(jí)聯(lián)應(yīng)用)以及內(nèi)部寄存器的數(shù)據(jù)必須穩(wěn)定。Q7輸出的數(shù)據(jù)在CP上升沿后經(jīng)過(guò)一段傳播延遲后變?yōu)橛行А?/span>
設(shè)計(jì)考量:
在實(shí)際應(yīng)用中,需要確保微控制器輸出的時(shí)鐘信號(hào)和控制信號(hào)滿(mǎn)足74HC165的時(shí)序要求。例如,如果時(shí)鐘頻率過(guò)高,可能導(dǎo)致數(shù)據(jù)建立時(shí)間和保持時(shí)間不足,從而引入錯(cuò)誤。通常,微控制器的數(shù)字I/O口足以滿(mǎn)足74HC165的時(shí)序要求,但在高速應(yīng)用中,應(yīng)查閱數(shù)據(jù)手冊(cè)中具體的時(shí)序參數(shù)。
5. 74HC165 的應(yīng)用場(chǎng)景
74HC165由于其并行轉(zhuǎn)串行的特性,廣泛應(yīng)用于以下領(lǐng)域:
輸入擴(kuò)展: 最常見(jiàn)的應(yīng)用是擴(kuò)展微控制器的輸入端口。例如,一個(gè)Arduino Uno只有有限的數(shù)字輸入引腳,但通過(guò)一個(gè)74HC165可以輕松讀取8個(gè)按鈕或開(kāi)關(guān)的狀態(tài),而只需要占用3-4個(gè)微控制器的引腳(數(shù)據(jù)、時(shí)鐘、載入、可選的時(shí)鐘使能)。
鍵盤(pán)接口: 在一些簡(jiǎn)單的鍵盤(pán)或按鈕矩陣中,74HC165可以用來(lái)掃描行或列,并將按下的鍵的狀態(tài)轉(zhuǎn)換為串行數(shù)據(jù)。
傳感器數(shù)據(jù)采集: 當(dāng)有多個(gè)數(shù)字傳感器(如光電開(kāi)關(guān)、限位開(kāi)關(guān)等)需要同時(shí)監(jiān)測(cè)時(shí),74HC165可以集中采集這些傳感器的狀態(tài),然后通過(guò)串行方式傳輸給微控制器。
多路開(kāi)關(guān)狀態(tài)監(jiān)測(cè): 在工業(yè)控制、自動(dòng)化設(shè)備中,需要監(jiān)測(cè)大量開(kāi)關(guān)、繼電器或其他數(shù)字信號(hào)的狀態(tài),74HC165可以有效簡(jiǎn)化布線和I/O設(shè)計(jì)。
數(shù)據(jù)總線復(fù)用: 在某些數(shù)據(jù)總線設(shè)計(jì)中,如果需要將并行數(shù)據(jù)發(fā)送到串行總線,74HC165可以作為中間轉(zhuǎn)換器。
級(jí)聯(lián)應(yīng)用: 多個(gè)74HC165可以級(jí)聯(lián),以讀取更多位的并行數(shù)據(jù)。例如,兩個(gè)74HC165可以組成16位并行輸入,三個(gè)則為24位,以此類(lèi)推。
6. 74HC165 編程示例
本節(jié)將提供基于兩種常見(jiàn)微控制器平臺(tái)——Arduino和STM32——的74HC165編程示例,以展示如何通過(guò)代碼控制74HC165并讀取并行輸入數(shù)據(jù)。
6.1. 硬件連接
在開(kāi)始編程之前,確保您的74HC165與微控制器正確連接。以下是一個(gè)典型的連接方案:
74HC165 引腳 | 對(duì)應(yīng)的微控制器引腳 (示例) | 功能說(shuō)明 |
VCC | +5V 或 +3.3V | 電源 |
GND | GND | 地 |
D0 - D7 | 連接到需要讀取的并行輸入源 | 并行輸入 |
PL | 數(shù)字輸出引腳 (例如 Arduino D8) | 載入控制 |
CP | 數(shù)字輸出引腳 (例如 Arduino D9) | 時(shí)鐘 |
CE | GND (通常接地使能) | 時(shí)鐘使能 |
Q7 | 數(shù)字輸入引腳 (例如 Arduino D10) | 串行數(shù)據(jù)輸出 |
重要提示:
CE引腳: 在大多數(shù)簡(jiǎn)單應(yīng)用中,可以將CE引腳直接接地(GND),使其始終處于使能狀態(tài),從而簡(jiǎn)化控制。如果需要?jiǎng)討B(tài)控制時(shí)鐘,則需要連接到一個(gè)微控制器數(shù)字輸出引腳。
上拉/下拉電阻: 如果您的并行輸入D0-D7連接的是不確定狀態(tài)的傳感器或開(kāi)關(guān),可能需要添加外部上拉或下拉電阻來(lái)確保其在未觸發(fā)時(shí)的邏輯狀態(tài)。例如,如果連接按鈕,通常需要上拉電阻。
6.2. Arduino 編程示例
這個(gè)示例演示如何使用Arduino Uno讀取連接到74HC165的8個(gè)開(kāi)關(guān)狀態(tài)。
Arduino 代碼:
C++// 定義連接74HC165的Arduino引腳const int PL_PIN = 8;
// Parallel Load / Shift_Loadconst int CP_PIN = 9;
// Clock Pulseconst int Q7_PIN = 10; // Serial Data Output (Data In for Arduino)void setup() {
// 設(shè)置引腳模式
pinMode(PL_PIN, OUTPUT);
pinMode(CP_PIN, OUTPUT);
pinMode(Q7_PIN, INPUT); // Q7是數(shù)據(jù)輸入到Arduino
// 初始化串行通信,用于調(diào)試輸出
Serial.begin(9600);
Serial.println("74HC165 讀取示例");
}void loop() {
byte data = read74HC165(); // 讀取74HC165的數(shù)據(jù)
// 將讀取到的數(shù)據(jù)打印到串口監(jiān)視器
Serial.print("讀取到的數(shù)據(jù) (二進(jìn)制): ");
printByteAsBinary(data);
Serial.println();
delay(500); // 每0.5秒讀取一次}// 函數(shù):從74HC165讀取8位數(shù)據(jù)byte read74HC165() {
byte incomingByte = 0; // 1. 啟動(dòng)并行載入:將PL拉低
digitalWrite(PL_PIN, LOW); // 短暫延時(shí)以確保PL穩(wěn)定,雖然HC系列速度很快,但良好的習(xí)慣
// delayMicroseconds(1);
// 2. 結(jié)束并行載入并進(jìn)入移位模式:將PL拉高
digitalWrite(PL_PIN, HIGH); // 確保數(shù)據(jù)穩(wěn)定后,可以開(kāi)始移位
// 3. 讀取8位數(shù)據(jù)
// 74HC165的串行輸出是最低有效位優(yōu)先(LSB first),但其內(nèi)部移位是從D7移出。
// 因此,第一次時(shí)鐘脈沖移出的是D7,第二次是D6,以此類(lèi)推。
// 如果你需要LSB優(yōu)先的字節(jié)順序,需要將接收到的位反轉(zhuǎn)順序。
// 在這里,我們將讀取到的位按照D7, D6, ..., D0的順序組合成一個(gè)字節(jié)。
for (int i = 0; i < 8; i++) { // 每次讀取一位之前,給一個(gè)時(shí)鐘脈沖
digitalWrite(CP_PIN, LOW); // CP拉低
// delayMicroseconds(1);
digitalWrite(CP_PIN, HIGH); // CP上升沿觸發(fā)移位
// delayMicroseconds(1); // 留出時(shí)間給數(shù)據(jù)穩(wěn)定
// 讀取Q7引腳上的數(shù)據(jù),并將其移入到incomingByte的正確位置
// 最先讀到的是最高位 (D7),所以將其放到字節(jié)的最高位
if (digitalRead(Q7_PIN) == HIGH) {
incomingByte = incomingByte | (1 << (7 - i)); // 設(shè)置對(duì)應(yīng)位為1
} else { // 保持對(duì)應(yīng)位為0(默認(rèn)就是0,所以這行可以省略,但為了清晰說(shuō)明)
incomingByte = incomingByte & ~(1 << (7 - i));
}
} return incomingByte;
}// 輔助函數(shù):將字節(jié)以二進(jìn)制形式打印void printByteAsBinary(byte b) { for (int i = 7; i >= 0; i--) {
Serial.print((b >> i) & 0x01);
}
}
代碼解釋?zhuān)?/strong>
引腳定義: 定義了Arduino連接到74HC165的三個(gè)控制引腳(PL, CP)和一個(gè)數(shù)據(jù)輸入引腳(Q7)。
setup()
函數(shù):將PL和CP引腳設(shè)置為輸出模式,因?yàn)锳rduino需要控制它們。
將Q7引腳設(shè)置為輸入模式,因?yàn)锳rduino要從這個(gè)引腳讀取數(shù)據(jù)。
初始化串口通信,用于調(diào)試。
loop()
函數(shù):重復(fù)調(diào)用
read74HC165()
函數(shù)來(lái)獲取數(shù)據(jù)。將獲取到的字節(jié)以二進(jìn)制形式打印出來(lái)。
read74HC165()
函數(shù):digitalWrite(CP_PIN, LOW);
和digitalWrite(CP_PIN, HIGH);
: 生成一個(gè)時(shí)鐘脈沖的上升沿。每次上升沿都會(huì)使74HC165內(nèi)部數(shù)據(jù)移位一位,并將當(dāng)前最高位(D7位,首次移位時(shí)是最初載入的D7位)通過(guò)Q7引腳輸出。digitalRead(Q7_PIN)
: 讀取Q7引腳的當(dāng)前狀態(tài)。incomingByte = incomingByte | (1 << (7 - i));
: 這是將讀取到的位組合成一個(gè)字節(jié)的關(guān)鍵。74HC165的移位順序是從D7到D0。第一次讀取到的是D7,第二次是D6,以此類(lèi)推。
1 << (7 - i)
會(huì)生成一個(gè)只有第(7 - i)
位是1的掩碼。例如,當(dāng)i=0
時(shí) (第一次循環(huán)),掩碼是10000000
(二進(jìn)制),用于設(shè)置incomingByte
的最高位 (bit 7)。當(dāng)i=7
時(shí) (最后一次循環(huán)),掩碼是00000001
(二進(jìn)制),用于設(shè)置incomingByte
的最低位 (bit 0)。|
(按位或) 操作用于將讀取到的位設(shè)置到incomingByte
的相應(yīng)位置。digitalWrite(PL_PIN, LOW);
: 將PL引腳拉低,觸發(fā)74HC165將并行輸入數(shù)據(jù)(D0-D7)異步載入到其內(nèi)部寄存器。digitalWrite(PL_PIN, HIGH);
: 將PL引腳拉高,結(jié)束并行載入,使74HC165進(jìn)入移位模式。循環(huán)8次: 為了讀取8位數(shù)據(jù),需要發(fā)送8個(gè)時(shí)鐘脈沖。
printByteAsBinary()
函數(shù): 一個(gè)輔助函數(shù),用于將字節(jié)數(shù)據(jù)以二進(jìn)制字符串的形式打印到串口監(jiān)視器,方便觀察。
6.3. STM32 編程示例 (HAL庫(kù))
對(duì)于STM32微控制器,我們通常使用HAL庫(kù)或LL庫(kù)。這里以HAL庫(kù)為例,演示如何配置GPIO并讀取74HC165的數(shù)據(jù)。
STM32CubeIDE 配置:
在STM32CubeIDE中,您需要首先配置GPIO引腳。假設(shè)您使用以下引腳:
PL_PIN: 例如 PA0 (GPIO_Output)
CP_PIN: 例如 PA1 (GPIO_Output)
Q7_PIN: 例如 PA2 (GPIO_Input)
確保將CP_PIN和PL_PIN配置為推挽輸出,Q7_PIN配置為浮空輸入或上拉輸入。
STM32 HAL庫(kù)代碼 (核心讀取函數(shù)):
C#include "main.h" // 包含CubeMX生成的頭文件#include <string.h> // For strlen#include <stdio.h>
// For sprintf// 定義連接74HC165的GPIO引腳和端口#define PL_GPIO_PORT GPIOA#define PL_GPIO_PIN
GPIO_PIN_0#define CP_GPIO_PORT GPIOA#define CP_GPIO_PIN
GPIO_PIN_1#define Q7_GPIO_PORT GPIOA#define Q7_GPIO_PIN
GPIO_PIN_2// UART句柄,用于printf輸出(如果配置了UART)extern UART_HandleTypeDef huart2;
// 假設(shè)您的UART2用于調(diào)試輸出/**
* @brief 從74HC165讀取8位并行數(shù)據(jù)
* @param None
* @retval 讀取到的8位數(shù)據(jù)
*/uint8_t Read_74HC165(void){ uint8_t received_data = 0; // 1. 啟動(dòng)并行載入:拉低PL引腳
HAL_GPIO_WritePin(PL_GPIO_PORT, PL_GPIO_PIN, GPIO_PIN_RESET); // 稍作延時(shí),確保PL引腳穩(wěn)定
// 僅在非常苛刻的時(shí)序要求下考慮,通常對(duì)于HC系列不需要微秒級(jí)延時(shí)
// for(volatile int i=0; i<10; i++);
// 2. 結(jié)束并行載入,進(jìn)入移位模式:拉高PL引腳
HAL_GPIO_WritePin(PL_GPIO_PORT, PL_GPIO_PIN, GPIO_PIN_SET); // 數(shù)據(jù)現(xiàn)在被鎖存,可以開(kāi)始移位
// 3. 循環(huán)8次,讀取8位數(shù)據(jù)
for (int i = 0; i < 8; i++)
{ // 生成一個(gè)時(shí)鐘脈沖的上升沿
HAL_GPIO_WritePin(CP_GPIO_PORT, CP_GPIO_PIN, GPIO_PIN_RESET); // CP拉低
// for(volatile int i=0; i<10; i++); // 短暫延時(shí)
HAL_GPIO_WritePin(CP_GPIO_PORT, CP_GPIO_PIN, GPIO_PIN_SET); // CP上升沿觸發(fā)移位
// for(volatile int i=0; i<10; i++); // 短暫延時(shí),留出數(shù)據(jù)穩(wěn)定時(shí)間
// 讀取Q7引腳的狀態(tài)
if (HAL_GPIO_ReadPin(Q7_GPIO_PORT, Q7_GPIO_PIN) == GPIO_PIN_SET)
{ // 將讀取到的位設(shè)置到received_data的正確位置
// 74HC165第一次移出的是D7,所以要放在最高位
received_data |= (1 << (7 - i));
}
} return received_data;
}// 輔助函數(shù):將字節(jié)以二進(jìn)制形式打?。ㄍㄟ^(guò)UART)void PrintByteAsBinary(uint8_t b) { char buffer[10];
// 8位 + null terminator
for (int i = 0; i < 8; i++) {
buffer[i] = ((b >> (7 - i)) & 0x01) ? '1' : '0';
}
buffer[8] = '