OpenEdv-开源电子网

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

DMA双缓冲停不下来,普通模式可以.

[复制链接]

30

主题

104

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
456475
金钱
456475
注册时间
2014-8-23
在线时间
59 小时
发表于 2015-10-1 11:05:08 | 显示全部楼层 |阅读模式
5金钱
为了试验双缓冲模式,就拿USART测试,刚开始是USART1,现在是USART3,同样的问题.

    USART_Cmd(USART3, ENABLE);  //使能串口1
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
    DMA_DeInit(DMA1_Stream4);
    DMA_StructInit(&DMA_InitStructure);
    DMA_InitStructure.DMA_Channel = DMA_Channel_7;
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART3->DR; //数据传输的外设首地址
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)Buffer0; //自己定义待发送数组的首地址,要强制转换为32位
    DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; //数据传输方向选择为内存->外设
    DMA_InitStructure.DMA_BufferSize = 4; //传输数据大小为8,大小要配合定义的数组类型和外设数据类型,否则会丢失或补充数据
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器自动增加禁止,因为这里只用到了 DR 数据寄存器
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址自增允许,因为要读取一个数组
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设的数据大小,因为 USART3_DR 数据寄存器为8位,故选Byte
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //这里也选 Byte
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //在普通DMA时候,DMA_Mode_Normal就是传一次,DMA_Mode_Circular,循环传输,但是在双缓冲下,怎么都是不停传.
    DMA_InitStructure.DMA_Priority = DMA_Priority_Low; //优先级为 High
    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;//双缓冲下面,这个功能怎么好像没用
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
    DMA_DoubleBufferModeConfig(DMA1_Stream4, (uint32_t)Buffer1, DMA_Memory_0);
    DMA_DoubleBufferModeCmd(DMA1_Stream4, ENABLE);

    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//抢占优先级0
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;//子优先级0
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
    NVIC_Init(&NVIC_InitStructure);//配置

    DMA_Init(DMA1_Stream4, &DMA_InitStructure);
    /*DMA 中断开*/
    DMA_ClearITPendingBit(DMA1_Stream4, DMA_IT_TCIF4);
    DMA_ITConfig(DMA1_Stream4, DMA_IT_TC, ENABLE);
    USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE);
    DMA_Cmd(DMA1_Stream4, ENABLE); 

在中断内,通过判断,时候传够20次传输,就结束,结果发现没效果.

[mw_shl_code=c,true] if(DMA_GetITStatus(DMA1_Stream4, DMA_IT_TCIF4) == SET) { DMA_ClearITPendingBit(DMA1_Stream4, DMA_IT_TCIF4); if(Buffer0[0] != 0xB0) { if(DMA_GetCurrentMemoryTarget(DMA1_Stream4)) { //现在访问是Buufer1,所以写Buffer0. for(i = 0; i < 4; i++) { Buffer0++; } } else { for(i = 0; i < 4; i++) { Buffer1--; } } } else { DMA_DoubleBufferModeCmd(DMA1_Stream4, DISABLE); // USART_DMACmd(USART3,USART_DMAReq_Tx,DISABLE); } }[/mw_shl_code]
如果不关闭USART_DMAReq_Tx就停不下来,如果关闭,最后一次传输漏了两个字节.怎么办.


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

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
发表于 2015-10-1 23:01:51 | 显示全部楼层
回复

使用道具 举报

42

主题

297

帖子

0

精华

高级会员

Rank: 4

积分
994
金钱
994
注册时间
2016-7-22
在线时间
318 小时
发表于 2016-11-16 13:20:36 | 显示全部楼层
使能双缓冲区模式时,将自动使能循环模式( DMA_SxCR 中的 CIRC 位的状态是“无关”)
这是中文参考手册 DMA双缓冲模式中提到的
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-4 08:38

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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