OpenEdv-开源电子网

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

基于STM32串口数据多种接收方式及数据管理:IT/IDLE(空闲中断)+DMA+FIFO

[复制链接]

80

主题

268

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
441
金钱
441
注册时间
2014-8-11
在线时间
84 小时
发表于 2020-1-16 18:53:54 | 显示全部楼层 |阅读模式
本帖最后由 战舰水手 于 2020-5-9 02:47 编辑

     之前在论坛上分享了一篇串口DMA双缓冲数据传输的帖子(http://www.openedv.com/forum.php?mod=viewthread&tid=64008&extra=),近期发现上传的源码附件没法下载了,该帖是我在早期项目需要的情况下基于F1学习状态下做的测试源码,并在之后的项目中不断进行了优化和实测。因为更换过几次电脑所以该贴的源码也找不到了。故打算重新制作一篇分享贴,将我在项目中的一些案例分享给大家。
     因为时间不是太充裕,故该贴会不定时更新,如果该贴中的原理和代码出现低级错误望大家积极指出,我会定时纠正。

源码基于STM32F1/4HAL库函数,部分内容基于正点原子相关示例完成,悉知。

更新日志:
1、2020/1/16
开贴开篇
2、2020/05/09
上传FIFO接口函数
上传基于MiniSTM32开发板的串口+IDLE+DMA+FIFO例程
3、待更新(DMA介入的数据接收方式及软双缓冲)


目录


一、简单的串口数据接收方式:
1、IT+尾字节判断
2、IT+定时器超时判断
3、IDEL(空闲中断)

二、数据队列管理FIFO(接口函数已上传附件)
  1. #define FIFO_SIZE 256 //定义接受串口数据的队列数组大小

  2. typedef enum
  3. {
  4.         FIFO_FREE  = 0     ,      //空闲
  5.         FIFO_OK    = 0     ,      //读取或写入成功
  6.         FIFO_BUSY  = 0x01  ,      //忙
  7.         FIFO_OVER  = 0x02  ,      //溢出错误
  8.         FIFO_NULL  = 0X03  ,      //缓存空,或者无新的数据需要处理
  9. }
  10. FIFO_STA_ENUM;    //FIFO状态枚举

  11. __packed typedef struct
  12. {
  13.         u8                  FIFO_STA;                   //FIFO当前状态   忙  空闲  溢出错误
  14.         u16           FIFO_BUF_SIZE;              //FIFO缓存中有效数据个数
  15.         u16           W_ADDR_NUM;                 //写指针
  16.         u16           R_ADDR_NUM;                 //读指针
  17.         u16           W_CIRCLE_CNT;               //写指针循环次数
  18.         u16           R_CIRCLE_CNT;                      //读指针循环次数
  19. <font color="Red">//以下错误字节数计数我主要是用来测试通讯协议和解析效率</font>
  20.         u16           W_ERR_NUM;                  //写错误字节计数
  21.         u16           R_ERR_NUM;                  //读错误字节计数
  22.         u8            FIFO_BUF[FIFO_SIZE] ;   //FIFO缓存
  23. }
  24. FIFO_typ;     //FIFO结构体


  25. //------------------------ User Function ------------------------------
  26. //队列申请内存
  27. u8 SRAM_DATA_Init(void);
  28. //清空FIFO
  29. void FIFO_CLR_BUF(FIFO_typ * FIFO);
  30. //返回可写入队列的数组长度最大值
  31. u16  FIFO_WRITE_VALID_NUM(FIFO_typ * FIFO);
  32. //返回从队列读出数组的最大长度
  33. u16  FIFO_READ_VALID_NUM(FIFO_typ * FIFO);
  34. //[底层]向队列缓存写入一个字节
  35. void FIFO_WRITE_BYTE_NO(FIFO_typ *FIFO,u8 data);
  36. //[底层]读取队列缓存一个字节
  37. u8 FIFO_READ_BYTE_NO(FIFO_typ *FIFO);
  38. //向队列缓存写入一个数组
  39. //返回 0  成功  其它失败
  40. u8  FIFO_WRITE_BUF(FIFO_typ *FIFO,u8 *buf,u16 len);
  41. //向队列缓存写入一个字节
  42. u8 FIFO_WRITE_BYTE(FIFO_typ *FIFO,u8 data);
复制代码


  1. //FIFO初始赋值
  2. void FIFO_CLR_BUF(FIFO_typ * FIFO)   //清空FIFO
  3. {
  4.     FIFO->FIFO_STA = FIFO_FREE; //状态为空闲
  5.   FIFO->FIFO_BUF_SIZE = FIFO_SIZE; //有效数据清零
  6.     FIFO->W_ADDR_NUM = 0;  //写指针清零
  7.     FIFO->R_CIRCLE_CNT = 0;//读指针循环次数清零
  8.     FIFO->W_CIRCLE_CNT = 0;//写指针循环次数清零
  9.   FIFO->R_ADDR_NUM = 0;  //读指针清零
  10.     FIFO->W_ERR_NUM = 0;
  11.     FIFO->R_ERR_NUM = 0;
  12. }


  13. //返回可写入队列的数组长度最大值
  14. u16  FIFO_WRITE_VALID_NUM(FIFO_typ * FIFO)
  15. {
  16.   if(FIFO->W_CIRCLE_CNT == FIFO->R_CIRCLE_CNT)
  17.         return  FIFO->FIFO_BUF_SIZE+FIFO->R_ADDR_NUM-FIFO->W_ADDR_NUM;
  18.     else
  19.         return FIFO->R_ADDR_NUM-FIFO->W_ADDR_NUM;
  20. }

  21. //返回从队列读出数组的最大长度
  22. u16  FIFO_READ_VALID_NUM(FIFO_typ * FIFO)
  23. {
  24.   if(FIFO->W_CIRCLE_CNT == FIFO->R_CIRCLE_CNT)
  25.         return  FIFO->W_ADDR_NUM-FIFO->R_ADDR_NUM;
  26.     else
  27.         return FIFO->FIFO_BUF_SIZE+FIFO->W_ADDR_NUM-FIFO->R_ADDR_NUM;
  28. }

  29. //[底层]向队列缓存写入一个字节
  30. void FIFO_WRITE_BYTE_NO(FIFO_typ *FIFO,u8 data)
  31. {
  32.     FIFO->FIFO_BUF[FIFO->W_ADDR_NUM] = data ;   //写入数据
  33.      
  34.   FIFO->W_ADDR_NUM++;      //一定要先写完 再地址变更
  35.      
  36.     if(FIFO->W_ADDR_NUM >= FIFO->FIFO_BUF_SIZE)  //如果到了缓存尾
  37.     {
  38.         FIFO->W_ADDR_NUM = 0 ;             //回归到缓存头
  39.           FIFO->W_CIRCLE_CNT++;
  40.     }
  41. }

  42. //[底层]读取队列缓存一个字节
  43. u8 FIFO_READ_BYTE_NO(FIFO_typ *FIFO)
  44. {
  45.     u8 data;
  46.     data = FIFO->FIFO_BUF[FIFO->R_ADDR_NUM] ;   //读取数据

  47.     FIFO->R_ADDR_NUM++;      //一定要先读完 再地址变更
  48.      
  49.     if(FIFO->R_ADDR_NUM >= FIFO->FIFO_BUF_SIZE)  //如果到了缓存尾
  50.     {
  51.             FIFO->R_ADDR_NUM = 0 ;             //回归到缓存头
  52.             FIFO->R_CIRCLE_CNT++;
  53.     }
  54.     return data;
  55. }

  56. //向队列缓存写入一个数组
  57. //返回 0  成功  其它失败
  58. u8  FIFO_WRITE_BUF(FIFO_typ *FIFO,u8 *buf,u16 len)
  59. {
  60.     u16 i=0;
  61.     if((FIFO_WRITE_VALID_NUM(FIFO))<len)   //如果缓存有效数据数量与写入总和  超过最大有效数据
  62.     {
  63.       return  FIFO_OVER;      //返回满
  64.     }

  65.     for(i=0;i<len;i++)
  66.     {
  67.         FIFO_WRITE_BYTE_NO(FIFO,buf[i]);  
  68.     }
  69.     return   FIFO_OK;
  70. }
复制代码
    上述接口函数中队列缓存的大小是由宏定义#define FIFO_SIZE 256决定,但我们在实际应用中可能涉及到多个外设数据通道需要用到该FIFO接口函数,这些通道对应的
队列缓存大小可能会不一致,这种情况下我们将结构体FIFO_typ中的数组做指针链表,即结构体中的变量为队列缓存的头地址,实现如下
  1. 背景:实现串口1队列缓存大小为256、串口2队列缓存大小为1024
  2. __packed typedef struct
  3. {
  4. u8 FIFO_STA; //FIFO当前状态 忙 空闲 溢出错误
  5. u16 FIFO_BUF_SIZE; //FIFO缓存中有效数据个数
  6. u16 W_ADDR_NUM; //写指针
  7. u16 R_ADDR_NUM; //读指针
  8. u32 W_CIRCLE_CNT; //写指针循环次数
  9. u32 R_CIRCLE_CNT; //读指针循环次数
  10. u16 W_ERR_NUM; //写错误字节计数
  11. u16 R_ERR_NUM; //读错误字节计数
  12. //u8 FIFO_BUF[FIFO_SIZE] ; //FIFO缓存
  13. <b><font color="Red">u8 *FIFO_BUF;//这里的变量用来指向队列缓存的头地址</font></b>
  14. }
  15. FIFO_typ; //FIFO结构体
  16. extern FIFO_typ *U1_RX_FIFO;
  17. extern FIFO_typ *U2_RX_FIFO;

  18. #define U1_RX_FIFO_BUF_SIZE 256
  19. #define U2_RX_FIFO_BUF_SIZE 1024

  20. //以下为结构体链表实现方法
  21. U1_RX_FIFO_BUF= (u8*)mymalloc(U1_RX_FIFO_BUF_SIZE) ;//队列缓存申请内存
  22. U2_RX_FIFO_BUF= (u8*)mymalloc(U2_RX_FIFO_BUF_SIZE) ;//队列缓存申请内存

  23. U1_RX_FIFO= (FIFO_typ*)mymalloc(sizeof(FIFO_typ)) ;//结构体申请内存
  24. U2_RX_FIFO= (FIFO_typ*)mymalloc(sizeof(FIFO_typ)) ;//结构体申请内存

  25. U1_RX_FIFO->FIFO_BUF_SIZE=U1_RX_FIFO_BUF_SIZE;
  26. U2_RX_FIFO->FIFO_BUF_SIZE=U2_RX_FIFO_BUF_SIZE;

  27. U1_RX_FIFO->FIFO_BUF=U1_RX_FIFO_BUF;//将申请到的队列缓存地址赋值给结构体中存储队列缓存地址的变量
  28. U2_RX_FIFO->FIFO_BUF=U2_RX_FIFO_BUF;//将申请到的队列缓存地址赋值给结构体中存储队列缓存地址的变量
复制代码

   以上的实现的接口函数中并没有涉及从队列中读取一个数组,这是由于数据读取后需要根据相关的通讯协议做解析,故此处只讲述接口函数的应用方法,如下:
  1. FIFO_STA_ENUM U1_RxData_Polling(void)
  2. {
  3.           u16 len,i;
  4.    //记录当前读写指针位置
  5.           u16 read_addr_num=U1_RX_FIFO->R_ADDR_NUM;
  6.           u16 read_circle_num=U1_RX_FIFO->R_CIRCLE_CNT;
  7.    u8 *CLC_BUF;//数据
  8.    u6 clc_byte_num;
  9.    //获取当前队列缓存中未处理的数据长度
  10.           len=FIFO_READ_VALID_NUM(U1_RX_FIFO);
  11.    if(len==0)
  12.    {
  13.         return FIFO_NULL;//返回无数据需处理
  14.    }
  15.    else
  16.    {
  17.        CLC_BUF=(u8*)mymalloc(len+1);
  18.        CLC_BUF[len]=0;
  19.        for(i=0;i<len;i++)
  20.        {
  21.             CLC_BUF[i]=FIFO_READ_BYTE_NO(U1_RX_FIFO);//将未处理的数据赋值给*CLC_BUF
  22.        }
  23.        //接下来就是根据具体通讯协议解析数据,如果是串口配置命令的话单次polling队列我都是只解析一个命令就退出
  24.       //此处要注意的是我们逐字节校验是否符合协议的话要把错误的字节数也记录下来形成真实的*CLC_BUF中已处理的数据(clc_byte_num),因为我们是直接将未处理的所有数据全部提取出来的,提取的时候读指针
  25.       //也就被移动到了未处理数据的最后,若单次polling我们解析出一条命令后退出polling那需要在退出前将读指针(U1_RX_FIFO->R_ADDR_NUM)放到我们实际停止的位置
  26.       。。。。。。。。
  27.       //以下实现将读指针放置在解析停止处
  28.       U1_RX_FIFO->R_ADDR_NUM = read_addr_num;
  29.       U1_RX_FIFO->R_CIRCLE_CNT = read_circle_num; //读指针归位               
  30.       for(i=0;i<clc_byte_num;i++)
  31.       {
  32.           FIFO_READ_BYTE_NO(U1_RX_FIFO); //将读指针放置在有效帧尾或写指针处
  33.       }     
  34.    }
  35.   
复制代码







三、DMA介入的数据接收方式

四、DMA双缓冲数据接收
1、软双缓冲
2、硬双缓冲


五、IDLE+DMA+FIFO应用示例
    背景:基于HAL库实现STM32F103RCT6串口1的接收IDLE+DMA+FIFO
    技术路线:
    1:DMA配置
  1. //DMA1的各通道配置
  2. //这里的传输形式是固定的,这点要根据不同的情况来修改
  3. //从存储器->外设模式/8位数据宽度/存储器增量模式
  4. //chx:DMA通道选择,DMA1_Channel1~DMA1_Channel7
  5. //串口1初始化时调用
  6. void U1_RX_DMA_Config(void)
  7. {
  8.           __HAL_RCC_DMA1_CLK_ENABLE();                        //DMA1时钟使能

  9.     __HAL_LINKDMA(&UART1_Handler,hdmarx,UART1RxDMA_Handler);                    //将DMA与USART1联系起来(发送DMA)
  10.    
  11.     //Rx DMA配置
  12.     UART1RxDMA_Handler.Instance=DMA1_Channel5;                          //通道选择
  13.     UART1RxDMA_Handler.Init.Direction=DMA_PERIPH_TO_MEMORY;             //外设到存储器
  14.     UART1RxDMA_Handler.Init.PeriphInc=DMA_PINC_DISABLE;                 //外设非增量模式
  15.     UART1RxDMA_Handler.Init.MemInc=DMA_MINC_ENABLE;                     //存储器增量模式
  16.     UART1RxDMA_Handler.Init.PeriphDataAlignment=DMA_PDATAALIGN_BYTE;    //外设数据长度:8位
  17.     UART1RxDMA_Handler.Init.MemDataAlignment=DMA_MDATAALIGN_BYTE;       //存储器数据长度:8位
  18.     UART1RxDMA_Handler.Init.Mode=DMA_NORMAL;                            //外设普通模式
  19.     UART1RxDMA_Handler.Init.Priority=DMA_PRIORITY_MEDIUM;               //中等优先级
  20.    
  21.     HAL_DMA_DeInit(&UART1RxDMA_Handler);   
  22.     HAL_DMA_Init(&UART1RxDMA_Handler);
  23.         
  24.                 //HAL_NVIC_DisableIRQ(DMA1_Channel5_IRQn);                                //使能USART1_RX_DMA中断通道
  25.                 HAL_NVIC_SetPriority(DMA1_Channel5_IRQn,1,0);                        //抢占优先级1,子优先级0
  26. }

  27. void DMA1_Channel5_IRQHandler(void)
  28. {  
  29. #if SYSTEM_SUPPORT_OS                 //使用OS
  30.         OSIntEnter();   
  31. #endif
  32. //        HAL_UART_DMAStop(&UART1_Handler); //先停止DMA,暂停接收
  33.         if(DMA1->ISR&(1<<17))//传输完成
  34.         {
  35.                 DMA1->IFCR|=(1<<17);
  36.                 USART1RxDMA_callback();        //执行回调函数,读取数据等操作在这里面处理
  37.         }
  38.         if(DMA1->ISR&(1<<18))//传输半完成
  39.         {
  40.                 DMA1->IFCR|=(1<<18);
  41.         }
  42. #if SYSTEM_SUPPORT_OS                 //使用OS
  43.         OSIntExit();   
  44. #endif               
  45. }


  46. void USART1RxDMA_callback(void)
  47. {
  48.         if(USART1_DMA_Status.USART_IS_IDLE!=1)
  49.         {
  50.                 USART1_DMA_Status.DMA_ReceiveOK=1;
  51.                 FIFO_WRITE_BUF(U1_RX_FIFO,USART1_RX_DMA_BUF,USART1_RX_DMA_BUF_SIZE);
  52.         }
  53.         USART1_DMA_Status.USART_IS_IDLE=0;
  54. }
复制代码
   2:串口1空闲中断接收函数
  1. //串口接收空闲中断
  2. void UsartReceive_IDLE(UART_HandleTypeDef *huart)  
  3. {
  4.         //当触发了串口空闲中断
  5.           __IO uint32_t tmpreg;
  6.     if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET))
  7.     {
  8.                         if(huart->Instance == USART1)
  9.                         {
  10.                                 /* 1.清除标志 */
  11.                                 __HAL_UART_CLEAR_IDLEFLAG(huart); //清除空闲标志
  12.                                 tmpreg = huart->Instance->SR;      
  13.                                 tmpreg = huart->Instance->DR;
  14.                                 
  15.                                 /* 2.读取DMA */
  16.                                 HAL_UART_DMAStop(huart); //先停止DMA,暂停接收
  17.                                 /* 3.搬移数据进行其他处理 */
  18.                                 U1_RX_FIFO->FIFO_STA=FIFO_BUSY;        //队列忙                                
  19.                                 FIFO_WRITE_BUF(U1_RX_FIFO,USART1_RX_DMA_BUF,USART1_RX_DMA_BUF_SIZE - (__HAL_DMA_GET_COUNTER(&UART1RxDMA_Handler)));
  20.                                 U1_RX_FIFO->FIFO_STA=FIFO_FREE;  //队列空闲
  21.                                 USART1_DMA_Status.DMA_ReceiveOK=1;
  22.                                 USART1_DMA_Status.USART_IS_IDLE=1;
  23.                                 /* 4.开启新的一次DMA接收 */
  24.                                 HAL_UART_Receive_DMA(huart,(u8*)&USART1_RX_DMA_BUF, USART1_RX_DMA_BUF_SIZE); //重新DMA接收
  25.                                 __HAL_DMA_ENABLE_IT(&UART1RxDMA_Handler, DMA_IT_TC);
  26.                         }
  27.     }
  28.                 UNUSED(tmpreg);
  29. }

  30. //串口1中断服务程序
  31. void USART1_IRQHandler(void)                        
  32. {
  33. #if SYSTEM_SUPPORT_OS                 //使用OS
  34.         OSIntEnter();   
  35. #endif

  36.         UsartReceive_IDLE(&UART1_Handler);//串口空闲中断处理
  37.         HAL_UART_IRQHandler(&UART1_Handler);//HAL库串口处理
  38.         
  39. #if SYSTEM_SUPPORT_OS                 //使用OS
  40.         OSIntExit();                                                                                          
  41. #endif
  42. }
  43.   

  44. void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
  45. {         
  46.         if(huart->ErrorCode&HAL_UART_ERROR_ORE)
  47.         {               
  48.                 __HAL_UART_CLEAR_OREFLAG(huart);
  49.         }
  50. }
复制代码



     
1588962522(1).png
1588962372.png
1588959549(1).png

FIFO.rar

2.03 KB, 下载次数: 65

实现队列读写接口函数(未做结构体链表以满足不同队列长度)

MINISTM32 HAL库 USART+IDLE+DMA+FIFO.rar

6.54 MB, 下载次数: 114

MiniSTM32 HAL库

我是一只菜鸟,但我会大鹏展翅
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

80

主题

268

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
441
金钱
441
注册时间
2014-8-11
在线时间
84 小时
 楼主| 发表于 2020-1-16 19:02:20 | 显示全部楼层
应急催更或交流联系VX:SVS8888888
回复 支持 反对

使用道具 举报

3

主题

1155

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7462
金钱
7462
注册时间
2015-1-15
在线时间
1367 小时
发表于 2020-1-17 08:53:07 | 显示全部楼层
很好奇楼主FIFO串口通信是怎么运用的
一分耕耘一分收获。
回复 支持 反对

使用道具 举报

5

主题

179

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
8195
金钱
8195
注册时间
2016-9-7
在线时间
1113 小时
发表于 2020-1-17 10:39:30 | 显示全部楼层
嗯,期待您的分享了
回复 支持 反对

使用道具 举报

0

主题

6

帖子

0

精华

初级会员

Rank: 2

积分
78
金钱
78
注册时间
2019-5-5
在线时间
22 小时
发表于 2020-1-21 16:35:47 | 显示全部楼层
大扫福娃未付费电视
回复 支持 反对

使用道具 举报

3

主题

1155

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7462
金钱
7462
注册时间
2015-1-15
在线时间
1367 小时
发表于 2020-1-21 18:14:46 来自手机 | 显示全部楼层
广告做的666
回复 支持 反对

使用道具 举报

5

主题

43

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
202
金钱
202
注册时间
2016-1-23
在线时间
31 小时
发表于 2020-3-4 14:36:28 | 显示全部楼层
战舰水手 发表于 2020-1-16 19:02
应急催更或交流联系VX:SVS8888888

催更啊      
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

新手入门

积分
19
金钱
19
注册时间
2019-6-16
在线时间
6 小时
发表于 2020-3-12 21:45:03 | 显示全部楼层
不错, 正好用到
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

新手入门

积分
19
金钱
19
注册时间
2019-6-16
在线时间
6 小时
发表于 2020-3-12 21:45:27 | 显示全部楼层
看看,6666
回复 支持 反对

使用道具 举报

0

主题

10

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2019-7-25
在线时间
11 小时
发表于 2020-3-13 11:12:18 | 显示全部楼层
看看.........
回复 支持 反对

使用道具 举报

0

主题

5

帖子

0

精华

初级会员

Rank: 2

积分
53
金钱
53
注册时间
2019-8-3
在线时间
15 小时
发表于 2020-3-15 17:20:14 | 显示全部楼层
也别更了,在这吊人胃口,串口+dma+idle+消息队列不比你这香
回复 支持 反对

使用道具 举报

0

主题

5

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2019-10-29
在线时间
8 小时
发表于 2020-3-15 19:34:27 | 显示全部楼层
qq1203593632 发表于 2020-3-15 17:20
也别更了,在这吊人胃口,串口+dma+idle+消息队列不比你这香

老哥,求你发个例程可以吗?邮箱751191958@qq.com
回复 支持 反对

使用道具 举报

0

主题

12

帖子

0

精华

新手上路

积分
20
金钱
20
注册时间
2019-6-20
在线时间
2 小时
发表于 2020-3-16 09:28:01 | 显示全部楼层
谢谢分享~~~
回复 支持 反对

使用道具 举报

80

主题

268

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
441
金钱
441
注册时间
2014-8-11
在线时间
84 小时
 楼主| 发表于 2020-5-8 17:39:29 | 显示全部楼层

哈哈哈,都被疫情带小孩耽误了
我是一只菜鸟,但我会大鹏展翅
回复 支持 反对

使用道具 举报

80

主题

268

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
441
金钱
441
注册时间
2014-8-11
在线时间
84 小时
 楼主| 发表于 2020-5-8 17:40:39 | 显示全部楼层
qq1203593632 发表于 2020-3-15 17:20
也别更了,在这吊人胃口,串口+dma+idle+消息队列不比你这香

更还是要更的,哈哈哈,求交流学习
我是一只菜鸟,但我会大鹏展翅
回复 支持 反对

使用道具 举报

80

主题

268

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
441
金钱
441
注册时间
2014-8-11
在线时间
84 小时
 楼主| 发表于 2020-5-8 17:41:06 | 显示全部楼层

已着手
我是一只菜鸟,但我会大鹏展翅
回复 支持 反对

使用道具 举报

80

主题

268

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
441
金钱
441
注册时间
2014-8-11
在线时间
84 小时
 楼主| 发表于 2020-5-8 17:41:54 | 显示全部楼层
yklstudent 发表于 2020-1-17 08:53
很好奇楼主FIFO串口通信是怎么运用的

FIFO我有现成的先上传了,假装没托更
我是一只菜鸟,但我会大鹏展翅
回复 支持 反对

使用道具 举报

80

主题

268

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
441
金钱
441
注册时间
2014-8-11
在线时间
84 小时
 楼主| 发表于 2020-5-9 02:41:41 | 显示全部楼层
daqunZhu 发表于 2020-3-15 19:34
老哥,求你发个例程可以吗?邮箱

已上传例程,未做队列数据读取的接口函数,具体实现有文字描述
我是一只菜鸟,但我会大鹏展翅
回复 支持 反对

使用道具 举报

1

主题

4

帖子

0

精华

新手入门

积分
19
金钱
19
注册时间
2015-12-30
在线时间
5 小时
发表于 2020-5-21 16:25:07 | 显示全部楼层
感谢楼主分享!!!
回复 支持 反对

使用道具 举报

0

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
183
金钱
183
注册时间
2016-1-19
在线时间
54 小时
发表于 2020-6-19 14:05:16 | 显示全部楼层
好东西,谢谢
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-1 07:53

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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