bat脚本编译单片机程序

来源:互联网 发布:网络存储软件有哪些 编辑:程序博客网 时间:2024/05/29 15:55

最近做一个项目,要求写一个脚本文件来编译单片机源文件。当时就纳闷了,编写单片机源程序的Keil平台不是已经够强大了,为什么还要单独写一个bat脚本来对源程序进行编译???经过向大神请教,原来大神编写了智能家居的控制程序,调试时对于不同的家电都需要修改不同的宏定义(对于任何家电的控制都用一个宏定义来表示),这样每次调试时都得进Keil编译器,很浪费时间,再说由于有时候改动并不一定在已打开IED的情况,也不想每次都必须打开Keil来编译。于是就需要编写一个脚本文件来实现对源程序的编译,并且根据输入的不同能选择不同的宏定义来编译,这样就不需要每次都运行Keil了。

写bat脚本就得先明白它的命令语句。由于bat脚本文件是将一系列的DOS命令按一定的顺序集合为一个可执行的文本文件,该文本文件能按要求完成指定的功能,其扩展名为BAT或者CMD。(小知识:通过按下Ctrl+C组合键可强行终止一个批处理的执行过程。),所以下面我只列出我所使用的命令解释:

常用命令:
  1.REM和::  2.ECHO和@  3.PAUSE  4.GOTO和:  5.IF...else...  6.ERRORLEVEL  7.SET  8.FOR  9.%

1.REM 和 ::
REM为注释命令,一般用来给程序加上注解,该命令后的内容不被执行,但能回显。
::也起到注释作用,而且更简洁有效,与rem不同的是,::后的字符行在执行时都不会回显,无论是否用echo on打开命令行回显状态。
2.ECHO 和 @
@字符放在命令前将关闭命令回显,无论此时echo是否为打开状态。ECHO命令的常用功能如下:
(1)打开回显或关闭回显功能
     格式:echo [{on|off}]
如果想关闭“ECHO OFF/ON”自身的显示,在命令行前加上“@”。

(2)输出提示信息
     格式:ECHO 信息内容
(3)输出空行,即相当于输出一个回车
     格式:ECHO.
需要注意的是命令行中的“.”要紧跟ECHO后面,中间不能有空格。
(4)建立新文件或增加文件内容
     格式:ECHO 文件内容>文件名称
           ECHO 文件内容>>文件名称
其中>、>>为重定向符号,表示将内容输出到指定文件。

3.PAUSE
暂停命令,运行该命令后会显示“请按任意键继续”,按下任意键后则终止暂停状态,如想显示其他提示语,可与ECHO联用,例:echo 其他提示语 & pause > nul
4.GOTO 和 :
GOTO为跳转指令,跳转到以:开头的标号处,若标签匹配,则执行标签后的命令,标签的名称可以随便起,但最好是有意义的字符串,GOTO语句就是根据:和标签来寻找下一步运行的位置。
5.IF...else...
条件语句,依据判断值来执行相关的命令,主要有以下形式:
   IF [NOT] ERRORLEVEL number command

   IF [NOT] string1==string2 command
   IF [NOT] EXIST filename command
其中command命令可以是多条命令的组合,组合命令中也可以嵌套使用条件或循环命令。
6.ERRORLEVEL
命令执行返回值,用于判断命令执行状态,默认值为0,一般命令执行出错或者警告会使ERRORLEVEL值为1、2、3,可依据该值确定发生错误的级别。
7.SET
显示、设置或删除环境变量,格式如下:
SET [variable=[string]]

variable  指定环境变量
string    指定要赋给环境变量的一系列字符串
8.FOR
循环命令,基本格式为:
FOR %%variable IN (set) DO command [command-parameters]
%%variable  指定一个单一字母表示需替换的参数
set         指定一个或多个文件,可使用通配符
command     指定对每个文件执行的命令
command-parameters  指定参数或命令行开关
FOR循环带参数的用法有很多,可使用"FOR /? >文件名称"语句将FOR的帮助文档输出到指定文件,方便查看。

9.%
批处理变量引导符,可作为批处理的引用参数。引用变量用%var%,调用程序外部参数用%1至%9等等。
%0 批处理文件本身,包括完整的路径和扩展名
%1 第一个参数
%9 第九个参数
%* 从第一个参数开始的所有参数
参数%0可以实现调用批处理自身的特殊功能,以达到批处理本身循环的目的,也可以复制文件自身等等。

用命令行编译单片机的源文件流程是:编译源文件生成OBJ,然后链接OBJ,之后转换成HEX文件。这样就OK了,很简单。 
51.exe 编译c文件,BL51.EXE链接OBJ, OH51.EXE转换文件成HEX。

安装目录\C51.exe   C51Test.c

安装目录\BL51.exe  C51Test.obj TO Test

安装目录\OH51.exe  Test

注意:不要忘记把头文件复制到 \C51\INC 库目录中,以后使用比较方便。

在bat文件中运行C51编译器和工具,必须手动创建以下环境变量:
SET PATH=安装目录\C51\BIN;%PATH%
SET Dir=源程序目录...
SET C51INC=安装目录\C51\INC
SET C51LIB=安装目录\C51\LIB
C51有很多控制命令,这就就可以实现对宏定义的选取:
C51编译器提供许多控制命令控制编译,控制命令由一个或多个字母或数字组成,位于要编译的文件名之后,控制命令分为三类:源文件控制,目标控制,和列表控制。详细的控制命令及其说明可参考“安装目录\C51\HLP\c51.chm(或c51.pdf)”的帮助文档。其中DEFINE,DEBUG,INCDIR,WARNINGLEVEL控制命令的说明如下:

DEFINE
缩写:DF
默认值:无
参数:一个或多个符合C语言约定的名称,用逗号分隔。
描述:在编译命令行中定义预处理标志。

DEBUG
缩写:DB
默认值:没有调试信息被生成
参数:无
描述:指示编译器在obj文件中包含调试信息。

INCDIR
缩写:无
默认值:无
参数:源文件中include所包含文件的路径
描述:指定编译器include所包含文件的位置,编译器接收最多 512个路径声明,如果指定多个路径声明,路径名必须用分号隔开。


WARNINGLEVEL
缩写:WL
默认值:WARNINGLEVEL (2)
参数:0-2之间的一个数值
描述:通过指定warning的等级可忽略某些编译器警告。

概念都解释完了,那么不多说了,直接看bat的源程序如下,该程序可以扩展:

::close echo@echo off::clean screencls:: SET C51INC=C:\keil\C51\INC\Atmel\;C:\Keil\C51\INC\:: SET C51LIB=C:\Keil\C51\LIBset BINPath=BIN的路径set C51LIB=LIB的路径::SET source program Directory and source filenameset DIRName=bat文件所在目录set Status=0set SourceFile=%~nx1set ObjName=%~n1::set the macro defined constant valuesset valueone="0"set valuetwo="1"set valuethree="P0^0"::set the macro defined aliasset aliasone=aset aliastwo=bset aliasthree=LED::dispaly This programme is to make the C51 programme automateecho This programme is to make the C51 programme automate::if input not correctif "%1"=="" goto InputErrif "%1"=="/?" goto InputErrif "%1"=="help" goto InputErrif not "%~x1"==".c" goto InputErrif "%2"=="" (goto InputErrtwo) else if not "%2"=="0" (if not "%2"=="1" (goto InputErrtwo)    )if "%3"=="" (goto InputErrtwo) else if not "%3"=="0" (if not "%3"=="1" (goto InputErrtwo)    )if "%4"=="" (goto InputErrtwo) else if not "%4"=="0" (if not "%4"=="1" (goto InputErrtwo))@echo Go to workplaceD:cd %DIRName%@echo Clean have existed filegoto Clean:valuejudgeif "%2"=="1" (if "%3"=="1" (if "%4"=="1" (goto defineone) else goto definetwo) else (if "%4"=="1" (goto definethree) else goto definefour)) else if "%3"=="1" (if "%4"=="1" (goto definefive) else goto definesix) else (if "%4"=="1" (goto defineseven) else goto defineeight):LinkHEX::else link the .obj file%BINPath%BL51.exe %C51LIB%C51s.lib,%ObjName%.obj TO %ObjName%if errorlevel 1 goto LinkErr@echo Link Success...::generate .hex file%BINPath%OH51.exe %ObjName%if errorlevel 1 goto HEXErr@echo HEX Generate Success...set Status=1goto judge:defineone@echo building %ObjName%.c to %ObjName%.obj::build c51 programmer%BINPath%C51.exe %SourceFile% DF (%aliasone%='%valueone%',%aliastwo%='%valuetwo%',%aliasthree%='%valuethree%') DB INCDIR (外部库路径) WL (1)::if error, pause to see errorif errorlevel 1 goto BuildErr@echo building Success...@echo.@echo macro define sequence: 111goto LinkHEX:definetwo@echo building %ObjName%.c to %ObjName%.obj::build c51 programmer%BINPath%C51.exe %SourceFile% DF (%aliasone%='%valueone%',%aliastwo%='%valuetwo%') DB INCDIR (外部库路径) WL (1)::if error, pause to see errorif errorlevel 1 goto BuildErr@echo building Success...@echo.@echo macro define sequence: 110goto LinkHEX:definethree@echo building %ObjName%.c to %ObjName%.obj::build c51 programmer%BINPath%C51.exe %SourceFile% DF (%aliasone%='%valueone%',%aliasthree%='%valuethree%') DB INCDIR (外部库路径) WL (1)::if error, pause to see errorif errorlevel 1 goto BuildErr@echo building Success...@echo.@echo macro define sequence: 101goto LinkHEX:definefour@echo building %ObjName%.c to %ObjName%.obj::build c51 programmer%BINPath%C51.exe %SourceFile% DF (%aliasone%='%valueone%') DB INCDIR (外部库路径) WL (1)::if error, pause to see errorif errorlevel 1 goto BuildErr@echo building Success...@echo.@echo macro define sequence: 100goto LinkHEX:definefive@echo building %ObjName%.c to %ObjName%.obj::build c51 programmer%BINPath%C51.exe %SourceFile% DF (%aliastwo%='%valuetwo%',%aliasthree%='%valuethree%') DB INCDIR (外部库路径) WL (1)::if error, pause to see errorif errorlevel 1 goto BuildErr@echo building Success...@echo.@echo macro define sequence: 011goto LinkHEX:definesix@echo building %ObjName%.c to %ObjName%.obj::build c51 programmer%BINPath%C51.exe %SourceFile% DF (%aliastwo%='%valuetwo%') DB INCDIR (外部库路径) WL (1)::if error, pause to see errorif errorlevel 1 goto BuildErr@echo building Success...@echo.@echo macro define sequence: 010goto LinkHEX:defineseven@echo building %ObjName%.c to %ObjName%.obj::build c51 programmer%BINPath%C51.exe %SourceFile% DF (%aliasthree%='%valuethree%') DB INCDIR (外部库路径) WL (1)::if error, pause to see errorif errorlevel 1 goto BuildErr@echo building Success...@echo.@echo macro define sequence: 001goto LinkHEX:defineeight@echo building %ObjName%.c to %ObjName%.obj::build c51 programmer%BINPath%C51.exe %SourceFile% DB INCDIR (外部库路径) WL (1)::if error, pause to see errorif errorlevel 1 goto BuildErr@echo building Success...@echo.@echo macro define sequence: 000goto LinkHEX:Cleanif exist "%ObjName%.lst" del "%ObjName%.lst"if exist "%ObjName%.m51" del "%ObjName%.m51"if exist "%ObjName%.obj" del "%ObjName%.obj"if exist "%ObjName%" del "%ObjName%"if %Status% == 0 (   if exist "%ObjName%.hex" del "%ObjName%.hex"   ::Delay,unit is s   ping -n 3 127.0.0.0>nul   goto valuejudge):judgeif %Status% == 1 goto HEXOK@echo Hex generate fail!pausegoto ReturnDir:BuildErr@echo Sorry!%ObjName%.obj generate fail...pausegoto ReturnDir:LinkErr@echo Sorry!Link fail...pausegoto ReturnDir:HexErr@echo Sorry!HEX generate fail...pausegoto ReturnDir:InputErrecho Please enter correct C51 file nameecho Usage:[BAT file name] [C51 file name].c [value1(0 or 1)] [value2(0 or 1)] [value3(0 or 1)]pausegoto ReturnDir:InputErrtwoecho Please enter correct C51 define valueecho Usage:[BAT file name] [C51 file name].c [value1(0 or 1)] [value2(0 or 1)] [value3(0 or 1)]pausegoto ReturnDir:HEXOK@echo.@echo OK!%ObjName%.hex have generated...pausegoto ReturnDir:ReturnDirC:@echo on
运行BAT文件输入命令格式:
BAT文件名 源程序名称.c [1 or 0] [1 or 0] [1 or 0]
%0    %1   %2%3    %4
%0为BAT文件本身,%1为所要编译的源文件,其中后缀.c不能少,%2、%3、%4为选择进行宏定义的语句,只能为0或1,0表示不需要对应的宏定义语句,1表示选择了对应的宏定义语句。宏定义语句的别名和常量通过SET语句设定:
SET VARONE="0"; SET VARTWO="1"; SET VARTHREE="P0^0"
SET ALIASONE=A; SET ALIASTWO=B; SET ALIASTHREE=LED
如果想修改宏定义中的别名和常量,只需修改SET中等号右边的字符即可。


参考资料:

1.http://www.cnblogs.com/glaivelee/archive/2009/10/07/1578737.html

2.http://www.cnblogs.com/gleam/archive/2012/02/14/2350990.html


个人成果,转载请注明出处!!!

0 0
原创粉丝点击