按照网上的教程配置了串口和DMA,结果缓存数组里接收的所有字节始终是同一个字节,排查了好久,发现原来是对DMA源地址的设置有问题。我最开始的写法如下:
// 设置DMA源地址:串口数据寄存器地址*/
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)USART1->DR;
最后正确的写法如下:
// 设置DMA源地址:串口数据寄存器地址*/
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART1->DR);
UART+DMA接收数据发生错误就是这么一个小小的错误导致的...没有对USART1->DR变量先进行取地址操作。所以先对USART1->DR变量取地址后再强制类型转换为uint32_t类型就接收数据正常了。
详细解释:
USART1的定义是:
#define USART1 ((USART_TypeDef *) USART1_BASE)
USART1_BASE被强制转换为USART_TypeDef*类型。
USART_TypeDef是一个结构体定义如下:
typedef struct
{
__IO uint16_t SR;
uint16_t RESERVED0;
__IO uint16_t DR;
uint16_t RESERVED1;
__IO uint16_t BRR;
uint16_t RESERVED2;
__IO uint16_t CR1;
uint16_t RESERVED3;
__IO uint16_t CR2;
uint16_t RESERVED4;
__IO uint16_t CR3;
uint16_t RESERVED5;
__IO uint16_t GTPR;
uint16_t RESERVED6;
} USART_TypeDef;
(uint32_t)(&USART1->DR)这句代码含义就是:
取了结构体指针USART1中的DR变量后,得到它的地址然后强转为uint32_t类型。
记录一下这个踩到的坑。