You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32 L476RG通过USART读取PS/2键盘扫描码异常求助

在NUCLEO L476RG开发板上读取PS/2键盘扫描码的问题

PS/2与USART

我想利用STM32的USART硬件读取PS/2数据,如果这种方案不可行,请告知原因。根据资料查阅和示波器观测,PS/2协议在数据线上的数据包格式如下:

  • 1个起始位,始终为0;
  • 8个数据位,最低位优先;
  • 1个奇校验位;
  • 1个停止位,始终为1。

每个位在独立时钟信号的下降沿捕获,时钟空闲时为高电平,我的键盘时钟约为13.1kHz。给键盘供电3.3V时,双方输出均为3.3V,示波器波形显示连接STM32后正常。

问题现象

核心问题是按键时系统未产生中断,*RXNE(接收缓冲区非空标志)*始终为低,无中断触发。若使用0x55模式的自动波特率,仅会因自动波特率错误标志置位触发中断,其他模式均无任何反应。

已尝试的操作

我使用以下代码初始化STM32的USART1以读取键盘数据:

void init_keyboard(uint32_t baud)
{
// Enable clock to GPIOA
RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN;

// Enable clock to USART1
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;

// Configure UART
USART1->CR1 |= USART_CR1_RE  |   // Receiver enabled
               USART_CR1_PCE |   // Parity control enabled
               USART_CR1_PS  |   // Odd parity
               USART_CR1_M0  |   // 8 data bits
               USART_CR1_RXNEIE; // Enable RX interrupt

USART1->CR1 &= ~(USART_CR1_TE);

USART1->CR2 |= USART_CR2_CLKEN     | // Enable USART clock (sync mode)
               USART_CR2_ABREN     | // Enable auto Baud Rate
               USART_CR2_CPOL;       // Clock polarit 1 (idle high)


// The following need to be cleared for sync mode
USART1->CR2 &= ~(USART_CR2_LINEN);
USART1->CR3 &= ~(USART_CR3_SCEN  |
                 USART_CR3_HDSEL |
                 USART_CR3_IREN);

USART1->BRR |= (SystemCoreClock / baud); // set baud rate

USART1->CR1 |= USART_CR1_UE;

NVIC->ISER[1] |= (1 << (USART1_IRQn & 0x1F));

// Configure AF pins 8 and 10 to AF7 (USART)
GPIOA->AFR[1]  |= (GPIO_AF7_USART1 << 0);
GPIOA->AFR[1]  |= (GPIO_AF7_USART1 << 8);

// Configure PA8 (CK) and PA10 (RX) in alt. func. mode
GPIOA->MODER &= ~(GPIO_MODER_MODE8   | GPIO_MODER_MODE10);
GPIOA->MODER |=  (GPIO_MODER_MODE8_1 | GPIO_MODER_MODE10_1);

// Enable Global Interrupts
__enable_irq();
}

数据位默认最低位优先,默认在第一个边沿(下降沿)捕获,且已确认该波特率/复用功能码在9600波特率的标准UART连接中可行。

由于键盘波特率存在漂移(12.9-13.2kHz),我尝试启用自动波特率检测,测试了全部4种模式(起始位测量、下降沿到下降沿测量、0x55帧检测、0x7F帧检测)。仅0x7F模式有反应:读取非0x55的扫描码(按下除+外的按键)时触发自动波特率错误,但发送0x55帧(按下+键)时无任何反应。

主函数中已调用初始化函数,中断服务函数如下:

/* ISR for handling keypresses */
void USART1_IRQHandler(void);

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  init_keyboard(13120);

  while (1) {/* wait for interrupts */ }
}


void USART1_IRQHandler(void)
{
    if (USART1->ISR & USART_ISR_RXNE)
    {
        char read_byte = USART1->RDR;
        while (1) {/* catch here for debugging */ }
    }
}

内容的提问来源于stack exchange,提问作者M Tut

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 04:25:40