当前位置:文档之家› 单片机程序设计编程规范

单片机程序设计编程规范

单片机程序设计编程规范
单片机程序设计编程规范

单片机程序设计编程规范

本规范适用于松翰科技 8-bit MCU部门汇编程序编写准则,同样适用于代理商及重要客户工程师编程规范参考。本规范的目的为统一编程风格,保证程序编写质量,提高程序的可移植性和维护性。

大部分的规范严格, 品质要求高的软件公司对员工编写代码的风格都有硬性规定, 例如缩排的使用,TAB 的长度,函数变量的命名方式。这些规定的明显好处是可以统一规范不同程序员所编制的代码,提升程序代码的可读性与可维护性,同时统一格式的编程风格也为code review提供方便。

目录

一、设计总则

二、排版风格

三、程序可读性及可维护性

四、注释

五、变量命名规则

六、常量命名规则

七、标号命名规则

八、文件命名规则及文件分割

九、标准程序模块

十、附录

一、设计总则

1.程序质量的评估

程序的优劣可以从两个方面进行评估,定量指标和定性指标。

定量指标包括:

1) 程序代码执行效率;

2) 程序占用资源多少。

定性指标包括:

1) 可调试性,即是否方便排除程序语法错误;

2) 可测试性,即是否方便验证程序功能的正确性;

3) 可维护性,即是否方便程序的修改和升级;

4) 可移植性;

5) 可读性。

2、程序架构

为了便于维护和移植,推荐使用层次化的软件设计方法。可把整个软件分为三层:应用层、界面层和底层驱动层。各层之间的关系如下图所示。

层次化设计说明:

1) 底层驱动层主要包含直接和硬件相关的驱动程序,如数码管显示、按键、峰鸣器、继电器和电机控制等。底层的各个模块间要保持各自的独立性,不产生直接的数据交互,底层也不直接访问应用层,如果有需要,都要通过界面层进行数据交互。

2) 界面层主要提供数据交互,为应用层和底层驱动之间以及底层驱动层各模块之间提供数据的交互。

3) 应用层主要完成具体功能的实现,它要通过界面层控制底层驱动层各模块来完成所需功能,而不能越过界面层直接访问底层驱动层。所有的用户接口要在应用层来实现。

4) 一个好的架构必须将底层硬件包装起来,为应用程序提供一组丰富的函数操作(buffer or parameter),例如在中断的处理中,应用程序不需要资料中断的堆栈如何保护不需要知道地址操作, 只需要读取中断产生的旗标动作。

5) 在即时性软件系统里面,对达到高效率的实时性与反应力, 所以程序使

用大量的事件触发方式来设计任务。事件有可能来自外部的触发(key , rxdata , sensor detect, …)也可能是系统内部自行产生的(Timer, alarm, flag),与事件触发方式相对应的是定时查询方式(polling),一般来说polling 效率较差因为有多余的动作而且系统反应时间与查询polling时间间隔有关, 但是在小型的MCU系统里面用Polling方式反而简单许多。

3、设计基本原则

1) 尽量减少各个子程序功能模块间的耦合度(耦合度是指一个程序的执行对另一个程序的影响力),保证各自的独立性。一般情况下,建议子程序模块功能的划分要尽可能细化,功能尽量单一,减少子程序模块间的数据交互。

2) 在满足功能需求的情况下,可适当牺牲代码的执行速度,以保证程序的透明度。

3) 主要子程序模块间的交互,要通过特定的界面跟应用层进行沟通,可使用 FIFO(First in,First out)或是 Buffer 两种方式。每种子程序模块都可以有自己的FIFO。例如:就按键来说,一般有 Key buffer、Key FIFO 或直接进入AP FIFO三种设计方式。

Key buffer:一般用于保存数字按键信息。例如:在电话机的设计中,需要记录按键内容用于LCD 显示、最后数字确认、数字存储等,这时候需要把按键值的信息(0123456789*#)记录在 Key buffer 中。

Key FIFO:一些功能按键可以将相应信息列入到Key FIFO中,等待应用层的取用,这样可根据不同的工作模式进行不同的处理及动作。

这些类似的观念可以应用在许多周边中:

输入类:Key、RF Data input、UART data input、Switch input等。

输出类:LCD display、LED display、UART data output等。

APP FIFO(应用界面层):主要是将发生的事件储存在APP FIFO里面等待适当的时间依序处理,不然有可能造成系统在某一程序物件里面循环,从而降低系统的实时性(Real-Time)。

4)每个子程序模块只能有唯一一个程序入口地址在程序的首部,只能有唯一一个程序出口地址在程序的尾部。

例如:

以下的写法是不规范的(两个RET出口,存在调试时不易设立断点,程序可读性降低等问题):

lable:

b0bts0 fz

ret

clr y

ret

应该改为(只有一个出口位置,标号为 lable90,便于程序检查):

lable:

b0bts0 fz

jmp lable90

clr y

lable90:

ret

5) 上电复位时要对所有的RAM空间进行初始化(建议用户寄存器清零,系统寄存器进行必要设定),不要使用未经初始化的变量。RAM未经过完整的初始化,容易导致程序执行的不确定性,这一不良现象往往在批量生产中有所体现。(这点是工程师经常犯错的地方,须特别注意)

6) 系统中如果需要等待一些未知的应答信号,如通信或等待输入信号时,必须进行超时或异常处理,以防止程序进入“死等”状态。

例如在红外接收中,由于信号的突然消失或干扰从而无法得到一帧完整或正确的信息,这时需要复位接收程序的入口条件并退出接收程序,而不是一直等待信号的来临。不然无法进行下次接收甚至会影响到其它程序的执行。

7) 通过对系统数据结构的划分与组织的改进,以及对程序算法的优化来提高空间效率。这种方式是解决软件空间效率的根本办法。

8) 保证循环体内的工作量最小化。应仔细考虑循环体内的语句是否可以放

在循环体之外,使循环体内工作量最小,从而提高程序的执行效率。

9) 在多重循环中,应将最忙的循环放在最内层。

10) 中断处理程序应尽量短。有效的作法为:在中断中进行标记,在主程序中进行处理。但一些实时性要求较高的程序例外。此外,进入中断时应该保存涉及到的变量和寄存器。

11) 看门狗的正确使用。看门狗主要用于微控制器死机时的时间溢出复位,需要程序适时清除。正确的处理方式为:整个系统程序中尽量保证只有一处清看门狗位置,而且应处在主循环的主干位置。切记不可在定时中断中清狗,因为微控制器有时只是在主循环中死掉。(所有AC电源的应用程序都必须强迫加入看门狗选项尤其是条件式的看门狗有利于系统发生异常后的重启动)

二、排版风格

1、程序采用缩进风格编写,缩进为1个Tab 键,1个Tab键定义为8个空格位。

2、程序中的标号要从第一列开始书写。以“.”开头的预编译命令也要从第一列开始书写,其他预编译命令采用缩进风格编写。

例如:

1) 以“.”开头的预编译命令要从第一列开始书写,其他预编译命令采用缩进风格书写。

.LIST ;从第一列开始书写

INCLUDESTD macro1.h

.CONST

NUMBER EQU 55h

.DATA

wk00 DS 1

.CODE

ORG 0h

2) 标号要从第一列开始书写。

main: ;从第一列开始

jmp main ;缩进8个空格位

3)变量或常量的定义采用缩进风格。

例如:

.DATA

keybuf DS 1

.CONST

NUMBER EQU 8

4)定义变量或常量时,变量名或常量名与命令符之间使用2个Tab键(相当于16个空格位)分开,命令符与后面的操作数用1个Tab键(相当于8个空格位)分开。

例如:

keybuf DS 1

NUMBER EQU 55h

5)操作码与操作数之间用1个Tab键(相当于8个空格位)分开。

例如:

ORG 80h

mov a,NUMBER

table:

DW 1234h

6.)程序中两个操作数之间用一个“,”作为分隔符,“#”号与立即数之间不需要分隔符。

例如:

Mov a,#55h

7)标号要单独占一行。

8)相对独立的程序块之间必须加空行。

例如:

ORG 10h

INCLUDE sys.asm

INCLUDE int.asm

INCLUDE key.asm

9)程序语句后面若有注释,所有的注释要遵守上下对齐的原则。

例如:

b0mov l,#7fh ;use dp0x(hl) pointer

mov a,#00 ;set pointer = 007fh

应该书写为:

b0mov l,#7fh ;use dp0x(hl) pointer

mov a,#00 ;set pointer = 007fh

三、程序可读性与可维护性

1.程序中的语句、标号、变量使用小写英文字母,常量与预编译命令使用大写英文字母,以便和一般的语句进行区分。

例如:

NUMBER EQU 55h

.DATA

accbuf DS 1

.CODE

mov a,#NUMBER

2.表示不同进制的立即数,要在立即数后面加上不同的进制符号。

例如:

mov a,#00100011b

mov a,#23h

不建议使用:

mov a,#0x23

3.一般情况下,变量和常量要分开定义,不要混在一起。变量在“.DATA ”段中定义,采用命令符“DS” ,常量在”.CONST ”段中定义,采用命令符“EQU”。例如:

.CONST

NUMBER EQU 10

.DATA

Accbuf DS 1

4.程序中不使用未定义或意义不明确的常量。

例如:

下面的赋值方法要避免使用:

mov a,#3 ;不要直接使用意义不明确的数字

在常量中做定义

mov r,a

建议采用如下赋值方法:

.CONST

NUMBER EQU 3 ;循环次数

.CODE

mov a,#NUMBER

mov r,a

5.整个程序的结尾要以“ENDP”语句结束。

6.当一段代码在程序中有多个地方使用时,建议采用子程序调用或宏命令的方式来替代。如此,对该代码段的修改就可在一处完成,增强代码的可维护性。

7.程序中关系较为密切的子程序代码尽可能相邻。

8.避免程序中的垃圾代码,预留代码应以注释的方式出现。程序中的垃圾代码不仅占用额外的空间,而且还可能影响到程序的功能与性能,很可能给程序的测试、维护等造成不必要的麻烦。

四、注释

1.程序应该包括两个部分注释,说明部分和语句注释。一般情况下,源程序有效注释量必须在30%以上。

2.说明部分:

1) 源文件说明部分位于每个源文件的最前面,主要描述:文件名、作者、生成日期、联络方式、功能描述、版本号、软硬件平台、版权说明、修改记录等的简要说明,以英文书写。

例如:

/**********************************

File name: ;文件名Author: ;作者

Date: ;日期

Email: ;邮箱地址

Description: ;功能描述

Version: ; 版本号

Hardware&IDE ;软硬件平台

Copyright (C), SONIX TECHNOLOGY Co., Ltd.

History: ;修改记录

**********************************/

2)子程序说明部分位于每个子程序的最前面,主要描述:子程序名称、功能、设计原理、所用变量、入口条件、出口信息、调用模块、堆栈层数、影响资源、算法简述、使用说明和修改记录等。

例如:

/*****************************

Subroutine: ;子程序名称

Description: ;子程序功能的描述

Principium: ;程序设计原理

Calls: ;被本子程序调用的子程序清单Variables: ;本子程序中所用到的临时变量Input: ;子程序调用所需要基本参数的说明Output: ;子程序调用后运算结果的说明Stack: ;占用的堆栈层数

History: ;修改记录

******************************/

3.边写代码边注释,修改代码的同时修改相应注释,以保证注释与代码的一致性。不再有用的注释要删除。

4.要避免在注释中使用缩写,特别是非常用缩写。

5.程序在必要的地方必须有注释,注释要准确、易懂、简洁。注释要有意义,如果有需要,还要详细描述相关含义。

例如:

以下是无意义的注释

mov a,#5 ;把5 赋给 acc

mov wk00,a ;把 acc 赋给 wk00

应该如下注释:

mov a,#5 ;设置循环次数为5 次

mov wk00,a

6.注释应与其描述的代码相近,对代码的注释应放在其上方或右方(对单条语句的注释)的相邻位置,不可放在下方,如放于上方则需与其上面的代码用空行隔开。

例如:

clr wk00

; Check Read index = FiFo Limit

cmprs a,r ;Is Read index = Limit

Jmp @f

7.注释格式尽量统一,对多行注释建议使用“/* …… */”,对单行的注释建议使用“;”。

8.注释应考虑程序易读及外观排版因素,语言尽量统一。对不能进行准确英文表达的建议使用中文。

9.对有含义的变量、常量,如果其命名不是充分自注释的,在声明时都必须加以注释,说明其含义。

五、变量命名规则

1.变量的名称要采用有意义的英文单词小写缩写。可以采用以下几种方式进行缩写命名:

1)去掉所有不在词头的元音字母。如 screen可以简写为scrn。

2)使用每个单词的头几个字母。如 channelactivation 可以简写为chanactiv。

3)使用变量名中具有典型意义的单词。如 numberofcycle 可以简写为cyclenumber。

4)去掉无用的单词后缀 ing、ed 等。如 pagingrequest 可以简写为pagreq。

5 )尽量使用标准或惯用的缩写形式,缩写应该保持一致性。如 serial peripheralinterface 可以简写为 spi。

6)部门已经完成函式的变量名称, 如果没有特别原因, 发展人员延续使用以增加可读性

2.在定义部分要加入注释来说明变量的含义。

3.变量的定义要在“.DATA”段中。

4.变量标识符的长度不超过16 个字符。

5.序会用到起码三种变量

1)全局变量名称前面不加任何修饰。

2)局部变量利用 wk00 , wk01 ….wk0n 来表示, 每个独立程序里面用到的Local var.可有效节省RAM。

3)中断局部变量中断里面用的 Interrupt local var.利用 Iwk00, Iwk01 以作为区隔(注意中断使用的变量必定要小心的跟主程序区隔开,不然影响系统稳定性相当大)。

例如:

.DATA

accbuf ds 1 ;全局变量

l_number ds 5 ;局部变量

6.位定义。程序多处会经常对寄存器的某一位进行操作,可以在变量定义时对需要用到的位进行定义,建议名称以”f_”开头。

7.临时工作寄存器的定义。程序中经常需要用到一些临时存储数据的寄存器,我们称之为临时工作寄存器,这些临时工作寄存器的命名方法为“wk”加上一个二位数字组成,这个数字可以从“00”开始随着需要定义的临时工作寄存器的数量的增加而增加。需要特别说明的是,临时工作寄存器的使用可以大量节省 RAM 空间,但是要注意相应的生命周期,必须在子程序退出之前,将空间释放以便其它子程序使用。

8.在中断处理程序中用到的寄存器,为了和一般的临时工作寄存器作以区分,可以在寄存器前面加英文字母“i”来命名。在使用时需要加以注意,不要和主程序中的变量复用。

例如:

.DATA

wk00 ds 1

wk01 ds 1

wk02 ds 1

iwk00 ds 1 ;中断中要用到的临时工作寄存器iwk01 ds 1 ;中断中要用到的临时工作寄存器…

.CODE

Mov a,r

Mov wk00,a

mov a,wk01

mov r,a

六、常量命名规则

1.常量的名称要采用有意义的英文单词大写缩写。

2.常量要定义在“.CONST”段中。

3.在定义部分要加入注释来说明常量含义。

4.量标识符的长度不超过16个字符。

5.系统寄存器中常用到的某些位可以再额外进行定义,但要有意义:

P_key1 EQU P1.0 ;P_ 打头表示为 Port 定义

Pm_key1 EQU P1m.0 ;Pm_ 打头表示为 Port 方向定义

七、标号命名规则

1.标号的名称要采用有意义的英文单词小写缩写。

2.子程序标号定义。在同一个子程序中,所有的标号应该有规律可寻。建议第一个标号为子程序名,下面所用到的标号用子程序名添加数字表示,从而便于今后程序的添加和修改。数字尽量使用两位数,在子程序的退出位置,数字一般为”90”。

例如:

在一段按键扫描程序中,如下的标号是不可取的。

Label:

LabelOK

LabelFail

LabelQuit

Labelfun:

LabelEnd:

Ret

(设计师要花许多精神命名label, 同时不容易看出子程序的结构关西,所以建

议在子程序里面别在花精神命名,都用号码表示)(详细的动作都用注解来说明)应该改为:

;***************************************************

;Sub-routine , Name : label

;***************************************************

Label:

If the condition fail then go to Label90

;program begin here

Label10:

;注解都写在这里

Label20:

;最后结尾结束的label都用90当做结尾

:有助于程序的阅读

Label90:

Ret

3.为了使程序的结构更加清晰,子程序的命名要尽量能显示出相互间的调用关系。由 main 主循环中直接调用的程序,要以“mn_”作为标号的开头,下面仅列出一些常用的子程序名称,其它类似情况可同样处理。

mn_app ;系统应用程序

mn_intgnd ;中断与主程序之间的界面子程序

mn_key ;按键扫描子程序

mn_lcd ;LCD 显示子程序

mn_led ;LED 显示子程序

mn_tone ;声音处理子程序

mn_epp ;EEPROM 读写操作

mn_bio ;基本输入/输出控制

mn_adc ;ADC 输入及处理

mn_debug ;debug 处理程序

4.程序的几个常用入口地址命名如下:

复位入口: reset

中断入口: isr

主程序入口: main

例如:

org 0

jmp reset

org 8

jmp sr ;ISR(Interrupt Service Routine)

org 10

;有效程序开始地址

reset:

;进入主程序前的一些准备工作(预处理)

premain:

;主程序循环圈

main:

Jmp main

八、文件名的命名规则及文件分割

1.在一个项目中要包括两种文件:源文件和头文件。源文件是程序体,扩展名为“ .asm ”,头文件包括了变量、常量、宏命令的定义,扩展名为”.inc”。

2.头文件的命名

头文件用三个不同的文件来分别定义常量、变量、宏命令,其命名方法如下:常量定义文件: xxx_equ.inc

变量定义文件: xxx_ram.inc

宏命令定义文件: xxx_macro.inc

其中,xxx 表示项目的名称。

例如:

作一个电话机的完整程序,头文件可如下定义:

常量定义文件: phone_equ.inc

变量定义文件: phone_ram.inc

宏命令定义文件: phone_macro.inc

3.源文件分为主文件、子文件。主文件包括了项目的主程序,它描述了芯片信息、CODEOPTION 信息及项目包含的其它子文件模块。子文件是由各个子程序模块组

成,功能相近的子程序要放在一个文件中,文件名可以用

“项目名+模块功能的缩写+扩展名”表示。下面列举一些常用的文件名:

主程序文件: xxx_main.asm

常用的子文件定义:

中断服务程序模块: xxx_int.asm

进程处理模块: xxx_pro.asm

系统处理程序: xxx_sys.asm

按键处理模块: xxx_key.asm

LCD显示模块: xxx_lcd.asm

其中,xxx 表示项目的名称。

九、标准程序模块

常用功能模块尽量采用附件提供的标准程序,如果无法使用标准的程序模块,那么所编写的程序一定要符合规范要求。所提供的标准程序如下,详细的源代码在附录中。

1. mn_key ;单键扫描子程序

2. mn_mulkey ;多键处理子程序

3. mn_tone ;声音处理子程序

4. mn_lcd ;LCD 显示子程序

5. mn_i2c ;I2C 操作子程序

6. mn_sio ;SIO 操作子程序

7. mn_1wire ;单总线操作子程序

8. mn_uart ;UART 子程序

9. wr_fifo ;写 FIFO

10. rd_fifo ;读 FIFO

11. ram2ram ;RAM 到 RAM 的数据传递

12. rom2ram ;ROM 到 RAM 的数据传递

13. math ;基本运算程序

实例说明

1.初始化

1)当程序上电复位时,一个完整的用户寄存器初始化或清零动作是非常重要的,否则容易造成程序执行的不确定性。

例如:

pre_clrRAM:

b0mov y,#0 ;清 RAM bank0

b0mov z,#48

@@:

Clr @yz

decms z

jmp @b

clr @yz

ret

2) 系统寄存器必须进行初始化,比如说 I/O 口方向和输出电平等。需要特别说明的是输出口的初始化必须按照下列顺序来处理:

(1) 设定相应 I/O 口输出高低电平

(2) 将相应 I/O 口为输出口如此可确保 MCU 的 I/O 口从输入模式转为输出模式时不会有脉冲的存在。而在 I/O 口控制频繁变化(如通信)时更要引起注意。

例如:

(3) mov a,# 11111111b

;如果 p1.0 和 p1.1 原来为输入高电平,当直接切换为输出方式时会有高电平脉冲的输出,而这不是所希望的。

b0mov p2m,a

mov a,# 11111100b

b0mov p2,a

(4) mov a,#00001100b

b0mov p2,a

;这样处理 p1.0 和 p1.1 就避免了高电平脉冲的输出

mov a,#11111111b ;

b0mov p2m,a

开机时后IO toggle的作法:

利用暂时没有用到的IO 做 toggle 可有效观察以下几点

1) 系统是否正常开机

2) 是否发生 reset or watchdog reset 现象

3) 程序是否重头运行

观察IO toggle pulse width 可以了解 Internal RC频率的准确性或是协助调整外部RC数值

以上方法可以有效协助量产生产问题

开机时后 Test Mode 的作法:

Test Mode 必须在开机时后按下某些组合按键同时通过de-bounce 才可进入test mode

2.按键处理

1)一般来说key的处理是所有程序的基础教科书里面所教导的key处理观念大多以delay 循环与多次检查来处理弹跳事件,但是此种方法由于导入delay 循环大大降低系统实时性,而大多使用者都没有警觉此问题依然延续此观念设计 key scan and de-bounce 技巧,此份文件详细叙述key处理观念。

2)家电产品中经常用到抗干扰的测试EFT ,会从电源端打入噪声测试系统抗噪声能力, 如果 key 处理不好会有key误动作产生,一般使用者会在key scan 地方加入电容以减低此问题的产生,但是此方法还是无法完全避免此问题同时还增加硬件成本,这里提出的de-bounce 观念可以完全解决此问题。

3)按键处理很多程序员都会将系统的程序设计与key程序结合没有分开结构,这造成很多程序就以key程序变成程序主体来运行,这里提出将 key 动作得出的 keycode 到 fifo(first in first out)中,使得AP系统得以在有空闲的时候才处理 key code 动作 ,程序架构自然形成。

4)一般来说 key 处理都只侦测key down ,但是在某些系统确有key down and keyup 的要求,这方面可以透过 key in buffer 的储存new/old buffer XOR 比对得到key event,更深一层的技巧侦测多按键处理更是需要利用 new/old

51单片机课程设计

课程设计说明书
课程设计名称






学生姓名
指导教师
单片机原理及应用课程设计 电子信息工程 140405 20141329 李延琦 胡黄水
2016 年 12 月 26 日

课程设计任务书
课程设计 题目
酒精测试仪
起止日期
2016 年 12 月 26 日— 2017 年 1 月 6 日
设计地点
计算机科学与工程学 院单片机实验室 3409
设计任务及日程安排: 设计任务:分两部分: (一)、设计实现类:进行软、硬件设计,并上机编程、联线、调试、 实现; 1.电子钟的设计 2.交通灯的设计 3.温度计的设计 4.点阵显示 5.电机调速 6.电子音乐发声(自己选曲) 7.键盘液晶显示系统 (二)、应用系统设计类:不须上机,查资料完成软、硬件设计画图。 查资料选定题目。 说明:第 1--7 题任选其二即可。(二)里题目自拟。 日程安排: 本次设计共二周时间,日程安排如下: 第 1 天:查阅资料,确定题目。 第 2--4 天:进实验室做实验,连接硬件并编写程序作相关的模块实验。 第 5--7 天:编写程序,并调试通过。观察及总结硬件实验现象和结果。 第 8--9 天:整理资料,撰写课程设计报告,准备答辩。 第 10 天:上交课程设计报告,答辩。 设计报告要求:
1. 设计报告里有两个内容,自选题目内容+附录(实验内容),每 位同学独立完成。 2. 自选题目不须上机实现,要求能正确完成硬件电路和软件程序 设计。内容包括: 1) 设计题目、任务与要求 2)硬件框图与电路图 3) 软件及流程图 (a)主要模块流程图 (b)源程序清单与注释 4) 总结 5) 参考资料 6)附录 实验上机调试内容
注:此任务书由指导教师在课程设计前填写,发给学生做为本门课程设计 的依据。

MCS-51系列单片机程序的设计论文一

MCS-51系列单片机程序的设计论文 程序设计是单片机开发最重要的工作,程序设计就是利用单片机的指令系统,根据应用系统(即目标产品)的要求编写单片机的应用程序,其实我们前面已经开始这样做过了,这一课我们不是讲如何来设计具体的程序,而是教您设计单片机程序的基本方法。不过在讲解程序设计是单片机开发最重要的工作,程序设计就是利用单片机的指令系统,根据应用系统(即 目标产品)的要求编写单片机的应用程序,其实我们前面已经开始这样做过了,这一课我们不是讲如何 来设计具体的程序,而是教您设计单片机程序的基本方法。不过在讲解之前还是有必要先了解一下单片 机的程序设计语言。 一.程序设计语言 这里的语言与我们通常理解的语言是有区别的,它指的是为开发单片机而设计的程序语言,如果 您没有学过程序设计可能不太明白,我给大家简单解释一下,您知道微软的VB,VC 吗?VB,VC 就是为 某些工程应用而设计的计算机程序语言,通俗地讲,它是一种设计工具,只不过这种工具是用来设计计 算机程序的。要想设计单片机的程序当然也要有这样一种工具(说设计语言更确切些),单片机的设计 语言基本上有三类: 1.完全面向机器的机器语言 机器语言就是能被单片机直接识别和执行的语言,计算机能识别什么?以前我们讲过--是数字“0” 或“1”,所以机器语言就是用一连串的“0”或“1”来表示的数字。比如:MOV A,40H;用机器语言 来表示就是11100101 0100000,很显然,用机器语言来编写单片机的程序不太方便,也不好记忆,我 们必须想办法用更好的语言来编写单片机的程序,于是就有了专门为单片机开发而设计的语言: 2.汇编语言 汇编语言也叫符号化语言,它使用助记符来代替二进制的“0”和“1”,比如:刚才的MOV A, 40H 就是汇编语言指令,显然用汇编语言写成的程序比机器语言好学也好记,所以单片机的指令普遍采 用汇编指令来编写,用汇编语言写成的程序我们就叫它源程序或源代码。可是计算机不能识别和执行用 汇编语言写成的程序啊?怎么办?当然有办法,我们可以通过“翻译”把源代码译成机器语言,这个过 程就叫做汇编,汇编工作现在都是由计算机借助汇编程序自动完成的,不过在以前,都是靠手工来做的。 值得注意的是,汇编语言也是面向机器的,它仍是一种低级语言。每一类计算机

51单片机控制LED灯程序设计

51单片机:LED灯亮灯灭程序设计 1.功能说明:控制单片机P1端口输出,使P1.0位所接的LED点亮,其他7只灯熄灭。 程序: 01: MOV A , #11111110B ; 存入欲显示灯的位置数据 02: MOV P1,A ; 点亮第一只灯 03: JMP $ ; 保持当前的输出状态 04: END ; 程序结束 2.功能说明:单片机P1端口接8只LED,点亮第1、3、4、6、7、8只灯。 程序:

01:START: MOV A , #00010010B ; 存入欲显示灯的位置数据 02:MOV P1,A ; 点亮灯 03:JMP START ; 重新设定显示值 04:END ; 程序结束 3.功能说明:单片机P1端口接8只LED,每次点亮一只,向左移动点亮,重复循环。 程序: 01:START: MOV R0, #8 ;设左移8次 02:MOV A, #11111110B ;存入开始点亮灯位置

03:LOOP: MOV P1, A ;传送到P1并输出 04:RL A ;左移一位 05:DJNZ R0, LOOP ;判断移动次数 06:JMP START ;重新设定显示值 07:END ;程序结束 4.功能说明:单片机P1端口接8只LED,每次点亮一只,向右移动点亮,重复循环。 程序: 01:START: MOV R0, #8 ;设右移8次

02:MOV A, #01111111B ;存入开始点亮灯位置03: LOOP: MOV P1, A ;传送到P1并输出 04: ACALL DELAY ;调延时子程序05: RR A ;右移一位 06: DJNZ R0, LOOP ;判断移动次数07: JMP START ;重新设定显示值08: DELAY: MOV R5,#50 ; 09:DLY1: MOV R6,#100 ; 10: DLY2: MOV R7,#100 ;

51单片机DIY做PLC编程精编版

51单片机DIY做PLC编程 有朋友想定制一个净水机控制器,有一些独特的功能要增加,但是商品控制板没有这样的功能,问我能否做一个,我觉得单片机完全能满足这种简单的控制需要,上手开始编程序时候突然感到,用PLC逻辑编这种功能是非常简单轻松的,而如果用汇编或C编却感觉有点棘手,编程效率不高,所以想为何不在单片机上实现PLC的逻辑呢? 上网搜索尝试看能否找到合适的程序下载来稍微改改就能用的呢?方案几年前就有了,实际上是利用三菱的低档PLC编程软件编辑好梯形图,存盘后用专用的格式转换工具转换成HEX单片机烧写文件烧进去,尝试下载三菱PLC工具软件,但是在我的WIN7-64位系统上不能正常工作,好容易换了系统装好开发工具,但是初次上手这款开发工具,界面挺复杂的,懒得研究各个按钮的使用,由于是单片机的硬件,对于程序的编制和转换有很多限制条件,否则是转换不成功的,嫌麻烦,放弃! 某宝倒是有百元PLC板出售,但是为了这么个简单的东西专门买个全功能板子有点浪费,而且其编程软件仍然是三菱的盗版软件,算了,再想办法把。 由于工作中经常接触PLC程序,对其工作原理也略知一二,网上也有相关的说明介绍,其实就是三个主要步骤,第一步扫描IO输入,第二步执行逻辑,第三步输出逻辑到IO,很简单的,最早PLC也是用单片机实现的,我为何不用汇编在51上搭建一个架构,简单的逻辑编制进去就能运转呢? 其中逻辑执行步骤还是有点意思的,需要把PLC逻辑翻译成单片机的汇编语言执行,这块开始也没有把握,后来搜索到一篇百度文章,介绍了一下三菱PLC逻辑是如何翻译成汇编的,我看了下估计其实是利用反汇编工具把HEX反编译成的ASM代码,并不清晰明了,而且还带着反汇编时候的行号,仅供参考了。 搜索结果中也有几篇论文,涉及到在51单片机上实现PLC逻辑的内容,但是那些论文都是充数的,仅仅几个IO逻辑,没有什么定时器,计数器功能的体现,哎!仅供参考! 看来这个PLC系统还是需要自己写了!OK!既然决定自己重写,那就开工吧!利用春节休假时间,编制了如下ASM51汇编PLC代码: 代码主要架构如下: 1、IO定义部分:根据所使用的单片机IO口数量,任意指定多少个I多少个O,那几个脚是I,哪几个是O都可以任意指定,在这个51系统里面设计了最大32个I,32个O,占用64个位寻址区域,其实用不到那么多,也可以分配给其它需要的标志位用,因为51系统总可位寻址地址只有128位,需要仔细分配.

51单片机C语言程序设计复习资料

2013-2014学年上期51单片机C语言程序设计重修复习提纲考试方式:闭卷考试。 考试题型: 填空题(每空1分,共18分);单项选择题(每空2分,共18分);问答及计算题(每题4分,共16分);编程及程序阅读题(5小题,共48分)。 考试分数: 卷面成绩70%+平时成绩15%+实验成绩15%,未缺席、无课堂违纪、作业全交且认真完成的同学平时成绩可获得满分,缺席一次平时成绩扣30分,实验好评次数3次以上且实验报告全优的同学实验成绩可得满分,实验缺席一次扣30分。缺席实验和旷课共3次以上者,无考试资格。 考试时间: 18周周一(12月30日)下午14:00:16:00,考试地点:具体考室另行通知希望大家认真复习,认真听讲,不懂就问,考试成绩不及格允许查卷,如查卷卷面批阅无误成绩不做更改。 编程题为实验或实验类似的题目有3题,其余2题也取自课堂讲授例题,请务必认真复习。第一章单片机概述及单片机知识回顾 掌握什么是单片机、单片机的应用、常见单片机类型、十进制、十六进制、二进制数制转换知识。掌握单片机的硬件组成、CPU的结构、程序计数器PC的功能、存储器结构、机器周期的计算、会画出单片机的最小系统电路图及回答单片机最小系统的组成。 第二章C51语言程序设计基础(本章填空题和选择题比重较大请务必认真复习)掌握C51语言进行软件开发与汇编语言相比的优点、掌握C51的数据类型、特殊功能位的定义、C51的基本运算(位运算重点复习)、数组的定义、C51的结构及函数。 第三章AT89S51片内并行端口及编程(本章有编程题) 掌握P0-P3并行端口的特点,会开关量检测及流水灯程序的编程。 第四章AT89S51单片机的中断系统(本章有编程题) 掌握中断系统的结构、中断请求响应被满足的条件、外部中断的触发选择方式、外部中断的使用与编程。 第五章AT89S51单片机的定时器/计数器(本章有编程器) 掌握定时器的结构,TOMD及TCON的使用,定时器方式0和方式1的特点、会计算定时器初值,会用定时器中断产生PWM波形,会用定时器对外部事件进行计数。 第六章AT89S51单片机的串行口(本章有计算题) 掌握串行通信的基础知识(课本没有的内容请参照课堂讲授笔记或PPT)、串行口的四种工作方式的特点、会计算奇偶校验码、会根据波特率计算T1的初值。 第七章AT89S51单片机与输入/输出外设接口(本章有编程题) 掌握数码管动态显示的原理、掌握矩阵式键盘的原理与编程(矩阵键盘编程必考,但不会考4X4键盘)。 第八章AT89S51单片机与D/A与A/D转换器的接口(本章有编程题) 掌握AD与DA转换的接口、ADC和DAC的技术指标、常用AD和DA转换器。掌握ADC0809和TLC2543的使用与编程(2器件其中之一有编程题)。 第九章AT89S51单片机应用系统与调试(本章有编程题) 掌握单片机应用系统的软件抗干扰方法。

基于51单片机秒表的程序设计[1]

基于51单片机秒表的程序设计 1.设计目的: (1)利用单片机定时器中断和定时器计数方式实现秒、分定时。 (2)通过LED显示程序的调整,熟悉8155与8051,8155与LED的接口技术,熟悉LED动态显示的控制过程。 (3)通过键盘程序的调整,熟悉8155与矩阵式键盘的接口技术,熟悉键盘扫描原理。 (4)通过阅读和调试简易秒表整体程序,学会如何编制含LED动态显示、键盘扫描和定时器中断等多种功能的综合程序,初步体会大型程序的编制和调试技巧。 2.设计步骤与要求 (1)要求:以8位LED右边2位显示秒,左边6位显示0,实现秒表计时显示。以4×4矩阵键盘的KE0、KE1、KE2等3键分别实现启动、停止、清零等功能。 (2)方法:用单片机定时器T0中断方式,实现1秒定时;利用单片机定时器1方式3计数,实现60秒计数。用动态显示方式实现秒表计时显示,用键盘扫描方式取得KE0、KE1、KE2的键值,用键盘处理程序实现秒表的启动、停止、清零等功能。 (3)软件设计:软件整体设计思路是以键盘扫描和键盘处理作为主程序,LED动态显示作为子程序。二者间的联系是:主程序查询有无按键,无按键时,调用二次LED动态显示子程序(约延时8ms)后再回到按键查询状态,不断循环;有按键时,LED动态显示子程序作为按键防抖延时被连续调用二次(约延时16ms),待按键处理程序执行完后,再回到按键查询状态,同时兼顾了按键扫描取值的准确性和LED动态显示的稳定性。秒定时采用定时器T0中断方式进行,60秒计数由定时器1采用方式3完成,中断及计数的开启与关闭受控于按键处理程序。由上述设计思路可设计出软件流程图如图1.1所示。 (5)程序编制:编程时置KE0键为“启动”,置KE1键为“停止”,置KE2键为“清零”,因按键较少,在处理按键值时未采用散转指令“JMP”,而是采用条件转移指令“CJNE”,每条指令后紧跟着一条无条件跳转指令“AJMP”,转至相应的按键处理程序,如不是上述3个按键值则

51单片机C语言学习知识编程基础学习知识及其实例

基础知识:51单片机编程基础 第一节:单数码管按键显示 第二节:双数码管可调秒表 第三节:十字路口交通灯 第四节:数码管驱动 第五节:键盘驱动 第六节:低频频率计 第七节:电子表 第八节:串行口应用 基础知识:51单片机编程基础 单片机的外部结构: 1. DIP40双列直插; 2. P0,P1,P2,P3四个8位准双向I/O引脚;(作为I/O输入时,要先输出高电平) 3. 电源VCC(PIN40)和地线GND(PIN20); 4. 高电平复位RESET(PIN9);(10uF电容接VCC与RESET,即可实现上电复位) 5. 内置振荡电路,外部只要接晶体至X1(PIN18)和X0(PIN19);(频率为主频的12倍) 6. 程序配置EA(PIN31)接高电平VCC;(运行单片机内部ROM中的程序) 7. P3支持第二功能:RXD、TXD、INT0、INT1、T0、T1 单片机内部I/O部件:(所为学习单片机,实际上就是编程控制以下I/O部件,完成指定任务) 1. 四个8位通用I/O端口,对应引脚P0、P1、P2和P3; 2. 两个16位定时计数器;(TMOD,TCON,TL0,TH0,TL1,TH1) 3. 一个串行通信接口;(SCON,SBUF) 4. 一个中断控制器;(IE,IP) 针对AT89C52单片机,头文件AT89x52.h给出了SFR特殊功能寄存器所有端口的定义。 C语言编程基础: 1. 十六进制表示字节0x5a:二进制为01011010B;0x6E为01101110。 2. 如果将一个16位二进数赋给一个8位的字节变量,则自动截断为低8位,而丢掉高8位。 3. ++var表示对变量var先增一;var—表示对变量后减一。 4. x |= 0x0f;表示为x = x | 0x0f; 5. TMOD = ( TMOD & 0xf0 ) | 0x05;表示给变量TMOD的低四位赋值0x5,而不改变TMOD的高 四位。 6. While( 1 ); 表示无限执行该语句,即死循环。语句后的分号表示空循环体,也就是{;}

基于51单片机的C语言程序设计资料

基于51单片机的C语言程序设计实训100例 第01 篇基础程序设计 01 闪烁的LED /* 名称:闪烁的LED 说明:LED按设定的时间间隔闪烁 */ #include #define uchar unsigned char #define uint unsigned int sbit LED=P1^0; //延时 void DelayMS(uint x) { uchar i; while(x--) { for(i=0;i<120;i++); } } //主程序 void main() { while(1) { LED=~LED; DelayMS(150); } } 02 从左到右的流水灯 /* 名称:从左到右的流水灯 说明:接在P0口的8个LED 从左到右循环依次点亮,产生走 马灯效果 */ #include #include #define uchar unsigned char #define uint unsigned int

//延时 void DelayMS(uint x) { uchar i; while(x--) { for(i=0;i<120;i++); } } //主程序 void main() { P0=0xfe; while(1) { P0=_crol_(P0,1); //P0的值向左循环移动 DelayMS(150); } } 03 8只LED左右来回点亮 /* 名称:8只LED左右来回点亮 说明:程序利用循环移位函数_crol_和_cror_形成来回滚动的效果*/ #include #include #define uchar unsigned char #define uint unsigned int //延时 void DelayMS(uint x) { uchar i; while(x--) { for(i=0;i<120;i++); } } //主程序 void main() { uchar i; P2=0x01; while(1) {

51单片机时钟程序设计

51单片机时钟程序设计 一、任务 设计数字时钟显示电路,能够显示时分秒。电路框图如图所示。 1:时钟产生→ 2:分秒产生→3:数码显示 二、要求 (1)正常显示时间的时分秒; (2)整点提示; (3)初始时间时分秒设置。 (4)设计报告应包括系统总体框图、完整的电路原理图、主要的测试结果。 朋友以下是本人历时一个月殚精竭虑自主开发的一个8位51单片机时钟程序,望吾之兄弟姐妹习之,此程序乃采用一键控制,通过感知按下键持续时间的长短来进行调整时间,闹铃,6只共阳数码管输出显示,此外还包括整点铃声功能,在看程序之前我先交代一下运行该程序的硬件要求:12M晶振,P0端口驱动显示,P2.0到P2.5控制显示扫描,P2.7输出铃声,注意:铃声功放三极管应采用pnp管。以下是该程序: ORG 00H SETB TR0 JMP START ORG 000BH LJMP T0 START: MOV IE,#82H MOV TMOD,#01H MOV DPTR,#TAB MOV SP,#60H MOV 20H,#0 MOV R0,#0 MOV R1,#0 MOV R2,#0 MOV R3,#0 MOV R4,#0 MOV R5,#0 MOV R6,#0 MOV R7,#0 MOV 50H,#0 MOV 51H,#0 MOV 52H,#0 MOV 53H,#0 MOV 54H,#0 MOV 55H,#0 MOV A,TL0 ADD A,0B5H

MOV TL0,A MOV TH0,#3CH LOOP: ANL 20H,#08H UNSV: MOV R1,#0 LCALL DISPLAY JB 03H,LOP1 LCALL SOUND LCALL HDLY LOP1: MOV P3,#0FEH ;按键监视MOV A,P3 CJNE A,#0FEH,LOP2 MOV R1,#0 JMP LOOP LOP2: MOV R1,#2 ;误按判断LOP3: LCALL HD DJNZ R1,LOP3 JNB 04H,LOOP CLR 04H LOP4: INC R1 MOV C,00H ;调秒 CPL C MOV 00H,C LCALL HDLY CJNE R1,#40,LOP5 JMP LOOP LOP5: JNB 05H,LOP4 CLR 05H MOV R1,#0 LCALL HD CLR 00H JB 04H,TF MOV R2,#0 MOV R3,#0 JMP LOP4 TF: CLR 04H LOP6: INC R1 MOV C,01H ;调分 CPL C MOV 01H,C LCALL HDLY CJNE R1,#40,LOP7 JMP LOOP

51单片机C语言程序设计经典案例

项目三C51程序设计语言基础 任务1 C51程序的识读 1.C51程序结构 例3-1 P_test /********************* //注释,还可用//注释掉一行 File name:P_test.c Chip name:STC89C51RC Clock frequency:1.20MHz ***********************/ #include “reg52.h”//预处理命令,文件包含预处理命令,后缀名都是.h,标准的MCS-51单片机头文件为”reg51.h”,STC89系列单片机头文件为”reg52.h” #define unit unsigned int //宏定义预处理命令 sbit BZ=P3`7 ; sbit key=P1`0; void delay(unit ms) { unit i; while( ms --) { for(i=0;i<120;i++); } } void main(void) { while(1) { if(key==0) { BZ=0x0; delayms(10); BZ=0x1; delayms(50); P0=0xFF; } else { P0=~P0; delayms(500); } } } 2.C51的数据类型

位变量型bit 字符型无符号字符型unsigned char 有符号字符型signed char C51的数据类型整数型无符号整数型unsigned int 基本类型有符号整数型signed int 长整数型无符号长整数型unsigned long int 有符号长整数型signed long int 实数型(浮点型)单精度浮点型float 双精度浮点型double 数组类型array 结构体类型struct 构造类型共用体union 枚举enum 指针类型 空类型(void) 表3-1 C51基本数据类型的长度和值域 类型长度/bit 长度/byte 范围 位变量型bit 1 0 ,1 无符号字符型unsigned char 8 单字节0-255 有符号字符型signed char 8 单字节-128-127 无符号整数型unsigned int 16 双字节0-65536 有符号整数型signed int 16 双字节-32768-32767 无符号长整数型unsigned long int 32 四字节 有符号长整数型signed long int 32 四字节 单精度浮点型float 32 四字节 双精度浮点型double 32 四字节 一般指针类型24 三字节 3.C51的标识符和关键字 标识符是由字母、数字和下划线组成的字符串,第一个字符必须是字母或下划线,不超过32个字符。 表3-2 C51中的关键字 关键字用途说明 auto 存储种类声明用来声明局部变量 bdata 存储器类型说明可位寻址的内部数据存储器 break 程序语句退出最内层循环体 bit 位变量语句位变量的值是1(true)或0(flase)case 程序语句switch语句中的选择项 char 数据类型的声明单字节整数型或字符型数据

51单片机C语言程序设计经典案例

项目三C51 程序设计语言基础任务 1 C51 程序的识读 1. C51 程序结构 例3-1 P_test /********************* // 注释,还可用//注释掉一行 Chip name:STC89C51RC Clock frequency:1.20MHz ***********************/ #inelude “eg52.h”//预处理命令,文件包含预处理命令,后缀名都是.h,标准的MCS-51单片机头文件为”reg51.h”,STC89 系列单片机头文件为”reg52.h” #define unit unsigned int //宏定义预处理命令 sbit BZ=P3'7 ; sbit key=P1'0; void delay(unit ms) { unit i; while( ms --) { for(i=0;i<120;i++); } } void main(void) { while(1) { if(key==0) { BZ=0x0; delayms(10); BZ=0x1; delayms(50); P0=0xFF; } else { P0=~P0; delayms(500); } } } 2. C51 的数据类型

位变量型bit 字符型无符号字符型un sig ned char 有符号字符型s ig ned char C51的数据类型 整数型J 无符号整数型un sig ned int 有符号整数型sig ned int 长整数型无符号长整数型un sig ned long int 有符号长整数型sig ned long int 实数型(浮点型)单精度浮 点型float 双精度浮点型double 「数组类型array 结构体类型struct 构造类型共用体union 枚举enum 指针类型 空类型(void) 类型长度/bit长度/byte范围 位变量型bit10,1 无符号字符型un sig ned char8单字节0-255 有符号字符型sig ned char8单字节-128-127 无符号整数型un sig ned int16双字节0-65536 有符号整数型sig ned int16双字节-32768-32767 无符号长整数型un sig ned long int32四字节 有符号长整数型sig ned long int32四字节 单精度浮点型float32四字节 双精度浮点型double32四字节 一般指针类型24三字节 3. C51的标识符和关键字 标识符是由字母、数字和下划线组成的字符串,第一个字符必须是字母或下划线,不超过32个字符。 关键字用途说明 auto存储种类声明用来声明局部变量 bdata存储器类型说明可位寻址的内部数据存储器 break程序语句退出最内层循环体 bit位变量语句位变量的值是 1 (true )或0 (flase) case程序语句switch语句中的选择项 char数据类型的声明单字节整数型或字符型数据

51单片机C语言编程实例

基础知识:51单片机编程基础 单片机的外部结构: 1.DIP40双列直插; 2.P0,P1,P2,P3四个8位准双向I/O引脚;(作为I/O输入时,要先输出高电平) 3.电源VCC(PIN40)和地线GND(PIN20); 4.高电平复位RESET(PIN9);(10uF电容接VCC与RESET,即可实现上电复位) 5.内置振荡电路,外部只要接晶体至X1(PIN18)和X0(PIN19);(频率为主频的 12倍) 6.程序配置EA(PIN31)接高电平VCC;(运行单片机内部ROM中的程序) 7.P3支持第二功能:RXD、TXD、INT0、INT1、T0、T1 单片机内部I/O部件:(所为学习单片机,实际上就是编程控制以下I/O部件,完成指定任务) 1.四个8位通用I/O端口,对应引脚P0、P1、P2和P3; 2.两个16位定时计数器;(TMOD,TCON,TL0,TH0,TL1,TH1) 3.一个串行通信接口;(SCON,SBUF) 4.一个中断控制器;(IE,IP) 针对AT89C52单片机,头文件AT89x52.h给出了SFR特殊功能寄存器所有端口的定义。 C语言编程基础: 1.十六进制表示字节0x5a:二进制为01011010B;0x6E为01101110。 2.如果将一个16位二进数赋给一个8位的字节变量,则自动截断为低8位,而丢掉 高8位。 3.++var表示对变量var先增一;var—表示对变量后减一。 4.x |= 0x0f;表示为x = x | 0x0f; 5.TMOD = ( TMOD & 0xf0 ) | 0x05;表示给变量TMOD的低四位赋值0x5,而不改变 TMOD的高四位。 6.While( 1 ); 表示无限执行该语句,即死循环。语句后的分号表示空循环体,也就是 {;} 在某引脚输出高电平的编程方法:(比如P1.3(PIN4)引脚) 代码

51单片机C语言程序设计Proteus仿真实训 2

基于8051+Proteus仿真案例 第01 篇基础程序设计01 闪烁的LED /* 名称:闪烁的LED 说明:LED按设定的时间间隔闪烁 */ #include #define uchar unsigned char #define uint unsigned int sbit LED=P1^0; //延时 void DelayMS(uint x) { uchar i; while(x--) { for(i=0;i<120;i++); } } //主程序 void main() { while(1) { LED=~LED; DelayMS(150); } } 02 从左到右的流水灯 /* 名称:从左到右的流水灯 说明:接在P0口的8个LED 从左到右循环依次点亮,产生走 马灯效果 */ #include #include #define uchar unsigned char #define uint unsigned int

//延时 void DelayMS(uint x) { uchar i; while(x--) { for(i=0;i<120;i++); } } //主程序 void main() { P0=0xfe; while(1) { P0=_crol_(P0,1); //P0的值向左循环移动 DelayMS(150); } } 03 8只LED左右来回点亮 /* 名称:8只LED左右来回点亮 说明:程序利用循环移位函数_crol_和_cror_形成来回滚动的效果*/ #include #include #define uchar unsigned char #define uint unsigned int //延时 void DelayMS(uint x) { uchar i; while(x--) { for(i=0;i<120;i++); } } //主程序 void main() { uchar i; P2=0x01; while(1) {

基于51单片机的C语言程序设计

基于51单片机的C语言程序设计

基于51单片机的C语言程序设计实训100例 第01 篇基础程序设计 01 闪烁的LED /* 名称:闪烁的 LED 说明:LED按设定 的时间间隔闪烁 */ #include #define uchar unsigned char #define uint unsigned int sbit LED=P1^0; //延时 void DelayMS(uint x) { uchar i; while(x--) { for(i=0;i<120;i++); }

} //主程序 void main() { while(1) { LED=~LED; DelayMS(150); } } 02 从左到右的 流水灯 /* 名称:从左 到右的流水灯 说明:接在P0口的8个LED从左到右循环依次点亮,产生走马灯效果 */ #include #include #define uchar unsigned char

#define uint unsigned int //延时 void DelayMS(uint x) { uchar i; while(x--) { for(i=0;i<120;i++); } } //主程序 void main() { P0=0xfe; while(1) { P0=_crol_(P0,1); //P0的值向左循环移动 DelayMS(150); } } 03 8只LED左右来回点亮

/* 名称:8只LED左右来回点亮 说明:程序利用循环移位函数_crol_和_cror_形成来回滚动的效果 */ #include #include #define uchar unsigned char #define uint unsigned int //延时 void DelayMS(uint x) { uchar i; while(x--) { for(i=0;i<120;i++); }

51单片机C语言编程100例

目录 实例3:用单片机控制第一个灯亮 (3) 实例4:用单片机控制一个灯闪烁:认识单片机的工作频率 (3) 实例5:将 P1口状态分别送入P0、P2、P3口:认识I/O口的引脚功能 (4) 实例6:使用P3口流水点亮8位LED (4) 实例7:通过对P3口地址的操作流水点亮8位LED (5) 实例8:用不同数据类型控制灯闪烁时间 (6) 实例9:用P0口、P1 口分别显示加法和减法运算结果 (8) 实例10:用P0、P1口显示乘法运算结果 (8) 实例11:用P1、P0口显示除法运算结果 (9) 实例12:用自增运算控制P0口8位LED流水花样 (9) 实例13:用P0口显示逻辑"与"运算结果 (10) 实例14:用P0口显示条件运算结果 (10) 实例15:用P0口显示按位"异或"运算结果 (10) 实例16:用P0显示左移运算结果 (10) 实例17:"万能逻辑电路"实验 (11) 实例18:用右移运算流水点亮P1口8位LED (11) 实例19:用if语句控制P0口8位LED的流水方向 (12) 实例20:用swtich语句的控制P0口8位LED的点亮状态 (12) 实例21:用for语句控制蜂鸣器鸣笛次数 (14) 实例22:用while语句控制LED (15) 实例23:用do-while语句控制P0口8位LED流水点亮 (16) 实例24:用字符型数组控制P0口8位LED流水点亮 (16) 实例25:用P0口显示字符串常量 (17) 实例26:用P0 口显示指针运算结果 (18) 实例27:用指针数组控制P0口8位LED流水点亮 (18) 实例28:用数组的指针控制P0 口8 位LED流水点亮 (19) 实例29:用P0 、P1口显示整型函数返回值 (20) 实例30:用有参函数控制P0口8位LED流水速度 (21) 实例31:用数组作函数参数控制流水花样 (22) 实例32:用指针作函数参数控制P0口8位LED流水点亮 (23) 实例33:用函数型指针控制P1口灯花样 (24) 实例34:用指针数组作为函数的参数显示多个字符串 (25) 实例35:字符函数ctype.h应用举例 (26) 实例36:内部函数intrins.h应用举例 (27) 实例37:标准函数stdlib.h应用举例 (27) 实例38:字符串函数string.h应用举例 (28) 实例39:宏定义应用举例2 (28) 实例40:宏定义应用举例2 (29) 实例41:宏定义应用举例3 (29) 实例42:用定时器T0查询方式P2口8位控制LED闪烁 (30) 实例43:用定时器T1查询方式控制单片机发出1KHz音频 (31) 实例44:将计数器T0计数的结果送P1口8位LED显示 (31)

51单片机脉冲产生程序设计

独立键盘控制输出脉冲信号 用51单片机用独立键盘控制输出4种频率:1Hz、2Hz、10Hz、50Hz,占空比为50%的脉冲信号。 #include<> #define uint unsigned int #define uchar unsigned char sbit d0=P1^0; sbit d1=P3^2; uint num=0,counter=0; void delay(uint x) { uint i,j; for(i=x;i>0;i--) for(j=110;j>0;j--); } void main() { d1=1; d0=1; d2=1; num=0; IT0=1; EX0=1; TMOD=0x01; TH0=(65536-1000)/256; TL0=(65536-1000)%256; EA=1; ET0=1; TR0=1; while(1) { } } void Int0() interrupt 0 { delay(10); if(d1==0) { d1=1; num++; if(num==4)

num=0; counter=0; } } void Timer0(void) interrupt 1 { TH0=(65536-1000)/256; TL0=(65536-1000)%256; counter++; if(num==0) { if(counter<=500) d0=0; if(counter>500) d0=1; if(counter==1000) counter=0; } if(num==1) { if(counter<=250) d0=0; if(counter>250) d0=1; if(counter==500) counter=0; } if(num==2) { if(counter<=50) d0=0; if(counter>50) d0=1; if(counter==100) counter=0; } if(num==3) { if(counter<=10) d0=0; if(counter>10) d0=1;

单片机C51程序设计课后习题答案

第一章 1. 给出下列有符号数的原码、反码和补码(假设计算机字长为8 位)。 +45 -89 -6 +112 答:【+45】原=00101101,【+45】反=00101101,【+45】补=00101101【-89】原=,【-89】反=,【-89】补= 【-6】原=,【-6】反=,【-6】补= 【+112】原=01110000,【+45】反=01110000,【+45】补=01110000 2. 指明下列字符在计算机内部的表示形式。 AsENdfJFmdsv120 答:41H 73H 45H 4EH 64H 66H 4AH 46H 6DH 64H 73H 76H 31H 32H 30H 3. 什么是单片机? 答:单片机是把微型计算机中的微处理器、存储器、I/O接口、定时器/计数器、串行接口、中断系统等电路集成到一个集成电路芯片上形成的微型计算机。因而被称为单片微型计算机,简称为单片机。 4. 单片机的主要特点是什么? 答:主要特点如下: 1) 在存储器结构上,单片机的存储器采用哈佛(Harvard)结构 2) 在芯片引脚上,大部分采用分时复用技术 3) 在内部资源访问上,采用特殊功能寄存器(SFR)的形式

4) 在指令系统上,采用面向控制的指令系统 5) 内部一般都集成一个全双工的串行接口 6) 单片机有很强的外部扩展能力 5. 指明单片机的主要应用领域。 答:单机应用:1) 工业自动化控制;2) 智能仪器仪表;3) 计算机外部设备和智能接口;4) 家用电器 多机应用:功能弥散系统、并行多机处理系统和局部网络系统。 第二章 1. MCS-51单片机由哪几个部分组成? 答:MCS-51单片机主要由以下部分组成的:时钟电路、中央处理器(CPU)、存储器系统(RAM和ROM)、定时/计数器、并行接口、串行接口、中断系统及一些特殊功能寄存器(SFR)。 2. MCS-51的标志寄存器有多少位,各位的含义是什么? 答:MCS-51的标志寄存器PSW有8位; D D D D D D D D 含义如下: C:进位或借位标志位。 AC:辅助进位或借位可标志位。 F0:用户标志位。是系统预留给用户自己定义的标志位。

LCD按键显示51单片机程序设计

#include #include #include #define uint unsigned int #define uchar unsigned char sbit lcdrs=P2^2; sbit lcdrw=P2^3; sbit lcde=P2^4; uchar num,key; int i,length1,length2,length3; uchar sting1[]={"0903010"}; uchar sting2[]={"hello"}; uchar sting3[]={"happy"}; uchar getkey(void); void delayms(uchar j); void delay1ms(uint time); void lcdinit(void); void lcdsendc(uchar c); void lcdsendd(uchar c); void lcdbusy(void); void jumpkey(uchar k); void delayms(uchar j) { uchar n,m; for(n=0;n

lcdsendc(0x06); delay1ms(200); lcdsendc(0x0c); delay1ms(200); } void lcdsendc(uchar c) { P1=c; lcdrs=0; lcdrw=0; lcde=0; lcde=1; } void lcdsendd(uchar c) { P1=c; lcdrs=1; lcdrw=0; lcde=0; lcde=1; } void lcdbusy() { uchar ma; lcdrs=0; lcdrw=1; lcde=1; ma=P1; if(ma&&0x80==0x80) delay1ms(1); }

51单片机秒表程序设计

湖北民族学院—信息工程学院—单片机综合实验报告 51单片机课程设计 题目秒表程序设计 专业能源工程及其自动化 班级 2012能源01 学号 1204180126 姓名颜亮 指导教师苏文静 学院名称电气信息学院 2012年 6 月 8 日

一、课题任务要求 用AT89C 51设计一个2位LED数码显示“秒表”,显示时间为00~99秒,每秒自动加一。即数码显示管在原先的计数上快速加一。 二、设计思路 1、使用单片机,设计秒表,能显示分分秒秒; 2、使用三个按键停止,开始,复位,其中“开始”按键当开关由上向下拨时开始计时,此时若再拨“开始”按键则数码管暂停;“清零”按键当开关由上向下拨时数码管清零,此时若再拨“开始”按键则又可重新开始计时; 3、使用液晶或数码管显示; 4、使用定时器中断。 三、硬件设计 3.1、单片机介绍 单片机:AT89C51是一种带4K字节闪存可编程可擦除只读存储器的低电压、高性能CMOS 8位微处理器。单片机的可擦除只读存储器可以反复擦除1000次。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。 AT89C51主要特性: ·与MCS-51 兼容 ·低功耗的闲置和掉电模式 ·4K字节可编程闪烁存储器 ·全静态工作:0Hz-24MHz ·寿命:1000写/擦循环 ·数据保留时间:10年 ·三级程序存储器锁定 ·128×8位内部RAM

·片内振荡器和时钟电路 ·32可编程I/O线 ·两个16位定时器/计数器 ·5个中断源 ·可编程串行通道 3.2管脚说明: VCC:供电电压。 GND:接地。 P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。当P1口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。 P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。 P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。 P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL 门电流。当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。 P3口也可作为AT89C51的一些特殊功能口。

相关主题
文本预览
相关文档 最新文档