OpenEdv-开源电子网

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

L011芯片:串口Idle中断+DMA接收数据分帧、如何把每帧数据放在缓冲区前头?

[复制链接]

84

主题

558

帖子

0

精华

高级会员

Rank: 4

积分
801
金钱
801
注册时间
2014-9-30
在线时间
136 小时
发表于 2021-5-9 20:54:33 | 显示全部楼层 |阅读模式
11金钱
想用 CubeMX + HAL 库 节省时间【打算囫囵吞枣】
可是:这个“枣子”——吞不下 啊——STM32L011 芯片:
串口 Idle中断+DMA接收数据分帧、如何修改程序???
——才能把【每帧数据都放在缓冲区前头每帧覆盖】??


蓝牙芯片传来的数据:已经是分帧的,我这里每帧数据
8字节,偶尔会出现:16字节的一帧数据。缓冲区长度
20字节,我需要每帧数据都放在缓冲区前头每帧覆盖


考虑到:单片机上电的时候不一定恰好是帧空白的时候,
8字节的帧有可能从第6字节开始接收,这样收到2字节
就会产生 Idle 中断,收到的数据长度就是2,缓冲区应该
只有最前面的两个字节被改写。
数据分帧.png
现在的问题是:如何在 Idle 中断里边(首先停止 DMA 已办)
然后如何去修改 DMA 的数据指针?以便 下一帧数据 覆盖
缓冲区的最前面的存储单元 。(附件 完整CubeMX工程)

BlueMas.rar (3.63 MB, 下载次数: 4)

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

使用道具 举报

84

主题

558

帖子

0

精华

高级会员

Rank: 4

积分
801
金钱
801
注册时间
2014-9-30
在线时间
136 小时
 楼主| 发表于 2021-5-9 20:57:19 | 显示全部楼层
按理说:rx_buffer 的 17,18,19 三个 存储单元

应该 永远都是 初始数值,不会被写入 啊 !?
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2021-5-9 22:46:19 | 显示全部楼层
你不重新初始化一次就完了么?
重启DMA。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

6

主题

1097

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3571
金钱
3571
注册时间
2014-12-2
在线时间
365 小时
发表于 2021-5-10 08:20:22 | 显示全部楼层
idle中断里面重新把DMA内存写指针指向buffer第一个字节,并重启DMA即可。

另外,为了防止在处理当前帧数据的时候,DMA又来了新数据, 导致被覆盖,可以考虑使用双缓冲,或者在IDLE中断里直接把这帧数据memcpy拷贝走
坚决不用寄存器,拒绝重复造轮子。
回复

使用道具 举报

84

主题

558

帖子

0

精华

高级会员

Rank: 4

积分
801
金钱
801
注册时间
2014-9-30
在线时间
136 小时
 楼主| 发表于 2021-5-10 09:32:33 | 显示全部楼层
谢谢 原子大哥 的关注 :   。。。

流程其实很清晰的——(好在 Idle 中断分帧 已经很好了)
——进入 Idle 中断——
1、终止 DMA ,终止 USART 。
2、清除 Idle 冲断标志位 。
3、赶紧从 rx_buffer 复制提取数据 。
4、然后 复位 DMA,重新开启 USART 。
【复位 DMA 之后 新的一帧 数据才能 覆盖 头部存储区】


可是这 四个步骤 具体怎么 写呢 !?





回复

使用道具 举报

0

主题

114

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2583
金钱
2583
注册时间
2019-10-18
在线时间
414 小时
发表于 2021-5-10 09:40:31 | 显示全部楼层
本帖最后由 decai 于 2021-5-10 09:45 编辑

写过stm32l151的.其实很简单.
在idle中断中,关dma,如果要原来的数据,那就先转移走.
不要,那就直接初始化dma.如果闲库慢.直接寄存器操作.
我的原来程序就不要原来的数据,和你一样是覆盖,
那么就是进idle中断,关dma,转移数据,设置dma,开dma
不带数据转移的语句,就4条语句.关一条,设置缓冲地址和缓冲长度2条,开dma等1条
回复

使用道具 举报

84

主题

558

帖子

0

精华

高级会员

Rank: 4

积分
801
金钱
801
注册时间
2014-9-30
在线时间
136 小时
 楼主| 发表于 2021-5-10 16:25:14 | 显示全部楼层
xkwy 发表于 2021-5-10 08:20
idle中断里面重新把DMA内存写指针指向buffer第一个字节,并重启DMA即可。

另外,为了防止在处理当前帧数 ...

仍然谢谢 关注 。。我的问题是 :
如何写 正确的 HAL库 语句 来实现
idle中断里面重新把DMA内存写指针指向buffer第一个字节


具体这个 语句怎么写 。网络上 有两种 写法呢 。囫囵吞枣。


回复

使用道具 举报

84

主题

558

帖子

0

精华

高级会员

Rank: 4

积分
801
金钱
801
注册时间
2014-9-30
在线时间
136 小时
 楼主| 发表于 2021-5-10 16:36:27 | 显示全部楼层
本帖最后由 caosix 于 2021-5-10 17:08 编辑
正点原子 发表于 2021-5-9 22:46
你不重新初始化一次就完了么?
重启DMA。

需外部声明 rx_len 和 recv_end_flag
void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */
    uint8_t TmpCnt;
    for (TmpCnt=0;TmpCnt<8;TmpCnt++) OutBuf[TmpCnt] = rx_buffer[TmpCnt];
    __HAL_UART_CLEAR_IDLEFLAG(&huart2); //清除串口空闲中断标志位
    /*  temp = huart2.Instance->SR;
        temp = huart2.Instance->DR;     */
    rx_len =  20 - (hdma_usart2_rx.Instance->CNDTR);
    __HAL_DMA_DISABLE(&hdma_usart2_rx); //关闭DMA
    DMA1_Channel5->CNDTR = 0xFA;        //复位DMA指针
    __HAL_DMA_ENABLE(&hdma_usart2_rx);  //使能DMA
    for (TmpCnt=0;TmpCnt<20;TmpCnt++) rx_buffer[TmpCnt] = 0x30;  //清除缓冲区
    HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_4);
    recv_end_flag = 1;
  /* USER CODE END USART2_IRQn 0 */
    HAL_UART_IRQHandler(&huart2);
}
囫囵吞枣啊:网上的 例程抄了 几个,
清除Idle中断标注 有两种写法 可是 STM32L011
不接受 红色 /* 注释 */ 的写法,俺也不知所错
——————————————————————————————————————


回复

使用道具 举报

84

主题

558

帖子

0

精华

高级会员

Rank: 4

积分
801
金钱
801
注册时间
2014-9-30
在线时间
136 小时
 楼主| 发表于 2021-5-10 16:51:44 | 显示全部楼层
xkwy 发表于 2021-5-10 08:20
idle中断里面重新把DMA内存写指针指向buffer第一个字节,并重启DMA即可。

另外,为了防止在处理当前帧数 ...

你说 为了防止在处理当前帧数据的时候,DMA又来了新数据, 导致被覆盖


你放心 一包数据只有 8个字节 ,数据包之间 空闲时间很长 。
而且 我就是 需要 —— 覆盖数据只希望 数据头 对准[0] 。


蓝牙模块 传来的数据 : 有时候 “粘包” 为 16字节 一包 ,
——— 我这时候 可以 随意 丢去 前8字节 或者 后8字节


【重点是:要保证:数据头 对准 OutBuf [0] 位置 啊 。】
因为是——实时控制系统:“粘包” 的数据 可以随意 丢弃 。


54645.png

回复

使用道具 举报

84

主题

558

帖子

0

精华

高级会员

Rank: 4

积分
801
金钱
801
注册时间
2014-9-30
在线时间
136 小时
 楼主| 发表于 2021-5-10 17:13:45 | 显示全部楼层
decai 发表于 2021-5-10 09:40
写过stm32l151的.其实很简单.
在idle中断中,关dma,如果要原来的数据,那就先转移走.
不要,那就直接初始化d ...

谢谢 关注 。。其实 主要是 HAL 的 具体 语句 该怎么写 !
————程序 框架 和 流程 其实 没什么 难度————
7878.png
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-24 09:14

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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