OpenEdv-开源电子网

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

求助,串口DMA接收只能进一次中断,再收到一个字节就收不到了,万分苦恼中!

[复制链接]

2

主题

2

帖子

0

精华

新手入门

积分
30
金钱
30
注册时间
2013-8-28
在线时间
0 小时
发表于 2013-10-9 16:29:07 | 显示全部楼层 |阅读模式

 以MINISTM32的扩展实验26 fatfs为模板,想做一个通过usmart从串口接收文件存入SD卡的实验,用非DMA方式因为写SD卡时间较长,速度最多只能达到14400bps。为了加快速度,考虑DMA接收,开辟两块缓存,各200字节,写满一块就把dma存储地址改到另一块上继续DMA接收,同时把写满的缓存内容写入SD卡。
现在遇到的问题是,开启接收DMA后,第一次中断正常进入中断服务程序,但是之后,无论如何初始化DMA接收的寄存器设置(即使设置为与初始化相同的代码),也无法再进入中断,而且观察DMA1_Channel5->CNDTR的值,发现再收到一个字符就停止了。
更奇怪的是,在退出接收文件的代码后,调用uart_init(72,14400); 可恢复正常的usmart操作,再次开启文件传输功能时,还能再进一次中断,显然应该认为此时的DMA初始化成功。但在中断处理程序中调用uart_init(72,14400); 再操作DMA初始化则仍然无法第二次进入中断。
DMA初始化部分程序如下:
//串口1接收的DMA初始化
 void MYDMA_rec_Conf(u32 cmar,u16 cndtr)
{
 
 u32 DR_Base;    //做缓冲用,不知道为什么.非要不可
 RCC->AHBENR|=1<<0; //开启DMA1时钟
 delay_ms(5);//加延时试试。
 DR_Base=cmar;    
// DMA1_MEM_LEN=cndtr;     //保存DMA传输数据量
// DMA_CHx->CNDTR=cndtr;   //DMA1,传输数据量
 DMA1_Channel5->CNDTR=cndtr;
 //DMA1_Channel5->CPAR=DR_Base;    //DMA1 外设地址 
 DMA1_Channel5->CMAR=DR_Base;   //DMA存储器地址
 DMA1_Channel5->CPAR=(u32)&USART1->DR;    //DMA1 外设地址 
 DMA1_Channel5->CCR=0X00000000;   //复位
 DMA1_Channel5->CCR &= ~(1<<4);    //从外设读
 DMA1_Channel5->CCR &= ~(1<<5);    //普通模式,不执行循环操作
 DMA1_Channel5->CCR &= ~(1<<6);    //外设地址非增量模式
 DMA1_Channel5->CCR |= 1<<7;       //存储器增量模式
 DMA1_Channel5->CCR &= ~(3<<8);    //外设数据宽度为8位
 DMA1_Channel5->CCR &= ~(3<<10);   //存储器数据宽度8位
 DMA1_Channel5->CCR |= 1<<12;      //中等优先级
 DMA1_Channel5->CCR &= ~(1<<14);   //非存储器到存储器模式
  
  //传输完成中断
 DMA1_Channel5->CCR |= 1<<1;         //允许传输完成中断
// DMA1_Channel5->CCR |= 1<<2;         //允许半传输完成中断
 MY_NVIC_Init(2,2,DMA1_Channel5_IRQChannel,2);//组2,最低优先级 
 
}
void DMAChannel5_IRQHandler(void)
{
 LED1=!LED1;
//以下为dma接收的代码
     DMA1->IFCR|=1<<16;  //清除通道5的全局中断标志
   if (buffno==0)
   {
    DMA1_Channel5->CCR&=~(1<<0); //关闭DMA传输
    USART1->CR3&=~(1<<6); //关闭uart1的dma接收
  MYDMA_rec_Conf((u32)USDMA_RX_BUF[1],USART_REC_LEN);
  USART1->CR3|=1<<6; //开启uart1的dma接收    
 DMA1_Channel5->CCR|=1<<0;          //开启DMA传输

    USART1->CR3|=1<<6; //开启uart1的dma接收    
    buffno=1;//切换到buff1的标志
    mf_write(USDMA_RX_BUF[0],USART_REC_LEN);  
   }
   else
   {
    DMA1_Channel5->CCR&=~(1<<0); //关闭DMA传输
    USART1->CR3&=~(1<<6); //关闭uart1的dma接收
    MYDMA_rec_Conf((u32)USDMA_RX_BUF[0],USART_REC_LEN);
    USART1->CR3|=1<<6; //开启uart1的dma接收
    DMA1_Channel5->CCR|=1<<0;          //开启DMA传输

     buffno=0;//切换到buff0
     mf_write(USDMA_RX_BUF[1],USART_REC_LEN);
   }

//以上为dma接收的代码  
}

我已经焦头烂额了,不知道问题出在哪里,请各位高手指教!

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

使用道具 举报

81

主题

270

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
452
金钱
452
注册时间
2014-8-11
在线时间
87 小时
发表于 2016-1-15 15:37:10 | 显示全部楼层
我也是一样的问题,请问你是怎么解决的
回复 支持 1 反对 0

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-10-9 17:45:58 | 显示全部楼层
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

14

主题

171

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
450
金钱
450
注册时间
2017-3-31
在线时间
118 小时
发表于 2017-4-7 13:16:37 | 显示全部楼层
战舰水手 发表于 2016-1-15 15:37
我也是一样的问题,请问你是怎么解决的

我也遇到这个问题了,你解决了么?
回复 支持 反对

使用道具 举报

27

主题

132

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
328
金钱
328
注册时间
2018-7-20
在线时间
117 小时
发表于 2018-8-16 17:56:31 | 显示全部楼层
标准库遇到了同样的问题,这个寄存器版本的程序实在看不懂
我只喜欢喜欢我的人
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-18 15:01

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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