野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 101|回复: 1

STM32F407串口乱码

[复制链接]
发表于 6 天前 | 显示全部楼层 |阅读模式
不知道什么原因使用中断进行串口收发是正常的,但是使用DMA进行串口收发,数据都是乱码。使用了例程代码也是一样的乱码输出。确认了时钟树是正常的。有人遇到过吗?

#define     G_DMA_RX_LEN 100
#define     G_DMA_TX_LEN 100
uint8_t     g_dma_rx_buff[G_DMA_RX_LEN];
uint8_t     g_dma_tx_buff[G_DMA_TX_LEN];
uint16_t     g_tx_buff_len = 0;

static void Usart1GpioInit(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_AHB1PeriphClockCmd(USART1_GPIO_CLK,ENABLE);                             //使能GPIOA时钟
    GPIO_InitStructure.GPIO_Pin = USART1_GPIO_PIN;                                 //GPIOA9与GPIOA10
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;                                //复用功能
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                            //速度50MHz
    GPIO_Init(USART1_GPIO_PORT,&GPIO_InitStructure);                             //初始化PA9,PA10
    //串口1对应引脚复用映射
    GPIO_PinAFConfig(USART1_GPIO_PORT,USART1_TX_SOURCE,USART1_TX_AF);             //GPIOA9复用为USART1
    GPIO_PinAFConfig(USART1_GPIO_PORT,USART1_RX_SOURCE,USART1_RX_AF);             //GPIOA10复用为USART1
}
static void Usart1Config(void)
{
    USART_InitTypeDef USART_InitStructure;
    RCC_APB2PeriphClockCmd(USART1_CLK,ENABLE);                                    //使能USART1时钟
    //USART1 初始化设置
    USART_InitStructure.USART_BaudRate = USART1_BAUDRATE;                        //波特率设置
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;                    //字长为8位数据格式
    USART_InitStructure.USART_StopBits = USART_StopBits_1;                        //一个停止位
    USART_InitStructure.USART_Parity = USART_Parity_No;                            //无奇偶校验位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;                //收发模式
    USART_Init(USART1, &USART_InitStructure);                                     //初始化串口1   
}
static void Usart1NvicInit(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    //Usart1 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;                            //串口1中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;                        //抢占优先级1
    NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;                            //子优先级3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);   
}
static void Usart1DmaRxInit(void)
{
    DMA_InitTypeDef  DMA_InitStructure;
    RCC_AHB1PeriphClockCmd(USART1_DMA_CLK,ENABLE);                                //DMA2时钟使能
    DMA_DeInit(USART1_RX_DMA_STREAM);
    while (DMA_GetCmdStatus(USART1_RX_DMA_STREAM) != DISABLE){}                    //等待DMA可配置
    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable ;
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full ;
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single ;                 //存储器突发单次传输
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    //  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;   // DMA_Mode_Circular  DMA_Mode_Normal
    DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t) (&(USART1->DR)) ;
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
    /* Configure RX DMA */
    DMA_InitStructure.DMA_Channel = USART1_RX_DMA_CHANNEL ;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                               // DMA_Mode_Circular  DMA_Mode_Normal
    DMA_InitStructure.DMA_BufferSize = G_DMA_RX_LEN;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory ;
    DMA_InitStructure.DMA_Memory0BaseAddr =(uint32_t)g_dma_rx_buff;
    DMA_Init(USART1_RX_DMA_STREAM,&DMA_InitStructure);
    DMA_Cmd(USART1_RX_DMA_STREAM,ENABLE);                                          //开启接收
    USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);

}

static void Usart1DmaTxInit(void)
{
    DMA_InitTypeDef  DMA_InitStructure;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);                            //DMA2时钟使能
    DMA_DeInit(USART1_TX_DMA_STREAM);
    while (DMA_GetCmdStatus(USART1_TX_DMA_STREAM) != DISABLE){}                    //等待DMA可配置
    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable ;
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full ;
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single ;                 //存储器突发单次传输
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    //  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;   // DMA_Mode_Circular  DMA_Mode_Normal
    DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t) (&(USART1->DR)) ;
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
    /* Configure TX DMA */
    DMA_InitStructure.DMA_Channel = USART1_RX_DMA_CHANNEL ;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                               // DMA_Mode_Circular  DMA_Mode_Normal
    DMA_InitStructure.DMA_BufferSize = G_DMA_TX_LEN;
    DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral ;
    DMA_InitStructure.DMA_Memory0BaseAddr =(uint32_t)g_dma_tx_buff ;
    DMA_Init(USART1_TX_DMA_STREAM,&DMA_InitStructure);
    USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);
}
void Usart1Init(void)
{
    Usart1GpioInit();
    Usart1Config();
    Usart1NvicInit();
    Usart1DmaRxInit();
    Usart1DmaTxInit();
   
    USART_ClearITPendingBit(USART1, USART_IT_IDLE);                                //开启串口接受中断
    USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);                                //开启空闲中断
    USART_Cmd(USART1, ENABLE);                                                  //使能串口1
}
void Usart1DmaSend(uint8_t *data_buf, uint16_t lengh)
{
    DMA_Cmd(USART1_TX_DMA_STREAM,DISABLE);
    Waiting_Disable_DMA(USART1_TX_DMA_STREAM);
    //DMA_ITConfig(USART1_TX_DMA_STREAM,DMA_IT_FE,ENABLE);
    //解析接收到的数据
    memset(g_dma_tx_buff, 0,G_DMA_TX_LEN );
    memcpy(g_dma_tx_buff,data_buf,lengh);
    /* Clear DMA Transfer Complete Flags */
    DMA_ClearFlag(USART1_TX_DMA_STREAM,DMA_FLAG_TCIF7);
    /* Clear USART Transfer Complete Flags */
    USART_ClearFlag(USART1,USART_FLAG_TC);   
    DMA_SetCurrDataCounter(USART1_TX_DMA_STREAM,lengh);   
    DMA_Cmd(USART1_TX_DMA_STREAM,ENABLE);   

}

void DMA2_Stream2_IRQHandler(void)
{
    uint16_t lengh=0;
    //清除标志
    if(DMA_GetFlagStatus(USART1_RX_DMA_STREAM,DMA_FLAG_TCIF2)!=RESET)//等待DMA2_Steam7传输完成
    {
        DMA_Cmd(USART1_RX_DMA_STREAM, DISABLE); //关闭DMA,防止处理其间有数据   
        lengh = G_DMA_RX_LEN - DMA_GetCurrDataCounter(USART1_RX_DMA_STREAM);   
        DMA_ClearFlag(USART1_RX_DMA_STREAM,DMA_FLAG_TCIF2 | DMA_FLAG_FEIF2 | DMA_FLAG_DMEIF2 | DMA_FLAG_TEIF2 | DMA_FLAG_HTIF2);//清除DMA2_Steam7传输完成标志  
        DMA_SetCurrDataCounter(USART1_RX_DMA_STREAM, G_DMA_RX_LEN);  
        memcpy(g_dma_tx_buff,g_dma_rx_buff,lengh);
        g_tx_buff_len = lengh;   
        //发送数据
        Usart1DmaSend(g_dma_tx_buff,g_tx_buff_len);        
        DMA_Cmd(USART1_RX_DMA_STREAM, ENABLE);     //打开DMA,
    }
}


回复

使用道具 举报

 楼主| 发表于 6 天前 | 显示全部楼层
改用配置寄存器正常了不清楚库配置哪里错了
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2025-12-31 07:56 , Processed in 0.109984 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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