标题: c51单片机中的动态内存分配问题 [打印本页]

作者: 会会会不会    时间: 2021-12-5 08:49
标题: c51单片机中的动态内存分配问题
这两天在学c51单片机 想着写一个贪吃蛇练练手,关于蛇的移动(头插尾出)就想着用队列(链表实现),因为之前也没专门学过c,发现链表用着比想象中麻烦好多,尤其是动态内存分配。c51中不能直接使用malloc和free等函数,要先初始化一个堆(init_mempool函数)但这个函数我看了官方文档也没看明白,照葫芦画瓢写了个差不多的,但会有很奇怪的现象--只能往右边走,而且走一会就停了 只有一个等在亮

堆初始化.png (7.99 KB, 下载次数: 116)

堆初始化

堆初始化

全局函数.png (6.22 KB, 下载次数: 122)

全局函数

全局函数

蛇初始化.png (36.2 KB, 下载次数: 120)

蛇初始化

蛇初始化

蛇的定义.png (89.74 KB, 下载次数: 143)

蛇的定义

蛇的定义

蛇位置更新.png (9.97 KB, 下载次数: 120)

蛇位置更新

蛇位置更新

移动蛇1.png (47.57 KB, 下载次数: 123)

蛇移动函数1

蛇移动函数1

移动蛇2.png (52.56 KB, 下载次数: 117)

蛇移动函数2

蛇移动函数2

主函数.png (99.83 KB, 下载次数: 126)

主函数

主函数

snake.rar

60.92 KB, 下载次数: 7

工程


作者: 啤酒瓶子老大    时间: 2021-12-5 11:05
本论坛有强大的搜索功能,搜索一下。有其它大佬的程序,先下载下来学习一下。事半功倍。
作者: Hephaestus    时间: 2021-12-5 12:04
你好歹用个STM8啊,8051这么陈旧的结构直接寻址能力只有120字节玩儿动态分配内存是不是开玩笑?
作者: 天ノ忆    时间: 2021-12-5 12:34
http://www.51hei.com/bbs/dpj-128647-1.html
作者: 会会会不会    时间: 2021-12-5 14:58
Hephaestus 发表于 2021-12-5 12:04
你好歹用个STM8啊,8051这么陈旧的结构直接寻址能力只有120字节玩儿动态分配内存是不是开玩笑?

我用的是89c516, 还是说不管是c51还是c516,我能访问的ram只有120字节?如果这么说的话倒也就合理了,走了两三下就不走了是因为之后的内存没法访问?
作者: 会会会不会    时间: 2021-12-5 15:01
  1. #include <stdlib.h>

  2. unsigned char xdata malloc_mempool [0x1000];


  3. void tst_init_mempool (void) {
  4.   int i;
  5.   xdata void *p;

  6.   init_mempool (&malloc_mempool, sizeof(malloc_mempool));

  7.   p = malloc (100);

  8.   for (i = 0; i < 100; i++)
  9.     ((char *) p)[i] = i;

  10.   free (p);
  11. }
复制代码
还有就是其中 unsigned char xdata malloc_mempool [0x1000]; 这条语句后面的 [0x1000] 是指定起始地址吗

作者: npn    时间: 2021-12-5 15:44
Hephaestus 发表于 2021-12-5 12:04
你好歹用个STM8啊,8051这么陈旧的结构直接寻址能力只有120字节玩儿动态分配内存是不是开玩笑?

STC8一出现,STM8就会慢慢淘汰了。
没看见代码里用了XDATA内存? 有64KB的寻址范围。
作者: Hephaestus    时间: 2021-12-5 16:28
npn 发表于 2021-12-5 15:44
STC8一出现,STM8就会慢慢淘汰了。
没看见代码里用了XDATA内存? 有64KB的寻址范围。

知名大厂如intel、Siemens(现Infineon)、Philips(现NXP)都曾经是51生产大厂,然而20年前纷纷停产了所有的51产品。如果真有市场,轮得到STC吃残羹剩饭?用STC的人声势浩大,但是有用吗?每个人出货量能有几片???跟STM8、PIC等单片机比产量,就是个笑话,别不以为耻反以为荣。
作者: npn    时间: 2021-12-5 18:41
Hephaestus 发表于 2021-12-5 16:28
知名大厂如intel、Siemens(现Infineon)、Philips(现NXP)都曾经是51生产大厂,然而20年前纷纷停产了所 ...

STC和STM的区别等于华为和三星的区别,这就是在国内越来越没人用三星,哪国的品牌只有那国人用的多。
作者: npn    时间: 2021-12-5 19:02
Hephaestus 发表于 2021-12-5 16:28
知名大厂如intel、Siemens(现Infineon)、Philips(现NXP)都曾经是51生产大厂,然而20年前纷纷停产了所 ...

3个月内有200多个STC的帖子,STM8的帖子不到30个,这就是在国内开始淘汰的原因,你可以站内高级搜索。
作者: 188610329    时间: 2021-12-5 20:00
楼上的,你们楼歪了!!!
作者: 188610329    时间: 2021-12-5 20:34
会会会不会 发表于 2021-12-5 14:58
我用的是89c516, 还是说不管是c51还是c516,我能访问的ram只有120字节?如果这么说的话倒也就合理了,走 ...

STC89c516  的话, RAM 是1280     , 256 IDATA(前部的128 可为DATA)  和 1024 的 XDATA 共计1280。

如其他品牌,你可以查找相关手册, 造51的太多了,没人能全知道。
作者: 188610329    时间: 2021-12-5 20:45
也就整个贪吃蛇,压根没必要整什么动态内存。而且,你本质上不应该把它当作“蛇”,就应该是认为是一个二维的流水灯,无非给这个流水灯加一些判断,比如下一个亮起的灯,由按键决定 横坐标 +-1 还是纵坐标 +-1。然后,这个新的灯的坐标,超出边界,则判定 GAME OVER , 这个灯的坐标,等于已经亮着的流水灯中的某一个灯的时候,判定 GAME OVER, 就够了。 如果你用的是 STC89C516的话,做8x8的贪吃蛇就没意思了,做16x16 的不好么? 刚好256,寻址正好1个字节,充分利用8位单片机的所有性能。
作者: 188610329    时间: 2021-12-5 23:35
会会会不会 发表于 2021-12-5 15:01
还有就是其中 unsigned char xdata malloc_mempool [0x1000]; 这条语句后面的 [0x1000] 是指定 ...

后面 0x1000 是长度, 表示你定义这个 数组 4K字节的长度, 这不是 一般的 8051 能够拥有的XDATA长度,要么是增强型51,要么是 真的外置扩展 芯片了。 至少如果你的是 STC89C516的话,是无法提供那么多的。
作者: npn    时间: 2021-12-6 07:51
188610329 发表于 2021-12-5 20:45
也就整个贪吃蛇,压根没必要整什么动态内存。而且,你本质上不应该把它当作“蛇”,就应该是认为是一个二维 ...

无论是什么点阵游戏,都属于二维流水灯,这类算法本身就有难度,你应该先用C或C++实现,然后再移植进去。
作者: 会会会不会    时间: 2021-12-6 13:27
188610329 发表于 2021-12-5 23:35
后面 0x1000 是长度, 表示你定义这个 数组 4K字节的长度, 这不是 一般的 8051 能够拥有的XDATA长度,要 ...

感谢!!
昨天看上面说不能用内存分配我就数组写了,用数组确实简单很多,但看了你说的,我把内存池调到一个合适大小就能正常运行了,但可惜运行一会就会出错了,我猜测可能是因为内存实在是太小了再加上碎片化导致运行一段时间后malloc就不能正确分配内存了。用struct和malloc主要还是c++的编程思路一直会影响我,看来以后写单片机还是得认清性能问题




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1