于 STC89C52 单片机的 UART 串口控制流水灯和数码管
时间: 2024-03-23 22:39:30 浏览: 79
好的,我可以帮你解答这个问题。下面是一个简单的C语言程序示例,通过单片机的UART串口控制流水灯和数码管。
```c
#include <reg52.h>
#include <intrins.h>
#define BAUDRATE 9600
sbit LATCH = P1^0; // 74HC595锁存器控制引脚
sbit SRCLK = P1^1; // 74HC595移位寄存器时钟引脚
sbit RCLK = P1^2; // 74HC595锁存器时钟引脚
sbit SER = P1^3; // 74HC595串行数据输入引脚
unsigned char disp_buf[4] = {0xFF, 0xFF, 0xFF, 0xFF}; // 数码管显示缓存
void delay(unsigned int t)
{
while(t--);
}
void init_uart()
{
TMOD |= 0x20;
TH1 = 0xFD;
TL1 = 0xFD;
TR1 = 1;
ES = 1;
EA = 1;
}
void uart_isr() interrupt 4
{
if(RI)
{
char c = SBUF;
switch(c)
{
case '0':
P0 = 0xFF;
break;
case '1':
P0 = 0xFE;
break;
case '2':
P0 = 0xFC;
break;
case '3':
P0 = 0xF8;
break;
case '4':
P0 = 0xF0;
break;
case '5':
P0 = 0xE0;
break;
case '6':
P0 = 0xC0;
break;
case '7':
P0 = 0x80;
break;
case 'a':
disp_buf[0] = 0x3F;
disp_buf[1] = 0x06;
disp_buf[2] = 0x5B;
disp_buf[3] = 0x4F;
break;
case 'b':
disp_buf[0] = 0x7C;
disp_buf[1] = 0x5E;
disp_buf[2] = 0x5E;
disp_buf[3] = 0x3C;
break;
case 'c':
disp_buf[0] = 0x3D;
disp_buf[1] = 0x42;
disp_buf[2] = 0x42;
disp_buf[3] = 0x3D;
break;
case 'd':
disp_buf[0] = 0x7C;
disp_buf[1] = 0x42;
disp_buf[2] = 0x42;
disp_buf[3] = 0x3C;
break;
default:
break;
}
RI = 0;
}
}
void shift_byte(unsigned char byte)
{
unsigned char i;
for(i = 0; i < 8; i++)
{
SRCLK = 0;
SER = byte & 0x80;
byte <<= 1;
SRCLK = 1;
}
}
void update_disp()
{
unsigned char i;
for(i = 0; i < 4; i++)
{
LATCH = 0;
shift_byte(disp_buf[i]);
LATCH = 1;
RCLK = 0;
RCLK = 1;
}
}
void main()
{
init_uart();
while(1)
{
update_disp();
delay(5000);
disp_buf[0] = _crol_(disp_buf[0], 1);
disp_buf[1] = _crol_(disp_buf[1], 1);
disp_buf[2] = _crol_(disp_buf[2], 1);
disp_buf[3] = _crol_(disp_buf[3], 1);
}
}
```
在上述程序中,通过单片机的UART串口接收PC端发送的指令,并根据指令控制流水灯和数码管的显示。指令格式为一个字符,取值范围为0~7和a~d,表示流水灯和数码管的不同状态。例如,当接收到字符'0'时,流水灯关闭;当接收到字符'1'时,流水灯从左往右移动一个灯;当接收到字符'a'时,数码管显示"abcd",以此类推。
其中,74HC595是一个串行输入并行输出的移位寄存器。通过向74HC595的串行输入引脚SER输入数据,然后通过SRCLK和RCLK两个时钟引脚控制锁存器的移位和锁存操作,从而实现对多个LED灯或数码管的控制。
阅读全文