打印
[STM32F4]

关于DMA串口发送设置问题

[复制链接]
1306|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;       //使能
}

使用特权

评论回复
5
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写入数值,再开启通道  这样是不是就可以实现传输了

使用特权

评论回复
6
eyesmall|  楼主 | 2015-3-8 22:45 | 只看该作者
香水城 发表于 2015-3-6 11:57
“单次”是和“连续”模式对应的。

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

总是对很基础的东西理解的不是很透彻  多谢版主

使用特权

评论回复
7
diweo| | 2015-3-10 20:59 | 只看该作者
eyesmall 发表于 2015-3-8 22:43
在阅读公司现有串口程序时发现,DMA每次发送数据  都要先deinit 一下DMA    这个工鞥应该是让DMA相关配置 ...

是的。

使用特权

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

本版积分规则

10

主题

145

帖子

0

粉丝