找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2373|回复: 22
打印 上一主题 下一主题
收起左侧

单片机串口收到的数据大于缓冲区怎么办?

  [复制链接]
回帖奖励 30 黑币 回复本帖可获得 2 黑币奖励! 每人限 1 次
跳转到指定楼层
楼主
stc89c516RD+单片机开发板
好像ram就只有1280B, 就是1k多一点

想通过esp8266访问网络文件下载下来(到sd卡里),就一个http响应头就占了几百字节
我的缓冲区是256字节(加上其他数据,很容易就把ram占满了),做成环形那种的
不过服务端随便返回一点数据加上http头,就超过256字节了,就是说buffer接收到的已经不是完整的了,即使不断循环读取,也可能读不完整的是吗?要下载的文件是10M左右的,这可怎么办,是不是要高档一点的stm32才行呀?已经买了好多东西,没银子了
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:94031 发表于 2022-8-18 06:13 | 只看该作者
先用简单单片机学习简单应用,基础好了再学复杂应用。
回复

使用道具 举报

板凳
ID:546770 发表于 2022-8-18 08:37 | 只看该作者
51单片机确实资源不太够,不过可以替换成最新的STC8或者STC32这种资源应该就够用了,程序向下兼容,不需要怎么改,价格也不是很贵。
回复

使用道具 举报

地板
ID:401564 发表于 2022-8-18 08:52 | 只看该作者
STC8A8K64D4
8K的SRAM,还有MDA
STC32
12K的SRAM,32位单片机
回复

使用道具 举报

5#
ID:544776 发表于 2022-8-18 08:59 | 只看该作者
啊,我当初是直接使用esp32玩的,从联网到控制全部能实现;当然我控制所需的IO不多
回复

使用道具 举报

6#
ID:1034262 发表于 2022-8-18 10:01 | 只看该作者
换STC8H8K64U或STC32G12K128吧,速度快10倍以上,内存分别为8K和12K。
回复

使用道具 举报

7#
ID:258566 发表于 2022-8-18 11:32 | 只看该作者
边读边分析,不是合适的信息就舍弃,遇到包头后,把后面的信息记录。
如果采集公共信息(如电脑上可以访问的天气信息网页),也可以这样做。
如chrome浏览器,右键检查。一般网页的元素的class和id是唯一的,即不重名

1.jpg (28.84 KB, 下载次数: 21)

1.jpg
回复

使用道具 举报

8#
ID:883242 发表于 2022-8-18 14:07 | 只看该作者
真缺$$$就学着用esp8266开发啊!

esp8266有两种玩儿法,一种是把他当成串口转WiFi模块,你显然是用的这种,很简单容易上手。

还有一种玩儿法,把8266当成是带WiFi功能的单片机,你会发现8266的性能和资源不知道比你现在用的死忒惨好到哪里去了,缺点是没有仿真器,只能盲测,看看好不好用,反正你现在的单片机也没有仿真器。
回复

使用道具 举报

9#
ID:255908 发表于 2022-8-19 10:18 | 只看该作者
外扩内存模块
回复

使用道具 举报

10#
ID:799053 发表于 2022-8-19 20:05 | 只看该作者
外加RAM和rom 有专门的RAM rom芯片
回复

使用道具 举报

11#
ID:372579 发表于 2022-8-20 21:58 | 只看该作者
其实用stc的12系列也是很不错的。
回复

使用道具 举报

12#
ID:517951 发表于 2024-10-9 08:11 | 只看该作者
现在STC有新的51单片机增加了内存了, 再也不用担心缓存不够了. AI8051U, 2K data +32K xdata, 又多了ic选型哦.
回复

使用道具 举报

13#
ID:982617 发表于 2024-10-9 16:19 | 只看该作者
你遇到的问题很常见,因为单片机内存有限,处理大量数据确实很困难。你的思路是对的,环形缓冲区是常用的方法,但是对于大文件下载,它就力不从心了。  以下几点分析和建议:  内存限制: STC89C516RD+的RAM只有1280B确实比较小,即使使用环形缓冲区也无法容纳完整的 HTTP 响应头和文件数据。 HTTP协议的特性: HTTP 协议使用分块传输,数据会分成多个块,每个块都带有自己的头信息,这会导致数据接收变得复杂。 文件大小问题: 10M 的文件对单片机来说确实比较大,需要精心设计才能完成下载。 解决方法:  升级单片机: 你的想法是对的,使用内存更大的单片机,例如 STM32 就可以有效解决这个问题。STM32 有多种型号,可以根据你的需求选择合适的型号,例如 STM32F103ZET6 有 64 KB 的 Flash 和 20 KB 的 RAM,足以处理你的下载任务。 使用 SD 卡直接存储: 你可以将数据直接写入 SD 卡,避免使用大量 RAM。但是,你需要考虑 SD 卡的读写速度和性能,可能需要进行一些优化才能提高效率。 分段下载: 将文件分成多个小块,每次只下载一小块数据,并将数据存储到 SD 卡中。可以使用 HTTP 的 Range 头来指定下载的范围。 优化代码: 仔细优化代码,减少内存占用,例如使用更小的数据类型,压缩数据等等。 使用外部 RAM: 如果你想继续使用 STC89C516RD+,可以考虑使用外部 RAM 来扩展内存,但是需要额外增加一些硬件电路。 建议方案:  使用 STM32 单片机: 这可能是最简单、最有效的解决方案。 使用 SD 卡直接存储: 如果你想要继续使用 STC89C516RD+,可以使用 SD 卡直接存储数据,但是需要考虑 SD 卡的性能和效率。 其他注意事项:  数据校验: 在下载过程中,需要进行数据校验,以确保数据的完整性。 错误处理: 需要处理下载过程中可能出现的错误,例如网络连接断开、数据传输错误等等。 最后,建议你根据自己的需求选择合适的方案,并根据方案进行代码设计和实现。
回复

使用道具 举报

14#
ID:982617 发表于 2024-10-9 16:20 | 只看该作者
关于 STC89C516RD 和 ESP8266 结合使用 SD 卡下载文件时的 RAM 限制问题,以下是一些详细的信息。

首先,STC89C516RD 是一款单片机,其内存配置有一定的限制。该单片机的内部 RAM 可以达到 256 字节,而外部 RAM 可通过 ALE 脚扩展。这一限制可能会影响你在处理大型文件时的存储能力,尤其是在进行 SD 卡数据读写操作时。

ESP8266 是一种广泛使用的 Wi-Fi 模块,适用于各种物联网项目。其内置的 RAM 相对较小(通常为 80 KB),在处理文件操作时,特别是当需要缓存数据时,会面临挑战。如果你试图通过 ESP8266 读取 SD 卡中的文件并将数据传输给计算机,可能会因为 RAM 不够而导致操作失败或性能不佳。

在设计系统时,可以考虑以下几点来优化内存使用:

1. **分块读取文件**:避免将整个文件一次性加载入内存,而是分块读取并处理,这样可以大幅降低 RAM 的占用。
2. **使用外部存储**:利用 STC89C516RD 与外部 RAM 的组合,缓存一些中间数据,或者使用更大的外部 RAM 来处理数据。
3. **优化代码**:检查并优化代码中可能的内存泄漏和不必要的对象创建,确保 RAM 的使用尽可能高效。
4. **使用简化的数据格式**:如果可能,尽量使用较小的数据格式和简单的数据结构。

需要注意的是,在进行 SD 卡操作时,速度也是一个需要考虑的因素,因为 SD 卡的读取速度往往比 RAM 的速度慢,因此必须确保数据读取的逻辑优化,以避免系统响应迟缓。

如果你在实际的编程中遇到具体问题,可以参考以下链接获取更详细的讨论和解决方案:[ESP8266 SD卡操作失败](mydigit cn/thread-344350-1-1.html)。此外,ESP8266 的示例程序和文档也可以为你提供帮助。
总结而言,合理的内存管理和数据处理策略将是成功实现 STC89C516RD 与 ESP8266 进行 SD 卡文件下载的重要因素。
回复

使用道具 举报

15#
ID:1133246 发表于 2024-10-9 17:12 | 只看该作者
超过的话会数据覆盖吧
回复

使用道具 举报

16#
ID:1135936 发表于 2024-11-8 23:20 | 只看该作者
当单片机串口接收到的数据大于缓冲区大小时,可以采取以下几种策略来处理:  1. **增加缓冲区大小**:    - 如果可能的话,增加缓冲区的大小以适应更多的数据。  2. **使用环形缓冲区**:    - 环形缓冲区(Ring Buffer)是一种常见的数据结构,可以高效地处理数据流。当缓冲区满时,新数据会覆盖最老的数据。  3. **分批发送/接收数据**:    - 将数据分批次发送或接收,确保每次操作都不会超出缓冲区的大小。  4. **流控制**:    - 使用串口通信中的流控制机制(如XON/XOFF或RTS/CTS)来暂停数据的发送,直到缓冲区有足够的空间。  5. **数据处理优化**:    - 优化数据处理流程,尽快处理并清空缓冲区中的数据。  6. **中断处理**:    - 利用中断服务例程(ISR)来处理接收到的数据,确保缓冲区不会溢出。  以下是一些具体的实施步骤:  - **检查缓冲区状态**:   在接收数据前,先检查缓冲区是否有足够空间。如果没有,可以暂停接收或通知发送方暂缓发送。  - **实现流控制**:   如果单片机支持硬件流控制,可以在软件中实现相应的逻辑。当缓冲区接近满时,发送XOFF字符来停止数据流;当缓冲区有空间时,发送XON字符来恢复数据流。  - **增加缓冲区**:   如果内存允许,增加缓冲区的大小。注意,增加缓冲区大小会占用更多的RAM资源。  - **优化数据处理**:   确保数据处理速度足够快,以跟上数据接收的速度。这可能需要优化代码或使用更高效的数据处理算法。  - **使用环形缓冲区**:   环形缓冲区可以连续地存储数据流,当缓冲区满时,新数据会覆盖旧数据。以下是环形缓冲区的基本实现框架:   c #define BUFFER_SIZE 1024  typedef struct {     unsigned char buffer[BUFFER_SIZE];     volatile unsigned int head;     volatile unsigned int tail; } RingBuffer;  void RingBuffer_Init(RingBuffer *rb) {     rb->head = 0;     rb->tail = 0; }  int RingBuffer_Put(RingBuffer *rb, unsigned char data) {     int next = (rb->head + 1) % BUFFER_SIZE;     if (next == rb->tail) {         // Buffer is full         return -1;     }     rb->buffer[rb->head] = data;     rb->head = next;     return 0; }  int RingBuffer_Get(RingBuffer *rb, unsigned char *data) {     if (rb->head == rb->tail) {         // Buffer is empty         return -1;     }     *data = rb->buffer[rb->tail];     rb->tail = (rb->tail + 1) % BUFFER_SIZE;     return 0; }    - **错误处理**:   在接收数据的过程中,如果检测到缓冲区溢出,应该有相应的错误处理机制,比如记录错误、重置缓冲区或通知用户。  在实施上述策略时,要确保代码的稳定性和可靠性,以保障系统的正常运行。
回复

使用道具 举报

17#
ID:712097 发表于 2024-11-9 11:11 | 只看该作者
既然上ESP8266了,就直接用它开发吧。
它RAM有160K,不够可以外接外部的spi flash(如:w25q32)扩展。
回复

使用道具 举报

18#
ID:624769 发表于 2024-11-9 14:34 | 只看该作者
假定传输速率 115200, 那么传输1字节 也需要 87us 你知道 87us 时间,单片机能干多少事么? 正常来讲,这程序只要写的不是太拉垮,256字节的缓存是 绝对不会溢出的。
回复

使用道具 举报

19#
ID:724465 发表于 2024-11-13 17:35 | 只看该作者
像这种应用应该是在8266里面把HTTP内容处理完,把最简单的数据发给51
回复

使用道具 举报

20#
ID:597405 发表于 2024-11-13 20:29 | 只看该作者
这还不简单,你知道怎么读取优盘数据吗?就是这道理。就是时间稍微长点。我以前存数据都是放在外接U盘。写程序时,不管外部数据多大多长,一律按2个字节分别读,然后打包储存在U盘,然后就是读取的时候,分别读出来,在合成。不要让单片机占太多的内存。用51也可以,像你说的那种网络数据,大概2秒的样子能完成
回复

使用道具 举报

21#
ID:961114 发表于 2024-11-14 09:01 | 只看该作者
用AI8051U   32位8051,34K RAM, 64K Flash, TFPU/硬件浮点三角函数运算器
最重要的是兼容89C52
回复

使用道具 举报

22#
ID:1136460 发表于 2024-11-14 20:06 | 只看该作者
面对单片机串口接收数据大于缓冲区的问题,可以采取以下几种策略:

1. **分块处理数据**:由于你的单片机RAM有限,可以考虑将大文件分块下载。每次只处理一小部分数据,处理完后再请求下一部分。这样可以避免一次性将大量数据加载到RAM中。

2. **使用外部存储**:考虑到你要下载的文件大小为10M,单片机的RAM显然不足以一次性处理这么多数据。可以使用SD卡等外部存储设备来暂存数据。在接收数据时,可以边接收边写入SD卡,而不是全部加载到RAM中。

3. **优化缓冲区管理**:你已经在使用环形缓冲区,这是个很好的开始。确保你的环形缓冲区管理逻辑能够有效地处理数据溢出的情况,例如,当新数据到来而缓冲区已满时,可以考虑丢弃最早的数据。

4. **使用DMA(直接内存访问)**:如果可能的话,使用DMA来处理数据传输可以减轻CPU的负担,提高数据处理的效率。

5. **升级硬件**:如果上述方法仍然不能满足需求,可能需要考虑升级到具有更大RAM的单片机,比如STM32系列。STM32单片机通常具有更大的RAM和更强大的处理能力,更适合处理大数据量的任务。

6. **优化通信协议**:如果可能,可以与服务器端协商,看是否可以减少HTTP响应头的大小,或者使用更高效的数据传输协议。

7. **流式处理**:在处理接收到的数据时,尽量采用流式处理的方式,即边接收边处理,而不是等到全部数据接收完毕再处理。

8. **使用ESP8266的AT命令**:ESP8266支持AT命令来处理TCP/IP连接和数据传输,可以利用这一点来减轻单片机的负担。例如,可以让ESP8266直接将数据写入SD卡,而不是通过单片机中转。

通过这些策略,你应该能够有效地处理大文件的下载和存储问题,即使在RAM有限的单片机上。
回复

使用道具 举报

23#
ID:1136497 发表于 2024-11-15 10:18 | 只看该作者
你可以在串口设置一个结构体呀,结构体包含地址start 地址end,支持回滚。只要记录每次传进来数据的个数,在数据放入之前进行处理,如果大于剩余个数就回滚,小于就按上次结束的位置开始放
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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