OpenEdv-开源电子网

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

STM32使用串口1配合DMA接收不定长数据,大大减轻CPU载荷。

  [复制链接]

20

主题

468

帖子

3

精华

金牌会员

Rank: 6Rank: 6

积分
1681
金钱
1681
注册时间
2014-2-25
在线时间
229 小时
发表于 2015-12-2 15:14:20 | 显示全部楼层 |阅读模式
本帖最后由 peng1554 于 2023-11-8 16:05 编辑

最近经常看见坛友在论坛上问串口接收的问题,我之前刚好由于项目需要用到PLC的PPI协议,需要不停地利用串口接收数据,一开始的时候采用单字节中断的方式接收判断。但是用来做通信的时候需要不停的产生串口接收中断,会严重影响主程序的运行。后来采用DMA接收的方式,但是一般情况下配置的DMA都是接定长的串口数据,对于未知长度的串口数据接收并不适用。后来在网上发现了一种方法可以利用串口的</span><span style="font-size:16px;background-color:#FFE500;">空闲中断+DMA接收的方法完美解决此类问题,特别适用于不需要每个就收字节都判断的串口数据接收,下面说一下事实现思路和程序。

实现思路:采用STM32F103的串口1,并配置成空闲中断模式且使能DMA接收,并同时设置接收缓冲区和初始化DMA。那么初始化完成之后,当外部给单片机发送数据的时候,假设这帧数据长度是100个字节,那么在单片机接收到一个字节的时候并不会产生串口中断,而是DMA在后台把数据默默地搬运到你指定的缓冲区里面。当整帧数据发送完毕之后串口才会产生一次中断,此时可以利用</span><span style="font-size:16px;">DMA_GetCurrDataCounter();函数计算出本次的数据接受长度,从而进行数据处理。<br>

应用对象:适用于各种串口相关的通信协议,如:MODBUS,PPI ;还有类似于GPS数据接收解析,串口WIFI的数据接收等,都是很好的应用对象。<br>


关键代码分析:
usart.H
#ifndef __USART_H
#define __USART_H
#include "stdio.h"
#include "sys.h"

#define DMA_Rec_Len 200      //定义一个长度为200个字节的数据缓冲区。(建议定义的长度比你可能接收到的最长单帧数据长度长!)</span><br>

void uart_init(u32 bound);
void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx);



usart.C
//初始化IO 串口1
//bound:波特率
void uart_init(u32 bound)
        {
    //GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
          USART_InitTypeDef USART_InitStructure;
          NVIC_InitTypeDef NVIC_InitStructure;
          DMA_InitTypeDef DMA_InitStructure;
        
          RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);        //使能USART1,GPIOA时钟
                RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);        //使能DMA传输
                RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//使能USART2时钟
               
           USART_DeInit(USART1);  //复位串口1
         //USART1_TX   PA.9
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA9

    //USART1_RX          PA.10
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化PA10

   //Usart1 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                //子优先级3
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
          NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器

   //USART 初始化设置
                USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
                USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
                USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
                USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
                USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
                USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;        //收发模式

    USART_Init(USART1, &USART_InitStructure); //初始化串口
    USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);//开启空闲中断
                USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);   //使能串口1 DMA接收
    USART_Cmd(USART1, ENABLE);                    //使能串口

    //相应的DMA配置
                DMA_DeInit(DMA1_Channel5);   //将DMA的通道5寄存器重设为缺省值  串口1对应的是DMA通道5
                DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR;  //DMA外设ADC基地址
                DMA_InitStructure.DMA_MemoryBaseAddr = (u32)DMA_Rece_Buf;  //DMA内存基地址
                DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  //数据传输方向,从外设读取发送到内存
                DMA_InitStructure.DMA_BufferSize = DMA_Rec_Len;  //DMA通道的DMA缓存的大小
                DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变
                DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增
                DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //数据宽度为8位
                DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位
                DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  //工作在正常缓存模式
                DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级
                DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输
                DMA_Init(DMA1_Channel5, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器

                DMA_Cmd(DMA1_Channel5, ENABLE);  //正式驱动DMA传输
               
               
        DMA_DeInit(DMA1_Channel4);   //将DMA1的通道4寄存器重设为缺省值

        DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR;  //DMA外设基地址
        DMA_InitStructure.DMA_MemoryBaseAddr = (u32)DMA_Rece_Buf;  //DMA内存基地址
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  //数据传输方向,从内存读取发送到外设
        DMA_InitStructure.DMA_BufferSize = DMA_TX_Len;  //DMA通道的DMA缓存的大小
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //数据宽度为8位
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位
        DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  //工作在正常模式
        DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输
        DMA_Init(DMA1_Channel4, &DMA_InitStructure);               

}

//重新恢复DMA指针
void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx)
{
        DMA_Cmd(DMA_CHx, DISABLE );  //关闭USART1 TX DMA1 所指示的通道      
         DMA_SetCurrDataCounter(DMA_CHx,DMA_Rec_Len);//DMA通道的DMA缓存的大小
         DMA_Cmd(DMA_CHx, ENABLE);  //使能USART1 TX DMA1 所指示的通道
}        


//USART1开启一次DMA传输
void USART1_DMA_Send(u16 Trans_Len)
{
        USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);  //使能串口1 DMA
        DMA_Cmd(DMA1_Channel4, DISABLE );  //关闭USART1 TX DMA1 所指示的通道      
         DMA_SetCurrDataCounter(DMA1_Channel4,Trans_Len);//DMA通道的DMA缓存的大小
         DMA_Cmd(DMA1_Channel4, ENABLE);  //使能USART1 TX DMA1 所指示的通道
}

//串口中断函数
void USART1_IRQHandler(void)                        //串口1中断服务程序
        {
#ifdef OS_TICKS_PER_SEC                 //如果时钟节拍数定义了,说明要使用ucosII了.
        OSIntEnter();   
#endif
               
        if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
                {
                  USART_ReceiveData(USART1);//读取数据 注意:这句必须要,否则不能够清除中断标志位。我也不知道为啥!
                  Usart1_Rec_Cnt = DMA_Rec_Len-DMA_GetCurrDataCounter(DMA1_Channel5);        //算出接本帧数据长度
                  
                        //***********帧数据处理函数************//
                        printf ("The lenght:%d\r\n",Usart1_Rec_Cnt);
                        printf ("The data:\r\n");
//                        Usart1_Send(DMA_Rece_Buf,Usart1_Rec_Cnt);
                        USART1_DMA_Send(Usart1_Rec_Cnt);
                        printf ("\r\nOver! \r\n");
                        //*************************************//
                        USART_ClearITPendingBit(USART1, USART_IT_IDLE);         //清除中断标志
                        MYDMA_Enable(DMA1_Channel5);                   //恢复DMA指针,等待下一次的接收
     }
               
#ifdef OS_TICKS_PER_SEC                 //如果时钟节拍数定义了,说明要使用ucosII了.
        OSIntExit();                                                                                          
#endif
}


完整工程工程在附件里面。

串口通信 DMA接收不定长数据 DMA发送.rar

275.12 KB, 下载次数: 66

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

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
5
金钱
5
注册时间
2021-10-18
在线时间
0 小时
发表于 2021-10-18 23:43:09 | 显示全部楼层
源码在这里

串口通信 DMA接收不定长数据 DMA发送.rar

275.12 KB, 下载次数: 57

回复 支持 1 反对 0

使用道具 举报

22

主题

203

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
378
金钱
378
注册时间
2017-11-29
在线时间
135 小时
发表于 2018-11-19 22:57:04 来自手机 | 显示全部楼层
本帖最后由 wen619 于 2018-11-19 22:58 编辑

有一个问题 :串口芯片 比如8266返回的一帧数据 比如一共是600字节,前12字节引发一次空闲中断,剩下的588字节发完又引发一次空闲中断。如果依靠空闲中断接收数据 就有问题了,一次接收不完啊。这可咋办
回复 支持 3 反对 0

使用道具 举报

160

主题

967

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2097
金钱
2097
注册时间
2014-3-7
在线时间
491 小时
发表于 2018-3-27 11:58:15 | 显示全部楼层
其实可以用一个定时器来判断数据是否接收完了,毕竟空闲中断判断的时间太短只有一个字节长度,
回复 支持 1 反对 0

使用道具 举报

2

主题

50

帖子

0

精华

初级会员

Rank: 2

积分
120
金钱
120
注册时间
2012-5-7
在线时间
8 小时
发表于 2016-2-3 15:20:42 | 显示全部楼层
这个真心有用。谢谢啦。
耐心做事,好好做人。O(∩_∩)O!
回复 支持 0 反对 1

使用道具 举报

13

主题

123

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
242
金钱
242
注册时间
2013-1-6
在线时间
20 小时
发表于 2015-12-2 15:18:38 | 显示全部楼层
nice!学习了
回复 支持 反对

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2015-12-2 15:30:37 | 显示全部楼层
赞一个!有没有试过超出缓冲区是什么效果
机器生汇编,汇编生B,B生C,C生万物.... 经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂
https://github.com/ianhom
回复 支持 反对

使用道具 举报

20

主题

468

帖子

3

精华

金牌会员

Rank: 6Rank: 6

积分
1681
金钱
1681
注册时间
2014-2-25
在线时间
229 小时
 楼主| 发表于 2015-12-2 15:45:13 | 显示全部楼层
回复【3楼】ianhom:
---------------------------------
试过,循环覆盖了。要是接收的数据实在是很长,可以也把DMA的接收完成中断打开,先把缓冲区的数据读出来处理,或者更换缓冲区。
回复 支持 反对

使用道具 举报

13

主题

296

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2066
金钱
2066
注册时间
2012-5-26
在线时间
291 小时
发表于 2015-12-2 16:25:32 | 显示全部楼层
谢谢分享!!
活着才是王道!健康是一切的前提!
回复 支持 反对

使用道具 举报

17

主题

342

帖子

0

精华

高级会员

Rank: 4

积分
544
金钱
544
注册时间
2014-4-24
在线时间
20 小时
发表于 2015-12-2 16:31:10 | 显示全部楼层
很不错的样子~
回复 支持 反对

使用道具 举报

19

主题

96

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
253
金钱
253
注册时间
2015-4-29
在线时间
38 小时
发表于 2015-12-3 08:43:16 | 显示全部楼层
nice,值得学习
回复 支持 反对

使用道具 举报

7

主题

185

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2729
金钱
2729
注册时间
2015-12-27
在线时间
469 小时
发表于 2016-1-18 09:32:43 | 显示全部楼层
高手,我都没想过用空闲中断
回复 支持 反对

使用道具 举报

1

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
100
金钱
100
注册时间
2015-6-12
在线时间
11 小时
发表于 2016-1-18 09:59:56 | 显示全部楼层
学习了...
回复 支持 反对

使用道具 举报

15

主题

786

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3223
金钱
3223
注册时间
2015-7-26
在线时间
811 小时
发表于 2016-1-21 08:41:35 | 显示全部楼层
这么好的东西居然现在才发现............顶
我的博客:http://blog.csdn.net/itdo_just
回复 支持 反对

使用道具 举报

15

主题

786

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3223
金钱
3223
注册时间
2015-7-26
在线时间
811 小时
发表于 2016-1-21 08:49:44 | 显示全部楼层
空闲中断估计很少人用过,科普一下吧(网上资料显示):
总线空闲中断是在检测到在接收数据后,数据总线上一个字节的时间内,没有再接到数据后发生。也就是RXNE位被置位之后,才开始检测,只被置位一次,除非再次检测到RXNE位被置位,然后才开始检测下一次的总线空闲。
我的博客:http://blog.csdn.net/itdo_just
回复 支持 反对

使用道具 举报

36

主题

195

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
313
金钱
313
注册时间
2014-10-27
在线时间
34 小时
发表于 2016-1-21 09:30:55 | 显示全部楼层
好东西,赞!
回复 支持 反对

使用道具 举报

20

主题

468

帖子

3

精华

金牌会员

Rank: 6Rank: 6

积分
1681
金钱
1681
注册时间
2014-2-25
在线时间
229 小时
 楼主| 发表于 2016-1-21 10:42:10 | 显示全部楼层
229382777@qq.co 发表于 2016-1-21 08:49
空闲中断估计很少人用过,科普一下吧(网上资料显示):
总线空闲中断是在检测到在接收数据后,数据总线上一 ...

谢谢普及。
回复 支持 反对

使用道具 举报

11

主题

40

帖子

0

精华

初级会员

Rank: 2

积分
138
金钱
138
注册时间
2016-1-21
在线时间
35 小时
发表于 2016-1-22 18:04:02 | 显示全部楼层
好东西!
回复 支持 反对

使用道具 举报

3

主题

154

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
434
金钱
434
注册时间
2013-3-18
在线时间
82 小时
发表于 2016-1-22 23:30:52 | 显示全部楼层
怎么判断包结束?
回复 支持 反对

使用道具 举报

5

主题

30

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
202
金钱
202
注册时间
2015-3-18
在线时间
46 小时
发表于 2016-1-23 11:15:58 | 显示全部楼层
空闲模式认为一个字符的时间为空闲中断modbus协议认为3.5倍的字符时间为接受完成。请问空闲中断的时间是不是和配置的?
回复 支持 反对

使用道具 举报

5

主题

30

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
202
金钱
202
注册时间
2015-3-18
在线时间
46 小时
发表于 2016-1-23 11:16:56 | 显示全部楼层
如果把发送也改成DMA模式那就最好了。
回复 支持 反对

使用道具 举报

20

主题

468

帖子

3

精华

金牌会员

Rank: 6Rank: 6

积分
1681
金钱
1681
注册时间
2014-2-25
在线时间
229 小时
 楼主| 发表于 2016-2-3 11:46:34 | 显示全部楼层
xiaoergao 发表于 2016-1-23 11:16
如果把发送也改成DMA模式那就最好了。

这个有的,后来没有吧代码上传上来,配置方式一样的
回复 支持 反对

使用道具 举报

29

主题

311

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1530
金钱
1530
注册时间
2012-9-4
在线时间
262 小时
发表于 2016-2-3 13:12:40 | 显示全部楼层
收藏了,很有用,目前项目中正好需要,谢谢啦。。。。。
回复 支持 反对

使用道具 举报

3

主题

197

帖子

0

精华

高级会员

Rank: 4

积分
538
金钱
538
注册时间
2012-7-19
在线时间
63 小时
发表于 2016-2-3 22:47:53 | 显示全部楼层
发生 接收全都是dma  串口空闲有个问题就是只有一个字符的时间  这样的话发送如果不进行延时就可能导致前后两帧无法定界
回复 支持 反对

使用道具 举报

17

主题

465

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2154
金钱
2154
注册时间
2013-1-11
在线时间
509 小时
发表于 2016-2-4 11:48:50 | 显示全部楼层
GOOD,好样的
回复 支持 反对

使用道具 举报

49

主题

341

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
5259
金钱
5259
注册时间
2012-8-25
在线时间
1025 小时
发表于 2016-2-16 14:43:43 | 显示全部楼层
mark,有用
回复 支持 反对

使用道具 举报

3

主题

92

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
275
金钱
275
注册时间
2012-6-19
在线时间
37 小时
发表于 2016-2-18 17:01:08 | 显示全部楼层
学习了,感谢楼主。
回复 支持 反对

使用道具 举报

14

主题

76

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1422
金钱
1422
注册时间
2015-12-22
在线时间
325 小时
发表于 2016-2-18 17:34:29 | 显示全部楼层
不错,很好的总结
回复 支持 反对

使用道具 举报

7

主题

185

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2729
金钱
2729
注册时间
2015-12-27
在线时间
469 小时
发表于 2016-2-22 18:41:57 | 显示全部楼层
我怎么进不了空闲中断,必须是DMA方式才可以用空闲中断的吗?
回复 支持 反对

使用道具 举报

20

主题

468

帖子

3

精华

金牌会员

Rank: 6Rank: 6

积分
1681
金钱
1681
注册时间
2014-2-25
在线时间
229 小时
 楼主| 发表于 2016-2-22 20:01:03 | 显示全部楼层
钩月黄昏 发表于 2016-2-22 18:41
我怎么进不了空闲中断,必须是DMA方式才可以用空闲中断的吗?

不是的,跟接收中断没什么区别的
回复 支持 反对

使用道具 举报

7

主题

185

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2729
金钱
2729
注册时间
2015-12-27
在线时间
469 小时
发表于 2016-2-22 20:19:58 | 显示全部楼层
我在配置串口时使能空闲中断和接收中断,然后进不了空闲中断
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2016-2-22 20:36:12 | 显示全部楼层
不错,cool
回复 支持 反对

使用道具 举报

7

主题

185

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2729
金钱
2729
注册时间
2015-12-27
在线时间
469 小时
发表于 2016-2-22 20:54:11 | 显示全部楼层
用了接收中断貌似用不了空闲中断了
回复 支持 反对

使用道具 举报

6

主题

56

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
293
金钱
293
注册时间
2016-1-7
在线时间
54 小时
发表于 2016-2-22 22:26:17 | 显示全部楼层
支持,最近也普及了串口不等长的知识,COOL
回复 支持 反对

使用道具 举报

1

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
183
金钱
183
注册时间
2013-6-15
在线时间
32 小时
发表于 2016-2-23 08:51:27 | 显示全部楼层
mark,顶
回复 支持 反对

使用道具 举报

20

主题

468

帖子

3

精华

金牌会员

Rank: 6Rank: 6

积分
1681
金钱
1681
注册时间
2014-2-25
在线时间
229 小时
 楼主| 发表于 2016-2-23 18:41:55 | 显示全部楼层

哎呀,原子哥给cool了啊,赞。
回复 支持 反对

使用道具 举报

20

主题

468

帖子

3

精华

金牌会员

Rank: 6Rank: 6

积分
1681
金钱
1681
注册时间
2014-2-25
在线时间
229 小时
 楼主| 发表于 2016-2-23 18:43:44 | 显示全部楼层
钩月黄昏 发表于 2016-2-22 20:19
我在配置串口时使能空闲中断和接收中断,然后进不了空闲中断

你就仅仅配置成空闲中断试试能不能进入中断。最后加上DMA
回复 支持 反对

使用道具 举报

7

主题

185

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2729
金钱
2729
注册时间
2015-12-27
在线时间
469 小时
发表于 2016-2-24 13:34:12 | 显示全部楼层
试验了两个晚上的结果:1,开启了串口接收完成中断则无法进入空闲中断,2,在DMA中设立DMA接收完成中断,并且在中断中关闭DMA接收通道,不然数据帧长度超过DMA接收缓冲区设定长度会发现虽然进入了中断但是缓冲区的数据还是在写着。3.在空闲中断中重置DMA指针。这样最可靠,不然数据溢出后会影响通信
回复 支持 反对

使用道具 举报

20

主题

468

帖子

3

精华

金牌会员

Rank: 6Rank: 6

积分
1681
金钱
1681
注册时间
2014-2-25
在线时间
229 小时
 楼主| 发表于 2016-2-24 13:38:13 | 显示全部楼层
钩月黄昏 发表于 2016-2-24 13:34
试验了两个晚上的结果:1,开启了串口接收完成中断则无法进入空闲中断,2,在DMA中设立DMA接收完成中断,并 ...

嗯嗯,调试出来了就好
回复 支持 反对

使用道具 举报

11

主题

81

帖子

0

精华

高级会员

Rank: 4

积分
651
金钱
651
注册时间
2012-8-1
在线时间
68 小时
发表于 2016-2-24 16:02:47 | 显示全部楼层
好帖!谢谢分享!
回复 支持 反对

使用道具 举报

0

主题

5

帖子

0

精华

新手入门

积分
19
金钱
19
注册时间
2016-2-22
在线时间
2 小时
发表于 2016-2-25 07:01:57 | 显示全部楼层
顶顶顶顶顶顶顶顶
回复 支持 反对

使用道具 举报

7

主题

67

帖子

0

精华

初级会员

Rank: 2

积分
156
金钱
156
注册时间
2013-8-24
在线时间
16 小时
发表于 2016-2-26 22:31:24 | 显示全部楼层
认真的看完了,还是有所收获,之前这个也弄得挺久的,
回复 支持 反对

使用道具 举报

0

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
109
金钱
109
注册时间
2016-1-17
在线时间
44 小时
发表于 2016-2-27 21:09:28 来自手机 | 显示全部楼层
这个是stm32f107?
回复 支持 反对

使用道具 举报

20

主题

468

帖子

3

精华

金牌会员

Rank: 6Rank: 6

积分
1681
金钱
1681
注册时间
2014-2-25
在线时间
229 小时
 楼主| 发表于 2016-2-28 08:51:52 | 显示全部楼层

应该是103
回复 支持 反对

使用道具 举报

tranits 该用户已被删除
发表于 2016-2-29 08:35:54 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

1

主题

78

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
211
金钱
211
注册时间
2015-12-10
在线时间
49 小时
发表于 2016-3-24 02:06:26 | 显示全部楼层
好文,严重学习。

逆水行舟不进则退
回复 支持 反对

使用道具 举报

259

主题

806

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1887
金钱
1887
注册时间
2012-10-28
在线时间
353 小时
发表于 2016-3-26 19:10:25 | 显示全部楼层
你好,请问 这个有没有 使用 最新的库,cube / hal 的库制作的 ??
回复 支持 反对

使用道具 举报

20

主题

297

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1830
金钱
1830
注册时间
2013-7-29
在线时间
276 小时
发表于 2016-3-26 20:54:40 | 显示全部楼层
好样的!后面试下。
回复 支持 反对

使用道具 举报

33

主题

984

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
7952
金钱
7952
注册时间
2014-8-13
在线时间
1590 小时
发表于 2016-3-26 21:02:28 | 显示全部楼层
很好,这样就比较容易实现非阻塞传输模式了,真好
回复 支持 反对

使用道具 举报

0

主题

6

帖子

0

精华

新手上路

积分
21
金钱
21
注册时间
2016-4-27
在线时间
2 小时
发表于 2016-4-27 17:55:30 | 显示全部楼层
能不能不用IDIE+DMA方式接收数据,而用DMA中断接收数据。
回复 支持 反对

使用道具 举报

2

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
170
金钱
170
注册时间
2016-3-22
在线时间
39 小时
发表于 2016-6-8 17:22:41 | 显示全部楼层
coolcoolcool
回复 支持 反对

使用道具 举报

3

主题

10

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
364
金钱
364
注册时间
2015-1-27
在线时间
42 小时
发表于 2016-6-8 20:58:21 | 显示全部楼层
非常好的学习资料!享受中。。多谢楼主的无私奉献
回复 支持 反对

使用道具 举报

5

主题

31

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
271
金钱
271
注册时间
2016-3-23
在线时间
49 小时
发表于 2016-6-16 12:11:38 | 显示全部楼层
给楼主,顶一个,多谢了。
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-24 12:02

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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