DMA在STM32H7上不工作的解决办法
问题
将STM32F0的DMA代码移植到STM32H7上时发现DMA ErrorCode寄存器为1,无法正常工作
原因
DMA缓冲区内存被放置在DTCM,最好将DMA缓冲区放在D2域(SRAM1,SRAM2和SRAM3)内,因为D2到D1桥会增加额外的延迟。
懒得写,咕了
问题
将STM32F0的DMA代码移植到STM32H7上时发现DMA ErrorCode寄存器为1,无法正常工作
原因
DMA缓冲区内存被放置在DTCM,最好将DMA缓冲区放在D2域(SRAM1,SRAM2和SRAM3)内,因为D2到D1桥会增加额外的延迟。
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
HAL_StatusTypeDef sd = HAL_UART_Transmit(&huart3, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
SDMMC
打开SDMMC2外设,Mode设置为SD 4 bits Wide bus
, 将does the board use uSD transceiver
禁用,时钟设置为32MHz。
FATFS
FATFS选项卡勾选SD Card
选项。这里需要注意:如果你的CODE_PAGE选择了非拉丁语言如中文,它将会生成代码页文件,该文件体积很大,STM32H750VB无法存储下来。会导致编译最后的链接失败。
进入FATFS的Platform Setting选项卡,在这里设置SD插入检测的引脚,将对应引脚GPIO设定为 Input 内部上拉,然后在这个页面选择该引脚即可。
环境
使用CubeMX生成的CustomHID工程,使用了三个端点进行通信:EP1(IN)模拟键盘,EP2(OUT)接收WINUSB通信,EP2(IN)发送WINUSB通信。
问题
EP1模拟键盘正常,EP2接收上位机软件通信正常,EP2发送数据不正常。表现为上位机接收不到数据,或数据不完整。
问题原因
在usbd_conf.c文件USBD_LL_Init
函数中,端点0的PMA地址设置出现了问题。问题出现在语句HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData, 0x00, PCD_SNG_BUF, 0x18);
上。
CubeMX默认计算的PMA地址为0x18,只适合最多用到两个端点的应用。
PMA区域从0开始保存了端点地址和端点缓冲区地址,每个端点占用了8个字节(OUT描述4字节,IN描述4字节),中间未用的端点位置是保留的。
当我们使用到端点3的时候,需要占用0,1,2,3共4个端点描述空间,也就是4x8=32字节=0x20,也就是端点0的缓冲区至少要在0x20后面。
解决办法
为了一劳永逸,预留所有8个端点的空间,8x8=64=0x40字节的端点描述区域,当然对于空间比较紧张的应用,可以根据需要计算。HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData, 0x00, PCD_SNG_BUF, 0x40);
其后的配置按需要依次重新计算。
附 例子
/* USER CODE BEGIN EndPoint_Configuration */
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x00 , PCD_SNG_BUF, 0x40);
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x80 , PCD_SNG_BUF, 0x80);
/* USER CODE END EndPoint_Configuration */
/* USER CODE BEGIN EndPoint_Configuration_CUSTOM_HID */
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , CUSTOM_HID_EPIN_ADDR , PCD_SNG_BUF, 0xC0);
/* USER CODE END EndPoint_Configuration_CUSTOM_HID */
/* USER CODE BEGIN EndPoint_Configuration_WINUSB */
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , WINUSB_EPIN_ADDR , PCD_SNG_BUF, 0x100);
HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , WINUSB_EPOUT_ADDR , PCD_SNG_BUF, 0x140);
/* USER CODE END EndPoint_Configuration_WINUSB */
参考链接
https://www.amobbs.com/thread-5692754-1-1.html#id=pid10899158
STM32没有内置的EEPROM,但是我们可以通过修改Linker Script重新划分内部存储空间以达到模拟EEPROM的效果,本文就STM32F042G6U来演示如何方便的将一页内部Flash存储空间映射到代码变量中。