打印

N32G455 RS485中断接收函数进入不了,请问是什么原因呀?

[复制链接]
2932|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
RS485能够发送数据,但是接收数据时一直进不了RS485中断函数,请大佬们指点一下void RS485_Init(void)
{
    GPIO_InitType GPIO_InitStruct;
    USART_InitType USART_InitStruct;
    NVIC_InitType NVIC_InitStruct;

    // 使能时钟(USART2在APB1总线上)
    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);
    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_USART2, ENABLE);

    // 配置方向控制引脚PA1
    GPIO_InitStruct.Pin = RS485_EN_GPIO_PIN;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitPeripheral(RS485_EN_GPIO_PORT, &GPIO_InitStruct);
    GPIO_ResetBits(RS485_EN_GPIO_PORT, RS485_EN_GPIO_PIN); // 默认接收模式

    // 配置USART2 TX引脚PA2(复用推挽输出)
    GPIO_InitStruct.Pin = GPIO_PIN_2;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitPeripheral(GPIOA, &GPIO_InitStruct);

    // 配置USART2 RX引脚PA3(浮空输入)
    GPIO_InitStruct.Pin = GPIO_PIN_3;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitPeripheral(GPIOA, &GPIO_InitStruct);

    // USART参数配置
    USART_InitStruct.BaudRate = 9600; // 波特率;
    USART_InitStruct.WordLength = USART_WL_8B;
    USART_InitStruct.StopBits = USART_STPB_1;
    USART_InitStruct.Parity = USART_PE_NO;
    USART_InitStruct.HardwareFlowControl = USART_HFCTRL_NONE;
    USART_InitStruct.Mode = USART_MODE_RX | USART_MODE_TX;
    USART_Init(USART2, &USART_InitStruct);

    // 使能接收中断
    USART_ConfigInt(USART2, USART_INT_RXDNE, ENABLE);
    USART_ConfigInt(USART2, USART_INT_IDLEF, ENABLE);

    // 配置NVIC
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStruct);

    // 使能USART
    USART_Enable(USART2, ENABLE);
}

// 发送函数
void RS485_SendData(uint8_t *pData, uint16_t len)
{
    // 设置为发送模式
    GPIO_SetBits(RS485_EN_GPIO_PORT, RS485_EN_GPIO_PIN);

    // 阻塞式发送数据
    for (uint16_t i = 0; i < len; i++)
    {
        //
        while (USART_GetFlagStatus(USART2, USART_FLAG_TXDE) == RESET)
            ; // 等待发送完成
        USART_SendData(USART2, pData[i]);
    }

    // 确保最后一位发送完成
    while (USART_GetFlagStatus(USART2, USART_FLAG_TXC) == RESET)
        ;

    // 恢复接收模式
    GPIO_ResetBits(RS485_EN_GPIO_PORT, RS485_EN_GPIO_PIN);
}

// 接收缓冲区和索引
#define RX_BUF_SIZE 128
volatile uint8_t rxBuffer[RX_BUF_SIZE];
volatile uint16_t rxIndex = 0;
void RS485_IRQHandler(void)
{
    if (USART_GetIntStatus(USART2, USART_FLAG_RXDNE) != RESET)
    {
        rxBuffer[rxIndex++] = USART_ReceiveData(USART2);
    }
    if (USART_GetIntStatus(USART2, USART_FLAG_IDLEF) != RESET)
    {
        if (rxBuffer[0] == 0xAA)
        {
            printf("rxBuffer = %x\r\n", rxBuffer[0]);
        }
    }

    rxIndex = 0;
    USART_ClrIntPendingBit(USART2, USART_INT_IDLEF);// 清除空闲中断
    /*清除空闲中断*/
    USART2->STS;
    USART2->DAT;
}


使用特权

评论回复

相关帖子

沙发
dffzh| | 2025-4-25 09:05 | 只看该作者
提供排查方法:
1、Debug仿真,单步调试,看相关寄存器和接收状态标志等值;
2、用示波器测试Rx的波形,看下是否有数据;
3、如果有波形,用逻辑分析仪的UART总线模式分析一下数据帧格式。

使用特权

评论回复
板凳
yzdel7| | 2025-4-25 18:22 | 只看该作者
你检查一下你的中断函数名称 RS485_IRQHandler 跟你的中断源绑定的名称是否相符。在你的Startup.s文件里,串口2中断绑定的名称是否是一致的。

使用特权

评论回复
地板
丙丁先生| | 2025-4-25 20:43 | 只看该作者
[技术讨论]  逐一分析 N32G455 RS485中断接收函数进入不了,请问是什么原因呀?    https://bbs.21ic.com/icview-3449084-1-1.html

使用特权

评论回复
5
丙丁先生| | 2025-4-25 20:44 | 只看该作者
dffzh 发表于 2025-4-25 09:05
提供排查方法:
1、Debug仿真,单步调试,看相关寄存器和接收状态标志等值;
2、用示波器测试Rx的波形,看 ...

感谢分享。

使用特权

评论回复
6
丙丁先生| | 2025-4-25 20:46 | 只看该作者
yzdel7 发表于 2025-4-25 18:22
你检查一下你的中断函数名称 RS485_IRQHandler 跟你的中断源绑定的名称是否相符。在你的Startup.s文件里, ...

不一致编译会报错吧?

使用特权

评论回复
7
幻想收藏家| | 2025-4-25 22:08 | 只看该作者
检查一下是否正确配置了中断优先级和使能了中断。另外,确认硬件连接是否正确,RS485模块是否正常工作。

使用特权

评论回复
8
yzdel7| | 2025-4-26 11:01 | 只看该作者
丙丁先生 发表于 2025-4-25 20:46
不一致编译会报错吧?

不一致编译器就当是个普通的函数了,不会报错。

使用特权

评论回复
9
cooldog123pp| | 2025-4-26 14:36 | 只看该作者
咋感觉你们的帖子是哪里复制过来的,背景都是白色的,很神奇,都是别的论坛解决不了的问题吗。

使用特权

评论回复
10
lipingpingli|  楼主 | 2025-4-27 22:15 | 只看该作者
幻想收藏家 发表于 2025-4-25 22:08
检查一下是否正确配置了中断优先级和使能了中断。另外,确认硬件连接是否正确,RS485模块是否正常工作。
...

中断优先级,硬件都确认了,485也正常工作用示波器抓了,但是就是到MCU无法触发中断

使用特权

评论回复
11
lipingpingli|  楼主 | 2025-4-27 22:17 | 只看该作者
cooldog123pp 发表于 2025-4-26 14:36
咋感觉你们的帖子是哪里复制过来的,背景都是白色的,很神奇,都是别的论坛解决不了的问题吗。 ...

自己VSCODE复制过来的

使用特权

评论回复
12
lipingpingli|  楼主 | 2025-4-27 22:23 | 只看该作者
dffzh 发表于 2025-4-25 09:05
提供排查方法:
1、Debug仿真,单步调试,看相关寄存器和接收状态标志等值;
2、用示波器测试Rx的波形,看 ...


中断优先级,硬件都确认了,485也正常工作用示波器抓了,但是就是到MCU无法触发中断.Debug中UART2寄存器中USART_CTRL1.UEN =1 ,USART_CTRL1.RXDNEIEN=1,USART_CTRL1.RXEN=1,但是就是无法触发USART.RXDNE这位置于1,怎么都不行,配置我都检查都没问题,好奇怪,疑惑

使用特权

评论回复
13
yzdel7| | 2025-4-28 00:03 | 只看该作者
这数据手册里写的有问题,检测到起始位就将USART_STS.RXDNE置1,建议你联系一下国民技术的FAE,试试先跳过RS485的芯片,用一个TTL转USB的模块,连接电脑用串口助手试一下收发,看看是否正常。

Screenshot_20250427_233303_WPS Office.jpg (256.88 KB )

Screenshot_20250427_233303_WPS Office.jpg

使用特权

评论回复
14
yzdel7| | 2025-4-28 00:17 | 只看该作者
你可以试试逻辑分析仪,接到单片机的RXD引脚,看看数据是否进来,如果数据结构没有问题,再考虑是否是单片机配置的问题。

使用特权

评论回复
15
dffzh| | 2025-4-28 08:51 | 只看该作者
lipingpingli 发表于 2025-4-27 22:23
中断优先级,硬件都确认了,485也正常工作用示波器抓了,但是就是到MCU无法触发中断.Debug中UART2寄存 ...

你可以先用以下方法排查外围硬件的影响,单独验证程序是否正常:
将MCU串口的TX和RX引脚直接与USB转TLL的串口工具连接
电脑端用串口助手发数据,与MCU通信测试看下是否正常;类似下面的串口工具:

连接图:

使用特权

评论回复
16
lipingpingli|  楼主 | 2025-4-28 15:11 | 只看该作者
yzdel7 发表于 2025-4-25 18:22
你检查一下你的中断函数名称 RS485_IRQHandler 跟你的中断源绑定的名称是否相符。在你的Startup.s文件里, ...

是一致的.现在有出现了一个原因是USART 状态寄存器 (USART_STS)的FEF帧错误被置1,请问这是为什么呀?
官方手册这样解释:
帧错误(Framing error)。
当检测到同步错位,过多的噪声或者检测到断开符,该位被硬件置位。由软件序列将其清零(先读USART_STS,再读USART_DAT)。
0:未检测到帧错误。
1:检测到帧错误或者断开帧(break frame)。
注意:该位不会产生中断,因为它和USART_STS.RXDNE 一起出现,硬件会在设置USART_STS.RXDNE 标志时产生中断。如果当前传输的数据既产生了帧错误,又产生了过载错误,硬件还是会继续该数据的传输,并且只设置OREF标志位。
在多缓冲区通信模式下,如果设置了USART_CTRL3.ERRIEN位,则设置FEF标志时会产生中断。

使用特权

评论回复
17
lipingpingli|  楼主 | 2025-4-28 15:12 | 只看该作者
dffzh 发表于 2025-4-28 08:51
你可以先用以下方法排查外围硬件的影响,单独验证程序是否正常:
将MCU串口的TX和RX引脚直接与USB转TLL的 ...

应该是是USART 状态寄存器 (USART_STS)的FEF帧错误被置1,请问这个怎么解决呀?
官方手册这样解释:
帧错误(Framing error)。
当检测到同步错位,过多的噪声或者检测到断开符,该位被硬件置位。由软件序列将其清零(先读USART_STS,再读USART_DAT)。
0:未检测到帧错误。
1:检测到帧错误或者断开帧(break frame)。
注意:该位不会产生中断,因为它和USART_STS.RXDNE 一起出现,硬件会在设置USART_STS.RXDNE 标志时产生中断。如果当前传输的数据既产生了帧错误,又产生了过载错误,硬件还是会继续该数据的传输,并且只设置OREF标志位。
在多缓冲区通信模式下,如果设置了USART_CTRL3.ERRIEN位,则设置FEF标志时会产生中断。

使用特权

评论回复
18
dffzh| | 2025-4-28 16:11 | 只看该作者
lipingpingli 发表于 2025-4-28 15:12
应该是是USART 状态寄存器 (USART_STS)的FEF帧错误被置1,请问这个怎么解决呀?
官方手册这样解释:
帧 ...

帧错误一般不就是数据波形不符合UART协议格式;
有按照我提供的方法验证吗?
排查问题的时候一定要尽量解耦,就是想办法缩小到最小系统,这样才能抽丝剥茧,找到是硬件还是软件问题;
或者你把V信号发来,我加你,帮你看下

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

8

帖子

0

粉丝