【自学嵌入式:51单片机】用UART串口通信和矩阵按键实现快速打开win系统中的一些程序
如题,代码实际非常简单,简单说一下我的矩阵按键映射
我矩阵按键映射是
1 2 3 20
4 5 6 23
7 8 9 26
11 12 13 30
因为我最开始用矩阵键盘做9x9非0数字键,懒得改了
相关电路

单片机端程序源码
单片机端程序源码如下
#include <REGX52.H>
#define uint8 unsigned char
#define uint16 unsigned int
uint8 KeyNum = 0; //键码值
//延迟函数
void Delay(uint16 xms) //@11.0592MHz
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
//矩阵按键识别
uint8 matrixKey()
{
uint8 KeyNumber=10; //当前按键对应的数字
// 第一步:检测行
P1 = 0x0F; // 行线(P17-P14)置0,列线(P13-P10)保持高(默认)
//高电平会被低电平拉低
Delay(10); //消抖,让按键确定按下来
//有按键输入才检测
if(P1 != 0x0F)
{
//先扫描行
switch(P1)
{
case (0x07):
KeyNumber = 1;
break;
case (0x0B):
KeyNumber = 2;
break;
case (0x0D):
KeyNumber = 3;
break;
case (0x0E):
KeyNumber = 20;
break;
}
//再扫描列
P1=0XF0;
switch(P1)
{
case (0x70):
Delay(20); //消抖
while(P1 == 0x70);
Delay(20); //消抖
KeyNumber = KeyNumber;
break;
case (0xB0):
Delay(20); //消抖
while(P1 == 0xB0);
Delay(20); //消抖
KeyNumber+=3;
break;
case (0xD0):
Delay(20); //消抖
while(P1 == 0xD0);
Delay(20); //消抖
KeyNumber+=6;
break;
//第四行比较特殊,都是0
case (0XE0):
Delay(20); //消抖
while(P1 == 0xE0);
Delay(20); //消抖
KeyNumber+=10;
break;
}
}
Delay(10);
return KeyNumber;
}
//初始化UART串口
void initUART()
{
SCON = 0x50; // 0101 0000 工作模式1,允许接收
TMOD = 0x20; //设置定时器T1工作模式,8位自动重载
// 8位自动重载,省得手动填充波特率
TH1 = 0xFA; //用4800波特率,按公式计算一下是256-6=250
TL1 = 0xFA;
ES = 1; //打开串口
EA = 1; //开总中断
TR1 = 1; //打开波特率发生器(定时器1)
}
//Uart串口通信需要发送的字节
void sentUART(uint8 Byte)
{
TI = 1; //打开发送中断,准备发送数据
SBUF = Byte; //待发送数据写入缓存
while(TI == 0); //TI变成1才算发送完成,等待它发送完成
TI = 0; // 软件复位
}
void main()
{
initUART();
while(1)
{
KeyNum = matrixKey();
//默认不发,按下才发
if(KeyNum != 10)
{
sentUART(KeyNum);
}
}
}
电脑端Python串口通信源码
import serial
import serial.tools.list_ports
import subprocess # 用于后续打开应用程序
import ctypes
import sys
import webbrowser
# 判断是否是管理员状态
def is_admin():
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
# 以管理员模式运行
def run_as_admin():
ctypes.windll.shell32.ShellExecuteW(
None, "runas", sys.executable, sys.argv[0], None, 1)
sys.exit()
def find_mcu_port():
"""自动检测可能的51单片机串口"""
ports = list(serial.tools.list_ports.comports())
for port in ports:
# 尝试识别常见的51单片机端口特征
# 可根据实际设备修改识别条件
if ("USB-SERIAL" in port.description or
"CH340" in port.description or # 常见的USB转串口芯片
"COM6" in port.device): # 包含用户提到的COM6
return port.device
# 如果没有找到特定设备,返回第一个可用端口
if ports:
return ports[0].device
return None
def handle_key_press(key_code):
# 1打开记事本
if key_code == 1:
open_application("C:/Windows/System32/notepad.exe");
# 2打开CMD
elif key_code == 2:
subprocess.Popen(
"cmd.exe",
creationflags=subprocess.CREATE_NEW_CONSOLE # 关键参数:创建新控制台窗口
)
# 3打开资源管理器
elif key_code == 3:
open_application("C:/Windows/explorer.exe");
# 20(实际上是第一行第四个按键,我那个程序的逻辑是只启用9x9键盘,就没做4x4键盘准确数字映射,不过无所谓)
# 20打开系统设置
elif key_code == 20:
subprocess.run(['start', 'ms-settings:'], shell=True, check=True)
# 4打开Bing搜索
elif key_code == 4:
webbrowser.open("https://cn.bing.com/")
# 以此类推,懒得写了
def open_application(app_path):
"""打开指定的应用程序"""
try:
subprocess.Popen(app_path)
print(f"已打开应用: {app_path}")
except Exception as e:
print(f"打开应用失败: {e}")
def main():
# 查找单片机端口
port = find_mcu_port()
if not port:
print("未找到可用的串口,请检查单片机连接")
return
print(f"已找到单片机,使用串口: {port}")
# 配置串口参数
ser = None
try:
ser = serial.Serial(
port=port,
baudrate=4800,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=1 # 超时时间,单位秒
)
print("串口连接成功,等待按键数据...")
print("按Ctrl+C退出程序")
# 读取串口输入信息并输出。
while True:
com_input = ser.read(1)
# bytes 转 int
val = int.from_bytes(com_input, byteorder='little', signed=False)
if com_input: # 如果读取结果非空,则输出
handle_key_press(val);
except serial.SerialException as e:
print(f"串口通信错误: {e}")
except KeyboardInterrupt:
print("\n程序已手动退出")
finally:
if ser and ser.is_open:
ser.close()
print("串口已关闭")
if __name__ == "__main__":
main()
这样按下对应按键能打开快捷操作
浙公网安备 33010602011771号