In the MCU system, when the parallel port's IO resources are insufficient, the 74LS164 can be used to expand the parallel IO port, thus saving the MCU's IO resources. The 74LS164 is a serial-in, parallel-out shift register with a clear terminal, making it an efficient solution for expanding output capabilities.
When using the microcontroller's serial port for display purposes, it should operate in a transmission mode. The timing of this process is critical. As shown in the timing diagram, once data is loaded into the serial port’s buffer (SBUF), the 8-bit data is transmitted from the lowest bit (D0) to the highest bit (D7) at a baud rate of Fosc/12 via the RXD pin. Once the transmission completes, the interrupt flag TI is set to "1" to signal the end of the transmission. It is important to note that the order of the bits matters significantly, as it determines the correct cooperation between the MCU's serial port and the 74LS164.
Figure 2 illustrates the operation timing of the 74LS164, a serial-in, parallel-out shift register. When the enable B (pin 2) is low, the register is disabled. When B is high, data can be input through terminal A (pin 1). The first data bit is then output from pin 3. After receiving 8 bits, the first input bit (D0) appears at the QH terminal, while the last received bit (D7) is at the QA terminal.
The hardware circuit described in some articles may lead to errors due to a misunderstanding of the bit order. For instance, if the glyph code treats segment a as D0 and segment h as D7, the output will be reversed. This results in incorrect display patterns. To fix this, the glyph code must be adjusted accordingly, as shown in Table 2, ensuring that the segments are correctly ordered from a to h on the QA to QH pins.
Alternatively, if the original glyph codes are preferred, the connections between the display and the 74LS164 can be rearranged, as illustrated in Figure 4. This allows the same glyph codes to be used without modifying the software.
Through analysis of the MCU's serial port timing and the 74LS164’s operation, two effective methods for combining software and hardware have been presented. These approaches were successfully applied in an intelligent centrifugal switch speedometer project, where the adjusted glyph codes matched the hardware configuration, resulting in accurate displays.
Additionally, similar challenges may arise when working with other shift registers like the 74LS165. In such cases, the same method of analyzing timing and bit order should be followed.
A Proteus simulation diagram and corresponding code are provided below for reference. The code includes functions for initializing timers, controlling the shift register, refreshing the display buffer, and handling interrupts. By implementing these functions, the system can accurately control the display using the 74LS164.
```c
#include "reg51.h"
#define HIGH 1
#define LOW 0
#define SEG_PORT P0
sbit DATA = P0^4;
sbit CLK = P0^5;
unsigned char Timer0IRQEvent = 0;
unsigned char Time1SecEvent = 0;
unsigned int TimeCount = 0;
unsigned char SegCurPosition = 0;
code unsigned char SegCode[10] = {~0x3F, ~0x06, ~0x5B, ~0x4F, ~0x66, ~0x6D, ~0x7D, ~0x07, ~0x7F, ~0x6F};
code unsigned char SegPosition[4] = {0xFE, 0xFD, 0xFB, 0xF7};
unsigned char SegBuf[4] = {0};
void LS164_DATA(unsigned char x) {
if (x)
DATA = 1;
else
DATA = 0;
}
void LS164_CLK(unsigned char x) {
if (x)
CLK = 1;
else
CLK = 0;
}
void LS164Send(unsigned char byte) {
unsigned char j;
for (j = 0; j <= 7; j++) {
if (byte & (1 << (7 - j))) {
LS164_DATA(HIGH);
} else {
LS164_DATA(LOW);
}
LS164_CLK(LOW);
LS164_CLK(HIGH);
}
}
void SegRefreshDisplayBuf(void) {
SegBuf[0] = TimeCount % 10;
SegBuf[1] = TimeCount / 10 % 10;
SegBuf[2] = TimeCount / 100 % 10;
SegBuf[3] = TimeCount / 1000 % 10;
}
void SegDisplay(void) {
unsigned char t;
SEG_PORT = 0x0F;
t = SegCode[SegBuf[SegCurPosition]];
LS164Send(t);
SEG_PORT = SegPosition[SegCurPosition];
if (++SegCurPosition >= 4)
SegCurPosition = 0;
}
void TimerInit(void) {
TH0 = (65536 - 5000) / 256;
TL0 = (65536 - 5000) % 256;
TMOD = 0x01;
}
void Timer0Start(void) {
TR0 = 1;
ET0 = 1;
}
void PortInit(void) {
P0 = P1 = P2 = P3 = 0xFF;
}
void main(void) {
PortInit();
TimerInit();
Timer0Start();
SegRefreshDisplayBuf();
EA = 1;
while (1) {
if (Timer0IRQEvent) {
Timer0IRQEvent = 0;
if (Time1SecEvent) {
Time1SecEvent = 0;
if (++TimeCount >= 9999)
TimeCount = 0;
SegRefreshDisplayBuf();
}
SegDisplay();
}
}
}
void Timer0IRQ(void) interrupt 1 {
static unsigned int cnt = 0;
TH0 = (65536 - 5000) / 256;
TL0 = (65536 - 5000) % 256;
Timer0IRQEvent = 1;
if (++cnt >= 200) {
cnt = 0;
Time1SecEvent = 1;
}
}
```
This code demonstrates how the 74LS164 can be effectively used with the MCU’s serial port to drive a seven-segment display. The functions ensure that the correct segment codes are sent in the right order, allowing the display to show accurate numerical values.
Rental Led Video Wall,Lightweight LED Message Display,Flexible Curve LED Video Wall,waterproof Rental LED video billboard,Stable Stage Video Screen Backdrop,Stage rental LED screen panel
Shenzhen Xinfei Century Technology Co., Ltd. , https://www.rgbdancing.com