OpenEdv-开源电子网

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

环形buf实现边存储AD采集数据边发送数据的程序思路

[复制链接]

85

主题

249

帖子

0

精华

高级会员

Rank: 4

积分
674
金钱
674
注册时间
2020-12-5
在线时间
202 小时
发表于 2021-9-22 17:37:34 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 车嘉炜 于 2021-9-22 17:39 编辑

在论坛学习了一个环形buf的代码但是还是没有完全搞懂,我想用环形buf实现的功能是ADC边采集数据存入buf中然后USB边从buf中读取数据,请问我该如何操作这个环形buf实现这样的功能?我AD采集的值是通过DMA直接存进c.a这个首地址吗(c是  struct Queue c; //定义的结构体,a是结构体中的数组)?DMA这个我试过发现数据没有办法存进去。还是通过ADC中断将刚刚得到的AD值用short EnQueue(struct Queue *p,int key)进队函数存进buf中?我usb发送数据的程序是要在主函数的while中一直判断队列是否为空,不为空就发送buf里的数据吗?
请各种大佬给我一个实现这个功能的思路。


#include <stdio.h>

#define M_S 3                        //定义数组长度,限制元素个数
//定义结构体
struct Queue
{
        int a[M_S];
        int front;                //前指针,指向队首
        int rear;                //后指针,指向对尾
};
//初始化
void InitQueue(struct Queue *p)
{
        p->front=p->rear=0;                        //初始化前后指针都指向0
}
//求长度
int QueueLength(struct Queue *p)
{
        return (p->rear-p->front+M_S)%M_S;        //求元素个数
}
//判断是否为空
short IsEmpty(struct Queue *p)
{
        if(p->front==p->rear)                //若前后指针指向同一个节点,则判断为空
                return 1;
        else
                return 0;
}
//判断是否为满
short IsFull(struct Queue *p)
{
        if(p->front==(p->rear+1)%M_S)                //若前指针等于(后指针+1)%数组大小,则判断为满
                return 1;
        else
                return 0;
}
//进队
short EnQueue(struct Queue *p,int key)
{
        if(IsFull(p))                                //若队列为满,则进队失败
                return 0;
        p->a[p->rear]=key;                        //否则将进队元素赋值给后指针所指的位置,后指针往后移动一格
        p->rear=(p->rear+1)%M_S;
        return 1;
}
//出队
short DeQueue(struct Queue *p,int *value)
{
        if(IsEmpty(p))                                //若队列为空,则出队失败
                return 0;
        *value=p->a[p->front];                        //传入一个指针保留出队元素,然后队首指向下一个元素
        p->front=(p->front+1)%M_S;
        return 1;
}
int main()
{

        struct Queue c;         //定义结构体
        InitQueue(&c);          //调用初始化函数,初始队列
        
        return 0;
}

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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2021-9-23 01:30:34 | 显示全部楼层
回复

使用道具 举报

80

主题

931

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3348
金钱
3348
注册时间
2013-5-28
在线时间
468 小时
发表于 2021-9-23 08:11:06 | 显示全部楼层
只要安排好ADC采集的速率,跟USB发送的时间,确定两个时间不会撞起来那其实是随便怎么弄.
ADC采集,DMA环形存储就好了.
然后就是USB发送.

假设USB速度快过ADC,那只要DMA开个中断,设个标志位然后USB发送就好了.
如果ADC快过USB,那是肯定丢数据的,无论如何都无法协调.除非ADC能停下来等
回复

使用道具 举报

12

主题

3394

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8664
金钱
8664
注册时间
2020-5-11
在线时间
4130 小时
发表于 2021-9-23 09:13:00 | 显示全部楼层
这段代码是软件实现"环形buf",
"ADC中断将刚刚得到的AD值用short EnQueue(struct Queue *p,int key)进队函数存进buf中"
"主函数的while中一直判断队列是否为空,不为空就发送buf里的数据"
说得对,这种方式不需要DMA,不要“通过DMA直接存进c.a这个首地址”。



专治疑难杂症
回复

使用道具 举报

85

主题

249

帖子

0

精华

高级会员

Rank: 4

积分
674
金钱
674
注册时间
2020-12-5
在线时间
202 小时
 楼主| 发表于 2021-9-23 09:25:57 | 显示全部楼层
LcwSwust 发表于 2021-9-23 09:13
这段代码是软件实现"环形buf",
"ADC中断将刚刚得到的AD值用short EnQueue(struct Queue *p,int key)进队 ...

感谢感谢&#128591;
回复

使用道具 举报

85

主题

249

帖子

0

精华

高级会员

Rank: 4

积分
674
金钱
674
注册时间
2020-12-5
在线时间
202 小时
 楼主| 发表于 2021-9-23 13:37:28 | 显示全部楼层
聚东风 发表于 2021-9-23 08:11
只要安排好ADC采集的速率,跟USB发送的时间,确定两个时间不会撞起来那其实是随便怎么弄.
ADC采集,DMA环形存 ...

您好,如何用DMA将AD值存进环形buf中呢?我试过(c是  struct Queue c; //定义的结构体,a是结构体中的数组)将DMA的外设地址设为ADC1_DR_Address,内存地址为(u32)(c.a)结果在DMA中断里发现AD值并没有存进这个内存地址
回复

使用道具 举报

80

主题

931

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3348
金钱
3348
注册时间
2013-5-28
在线时间
468 小时
发表于 2021-9-23 17:07:23 | 显示全部楼层
车嘉炜 发表于 2021-9-23 13:37
您好,如何用DMA将AD值存进环形buf中呢?我试过(c是  struct Queue c; //定义的结构体,a是结构体中的数 ...

你直接把DMA指针指向数组就不结了吗
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-8 02:38

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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