[STM32F4] 关于DMA串口发送设置问题

[复制链接]
1889|6
 楼主| eyesmall 发表于 2015-3-6 00:28 | 显示全部楼层 |阅读模式
如  DMA工作在内存到外设   工作模式为单次        不是很了解这里的单次如何理解,看例程  每发送一次数据都要从新设置相关所有参数    deinit          如果每次发送的数据大小一样    直接关闭发送 再启动发送不行吗   
这里的单次模式  是配置一次发送一次 还是开启一次发送工鞥发送一次 关闭再开启就会再次发送??
diweo 发表于 2015-3-6 08:30 | 显示全部楼层
数据传输数量CNDTR 寄存器:数据传输数量为0至65535。这个寄存器只能在通道不工作(DMA_CCRx的EN=0)时写入。通道开启后该寄存器变为只读,指示剩余的待传输字节数目。寄存器内容在每次DMA传输后递减。 数据传输结束后,寄存器的内容或者变为0;或者当该通道配置为自动重加载模式时,寄存器的内容将被自动重新加载为之前配置时的数值。 当寄存器的内容为0时,无论通道是否开启,都不会发生任何数据传输。

比如说你要发10个字节,配置好后,CNDTR=10,发完一个数据就减1,等减到0的时候,数据就发完了。如果是单次模式就一切结束。如果是循环模式就自动重装并且重新开始发送。
所以你说“ 如果每次发送的数据大小一样    直接关闭发送 再启动发送不行吗   ”是不行的。因为即使你通道开了,CNDTR还是0,还是不发数据。

DMA模块还是比较简单的,寄存器也不复杂,直接用寄存器操作好了。库函数太繁琐了。
香水城 发表于 2015-3-6 11:57 | 显示全部楼层
“单次”是和“连续”模式对应的。

单次就是说当启动DMA之前设置的NDTR值自减到0之后,本次DMA传输结束。

例如第一次要传64个数据,在64次传输完成后,DMA停止,即时此时还有来自对应外设的DMA请求。如果要再启动下一次64个数据或者20个数据的传输,不仅要重新使能DMA,还要重新配置NDTR,即新一次传输的长度,不能够“关闭再开启就会再次发送”
wowow 发表于 2015-3-6 12:00 | 显示全部楼层
这是我们用的F1的代码,F4的原理应该差不多
//初始化uart1的DMA发送,未启动
//uart1 TX对应DMA1_CH4
void InitUart1DmaT(void)
{
    DMA1_Channel4->CPAR = (u32)(&(USART1->DR));

    DMA1_Channel4->CCR = DMA_DIR_PeripheralDST
                    | DMA_PeripheralInc_Disable
                    | DMA_MemoryInc_Enable
                    | DMA_PeripheralDataSize_Byte
                    | DMA_MemoryDataSize_Byte
                    | DMA_Mode_Normal
                    | DMA_Priority_VeryHigh
                    | DMA_M2M_Disable
                    | DMA_IT_TC
                    | DISABLE;
    USART1->CR3 |= USART_DMAReq_Tx;
}

//uart1使用DMA_CH4发送数据
void sio1_write_dma(const char *pDat,u16 len){
    if(DMA1_Channel4->CCR & ENABLE) {//如果已经启动DMA
        while(!(DMA1->ISR & DMA_ISR_TCIF4));//等发送完成
        DMA1->IFCR |= DMA_IFCR_CTCIF4;  //清状态位
        DMA1_Channel4->CCR &= ~ENABLE;//禁DMA
    }
    DMA1_Channel4->CMAR = (u32)(pDat);  //设定数据地址
    DMA1_Channel4->CNDTR = len;         //设定数据长度
    DMA1_Channel4->CCR |= ENABLE;       //使能
}
 楼主| eyesmall 发表于 2015-3-8 22:43 | 显示全部楼层
diweo 发表于 2015-3-6 08:30
数据传输数量CNDTR 寄存器:数据传输数量为0至65535。这个寄存器只能在通道不工作(DMA_CCRx的EN=0)时写入。 ...

在阅读公司现有串口程序时发现,DMA每次发送数据  都要先deinit 一下DMA    这个工鞥应该是让DMA相关配置参数回复系统默认值。然后对DMA重新配置 包括CNDTR   其实这里面每次发送需要改变的数据只有CNDTR 其余操作和配置只需系统开启时初始化一次就可以,我觉得每次都初始化配置那么多参数 总会浪费一些时间,如果我每次传输数据前先关闭DMA通道  然后像CNDTR写入数值,再开启通道  这样是不是就可以实现传输了
 楼主| eyesmall 发表于 2015-3-8 22:45 | 显示全部楼层
香水城 发表于 2015-3-6 11:57
“单次”是和“连续”模式对应的。

单次就是说当启动DMA之前设置的NDTR值自减到0之后,本次DMA传输结束。

总是对很基础的东西理解的不是很透彻  多谢版主
diweo 发表于 2015-3-10 20:59 | 显示全部楼层
eyesmall 发表于 2015-3-8 22:43
在阅读公司现有串口程序时发现,DMA每次发送数据  都要先deinit 一下DMA    这个工鞥应该是让DMA相关配置 ...

是的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

168

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部