bat脚本编译单片机程序

最近做一个项目,要求写一个脚本文件来编译单片机源文件。当时就纳闷了,编写单片机源程序的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 screen
cls

:: SET C51INC=C:\keil\C51\INC\Atmel\;C:\Keil\C51\INC:: SET C51LIB=C:\Keil\C51\LIB
set BINPath=BIN的路径
set C51LIB=LIB的路径

::SET source program Directory and source filename
set DIRName=bat文件所在目录
set Status=0
set SourceFile=%~nx1
set ObjName=%~n1

::set the macro defined constant values
set valueone="0"
set valuetwo="1"
set valuethree="P0^0"

::set the macro defined alias
set aliasone=a
set aliastwo=b
set aliasthree=LED

::dispaly This programme is to make the C51 programme automate
echo This programme is to make the C51 programme automate

::if input not correct
if "%1"=="" goto InputErr
if "%1"=="/?" goto InputErr
if "%1"=="help" goto InputErr
if not "%~x1"==".c" goto InputErr
if "%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 workplace
D:
cd %DIRName%

@echo Clean have existed file
goto Clean

:valuejudge
if "%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=1
goto 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 error
if errorlevel 1 goto BuildErr
@echo building Success...
@echo.
@echo macro define sequence: 111
goto 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 error
if errorlevel 1 goto BuildErr
@echo building Success...
@echo.
@echo macro define sequence: 110
goto 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 error
if errorlevel 1 goto BuildErr
@echo building Success...
@echo.
@echo macro define sequence: 101
goto 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 error
if errorlevel 1 goto BuildErr
@echo building Success...
@echo.
@echo macro define sequence: 100
goto 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 error
if errorlevel 1 goto BuildErr
@echo building Success...
@echo.
@echo macro define sequence: 011
goto 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 error
if errorlevel 1 goto BuildErr
@echo building Success...
@echo.
@echo macro define sequence: 010
goto 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 error
if errorlevel 1 goto BuildErr
@echo building Success...
@echo.
@echo macro define sequence: 001
goto 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 error
if errorlevel 1 goto BuildErr
@echo building Success...
@echo.
@echo macro define sequence: 000
goto LinkHEX

:Clean
if 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
)

:judge
if %Status% == 1 goto HEXOK
@echo Hex generate fail!
pause
goto ReturnDir

:BuildErr
@echo Sorry!%ObjName%.obj generate fail...
pause
goto ReturnDir

:LinkErr
@echo Sorry!Link fail...
pause
goto ReturnDir

:HexErr
@echo Sorry!HEX generate fail...
pause
goto ReturnDir

:InputErr
echo Please enter correct C51 file name
echo Usage:[BAT file name] [C51 file name].c [value1(0 or 1)] [value2(0 or 1)] [value3(0 or 1)]
pause
goto ReturnDir

:InputErrtwo
echo Please enter correct C51 define value
echo Usage:[BAT file name] [C51 file name].c [value1(0 or 1)] [value2(0 or 1)] [value3(0 or 1)]
pause
goto ReturnDir

:HEXOK
@echo.
@echo OK!%ObjName%.hex have generated...
pause
goto ReturnDir

:ReturnDir
C:

@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

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

时间: 2024-10-14 06:45:54

bat脚本编译单片机程序的相关文章

bat脚本:Java一键编译(Javac java)

bat脚本:Java一键编译(Javac java) D:    是指D盘 javat是要编译的.java文件所在的文件夹 也就是D:\javat :start COLOR 0A cls D: cd javat set /p file=请输入待编译文件名: :re cls javac %file%.java java %file% set /p bool=是否重复运行(输入y,n): if %bool%==y (goto re) goto start 写好后,存为bat格式,然后双击打开.输入H

Bat 脚本学习 (基础篇)

[转]Bat 脚本学习 2015-01-05 14:13 115人阅读 评论(0) 收藏 举报 基础部分: ====================================================================== 一.基础语法: 1.批处理文件是一个“.bat”结尾的文本文件,这个文件的每一行都是一条DOS命令.可以使用任何文本文件编辑工具创建和修改. 2.批处理是一种简单的程序,可以用 if 和 goto 来控制流程,也可以使用 for 循环. 3.批处理的

第一个单片机程序(C言语编写)

忙活了半天,预备任务做了那么多,终于要编写我们的程序代码了.假如学过 C 言语的话,你应当很轻松的跟着我的编程本人写出来,假如没学过 C 言语也没紧要,你先照着我的抄,我会在适宜的地位写出来对 C 言语语法的说明,如许抄几回后再看看说明,就应当很明确了,抄的时分必定要仔细,特别标点符号弗成以搞错.第一个单片机程序: #include <reg52.h> //包括特别功用存放器界说的头文件 sbit LED = P0^0; //位地址声明,留意:sbit 必需小写.P 大写! void main

51单片机程序技巧

本系列文章探讨的主题都是在Keil uVision3集成编译环境下完成的,针对的是51系列单片机. 下面就介绍一下在我的单片机程序里必须要包含的一个头文件----"const.h",完整内容如下: #ifndef _CONST_H_ #define _CONST_H_ #include <intrins.h> #define TRUE 1 #define FALSE 0 typedef unsigned char BYTE; typedef unsigned int WOR

Bat脚本处理ftp超强案例解说

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://369369.blog.51cto.com/319630/842341 Bat脚本处理ftp超强案例解说 前言:    公司有几百台windows服务器,每次程序更新,如果是一台台拷数据,只怕安排十个人,一天都不一定做得完,所以就必须研究个全自动更新方案来,于是就 想到了FTP,做个主FTP站,在几百台客户机上启动BAT脚本,每30秒检测一次,如果主站有更新程序,就自动下载更新,

单片机入门指南系列(十五) 单片机程序下载失败总结

前面介绍了点亮第一个LED的全过程,很多人可能很幸运的点亮了LED,然而也很可能不少人非常不幸没有把程序下载进去.初学者常会遇到程序无法下载的情况,很多人在尝试多次未果后比较受打击,因此放弃了学习,实在太可惜了.鉴于此,这里列举了单片机程序下载失败的各种出错原因.判断方法和解决方法,是前人所遇到的种种原因的总结. STC单片机下载程序主要分为三部分:单片机最小系统.下载电路.计算机端.下载失败一般主要就从这三个方面来解决问题. 快速排错方法 如果你有或者能向别人借到一套可以正常下载程序的电脑.单

【KEIL&#183;单片机&#183;扫盲贴】关于ARM单片机程序内存使用情况的细致讨论。

接触了两年多时间的单片机编程本人对关于单片机程序内存如何耗费的问题一直懵懵懂懂,直到在近日看到某篇有关于MDK MAP文件介绍的帖子后才有种醍醐灌顶的感觉,这里我将分享在此之上的观点与见解以供大家讨论学习. 大家都知道ARM单片机的内部存储空间极其匮乏无论是从Flash还是RAM上,每每给单片机机编程都有一种惜字如金的感觉,工程师们一般会在容量有限的情况下规范其编程习惯简化代码避免冗余,那么首先我们如何知道的程序下载到单片机上到底占用了多少Flash程序运行又会使用多少RAM? 首先上一张图:

bat脚本参数 if goto choice for使用的学习笔记。

写过几次bat脚本,但一直没有总结,最近找到一个网页介绍bat,总结得很好,转自 http://www.jb51.net/article/49627.htm: 本文只总结我不会的,全面的看原网页就可以了. 1 参数 '%':参数符,%[1-9]表示参数,多个参数要用空格或tab隔开.变量可以从%0到%9,%0表示批处理命令本身,其它参数字符串用%1到%9顺序表示. 例3:C:根目录下一批处理文件名为t.bat,内容为: @echo off type %1 type %2 那么运行C:\>t a.

纯脚本编译WebRTC For Android

在WebRTC的范例工程中,有一个Android项目叫AppRTCDemo,可以实现广域网上的视频通话(VoIP).这篇文章旨在演示AppRTCDemo的编译,平台以Windows为例,但同样适用于Mac和Linux.切换到Linux环境请明确你当前使用的是什么平台,如果是Linux,那么可以忽略这一步:否则,你需要一台虚拟机.我正在使用该死的Windows,我比较推荐Vagrant,这是一款适合程序员使用的轻量级虚拟机,可以提供原汁原味的Linux控制台体验.检出编译脚本有一个开源项目叫web