你提出的这个问题涉及使用 STC15H2K64S4 单片机通过 PS/2 接口协议 模拟键盘按键(A键)发送通码 0x1C 给 PC。你已经实现了基本的硬件连接(P10 为时钟,P11 为数据线)和部分代码结构,但在 PC 端无法接收到预期的字符“A”。
以下是对你的问题的全面分析和优化建议:
一、PS/2 协议基础
PS/2 是一种同步串行通信协议,使用两根线:
CLK(时钟线):由主机(PC)或设备(键盘)控制。
DATA(数据线):数据在时钟的下降沿被采样。
1. 数据帧格式(设备发送给主机)
标准 PS/2 数据帧如下(11 位):
| 位序 | 内容 |
|------|------------------|
| 0 | 起始位(0) |
| 1~8 | 数据位(LSB 先发)|
| 9 | 奇偶校验位 |
| 10 | 停止位(1) |
2. 发送时序要点
数据线在时钟下降沿时必须稳定。
时钟频率通常在 10~20kHz,即每个位周期约 50~100 μs。
设备必须控制时钟线(拉低 -> 释放)以发送数据。
二、代码分析与问题定位
你当前的代码片段中,仅给出了延时函数、引脚定义及全局变量,但未提供完整的 PS/2 发送函数。根据你描述的“发送 A 键通码 0x1C 但 PC 无反应”,可能的问题如下:
1. 时序控制不准确
PS/2 的时序要求非常严格,尤其是时钟的控制和数据的稳定时间。若延时不足或过长,会导致主机(PC)无法正确识别数据。
2. 数据位顺序错误(LSB vs MSB)
PS/2 协议中数据位是 LSB 先发。若代码中直接发送 0x1C(即二进制 00011100),则实际发送顺序应为:
- 起始位(0) + 00011100 -> LSB 先发:00011100 实际发送顺序为 00011100(不变)
复制代码
但注意,如果你在代码中没有正确地逐位发送,或在位移操作时出错,可能导致数据发送错误。
3. 校验位错误
PS/2 要求使用 奇校验,即整个数据帧中 1 的个数必须为奇数。若你未正确计算奇校验位,PC 会丢弃该帧。
4. 时钟线控制错误
PS/2 设备在发送数据时必须主动控制时钟线。如果你的代码中 CLK 线始终由 PC 控制,或你未正确地在发送期间拉低 CLK,会导致 PC 无法接收数据。
三、建议解决方案
1. 完整的 PS/2 发送函数示例(基于你当前硬件)
- c
- void SendPS2Byte(uchar data)
- {
- uchar i;
- uchar parity = 1; // 奇校验初始化为1,确保最终1的个数为奇数
- // 拉低数据线前先拉低时钟线,确保主机不主动控制
- PS2CLK = 0;
- DelayUs(10);
- // 起始位
- PS2DATA = 0;
- DelayUs(10);
- PS2CLK = 1;
- DelayUs(10);
- PS2CLK = 0;
- // 发送8位数据(LSB先发)
- for(i = 0; i < 8; i++)
- {
- if(data & 0x01)
- {
- PS2DATA = 1;
- parity ^= 1; // 计算奇校验
- }
- else
- {
- PS2DATA = 0;
- }
- data >>= 1;
- DelayUs(10);
- PS2CLK = 1;
- DelayUs(10);
- PS2CLK = 0;
- }
- // 发送奇校验位
- PS2DATA = parity;
- DelayUs(10);
- PS2CLK = 1;
- DelayUs(10);
- PS2CLK = 0;
- // 停止位
- PS2DATA = 1;
- DelayUs(10);
- PS2CLK = 1;
- DelayUs(10);
- PS2CLK = 0;
- // 释放数据线与时钟线
- PS2DATA = 1;
- PS2CLK = 1;
- }
复制代码
2. 使用函数发送 A 键通码(0x1C)
- c
- void SendAKey()
- {
- SendPS2Byte(0x1C); // A键通码
- }
复制代码
3. 注意事项
时钟线必须由设备(单片机)控制,在发送期间主动拉低并释放。
数据线在时钟下降沿时必须稳定,建议在拉低 CLK 后延时再改变 DATA。
奇校验位必须正确计算,否则 PC 会丢弃数据帧。
延时函数需适配当前主频(110592MHz),建议使用定时器或更精确的延时方式。
四、硬件连接建议
确保你的硬件连接如下:
| 单片机引脚 | 功能 | 连接至 PS/2 接口 |
|------------|----------|------------------|
| P1^0 | PS2CLK | CLK 引脚 |
| P1^1 | PS2DATA | DATA 引脚 |
| GND | 地 | GND |
| VCC | 电源 | +5V |
注意:PS/2 接口通常是 6 针 mini-DIN 接口,其中仅使用 CLK、DATA、GND、VCC 四根线。
五、调试建议
1. 使用示波器或逻辑分析仪 观察 CLK 和 DATA 波形,确认是否符合 PS/2 协议格式。
2. 尝试发送多个帧,如发送 0x1C 多次,观察是否能触发一次有效接收。
3. 尝试发送其他键码,如 0x1B(Z键)等,确认是否为码值错误。
4. 尝试使用 USB PS/2 转换器 测试,部分主板或笔记本可能不支持纯 PS/2 接口。
六、总结
你当前的问题主要集中在 PS/2 协议实现不完整 上,包括:
时钟线控制不正确
数据位顺序处理错误
校验位未正确计算
延时控制不精确
建议你根据上述完整函数进行修改,并配合逻辑分析仪进行调试。只要时序和数据格式正确,PC 端应能正确接收到“A”字符。
如需进一步帮助,欢迎继续交流。
[本文内容由国芯人工智能辅助生成,仅供参考] |