Contents
  1. 1. 0x00 是单片机课设
  2. 2. 0x01 年轻人第一次做嵌入式
    1. 2.1. C 标准
    2. 2.2. 残念的printf
    3. 2.3. 扩展关键字
      1. 2.3.1. reentrant
      2. 2.3.2. idata
    4. 2.4. 贫瘠的标准库
  3. 3. 0x02 完成了
    1. 3.1. 哒哒哒疯狂按键
    2. 3.2. check your answer
    3. 3.3. 哪里不会就多点几次
  4. 4. 0x03 遗留的问题

0x00 是单片机课设

最近和同学在折腾单片机课的课设。我突发奇想的要用 LCD1602 做一个24点的游戏。虽然另一位小伙伴开始不太同意,不过最终还是确定了这个题目。经历了一个月的间歇性痛苦挣扎后,我们的作品终于初步完成了。

0x01 年轻人第一次做嵌入式

令人头痛的串行口驱动安装先略去不说,我们使用 Keil uVision4 和 C 来编写 STC89C52RC 的程序。STC89C52RC 有 512 bytes 的片内内存和 EEPROM 功能。开始我以为只要用C语言的程序就好了,然而在编写过程中却问题不断。

C 标准

Keil C51 以 ANSI C90 作为 C 标准。像 for (int i = 0; i < 5; i++)这样的语句是不能写的。另外main函数内部不能声明任何变量,都要把它们统统放到全局变量中。

残念的printf

我是属于面向printf调试那一类的,然而在 C51 中,printf被无情的剥夺了。毕竟单片机没有什么标准的输出设备。这对于我的程序调试是个不小的打击。所以我后来只能把其中可能有问题的部分复制出来,改成正常的 C 代码,编译调试。找到错误之后再改掉原来的 C51 代码。

扩展关键字

这里是让我最崩溃的地方了。Keil C51 有许多用于内存控制的扩展关键字,下面说一下让我头疼的两个关键字:

reentrant

这是由于我需要用到函数指针才碰到的问题。程序报错之后我上网搜索,很快发现了解决办法。虽然还是会有警告,但是程序的确正常执行了。

以下代码最后一行要添加 reentrant才能在 Keil 中编译通过。

1
2
3
4
5
6
7
8
9
10
#define uchar unsigned char
uchar Add(uchar a, uchar b) { return a + b; }
uchar Sub(uchar a, uchar b) { return a - b; }
uchar Mul(uchar a, uchar b) { return a * b; }
uchar Div(uchar a, uchar b) {
if (b == 0)
return -10000;
return a / b;
}
uchar (*op[4])(uchar, uchar) reentrant = {Add, Sub, Mul, Div};
idata

这是最让我迷惑的关键词了。它的解释是:间接寻址,包括整个内部 RAM 区 00H~FFH。然而,它和某个令我抓狂的问题联系在了一起—— ADDRESS SPACE OVERFLOW。开始的时候我以为是程序太复杂内存不够用了,但现在看来并不是这样(因为 data=146.1)。原本我的程序中有一个函数有 7 层循环,无论我怎么改,程序就是会报 ADDRESS SPACE OVERFLOW 错误(各种地方都会)。后来在我把 7 层循环改为 4 层之后才能正常编译。

有时候加上idata关键字会消除上面的问题,但有时候又会导致其他错误,包括程序显示不正常这种错误。所以说,现在我也还是没搞懂这里面的症结在哪。

贫瘠的标准库

标准库太少,连 time.h 都没有,想做个随机数就这么难吗?

以上有一部分参考了这里这儿,里面有些对以上问题的深入解释。

0x02 完成了

虽然有这样那样的问题,甚至有几次想要放弃换题了。但是我们还是幸运的完成了~虽然还是存在许许多多的问题,不过已经可以称它为一款游戏了。

哒哒哒疯狂按键

我们采用了高逼格的游标选择模式,就像以前的功能机那样。虽然确实麻烦了一些,但是按起来很爽!

check your answer

内置强大的计算功能,能够对你输入的任何算式进行计算,检查你的结果是否正确!这里使用的是调度场算法

LCD演示

那个 “Left!” 更是彰显了本组的英语水平(雾)。

哪里不会就多点几次

甚至内置了自动解题装置,在你算错之后再点击一次就可以查看正确答案了!

0x03 遗留的问题

  • 随机数问题,由于随机数种子是固定的,每次题目也是固定的。
  • 按键问题,有些按键不太灵敏或者容易连击。
  • 选择模式问题,现有的游标选择模式较为繁琐,按键布局也需要改进。
  • 小数问题,目前内部生成题目不会出现中间结果出现分数解法的题目。检查结果中间运算也都是整数。会出现1 / 3 == 0的问题。
  • 全排列问题,现在生成的 4 个数字未经过打乱处理,缺少很多题目。
Contents
  1. 1. 0x00 是单片机课设
  2. 2. 0x01 年轻人第一次做嵌入式
    1. 2.1. C 标准
    2. 2.2. 残念的printf
    3. 2.3. 扩展关键字
      1. 2.3.1. reentrant
      2. 2.3.2. idata
    4. 2.4. 贫瘠的标准库
  3. 3. 0x02 完成了
    1. 3.1. 哒哒哒疯狂按键
    2. 3.2. check your answer
    3. 3.3. 哪里不会就多点几次
  4. 4. 0x03 遗留的问题