硬汉嵌入式论坛

 找回密码
 立即注册
查看: 709|回复: 12
收起左侧

[UART] 串口DMA接收失败

[复制链接]

4

主题

90

回帖

102

积分

初级会员

积分
102
发表于 2025-5-4 12:25:26 | 显示全部楼层 |阅读模式
本帖最后由 Penguins 于 2025-5-4 12:26 编辑

使用Keil5 AC6环境将G4可运行的串口程序移植到H7,发送正常但接收失败,经查为未进入void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size),各位大神帮忙看看。

工程使用CubeMX生成,芯片为V版,未使用I-Cache和D-Cache,未配置MPU,改写sct文件如下。
[C] 纯文本查看 复制代码
LR_IROM1 0x08000000 0x00200000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00200000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   .ANY (+XO)
  }
  RW_IRAM1 0x20000000 0x00020000  {  ; RW data - 128KB DTCM
   .ANY (+RW +ZI)
  }
  RW_IRAM2 0x24000000 0x00080000  {  ; RW data - 512KB AXI SRAM
   *(.bss.RAM_D1)
   *(.data.RAM_D1)
  }
  RW_IRAM3 0x30000000 0x00048000  {  ; RW data - 128KB SRAM1 + 128KB SRAM2 + 32KB SRAM3
   *(.bss.RAM_D2)
   *(.data.RAM_D2)
  }
  RW_IRAM4 0x38000000 0x00010000  {  ; RW data - 64KB SRAM4
   *(.bss.RAM_D3)
   *(.data.RAM_D3)
  }
}


以下为G4已验证的UART+DMA驱动,带可变参数列表,支持连发。
[C] 纯文本查看 复制代码
#include "stdio.h"
#include "string.h"
#include "stdarg.h"

#define UART_BufSize        101

typedef struct {
    UART_HandleTypeDef *huart;
    char TxMsg[UART_BufSize];
    char RxMsg[UART_BufSize];
} myUART_HandleTypeDef;

void myUART_Start_Receive_DMA(myUART_HandleTypeDef *myhuart)
{
    memset(myhuart->RxMsg, 0, UART_BufSize);
    HAL_UARTEx_ReceiveToIdle_DMA(myhuart->huart, (uint8_t *)myhuart->RxMsg, UART_BufSize - 1);
}

void myUART_Transmit_DMA(myUART_HandleTypeDef *myhuart, const char *format, ...)
{
    va_list ap;
    va_start(ap, format);
    while (myhuart->huart->gState != HAL_UART_STATE_READY || myhuart->huart->hdmatx->State != HAL_DMA_STATE_READY);
    vsnprintf(myhuart->TxMsg, UART_BufSize, format, ap);
    va_end(ap);
    HAL_UART_Transmit_DMA(myhuart->huart, (uint8_t *)myhuart->TxMsg, strlen(myhuart->TxMsg));
}


以下为CubeMX生成的main.c文件中添加的部分,已确认myUART位于AXI SRAM,可被通用DMA读写。
[C] 纯文本查看 复制代码
__attribute__((section(".data.RAM_D1"))) myUART_HandleTypeDef myUART = { .huart = &huart1 };

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
    if (huart == myUART.huart && huart->RxEventType != HAL_UART_RXEVENT_HT)
    {
        myUART_Transmit_DMA(&myUART, "RxMsg: %s", myUART.RxMsg);
        myUART_Start_Receive_DMA(&myUART);
    }
}

int main(void)
{
    HAL_Init();
    SystemClock_Config();
      
    MX_GPIO_Init();
    MX_DMA_Init();
    MX_USART1_UART_Init();
  
    myUART_Transmit_DMA(&myUART, "H743VET6 UART1 Connected.\n");
    myUART_Transmit_DMA(&myUART, "Continuous sending test.\n");
    myUART_Start_Receive_DMA(&myUART);
      
    while (1)
    {
    }
}


回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2025-5-5 11:38:29 | 显示全部楼层
看下接收DMA的NDTR计数变化了没
回复

使用道具 举报

4

主题

90

回帖

102

积分

初级会员

积分
102
 楼主| 发表于 2025-5-5 12:27:52 | 显示全部楼层
eric2013 发表于 2025-5-5 11:38
看下接收DMA的NDTR计数变化了没

没有变化,还是HAL_UARTEx_ReceiveToIdle_DMA配置的初始值
回复

使用道具 举报

4

主题

90

回帖

102

积分

初级会员

积分
102
 楼主| 发表于 2025-5-5 13:39:15 | 显示全部楼层
对比了CubeMX在G4和H7生成的代码,除Stream选择不同外,只有H7多的FIFO功能默认为Disable的差别,其他都是一样的
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2025-5-5 16:55:28 | 显示全部楼层
Penguins 发表于 2025-5-5 12:27
没有变化,还是HAL_UARTEx_ReceiveToIdle_DMA配置的初始值

没动,说明配置有问题。
回复

使用道具 举报

5

主题

229

回帖

249

积分

高级会员

积分
249
发表于 2025-5-6 08:56:56 | 显示全部楼层
有没有可能你没配置DMA,工程发上来看看,以前我写的帖子 https://forum.anfulai.cn/forum.p ... p;extra=&page=2
回复

使用道具 举报

4

主题

90

回帖

102

积分

初级会员

积分
102
 楼主| 发表于 2025-5-6 12:49:00 | 显示全部楼层
拜托各位查查问题,昨晚测试发现IT接收也不能用

Project_UART.zip

1.02 MB, 下载次数: 3

H743VIT6

回复

使用道具 举报

5

主题

229

回帖

249

积分

高级会员

积分
249
发表于 2025-5-6 19:39:29 | 显示全部楼层
Penguins 发表于 2025-5-6 12:49
拜托各位查查问题,昨晚测试发现IT接收也不能用

H7的处理速度比G4快,你波特率改低了看看比如4800
回复

使用道具 举报

4

主题

90

回帖

102

积分

初级会员

积分
102
 楼主| 发表于 2025-5-7 01:29:22 | 显示全部楼层
非常抱歉辛苦两位大佬,是正好板子的RX引脚松动
回复

使用道具 举报

4

主题

90

回帖

102

积分

初级会员

积分
102
 楼主| 发表于 2025-5-7 01:30:23 | 显示全部楼层
太尴尬了
回复

使用道具 举报

4

主题

90

回帖

102

积分

初级会员

积分
102
 楼主| 发表于 2025-5-7 09:23:58 | 显示全部楼层
现在再继续引入Cache,使用SCB_CleanInvalidateDCache均可正常使用,如果想更换为SCB_InvalidateDCache_by_Addr和SCB_CleanDCache_by_Addr,是不是要注意32字节对齐?但是我的结构体定义如下,如何实现.TxMsg和.RxMsg以32字节对齐呢?还是AC6编译器。
[C] 纯文本查看 复制代码
#define UART_BufSize	101
typedef struct {
	UART_HandleTypeDef *huart;
	char TxMsg[UART_BufSize];
	char RxMsg[UART_BufSize];
} myUART_HandleTypeDef;
回复

使用道具 举报

5

主题

229

回帖

249

积分

高级会员

积分
249
发表于 2025-5-7 15:20:25 | 显示全部楼层
本帖最后由 旮旯旭 于 2025-5-7 15:21 编辑
Penguins 发表于 2025-5-7 09:23
现在再继续引入Cache,使用SCB_CleanInvalidateDCache均可正常使用,如果想更换为SCB_InvalidateDCache_by_ ...

typedef struct {
        UART_HandleTypeDef *huart;
        char *pTxMsg;
        char *pRxMsg;
} myUART_HandleTypeDef;

#define UART_BufSize 32  //32的整数倍
__ALIGNED(32) char g_U1RxBuffer[UART_BufSize];
__ALIGNED(32) char g_U1TxBuffer[UART_BufSize];

__RW_RAM_D1 myUART_HandleTypeDef myUART =
{
    .huart = &huart1,
    .pTxMsg = g_U1TxBuffer,
    .pRxMsg = g_U1RxBuffer,
};

建议结构体里面使用指针
回复

使用道具 举报

4

主题

90

回帖

102

积分

初级会员

积分
102
 楼主| 发表于 2025-5-7 16:21:19 来自手机 | 显示全部楼层
旮旯旭 发表于 2025-5-7 15:20
typedef struct {
        UART_HandleTypeDef *huart;
        char *pTxMsg;

感谢提供思路,不过这样应该是定义数组的时候带对齐和__RW_RAM_D1放在AXI SRAM,结构体直接放在DTCM了吧
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-12 00:48 , Processed in 0.049447 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表