OpenEdv-开源电子网

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

为什么没有填满DMA缓冲区数据就进入DMA中断

[复制链接]

1

主题

4

帖子

0

精华

新手入门

积分
28
金钱
28
注册时间
2012-7-24
在线时间
0 小时
发表于 2012-7-24 16:07:40 | 显示全部楼层 |阅读模式

本人为STM32初学者,请教各位大侠一个问题。
实现功能:用STM32实现DMA接收串口2数据,然后用LCD显示接收的数据。
遇到问题:我设置的是DMA传输完成中断,缓冲大小是512 bytes。但是串口每发送1个字节,就进入了一次DMA中断,甚是费解。不甚感激!!
我的代码如下:

//DMA目标缓冲,这里使用双缓冲
u8 USART2_DMA_Buf1[512] = NULL;
u8 USART2_DMA_Buf2[512] = NULL;
bool Buf_OK; //BUF是否已经可用
BUF_NO Free_BUf_NO;  //空闲的BUF
DMA_InitTypeDef DMA_InitStructure;

//DMA初始化
void USART_DMAToBuf1(void) 
{
    RCC_AHBPeriphClockCmd( RCC_AHBPeriph_DMA1, ENABLE);  // open DMA clock
    DMA_DeInit(DMA1_Channel6); //make the channel 6 default
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32) SRC_USART2_DR;  //BUF is from &(USART2->DR)
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32) USART2_DMA_Buf1;  // BUF is to USART2_DMA_Buf1
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; // set peripheral is the source
    DMA_InitStructure.DMA_BufferSize = 512;  // the Buffer of DMA, and uint is set next
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //???è???·?????÷??????
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //???????·????
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  // the unit of peripheral is byte
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // the unit of memory is byte
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // worked in the circular model
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // it is not memory to memory
    DMA_Init(DMA1_Channel6, &DMA_InitStructure); // initialize the dma

    DMA_ITConfig( DMA1_Channel6, DMA_IT_TC, ENABLE);

    /** DMA_ IT **/
    USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE); //enable the usart2 reception Interruption

    /** Init the BUF **/
    Free_BUf_NO = BUF_NO2;  //DMA_InitStructure.DMA_MemoryBaseAddr = (u32) USART2_DMA_Buf1;
    Buf_OK = FALSE; //No data transmitting is  completed
    DMA_Cmd(DMA1_Channel6, ENABLE);  //enable the dma
      


/*******************************************************************************
* Function Name  : USART2  to DMA IT Handler
* Description    : When DMA FULL,
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void DMA1_Channel6_IRQHandler(void)
{
    DMA1_Channel6_IRQHandler_Next();
}


void DMA1_Channel6_IRQHandler_Next(void)
{
      if(DMA_GetITStatus(DMA1_IT_TC6))
      {
        DataCounter = DMA_GetCurrDataCounter(DMA1_Channel6);  /// for debug
        DMA_ClearITPendingBit(DMA1_IT_GL6); //clear the whole flag

      /**transfer the operatorial BUF**/
        if(Free_BUf_NO == BUF_NO1)
          {
              DMA_InitStructure.DMA_MemoryBaseAddr = (u32) USART2_DMA_Buf1;
              DMA_Init(DMA1_Channel6, &DMA_InitStructure);
              Free_BUf_NO = BUF_NO2;
          }
         else
          {
              DMA_InitStructure.DMA_MemoryBaseAddr = (u32) USART2_DMA_Buf2;
              DMA_Init(DMA1_Channel6, &DMA_InitStructure);
              Free_BUf_NO = BUF_NO1;
          }

         Buf_OK = TRUE; // have the already data
        
      }
}


//USART2中断处理函数
void USART2_IRQHandler(void)
{
 USART2_ReceiveData();  //Send strings to STM32
}

//串口接收程序
void USART2_ReceiveData()
{

    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
    {
          USART_ClearITPendingBit(USART2, USART_IT_RXNE);
          USART2_DMA_Buf1[BufCounter] = (unsigned char)USART_ReceiveData(USART2);
          BufCounter++;
    } 

}


int main()
{
  System_Init();
  USART_TO_FLASH_DMA_Init();
  while(1)
  {
    if(Buf_OK == TRUE)
     {
        Buf_OK = FALSE; // operate the already data     
          while(1)
          {         
             LCD_ClearScreen();
             char lcd_str[32];
             for(int i=0; i<32; i++)
             {
               lcd_str=USART2_DMA_Buf1;
             }
             LCD_DisplayString((char *)lcd_str);
             Delay_xms(1000);
          }
     }
       
  }
}

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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2012-7-24 18:32:14 | 显示全部楼层
感觉你的DMA中断设置少了些东西.
 
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

1

主题

4

帖子

0

精华

新手入门

积分
28
金钱
28
注册时间
2012-7-24
在线时间
0 小时
 楼主| 发表于 2012-7-24 19:46:38 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
能具体说说少了什么吗?我是照着别人的例子做的。谢谢!
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2012-7-24 22:43:41 | 显示全部楼层
回复【3楼】weier:
---------------------------------
DMA的传输中断,可以有全部完成中断,也有半完成中断,你上面是怎么设置的?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

1

主题

4

帖子

0

精华

新手入门

积分
28
金钱
28
注册时间
2012-7-24
在线时间
0 小时
 楼主| 发表于 2012-7-27 11:20:38 | 显示全部楼层
回复【4楼】正点原子:
---------------------------------
我设置的是全部完成中断。可是程序运行的时候,不等到传输完成就进入DMA中断了。
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2012-7-27 11:34:24 | 显示全部楼层
这就怪了,可能你的设置有问题吧.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

1

主题

4

帖子

0

精华

新手入门

积分
28
金钱
28
注册时间
2012-7-24
在线时间
0 小时
 楼主| 发表于 2012-7-29 09:29:17 | 显示全部楼层
回复【6楼】正点原子:
---------------------------------
找到原因了。
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32) SRC_USART2_DR;  //BUF is from &(USART2->DR)
这句话中SRC_USART2_DR的宏定义有错误,我对应成USART1了。谢谢各位!以后要百般仔细才行,太马虎了。
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-27 01:47

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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