用串口助手发送8个字节的数据,在接收中断里面通过DMA搬运数据。但接收的数据有问题,第一个字节的数据搬运2次,最后一个字节的数据丢失。void uart_init(void)
{
UART_InitTypeDef uart0_config;
GPIO_InitTypeDef GPIO_InitStruct;
// DMA_InitTypeDef uart0_dma_config;
UART_StructInit(&uart0_config);
// 这些是默认配置,简单的应用只配置波特率即可
// uart1_config.DUPLEX = DISABLE; // 半双工模式使能,tx_data
// uart1_config.MD_EN = DISABLE; // Multi-drop 使能
// uart1_config.CK_EN = DISABLE; // 数据校验使能
// uart1_config.CK_TYPE = 0; // 奇偶校验配置 0:偶校验(EVEN);1: 奇校验(ODD)
// uart1_config.BIT_ORDER = 0; // 数据发送顺序配置 0:LSB;1:MSB
// uart1_config.STOP_LEN = 0; // 停止位长度配置 0:1-Bit;1:2-Bit
// uart1_config.BYTE_LEN = 0; // 数据长度配置 0:8-Bit;1:9-Bit
// uart1_config.ADR = 0; // 多机通讯时的从机地址
// uart1_config.RX_DONE = DISABLE; // 接收完成 DMA 请求使能
// uart1_config.TX_BUF_EMPTY = DISABLE; // 发送缓冲区空 DMA 请求使能
// uart1_config.TXD_INV = DISABLE; // TXD 输出极性取反
// uart1_config.RXD_INV = DISABLE; // RXD 输入极性取反
// uart0_config.TX_DONE = ENABLE; // 发送完成 DMA 请求使能
uart0_config.RX_DONE = ENABLE;
uart0_config.TX_BUF_EMPTY = ENABLE; // 发送缓冲区空 DMA 请求使能
uart0_config.IE = UART_IF_SendOver | UART_IF_RcvOver|UART_IF_SendBufEmpty; // 中断配置
uart0_config.BAUDRATE = 115200; // 波特率
UART_Init(UART0, &uart0_config);
/*UART0_485的GPIO配置*/
//uart0_485
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15;
GPIO_Init(GPIO0, &GPIO_InitStruct);
GPIO0_PDO |= BIT15; //写1
/* P0.14-RX0, UART0 */
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14 ;
GPIO_Init(GPIO0, &GPIO_InitStruct);
/*P1.0-TX0 UART0 */
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_Init(GPIO1, &GPIO_InitStruct);
GPIO_PinAFConfig(GPIO1, GPIO_PinSource_0, GPIO_AF_UART);
GPIO_PinAFConfig(GPIO0, GPIO_PinSource_14, GPIO_AF_UART);
/*开启UART的中断*/
NVIC_EnableIRQ(UART0_IRQn);
NVIC_SetPriority(UART0_IRQn, 1);
}
/*DMA接收来自外设的数据*/
void uart0_dma_485_recvdata(u8 *t, u16 len)
{
DMA_InitTypeDef uart0_dma_config;
// GPIO0_PDO &= ~BIT15;
uart0_dma_config.DMA_Channel_EN = ENABLE; /* DMA 通道使能*/
uart0_dma_config.DMA_IRQ_EN = ENABLE; /* DMA 中断使能 */
uart0_dma_config.DMA_RMODE = ENABLE; /* 多轮传输使能 */
uart0_dma_config.DMA_CIRC = DISABLE; /* 循环模式使能 */
uart0_dma_config.DMA_SINC = DISABLE; /* 源地址递增使能 */
uart0_dma_config.DMA_DINC = ENABLE; /* 目的地址递增使能 */
uart0_dma_config.DMA_SBTW = 0; /* 源地址访问位宽, 0:byte, 1:half-word, 2:word */
uart0_dma_config.DMA_DBTW = 0; /* 目的地址访问位宽, 0:byte, 1:half-word, 2:word */
uart0_dma_config.DMA_REQ_EN = DMA_REQ_UART0_RX; /* 通道 x 硬件 DMA 请求使能,高有效 */
uart0_dma_config.DMA_TIMES = 8; /* DMA 通道 x 数据搬运次数 */
uart0_dma_config.DMA_SADR = (u32)&UART0_BUFF; /* DMA 通道 x 源地址 */
uart0_dma_config.DMA_DADR = (u32)t; /* DMA 通道 x 目的地址 */
DMA_Init(DMA_CH0, &uart0_dma_config);
DMA_Trigger(DMA_CH0); //开始一次DMA传输
}
void UART0_IRQHandler(void)
{
if (UART_GetIRQFlag(UART0, UART_IF_SendOver)) /*发送完成中断*/
{
UART_ClearIRQFlag(UART0, UART_IF_SendOver);
// GPIO_ResetBits(GPIO0, GPIO_Pin_15);
}
if (UART_GetIRQFlag(UART0, UART_IF_RcvOver)) /*接收完成中断*/
{
UART_ClearIRQFlag(UART0, UART_IF_RcvOver);
uart0_dma_485_recvdata(ModbusSlave_RX_TempBuff, 8);
}
}
|