第一章 编写第一个单片机程序

第一章  编写第一个单片机程序(汇编语言篇)

据我所知,有经验的编程人员最讨厌空洞地说教。他们希望看到你写实实在在的程序。因此我决定不按一般地编写单片机书籍的常规行事。先写这一章----编写第一个单片机程序。让读者首先对开发单片机程序的一般过程及keilC开发环境有所了解。

遵循丹尼斯·里奇(Dennis Ritchie)的示例。在开始学习一种新的编程语言时,一般都首先创建一个简单的“Hello,World”程序。我也不想破坏这种传统。不要以为只有PC机的编程语言才能编写“Hello,World”程序,单片机上电后,一样可以通过串口或者其它通信端口发送“Hello,World”信息,然后用常用的串口调试助手之类的应用程序进行捕捉显示。

在进行你的第一个单片机程序编写之前,要先确定你是否有一个实际的程序运行环境。因此在开始写程序之前,建议大家一定要先按照附录D内“手把手教你如何搭建一个单片机程序运行环境”一文,然后根据所教授的方法搭建一个属于自己的程序运行平台,再继续下面的程序编写。

以下是具体的实现过程:

1、首先安装大名鼎鼎的keil软件。

2、在桌面上运行快捷方式:,出现如下图的操作环境。

3现在按照如下顺序开始新建一个项目。

a.选择菜单栏上的

b.选择New Project,出现窗口

c.在文件名栏,写入项目名称helloworld,然后点击保存。

之后出现选单,要求选择你所使用的单片机型号。(本书介绍的是LPC93X系列单片,选用的型号为LPC936)。

点击确定。出现窗口:

由于这次的例子代码是用汇编语言写的ASM文件,因此可以选择否。

此时项目已经建好:

但是此为一个空项目,需要新建文件以及加入文件。

d.新建文件:

如图点击选择Create a new file。

出现窗口Text1。

如图选择Save As。

在出现上图后,由于你将建立的是一个汇编程序文件,因此就可以在文件名处输入“helloworld.asm”。

此时,你的汇编程序文件已经建立起了。

e.将建立的helloworld.asm加入刚才建立的项目中,过程如图:

在建立的source group文件夹上点右键弹出选单,然后选择Add Files to GroupSource Group1

出现窗口,在文件类型处选择ASM Source,就会出现helloworld.asm文件。

选择helloworld.asm点击Add。

现在就可以开始你的第一个程序编写了。

1、先将下列程序输入KEIL程序编译器内,如下图:

图1.1

源程序如下:

 

/*  BYTE Registers  */

P0M1   EQU 84H

P0M2   EQU 85H

P1M1   EQU 91H

P1M2   EQU 92H

P2M1   EQU 0A4H

P2M2   EQU 0A5H

P3M1   EQU 0B1H

P3M2   EQU 0B2H

BRGR0  EQU 0BEH

BRGR1  EQU 0BFH

BRGCON EQU 0BDH

SSTAT  EQU 0BAH

ESR  EQU 0ACH

EST  EQU 0EDH

;===================================================================

;开始程序

ORG 0000H

LJMP MAIN

ORG 0080H

MAIN: MOV SP,#07H ;设置堆栈首地址

LCALL INITIAL_IO ;初始化IO端口

LCALL  UART_INIT ;初始化串口

SEND: MOV SBUF,#48H

LCALL WAIT_TI

MOV SBUF,#45H

LCALL WAIT_TI

MOV SBUF,#48H

LCALL WAIT_TI

MOV SBUF,#4CH

LCALL WAIT_TI

MOV SBUF,#4CH

LCALL WAIT_TI

MOV SBUF,#4FH

LCALL WAIT_TI

MOV SBUF,#20H

LCALL WAIT_TI

MOV SBUF,#57H

LCALL WAIT_TI

MOV SBUF,#4FH

LCALL WAIT_TI

MOV SBUF,#52H

LCALL WAIT_TI

MOV SBUF,#4CH

LCALL WAIT_TI

MOV SBUF,#4CH

LCALL WAIT_TI

MOV SBUF,#21H

LCALL WAIT_TI

JMP $

;=====================================================================

;功能程序

;=====================================================================

 

;-----------------------------------------------------------------------------------------------------

;初始化端口配置

;------------------------------------------------------------------------------------------------------

INITIAL_IO:

     MOV P0M1,#0FFH

     MOV   P0M2,#0FFH

 

MOV   P1M1,#0ACH

 

MOV   P1M2,#0CH

RET

;-----------------------------------------------------------------------------------------------

;串口通信

;----------------------------------------------------------------------------------------------

;初始化串口

UART_INIT:

MOV BRGCON,#00H

MOV  SCON,#50H // select BRG as UART Baud Rate Gen

MOV  SSTAT,#0A0H // separate Rx / Tx interrupts

MOV  BRGR0,#70H            // setup BRG for 19200 baud @ 7.373MHz internal RC oscillator

MOV  BRGR1,#01H

MOV  BRGCON,#03H

CLR  ESR //关闭接收中断

CLR EST //关闭发送中断

SETB EA //开中断

RET

 

;----------------------------------------------------------------------------------------------------

 

WAIT_TI: JBC TI,CLR_TI

JMP WAIT_TI

CLR_TI: RET

END

记得在代码录入的过程中经常存盘。有些语句的意思初学者可能不很明白,随着对本书的学习,语法问题会在今后逐渐学会。本章的目的是介绍开发单片机程序的一般过程,因此,刚开始你只要做到不把代码敲错就可以了。

2、点击图标,进行编译配置设置(由于以后还将介绍具体的配置方法,现在只需要按照图示配置即可)。

此时为默认选项。

 

按照上图在Create HEX File选项前打勾点击确定。这样在编译完成汇编或C语言代码后,将生成一个*.hex文件,否则将不会生成*.hex文件。

3、然后点击工具栏的图标编译所有文件。

4、在命令框内出现如下图所示的内容:

5、此时在你存放项目文件的目录内将生成一个helloworld.hex文件,将这个文件烧入PLC936单片机(烧录的详细过程请参考附录D----手把手教你如何搭建一个单片机程序运行环境),即可实现发送“HELLO WORLD !”给PC的功能。

以上是如何应用keil软件来建立项目、写入源代码、编译、生成hex文件全过程。现在来看看我们代码的运行效果(高手提示我们:任何代码都要测试了才能通过,经不起测试都是垃圾)。

看看我们的运行结果:

1、首先将烧好了的LPC936的串口通信端口和PC机的串口端口相连,然后打开串口调试助手,如下图。

选择波特率:19200

此时,启动LPC936单片机运行。

结果在串口调试助手的接收区却显示出了乱码,而不是出现“hello world!”的字样。

用宋丹丹的话说:太伤自尊了!一本正经搞了半天,最后还是搞出一堆垃圾。在确定了代码没敲错之后,我决定换一款单片机来验证我的程序。可其它单片机(如P89C61X2BA)没有LPC专用的波特率发生器,因此先对程序的初始化串口程序进行修改,不用LPC自带的波特率发生器,将其改为用T1(定时记数器1)作为波特率发生器,也就是将代码:

;----------------------------------------------------------------------------------------------

;初始化串口

UART_INIT:

MOV BRGCON,#00H

MOV  SCON,#50H // select BRG as UART Baud Rate Gen

MOV  SSTAT,#0A0H // separate Rx / Tx interrupts

MOV  BRGR0,#70H            // setup BRG for 19200 baud @ 7.373MHz 

MOV  BRGR1,#01H

MOV  BRGCON,#03H

CLR  ESR //关闭接收中断

CLR EST //关闭发送中断

SETB EA //开中断

RET

改为:

UART_INIT:

MOV    SCON,#50H  ;SCON = 0x50; //SCON: serail mode 1, 8-bit UART, 

MOV TMOD,#21H ;TMOD = 0x21; //TMOD: timer 1, 

MOV PCON,#80H ;电源管理;PCON = 0x80; //SMOD=1

MOV   TH1,#244

MOV   IE,#90H ;Enable Serial Interrupt   //EA=1;ES=1;

SETB  TR1  

RET

大家看看串口助手得到的效果:

结果还是一样……LPC也太不争气了!

之后我又将同样的用T1产生波特率的程序放在了P89C61X2BA上去运行。则得到了想要的结果:

 

估计现在有许多人都是不理解的,包括我在内。怎么会出现这种现象呢?经过多次的分析和思考,以及阅读官方提供的资料,始终没有解决这个问题,我开始估计是LPC936单片机的串口端口在设计上有某种缺陷,或是有些资料自己没有理解透彻。但是我们不能因为小小的挫折就放弃用LPC936实现hello world!的显示这一目的,因此我们要另想办法解决。

硬的不行,只有来软的了。现在我决定用两条I/O口线,模拟UART串口发送数据给PC,源代码如下:

P1M1    EQU 91H

P1M2    EQU 92H

;===================================================

;主程序

ORG 0000H

LJMP MAIN

ORG 0080H

 

 

MAIN: MOV SP,#10H

 

MOV   P1M1,#00H

MOV   P1M2,#01H

SETB P1.0

LCALL DELAY

LCALL DELAY

LCALL DELAY

MOV A,#48H

LCALL SEND_UART_BYTE

MOV A,#45H

LCALL SEND_UART_BYTE

MOV A,#4CH

LCALL SEND_UART_BYTE

MOV A,#4CH

LCALL SEND_UART_BYTE

MOV A,#4FH

LCALL SEND_UART_BYTE

MOV A,#20H

LCALL SEND_UART_BYTE

MOV A,#57H

LCALL SEND_UART_BYTE

MOV A,#4FH

LCALL SEND_UART_BYTE

MOV A,#52H

LCALL SEND_UART_BYTE

MOV A,#4CH

LCALL SEND_UART_BYTE

MOV A,#44H

LCALL SEND_UART_BYTE

MOV A,#21H

LCALL SEND_UART_BYTE

 

JMP $

;===========================================================

;发送字节

SEND_UART_BYTE:

CLR P1.0    ;发送起始位

LCALL DELAY

MOV C,ACC.0

MOV P1.0,C

LCALL DELAY

MOV C,ACC.1

MOV P1.0,C

LCALL DELAY

MOV C,ACC.2

MOV P1.0,C

LCALL DELAY

MOV C,ACC.3

MOV P1.0,C

LCALL DELAY

MOV C,ACC.4

MOV P1.0,C

LCALL DELAY

MOV C,ACC.5

MOV P1.0,C

LCALL DELAY

MOV C,ACC.6

MOV P1.0,C

LCALL DELAY

MOV C,ACC.7

MOV P1.0,C

LCALL DELAY

SETB P1.0    ;发送停止位

LCALL DELAY

RET

;============================================================

;延时(决定波特率)

DELAY: PUSH ACC

MOV R0,#90

DELAY1:

DJNZ R0,DELAY1

POP ACC

RET

 

 

END

按照前面所述的方法,将上面的源代码编译烧写之后,在串口调试助手内,将得到你所希望看到的hello world!的字样!(终于成功了……)

    现在都什么年代了这家伙怎么还在用石器时代的东西写程序?看到这里有些读者心里要问了下一章我就用C语言来写同样的程序也让大家看看什么叫做高层次

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值