OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4600|回复: 4

STM32F103 UART2通过DMA方式发送和接收 发不出去数据 求帮忙

[复制链接]

2

主题

14

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2017-11-7
在线时间
6 小时
发表于 2017-11-8 12:19:21 | 显示全部楼层 |阅读模式
新手,最近在学习DMA方式通信,但是过程中发现不知道什么问题,发送不出数据帮忙看下哪里的配置出了问题

[mw_shl_code=c,true]

void Init_NVIC(void)
{        
        NVIC_InitTypeDef NVIC_InitStructure;                        //定义一个NVIC向量表结构体变量

        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);        //设置中断组 为2
  
        NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;                                //配置串口1为中断源
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;           //设置占先优先级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                               //设置副优先级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                        //使能串口1中断
        NVIC_Init(&NVIC_InitStructure);                                                                                //根据参数初始化中断寄存器
       
        NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel6_IRQn;                                //配置串口1为中断源
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;           //设置占先优先级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                               //设置副优先级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                        //使能串口1中断
        NVIC_Init(&NVIC_InitStructure);                                                                                //根据参数初始化中断寄存器
       
        NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;                                //配置串口1为中断源
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;           //设置占先优先级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                               //设置副优先级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                        //使能串口1中断
        NVIC_Init(&NVIC_InitStructure);                                                                                //根据参数初始化中断寄存器
       
       
}



void Init_Usart2(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;                                        //定义一个GPIO结构体变量

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO ,ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 ,ENABLE);               
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);          //DMA1时钟
       

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;                                 //配置串口发送端口挂接到9端口
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                           //复用功能输出开漏
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                   //配置端口速度为50M
  GPIO_Init(GPIOA, &GPIO_InitStructure);                                           //根据参数初始化GPIOA寄存器       

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;          //接收
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;        //浮空输入(复位状态);                                          
  GPIO_Init(GPIOA, &GPIO_InitStructure);                                           //根据参数初始化GPIOA寄存器       
}




void Usart2_Configuration(uint32_t BaudRate)
{
        USART_InitTypeDef USART_InitStructure;                                                                    //定义一个串口结构体

        USART_InitStructure.USART_BaudRate            = BaudRate ;                                  //波特率115200
        USART_InitStructure.USART_WordLength          = USART_WordLength_8b;         //传输过程中使用8位数据
        USART_InitStructure.USART_StopBits            = USART_StopBits_1;                 //在帧结尾传输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(USART2, &USART_InitStructure);                                                                //根据参数初始化串口寄存器
  USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);                          // 开启 串口空闲IDEL 中断
        USART_Cmd(USART2, ENABLE);                                                                                             //使能串口外设
  USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);  // 开启串口DMA发送
  USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE); // 开启串口DMA接收
}


void DMA_Uart_Init(void)
{
       
extern u32 UART2_Tx_Buf[UART2_Tx_Buf_number];
extern u32 UART2_Rx_Buf[UART2_Rx_Buf_number];

    DMA_InitTypeDef DMA_InitStructure;
   
    /* DMA clock enable */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // 开启DMA1时钟
   
   
//=DMA_Configuration==============================================================================//

/*--- LUMMOD_UART_Tx_DMA_Channel DMA Config ---*/

    DMA_Cmd(DMA1_Channel7, DISABLE);                           // 关DMA通道
    DMA_DeInit(DMA1_Channel7);                                 // 恢复缺省值
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART2->DR);// 设置串口发送数据寄存器
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)UART2_Tx_Buf;         // 设置发送缓冲区首地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;                      // 设置外设位目标,内存缓冲区 -> 外设寄存器
    DMA_InitStructure.DMA_BufferSize = 1;                     // 需要发送的字节数,这里其实可以设置为0,因为在实际要发送的时候,会重新设置次值
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;        // 外设地址不做增加调整,调整不调整是DMA自动实现的
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                 // 内存缓冲区地址增加调整
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; // 外设数据宽度8位,1个字节
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;         // 内存数据宽度8位,1个字节
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                           // 单次传输模式
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;                 // 优先级设置
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                            // 关闭内存到内存的DMA模式
    DMA_Init(DMA1_Channel7, &DMA_InitStructure);               // 写入配置
                DMA_DeInit(DMA1_Channel7);                                                                                        //UART2的TX为DMA1通道7
    DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE);            // 开启发送DMA通道中断
    DMA_ClearFlag(DMA1_FLAG_GL7);                                 // 清除DMA所有标志
    DMA_Cmd(DMA1_Channel7, ENABLE);                            // 开启接收DMA通道,等待接收数据
   
/*--- LUMMOD_UART_Rx_DMA_Channel DMA Config ---*/

    DMA_Cmd(DMA1_Channel6, DISABLE);                           // 关DMA通道
    DMA_DeInit(DMA1_Channel6);                                 // 恢复缺省值
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART2->DR);// 设置串口接收数据寄存器
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)UART2_Rx_Buf;         // 设置接收缓冲区首地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                      // 设置外设为数据源,外设寄存器 -> 内存缓冲区
    DMA_InitStructure.DMA_BufferSize = UART2_most_Rx_Buf;                     // 需要最大可能接收到的字节数
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;        // 外设地址不做增加调整,调整不调整是DMA自动实现的
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                 // 内存缓冲区地址增加调整
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; // 外设数据宽度8位,1个字节
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;         // 内存数据宽度8位,1个字节
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                           // 单次传输模式
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;                 // 优先级设置
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                            // 关闭内存到内存的DMA模式
    DMA_Init(DMA1_Channel6, &DMA_InitStructure);               // 写入配置
                DMA_DeInit(DMA1_Channel6);//UART2的RX为DMA1通道6
    DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);            // 开启发送DMA通道中断
    DMA_ClearFlag(DMA1_FLAG_GL6);                                 // 清除DMA所有标志
    DMA_Cmd(DMA1_Channel6, ENABLE);                            // 开启接收DMA通道,等待接收数据
   
}

void DMA1_Channel7_IRQHandler(void)
{
    if(DMA_GetITStatus(DMA1_FLAG_TC7))
    {
                        DMA_ClearFlag(DMA1_FLAG_GL7);         // 清除标志
                        DMA_Cmd(DMA1_Channel7, DISABLE);   // 关闭DMA通道
    }
}




void DMA_UART2_Send_Data(u32 size)
{
  DMA1_Channel7->CNDTR =size; // 设置要发送的字节数目
  DMA_Cmd(DMA1_Channel7, ENABLE);        //开始DMA发送
}


void USART2_IRQHandler(void)
{
    if(USART_GetITStatus(USART2, USART_IT_IDLE) != RESET)  // 空闲中断
    {
                        DMA_Cmd(DMA1_Channel6, DISABLE);       // 关闭DMA ,防止干扰
                        DMA_ClearFlag( DMA1_FLAG_GL6 );           // 清DMA标志位
        //    LumMod_Rx_Data.index = LUMMOD_RX_BSIZE - DMA_GetCurrDataCounter(DMA1_Channel7); //获得接收到的字节数
        //    DMA1_Channel7->CNDTR = LUMMOD_RX_BSIZE;    //  重新赋值计数值,必须大于等于最大可能接收到的数据帧数目
                        DMA_Cmd(DMA1_Channel6, ENABLE);        
      USART_ReceiveData( USART2 ); // Clear IDLE interrupt flag bit  
    }
}

int main(void)
{
/********************************系统时钟配置***********************************************/       
        SystemInit();
        Delay_Ms(200);

/****************************初始化中断向量表配置*******************************************/       
        Init_NVIC();               
       
/**********************************IO口配置*************************************************/       
        Init_IO();                         //板内指示初始化
       
/***************************UART1串口IO口初始化配置*****************************************/       
        Init_Usart1();                                                  //用于调试串口打印数据
        Usart1_Configuration(115200);         
       
/***************************UART2串口IO口初始化配置*****************************************/       
        Init_Usart2();                                                  //用于调试串口打印数据
        Usart2_Configuration(115200);         
        DMA_Uart_Init();

/*==============================================================================================================================*/       
       
        while(1)
        {
                UART2_Tx_Buf[0]=0x1;
                UART2_Tx_Buf[1]=0x1;
                UART2_Tx_Buf[2]=0x1;
                UART2_Tx_Buf[3]=0x1;
                DMA_UART2_Send_Data(4);
                Delay_Ms(2000);
       
        }        //while(1)
}         //main       

[/mw_shl_code]
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

14

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2017-11-7
在线时间
6 小时
 楼主| 发表于 2017-11-8 12:44:34 | 显示全部楼层
我把DMA_DeInit(DMA1_Channel7); 删了就可以发送了     为什么呢   这个函数不是没问题吗
回复 支持 反对

使用道具 举报

2

主题

14

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2017-11-7
在线时间
6 小时
 楼主| 发表于 2017-11-8 12:44:49 | 显示全部楼层
求大神帮助啊   
回复 支持 反对

使用道具 举报

5

主题

35

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
217
金钱
217
注册时间
2017-11-6
在线时间
44 小时
发表于 2017-11-8 15:02:14 | 显示全部楼层
就算不懂,先根据字面意思来,init是初始化开启,deinit就反初始化,就是把它销毁了,关闭了;进去看这个函数啊,看看它执行了什么样的操作,是不是你需要的结果?
回复 支持 反对

使用道具 举报

11

主题

99

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
5584
金钱
5584
注册时间
2015-11-5
在线时间
714 小时
发表于 2017-11-12 00:08:47 | 显示全部楼层
你贴个中断的配置让别人怎么帮你分析啊,吧DMA和串口的配置发出来啊
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-9 14:44

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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