打印
[应用相关]

串口发送数据DMA中断的问题

[复制链接]
3052|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zb214|  楼主 | 2008-10-12 14:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在使用DMA做RS485通信的时候,需要在发送的时候将芯片设置为发送,在发送完毕设置为接收模式。但是用下面的代码,程序一直在发送的函数里面死循环,无法理解,下面是我的代码,请做过的朋友帮我分析一下谢谢!

时钟使能了的
 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);
中断向量也是打开了的
  /* Enable DMA1 channel2 IRQ Channel RS485发送完成中断 */
  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  GPIO也是设置好的

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_13 | GPIO_Pin_15;    //CAN TX(PB9),RS485 TX(PA9),SPI SCK(PB13),SPI MOSI(PB15)设置为复用功能推挽输出
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure); 

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;        //RS485 RX(PB11) 设置为输入浮空
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
      GPIO_Init(GPIOB, &GPIO_InitStructure);

/********************************************************************************
 *函数原型:  void    RS232_Init(u32 baud)                                                
 *参数说明:  baud: 波特率                                     
 *返回值:    无                                                               
 *说明:      USART 通讯口初始化程序 设置帧格式: 8 个数据位,无奇偶效验位,1个停止位 8N1
 *
     0:2400 bps  4.2MS 每字节
    1:9600bps   1MS 每字节
    2:19200bps  0.5MS 每字节
    3:38400bps  0.25 每字节
    4:115200bps 0.087MS 每字节  
* 对于通信接收数据打包的判断,一个就是接收数据超过64字节,另外就是超时的计算,超时
* 设定为各个通信波特率的,两字节传输时间没有收到数据就打包发出。                                              
 ********************************************************************************/
void    RS485Bus_Init(u8 BaudNum)    //USART 通讯口初始化程序
{
    USART_InitTypeDef USART_InitStructure;
    DMA_InitTypeDef DMA_InitStructure;    
    u32 baud = 19200;
    switch(BaudNum)
    {
        case    0:    baud = 2400;
                    break;
        case    1:    baud = 9600;
                    break;
        case    2:    baud = 19200;
                    break;    
        case    3:    baud = 38400;
                    break;    
        case    4:    baud = 115200;
                    break;        
         default  :    baud = 19200;
                    break;        
    }
    

    USART_InitStructure.USART_BaudRate = baud;            //波特率设置
      USART_InitStructure.USART_WordLength = USART_WordLength_8b;     //通讯格式 8N1,无硬件流控
      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(USART3, &USART_InitStructure);
 
  ///////////////////////////////////首先开启一次DMA传送使DMA1_FLAG_TC2 置位/////////////////////     
    DMA_DeInit(DMA1_Channel2);  
    DMA_InitStructure.DMA_PeripheralBaseAddr = USART3_DR_Base;
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)RS485BusTxData;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = 1;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel2, &DMA_InitStructure);
    
    DMA_ClearFlag(DMA1_FLAG_TC2);
    DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, ENABLE);    //使能发送完成中断

    /* DMA1 Channel3 (triggered by USART3_RX event) Config */
    DMA_DeInit(DMA1_Channel3);  
    DMA_InitStructure.DMA_PeripheralBaseAddr = USART3_DR_Base;
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)RS485BusRxData;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = RS485_BUF_NUM;
    DMA_Init(DMA1_Channel3, &DMA_InitStructure);

    USART_DMACmd(USART3, USART_DMAReq_Rx | USART_DMAReq_Tx, ENABLE);
 
    USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);     //接收空闲中断使能

    DMA_Cmd(DMA1_Channel2, ENABLE);
    DMA_Cmd(DMA1_Channel3, ENABLE);

      USART_Cmd(USART3, ENABLE); 
 }

/********************************************************************************
 *函数原型:  void RS232_SendData(void)                                               
 *参数说明:  Len      : 帧数据长度
 *             *data  : 指向发送数据寄存器组 
 *返回值:      无  
 *说明:      将待发送的数据发送出去                                          
 ********************************************************************************/
void RS485Bus_SendData(void)     //将待发送的数据发送出去
{    
    DMA_InitTypeDef DMA_InitStructure;

    RS485_TXEN;    //发送使能

    while (DMA_GetFlagStatus(DMA1_FLAG_TC2) == RESET);  //等待上一个数据帧发送完毕

     DMA_DeInit(DMA1_Channel2);  
    DMA_InitStructure.DMA_PeripheralBaseAddr = USART3_DR_Base;
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)RS485BusTxData;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = RS485BusTxNum;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel2, &DMA_InitStructure);

     DMA_ClearFlag(DMA1_FLAG_TC2);
    DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, ENABLE);    //使能发送完成中断

        
    DMA_Cmd(DMA1_Channel2, ENABLE);
}
发送完成中断函数,清标记,设置RS485为接收状态
void DMA1_Channel2_IRQHandler(void)
{
    //DMA1 Channel2 发送完成中断 */
    if(DMA_GetITStatus(DMA1_IT_TC2) != RESET)
    {
        DMA_ClearITPendingBit(DMA1_IT_TC2);         //清中断标志
        RS485_RXEN;              //接收使能
    }
}

沙发
zb214|  楼主 | 2008-10-12 15:14 | 只看该作者

在使用三极管做自动收发的时候

在使用三极管做自动收发的时候,没有使用到DMA中断,这个时候程序是没有问题的。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

23

帖子

0

粉丝