一、引 言

STC8051系列单片机主要使用Keil的C51编译器,STC32位8051单片机主要使用Keil的C251编译器。

STC8位单片机系列片上的XRAM空间从早期的256字节发展到现在的STC8系列的8K字节,STC官方的实验箱还给出了通过外部扩张将XRAM空间增加到32K字节的例子,完全可以跑RTOS实时多任务操作系统了。那么C51这个编译器能不能适应STC8位单片机的现状和未来的发展呢?

现在的STC32位的8051单片机系列片上的XRAM空间已经有12K字节(STC32G:4KB的EDATA和8KB的XDATA)和40K字节(STC16F:8KB的EDATA和32KB的XDATA),目前已经可以跑FreeRTOS实时多任务操作系统了。如果未来STC32F系列的XRAM超过64KB,甚至达到STC32F8M8M以后,C251这个编译器能不能适应STC32位单片机未来的发展呢?

通常理科大学生学习PC机上的C语言,这个C语言的教学标准是国家计算机等级考试,已经形成了固定的模式了:固定的等级考试题目类型,固定的教程和固定的教师队伍。如果要改变这个模式,笔者认为是要为这些理科教师和理科学生建立一个入门级(比如64 32学时课程)单片机C语言标准,教到什么程度,学些什么内容,正所谓没有规矩,不成方圆。

基于以上考虑和教学实践,笔者按照“全国计算机等级考试二级C语言程序设计考试大纲(2018年版)”的标准提出了“ STC8051单片机C351规范”,C351是C51和C251语言的一个子集,C351语法兼顾了入门的简单性要求,又能满足编写STC单片机RTOS实时多任务系统的复杂性要求。为了能够用C351语言编写STC单片机程序,笔者研制实现了“长缨8 C351编译器”,它是一个Windows下的没有界面的命令行可执行文件,可以直接对Keil的项目文件进行编译。

本系列文章将逐步地介绍C351单片机计算机语言的特点与编程方法,本文首先介绍在C351中用中文编程的方法。用中文进行C语言编程始终是一个有争议的话题:首先是能不能,能意味是中国自己的编译器。其次是方不方便,这个就仁者见仁智者见智,各人有各人的看法了。

二、英文程序

下面是一个在STC打狗棒开发板上运行的8个LED发光二极管左右闪动的单片机程序:

单片机c语言快速入门(C351编程1单片机C语言中文编程方法探讨)(1)

(1)这是一个很平凡的STC8051单片机C语言英文程序,对于STC89Cxx系列到STC8xx系列的单片机都适用,只是LED闪动的速度不同。这个程序用Keil编译器很容易通过,通常作为入门课程教学。

(2)第14行到第21行程序给出了程序运行的SFR定义,注意STC早期类型的单片机没有多种端口工作模式,也就没有第15和16行的端口模式配置寄存器。

(3)第24行到35行程序是延时函数定义,其中使用了3种循环语句类型,利用空循环来耗时间,实现软件延时。本例子是示意性的,延时未必是准确的以毫秒为单位。

(4)第38到44行程序是任务函数定义,第41行现按任务函数参数点亮LED灯,然后第42行延时指定的时间。这个例子主要延时函数调用。

下图是程序的主函数部分:

单片机c语言快速入门(C351编程1单片机C语言中文编程方法探讨)(2)

(5)主函数“main()”是用户程序的起点,STC8051单片机加电或者复位后从地址0x0000开始执行机器指令,执行完由编译器给出的引导(BOOT)程序后,从main函数开始执行用户编写的程序。

(6)第50行到第52行对LED灯连接的P2端口进行设置,设置为准双向工作模式。将关闭中断作为用户的第一行程序,是在掉过N次坑后的经验,是高可靠程序标准开始。

(7)第55行到58行程序是通常单片机程序应该具备的开机LOGO,明显地提示用户系统重新起点了。这里的LOGO先左4个LED亮1秒钟,后右4个LED亮1秒钟。

(8)像本范例这样的无操作系统的单片机程序任何时候都应该运行在用户程序的控制之下,这时用户程序不能从主函数main()中退出,。退出将引起未知的后果。因此第61行到64行形成一个无限循环,8个LED相邻两个交替发光。

下面是本程序运行效果的视频。

视频中可以看到STC打狗棒(STC8H8K64U)开发板插在了一块面包板上,一是有个固定的支撑物,二是避免管脚碰到哪里造成短路事故。

三、中文编程

探讨中文编程,以其坐而论道,不如提供实际例子来供大家评论。下图是一个与上英文程序对应的STC8051单片机C语言中文程序,用“长缨8 C351编译器”编译通过后,运行效果与前面英文的程序一致。

单片机c语言快速入门(C351编程1单片机C语言中文编程方法探讨)(3)

(9)用中文进行编程碰到的第一个问题是对于C语言的语法关键字是用中文还是用英文。如果决定用中文,可以利用C语言的宏定义功能来解决。

上面第14行程序包含了一个中文关键字宏定义的头文件,对本程序用到的C语言关键字宏定义为中文关键字。长缨8是用英文做关键字,在编译的过程中这些中文关键字会被恢复为英文的关键字,编译器能够正确的识别。

在中文语法分析技术中,实现中文分词是很困难的(类似的困难同样出现中文断句中,比如客人说“下雨天留客天留我不留”,你说客人的意思是他留不留?),因此笔者认为用中文语言编程,为了避免歧义,语法应该采用FORTH计算机语言的标准,由用户用空格将C语言关键字、变量名和函数名等用空格或者指定的数学符号分离开来,就像上面的程序那样。

(10)用中文进行编程碰到的第二个问题数值常数怎么办?比如像第17行程序,是写成中文的一百六十,还是写成阿拉伯数值160?如果写成中文,十六进制数怎么表达?

笔者觉得在中文C程序中数值表示就用传统的阿拉伯数字算了,毕竟商场里的价格也是阿拉伯数字表示的。

(11)在中文C语言中变量名应该可以用中文字,像第28行那样,这个大家都应该会认可的,毕竟现实中数量、单价和总计这种变量名大家都可以接受。

下图是程序的后半部分:

单片机c语言快速入门(C351编程1单片机C语言中文编程方法探讨)(4)

(12)可能有争议的是像上图第48行程序,宏定义名以及变量名可以用字符0~9开头吗?

长缨8 编译器计划支持中文编程,因此采用FORTH语言规范,将C语言程序中的空格作为优先级最高的“分界符”,将空格分开的字符串作为一个整体的“中文词”(英文的“word”)来进行语法分析。所以第48行用“1秒钟”来表达1000毫秒是允许的。

(13)中文程序语句分词问题的另一个例子是像前面第34和35行的“--”减一算符,它和后面的中文之间不需要空格,可以被编译器正确识别。但是如果要用中文“减一”来表示减一运算,就必须加空格,写成“减一 循环指标3”和“减一 循环指标2”的形式。

(14)在上面的中文C语言程序中,有大量的空格被用来分隔各个语法词,这样看起来很不像中文文章,令人不太习惯。长缨8只是一个简单的编译器,只能要求用户自己用空格来分词。在AI技术不断发展的趋势下,借助AI技术可以取消空格分词,未来的中文编程时用户直接用连续的中文描述解决问题的方法就行了,AI技术自动提取关键字和语法词,忽略中文辅助词,然后再提交给C语言编译器进行编译,输出单片机可以执行的机器代码。

附:下图是本文使用的C语言关键词替换头文件的内容:

单片机c语言快速入门(C351编程1单片机C语言中文编程方法探讨)(5)

,