打印

配置DMA中断接收串口数据,出现最后一个字节 数据问题

[复制链接]
9367|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
nylyt|  楼主 | 2009-2-15 01:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我在主板用DMA循环模式配置DMA中断接收USART的数据.databuffersize 配置为15个字节.采集模块接收到主板发送的命令后以固定的数据桢15个字节上传数据,在DEBUG中调试发现有时出现数据最后一个字节或2个字节乱码,造成数据错误,如果不用DMA方式而用USART串口中断接收数据则正确,这样说明下位机上传数据程序正确,但用DMA模式则会出现最后字节乱码问题,不知道什么原因.现在我用了一个被动解决方法就是DMA配置17个字节,下位机上传数据也用17个字节,然后在主程序中舍弃最后2个字节.只是利用了有效的15个字节.奇怪为什么会出现最后1或2字节数据错误的问题呢?
沙发
香水城| | 2009-2-15 08:39 | 只看该作者

是否你在上一次最后一个字节还没有送出前,就更换了缓冲

看看错误是否有规律

使用特权

评论回复
板凳
nylyt|  楼主 | 2009-2-15 14:55 | 只看该作者

有时是正确的,用15个字节的话我的后两个字节是校验,数据会

我是DMA中断程序中把缓冲区的内容读给另外开辟的一段数据空间,DMA中断程序
void DMA1_Channel6_IRQHandler(void)
{   u8 i;
   if(DMA_GetITStatus(DMA1_IT_TC6))
   { DMA_ClearITPendingBit(DMA1_IT_GL6);
     UartHaveData2=1;
     USART_ClearITPendingBit(USART2,USART_IT_RXNE);
     for(i=0;i<=12;i++)
     RxBuffer2=Receive_data;
   // ceshi++;
   }  
}

使用特权

评论回复
地板
nylyt|  楼主 | 2009-2-15 14:59 | 只看该作者

DMA中断程序

void DMA1_Channel6_IRQHandler(void)
{   u8 i;
   if(DMA_GetITStatus(DMA1_IT_TC6))
   { DMA_ClearITPendingBit(DMA1_IT_GL6);
     UartHaveData2=1;
     USART_ClearITPendingBit(USART2,USART_IT_RXNE);
     for(i=0;i<=14;i++)
     RxBuffer2=Receive_data;
   // ceshi++;
   }  
}
DMA配置程序
void DMA_Configuration(void)
{
  DMA_InitTypeDef DMA_InitStructure;
  /* DMA Channel6 (triggered by USART2 Rx event) Config */
  DMA_DeInit(DMA1_Channel6); 
  DMA_InitStructure.DMA_PeripheralBaseAddr = USART2_DR_Base;
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)Receive_data;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize =15;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
 // DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA1_Channel6, &DMA_InitStructure);

 DMA_ITConfig(DMA1_Channel6,DMA_IT_TC,ENABLE);
}

使用特权

评论回复
5
nylyt|  楼主 | 2009-2-15 15:04 | 只看该作者

请斑竹分析下可能的原因

下位机上传数据给主机是在主机DMA中断程序中接收完数据后才允许下面发数据

使用特权

评论回复
6
香水城| | 2009-2-15 20:51 | 只看该作者

请具体说明你的操作步骤,按照1、2、3

各个步骤之间的时间关系如何?

使用特权

评论回复
7
nylyt|  楼主 | 2009-2-17 18:01 | 只看该作者

步骤

1:用定时器定时10ms发数据桢给下为机,通讯速率57600通过串口2。发送使用查询模式发送。
2:发送完毕后,主机转为接收数据,接收完毕后置接收数据成功标志1,然后进行数据处理。如果数据有错误丢弃数据。
3:在数据发送模块中只要有数据成功接收标志,然后定时时间到就发送数据给下位机。整个网络是485,大概有14个下位机模块。
4:主机接收用DMA循环模式

使用特权

评论回复
8
香水城| | 2009-2-17 18:48 | 只看该作者

确认一下,你的所谓主机是否就是STM32?看起来是这样

根据你的描述,似乎不应该使用DMA循环模式。请看STM32技术参考手册中9.3.3节有关循环模式的说明:“当启动了循环模式,数据传输的数目变为0时,将会自动地被恢复成配置通道时设置的初值,DMA操作将会继续进行。”

现在的问题是,当接收数据传输的数目变为0时,而下位机又没有上传数据时,你是如果处理接收通道的?——关闭?保持开启?遇到干扰信号怎么办?


另外,如果使用DMA循环模式,当数据传输出现错误时,比如丢失一个字节,你的所有下位机上传数据将会错位(即收到数据包的最后一个字节始终是下个数据包的第一个字节)。

使用特权

评论回复
9
nylyt|  楼主 | 2009-2-17 21:19 | 只看该作者

主机是STM32

主机是STM32103vbt6,从机是101的,我描述的是功能的一部分,斑竹所言极是。我是第一次使用STM32,很多是在调试过程。从项目目前感觉STM32功能的确不错。还有我问的定时中断可以放多少全局变量问题,可能担心溢出。我又会到原来使用FREESCALE 和8位单片机的思维吧。
现在系统主从通讯可以自由通讯,主机还要使用MODBUS协议和上位机通讯利用串口1,通讯很好断线可以自动恢复,但主从模式所用的串口2原来利用中断USART2接收程序也无问题,只是现在系统功能块所添加的越来越多,怕频繁中断耽误系统进程,所以我就用 DMA中断接收,从实验室多日测试看用循环模式无问题,当接收数据传输的数目变为0时,而下位机又没有上传数据时,你是如果处理接收通道的?我处理是这样当DMA中断 后数据传输给另外数据缓存,然后就继续开启DMA中断,当然遇到干扰信号,舍弃校验码不对的数据。
下位机上传数据长度是固定的。
如果使用DMA循环模式,当数据传输出现错误时,比如丢失一个字节,你的所有下位机上传数据将会错位(即收到数据包的最后一个字节始终是下个数据包的第一个字节)。所言极是,这个问题真没仔细考虑,原来是利用类MODBUS判断数据祯的结束。但定时器我用的差不多了,需要模拟许多PWM信号,还有电机信号的转速测试。
斑竹有何更好的方案,难道我要利用一个定时器判断是否数据祯超时?

使用特权

评论回复
10
nylyt|  楼主 | 2009-2-17 21:27 | 只看该作者

从通讯的健壮性和出现故障可以自由恢复,斑竹有无更好提

STM32以后是我设计产品的主打产品,第一次使用实话一个字赞从性价比来说,我原来论坛问的一个问题说是NRST脚电压是2.0v,而VDD是正常,故障原因在万利帮助下已经找到,是外围的一个74LV07损坏,导致5V的电压可能加到STM32的IO导致内部电压紊乱了吧,奇怪的是STM32的模拟和数字电压都是正常只是复位电压不正常。

使用特权

评论回复
11
nylyt|  楼主 | 2009-2-17 21:37 | 只看该作者

我所做的项目是个出口机器产品使用

一个机器上面使用STM32大概17片,原来设计选型芯片的时候舍弃自己一惯使用的16位单片机,听了广州研讨会才了解这个芯片,调试进入尾声。现在是修补阶段,所以有些调试的时候问题也困惑着我,多些斑竹的回答,斑竹是我感觉21IC上支持很好的,不过感觉贵公司的各地办事处还有代理商支持力度要加大,很多生意都是从小到大的,目的只有双赢

使用特权

评论回复
12
nylyt|  楼主 | 2009-2-18 16:34 | 只看该作者

斑竹回应下,谢谢了

使用特权

评论回复
13
nylyt|  楼主 | 2009-2-18 23:32 | 只看该作者

一个字节就中断一次影响了MCU的效率

如果一个字节就中断一次,那用DMA的优势就发挥不了,和别的单片机串口中断就无区别。

使用特权

评论回复
14
nylyt|  楼主 | 2009-2-19 08:03 | 只看该作者

DMA中断中不会有串口接受数据

DMA中断中接收完一祯数据然后置发送数据允许,只有定时时间到和发送允许数据允许后,向下位机发送数据然后主机才DMA接收数据

使用特权

评论回复
15
香水城| | 2009-2-19 08:58 | 只看该作者

“向下位机发送数据然后主机才DMA接收数据”,这是如何控

也就是说你是如何控制让主机在向下位机发送数据时不执行DMA接收数据

使用特权

评论回复
16
nylyt|  楼主 | 2009-2-20 08:59 | 只看该作者

当下位机在接收完主机的数据祯后才向上发数据

下位机判断数据正确后才向上发数据

使用特权

评论回复
17
香水城| | 2009-2-20 10:08 | 只看该作者

我问的是主机如何控制

使用特权

评论回复
18
nylyt|  楼主 | 2009-2-20 21:36 | 只看该作者

主机向下发送数据的时候DMA是允许接收数据的

发送数据给从机的时候,主机允许接收数据。只是不会出现主机发送数据的同时,从机又向上传数据这样的逻辑

使用特权

评论回复
19
感知新生| | 2015-12-17 21:13 | 只看该作者
香水城 发表于 2009-2-15 08:39
看看错误是否有规律

我也遇到这个问题了  我的是通过DMA传输到串口输出,一组数据是6个字节,我分别发三组数据(就是三段程序,连续运行,每段程序发送一组数据),总是第二组数据的最后一个字节出错,如果我在DMA_cmd()处设置断点,分别发送这三组数据,这样数据就不出错。不知道是什么问题,很是困扰。

使用特权

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

本版积分规则

146

主题

296

帖子

1

粉丝