单片机必会程序2
学习51单片机必写的几个程序

学习51单片机必写的几个程序
51 单片机偶完全自学的,因为想学的时候离学校开课还早得很。
学完了单片机,现在学校课也开完了,收获很大。
现将偶学习经验写出来,供大家交流。
1、因为有了C 语言和汇编语言的基础,加上模电学得不错。
微机原理也上了。
所以我只花了半天的时间把51 的引脚功能和内部结构搞清楚了。
偶认为学51 重要的就是搞清内部结构和地址空间。
2、仅用了几个小时简单看了一下51 的汇编指令和C 语法。
我个人认为学习程序语言的语法规则是很简单的,且各种语言之间都有共通的地方,有了汇编和某种高级语言的基础学其它语言应该能很快上手。
3、直接编程练习,软件硬件实现。
我的第一个程序是跑马灯程序。
这个会让你熟悉端口的用法,普通流程控制。
当然是C 语言写一个,汇编写一个,实现同样的功能。
我的第二个程序是电子钟。
这个程序会使你对中断有更深入的了解和学会中断的应用,包括外部中断(调整时间)的应用。
同样C 和汇编两种方法实现。
还会学会数码管的驱动,动态
扫描,查表编程等。
我的第三个程序DS1821 温度计
这个程序使我学习如何从一个不熟悉的器件的数据资料读取其时序图,用单片机来模拟其时序以实现对器件的操作。
同样用C 和汇编同时实现。
我的第四个程序128 乘以64 液晶显示程序。
这个程序会学会液晶显示原理,单片机数据口线的操作等。
同样两种语言实。
单片机学习第四章汇编语言程序设计

ORG START:CLR
MOV SUBB JC MOV XCH MOV NEXT: NOP SJMP END
1000H C A,60H A,61H NEXT A,60H A, 61H 60H,A
$
;0→CY
;做减法比较两数 ;若(60H)小,则转移
;交换两数
整理课件
【例4.6】将R2中的一位十六进制数转换为 ASCII码,结果仍存放于R2中。
MOV R0, #0 SJMP NEXT4 NEXT2:MOV R0,A DEC R0 NEXT4:MOV 31H,R0 SJMP $ END
;取X ;与5比较
;X<5,则转NEXT2 ; ;设10<X,Y=X十1
;与1l比较 ;x>10,则转NEXT4
;5≤X≤10,Y=0
;X<5,Y=X-1 ;存结果
MOV
@R0,A
;保存结果
SJMP $
;原地踏步
END
整理课件
【例4.2】假设两个双字节无符号数,分别存 放在R1R0和R3R2中,高字节在前,低字 节在后。编程使两数相加,用R2R1R0存放 和。 对多字节的加法,存在最高位的进位问题。 如果最高位有进位,则和的字节数要比加 数或被加数的字节数多一个。
经常用于定义一个地址表。Yi为双字节数据, 它可以为十进制或十六进制的数,也可以 为一个表达式。高位数在前,低位数在后。
整理课件
• 例如: ORG 1000H DATA:DW 3241H,1234H,78H 上述程序将对从1000H单元开始的6个单元 赋值,赋值情况如何呢? (1000H)=32H,(1001H)=41H, (1002H)=12H,(1003H)=34H, (1004H)=00H,(1005H)=78H。
stc单片机程序烧录方法

STC单片机程序烧录方法介绍STC单片机是一种常用的嵌入式系统开发工具,用于控制各种电子设备。
在使用STC单片机时,烧录程序是必不可少的一步。
本文将详细介绍STC单片机程序烧录的方法和步骤。
准备工作在进行STC单片机程序烧录之前,需要准备以下材料和工具: 1. STC单片机:根据具体需求选择合适的型号; 2. 烧录器:常用的烧录器有STC-ISP、STC-USBISP 等; 3. 程序文件:将要烧录到单片机中的程序文件,通常为HEX或BIN格式; 4. 连接线:用于连接单片机和烧录器的数据线; 5. 电源线:用于给单片机供电的电源线; 6. 电脑:用于烧录程序的电脑。
步骤下面将详细介绍STC单片机程序烧录的步骤:步骤一:连接硬件1.将烧录器插入电脑的USB接口,并确保烧录器驱动已正确安装;2.将单片机插入烧录器的插座中,确保插入方向正确;3.使用数据线将烧录器与单片机连接,确保连接牢固;4.使用电源线给单片机供电,确保电源稳定。
步骤二:打开烧录软件1.打开电脑上的烧录软件,常用的软件有STC-ISP、STC-PROG等;2.在软件中选择正确的单片机型号,以及烧录器的连接方式和端口号。
步骤三:导入程序文件1.在烧录软件中选择“打开”或“导入”按钮,导入要烧录的程序文件;2.确认程序文件的格式和路径是否正确。
步骤四:设置烧录参数1.在烧录软件中选择“设置”或“选项”按钮,设置烧录参数;2.根据具体需求设置芯片的时钟频率、烧录方式等参数。
步骤五:烧录程序1.在烧录软件中选择“烧录”或“开始”按钮,开始烧录程序;2.烧录过程中,烧录器会将程序文件中的数据逐个写入单片机的存储器中;3.等待烧录完成,并在软件中查看烧录结果。
步骤六:测试程序1.确认程序已成功烧录到单片机中后,断开烧录器与单片机的连接;2.将单片机与外部电路连接,并给单片机供电;3.测试程序的功能和性能,确保程序正常运行。
注意事项在进行STC单片机程序烧录时,需要注意以下事项: 1. 确保烧录器与单片机的连接正确,避免插反或接触不良; 2. 在烧录过程中,确保烧录器和单片机的供电稳定; 3. 在选择烧录软件和设置烧录参数时,确保与单片机型号和程序文件格式相匹配; 4. 在烧录过程中,不要断开烧录器与单片机的连接或供电; 5. 在测试程序时,注意观察和记录程序的运行情况,及时排除问题。
单片机汇编指令

单片机汇编指令单片机(Microcontroller)是一种集成了微处理器和其他外设的集成电路芯片,用于控制各种电子设备。
在单片机的开发过程中,编程是必不可少的一部分,而汇编语言是一种常用于单片机编程的低级语言。
汇编语言是一种和机器语言十分接近的编程语言,使用简单的助记符(Mnemonic)来代表机器指令,方便程序员进行编程。
在单片机开发中,汇编语言的指令集是非常重要的知识,掌握好单片机的汇编指令对于编写高效、性能优良的程序至关重要。
本文将介绍一些常见的单片机汇编指令,供大家参考和学习。
一、数据传输指令1. MOV 指令:将数据从一个存储器位置或寄存器传输到另一个存储器位置或寄存器。
例如:MOV A, B ;将B的值传送给A寄存器MOV R1, #20 ;将数值20传送给R1寄存器2. LDA 和 STA 指令:分别用于将数据从存储器加载到累加器和将累加器中的数据存储到存储器中。
例如:LDA 0x20 ;将地址为0x20的存储器单元的数据加载到累加器STA 0x30 ;将累加器中的数据存储到地址为0x30的存储器单元3. XCH 指令:用于交换两个存储器位置或寄存器的数据。
例如:XCH A, B ;交换A和B寄存器的值二、算术指令1. ADD 和 SUB 指令:分别用于将数据相加和相减。
例如:ADD A, B ;将A和B的值相加,并将结果存储到A寄存器SUB A, B ;将B的值从A中减去,并将结果存储到A寄存器2. INC 和 DEC 指令:分别用于将数据递增和递减。
例如:INC A ;将A的值递增1DEC A ;将A的值递减1三、逻辑指令1. AND、OR 和 XOR 指令:分别用于进行逻辑与、逻辑或和逻辑异或操作。
例如:AND A, B ;将A和B的值进行逻辑与操作,并将结果存储到A寄存器OR A, B ;将A和B的值进行逻辑或操作,并将结果存储到A寄存器XOR A, B ;将A和B的值进行逻辑异或操作,并将结果存储到A寄存器2. NOT 指令:用于对一个存储器位置或寄存器中的数据进行逻辑非操作。
单片机 80C51单片机的软件基础_2

单片机 80C51单片机的软件基础_2在现代电子技术领域,单片机扮演着至关重要的角色。
80C51 单片机作为其中的经典代表,其软件基础是我们深入理解和应用它的关键。
首先,让我们来了解一下 80C51 单片机的指令系统。
指令是单片机能够执行的基本操作命令,就如同我们日常做事的具体步骤。
80C51单片机的指令系统丰富多样,包括数据传送指令、算术运算指令、逻辑运算指令、控制转移指令等等。
数据传送指令用于在单片机内部的寄存器、存储器之间进行数据的移动。
比如说,将一个数值从一个寄存器传送到另一个寄存器,或者将存储单元中的数据读取到寄存器中。
算术运算指令则能实现加法、减法、乘法、除法等基本的数学运算。
这在处理各种数据计算的任务中是必不可少的。
逻辑运算指令用于对数据进行逻辑与、或、异或等操作,帮助我们实现对数据的逻辑判断和处理。
控制转移指令则决定了程序的执行流程。
它可以让程序根据特定的条件跳转到指定的地址继续执行,从而实现分支和循环等功能。
接下来,我们说一说 80C51 单片机的编程语言。
常见的编程语言有机器语言、汇编语言和高级语言。
机器语言是单片机能够直接识别和执行的二进制代码。
它由一连串的 0 和 1 组成,虽然执行效率高,但编写和阅读都非常困难。
汇编语言是一种符号化的机器语言,使用助记符来代替机器指令的操作码,用地址符号或标号来代替地址码。
相比机器语言,汇编语言更易于理解和编写,但仍然需要对单片机的硬件结构有较深入的了解。
高级语言,如 C 语言,具有更高的可读性和可维护性。
它能够让开发者更专注于解决问题的逻辑,而不必过多地关注单片机的底层硬件细节。
使用高级语言编写的程序,经过编译后可以在 80C51 单片机上运行。
在软件开发过程中,编程工具也是不可或缺的。
Keil 就是一款常用的 80C51 单片机编程软件。
它提供了方便的代码编辑、编译、调试环境,能够大大提高开发效率。
编写好程序后,我们需要将其下载到单片机中。
第3章51系列单片机程序设计(C语言部分)

idata
间接寻址片内数据存储区,可访问片内全部RAM地址空间(256字节)
pdata
分页寻址片外数据存储区(256字节)由MOV @Ri访问(i=0,1)
xdata
片外数据存储区(64 KB)由MOVX @DPTR访问
code
程序存储器64 KB空间,由MOVC @DPTR访问
第3章 51系列单片机程序设计(C部分)
/* Ary37定义为abry[3]的第7位 */
第3章 51系列单片机程序设计(C部分)
3.5 数 组
数组:数组是一组类型相同 有序数据的集合。用数组名 和下标来唯一确定数组中的 元素。
第3章 51系列单片机程序设计(C部分)
3.5.1 一维数组
一、一维数组的定义 形式:类型说明符 数组名 [常量表达式]
使用C51进行编程时,MCS-51片内的I/O口与片外扩展的I/O可以统一在一个头文 件中定义,也可以在程序中(一般在开始的位置)进行定义。
对于MCS-51片内I/O口按特殊功能寄存器方法定义。 例如:
sfr P0=0x80 ; /* 定义P0口,地址为80H */ sfr P1=0x90 ; /* 定义P1口,地址为90H */
第3章 51系列单片机程序设计(C部分)
3.4.3 C51数据的存储类型与MCS-51存储结构
表 3.4.2 C51存储类型与MCS-51存储空间的对应关系
存储类型 与存储空间的对应关系
data
直接寻址片内数据存储区,访问速度快(128字节)
bdata
可位寻址片内数据存储区,允许位与字节混合访问(16字节)
据 浮点型(float) 类
型 指针类型
详细见表3.4.1
8051单片机常用指令

8051单⽚机常⽤指令3.2.1数据传送与交换类指令共有28条指令,包括以A,Rn,DPTR,直接地址单元,间接地址单元为⽬的的操作数的指令;访问外部RAM的指令;读程序存储器的指9.堆栈操作3.2 分类指令在介绍各条分类指令之前,将指令中的操作数及注释中的符号说明如下。
Rn:当前指定的⼯作寄存器组中的Ro-R7(其中n=0,1,2,…,7)。
Ri:当前指定的⼯作寄存器组中的RO,R1(其中i=0,1)。
(Ri):Ri间址寻址指定的地址单元。
((Ri)):Ri间址寻址指定地址单元中的内容。
dir:8位直接字节地址(在⽚内RAM和SFR存储空间中)。
#data8:8位⽴即数。
#datal6:16位⽴即数。
addrl6:16位地址值。
addrll:11位地址值。
bit:位地址(在位地址空间中)。
rel:相对偏移量(⼀字节补码数)。
下⾯介绍各条分类指令的主要功能和操作,详细的指令操作说明及机器码形式可见附录。
3.2.1数据传送与交换类指令共有28条指令,包括以A,Rn,DPTR,直接地址单元,间接地址单元为⽬的的操作数的指令;访问外部RAM的指令;读程序存储器的指令;数据交换指令以及准栈操作指令。
9.堆栈操作PUSH dir ;SP⼗1-6P,(dir)⼀(SP)POP dir ;((SP))⼀dir,SP-1--P ,例1 SP=07H,(35H)=55H,指令PUSH 35H执⾏后,55H送⼊08H地址单元,SP=08H。
例2 SP=13H,(13H)= 1FH,指令POP 25H执⾏后,1FH压⼊25H地址单元,SP此时为12H。
综合例把⽚内RAM中50H地址单元中的内容与40H地址单元中的内容互换。
⽅法⼀(直接地址传送法):MOV A ,50H数据传送与交换类指令是各类指令中数量最多、使⽤最频繁的⼀类指令,编程时应能⼗分熟练地灵活运⽤3.2.2算术运算类指令共有24条指令,主要包括加、减、乘、除、增量、减量和⼗进制调整等指令。
单片机函数

单片机函数单片机函数是一种用于编程控制的函数,主要用于单片机的内部功能和外部设备之间的交互。
当我们在单片机中编程时,可以使用已经定义好的函数来实现一些常见的功能,而不必每次都重复编写代码。
本文将介绍一些常见的单片机函数及其用法。
1.延时函数延时函数是单片机编程中最基本的函数之一、它用于在程序中添加延时,以控制程序的时间间隔。
延时函数可以通过软件实现,也可以通过硬件计数器来实现。
例如,对于某些需要精确控制时间的操作,我们可以使用硬件计数器来实现延时,而对于一些简单的延时操作,我们可以使用软件延时函数来实现。
2.输入输出函数输入输出函数用于读取输入设备或控制输出设备。
在单片机中,输入输出通常通过引脚来实现。
通过调用输入输出函数,我们可以读取或控制某个引脚的电平状态。
例如,如果我们希望读取一个传感器的数据,我们可以使用输入函数来读取传感器引脚的电平;如果我们想控制一个LED灯的亮灭,我们可以使用输出函数来控制LED引脚的电平状态。
3.中断函数中断函数是一种特殊的函数,它用于响应硬件中断。
当某个硬件事件发生时,中断函数会被自动调用,以便进行相应的处理。
例如,当一个按钮按下时,可以配置一个中断函数,以便在按钮按下时自动执行特定的操作。
中断函数通常是基于优先级的,可以设置不同的中断优先级来处理不同的中断事件。
4.串口通信函数串口通信函数是用于在单片机和外部设备之间进行串行通信的函数。
串行通信用于将数据以位的形式发送或接收,可以实现单片机与计算机、传感器、显示器等设备的数据传输。
串口通信函数通常包括初始化函数、发送函数和接收函数,通过调用这些函数,可以实现单片机与外部设备的数据交换。
5.定时器函数定时器函数是用于配置和控制单片机内部定时器模块的函数。
定时器可以用来产生特定时间间隔的中断,用于周期性地执行某个任务,例如定时发送数据、定时采集传感器数据等。
定时器函数通常包括配置函数、启动函数和停止函数,通过调用这些函数,可以实现定时器的设置和控制。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include "delay.h"/*------------------------------------------------uS延时函数,含有输入参数unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编,大致延时长度如下T=tx2+5 uS------------------------------------------------*/void DelayUs2x(unsigned char t){while(--t);}/*------------------------------------------------mS延时函数,含有输入参数unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编------------------------------------------------*/void DelayMs(unsigned char t){while(t--){//大致延时1mSDelayUs2x(245);DelayUs2x(245);}}#include"display.h"#include"delay.h"#define DataPort P0 //定义数据端口程序中遇到DataPort 则用P0 替换//sbit LA TCH1=P2^0;//定义锁存使能端口段锁存//sbit LA TCH2=P2^3;// 位锁存unsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9 unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码unsigned char TempData[8]; //存储显示值的全局变量/*------------------------------------------------显示函数,用于动态扫描数码管输入参数FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示如输入0表示从第一个显示。
Num表示需要显示的位数,如需要显示99两位数值则该值输入2------------------------------------------------*/void Display(unsigned char FirstBit,unsigned char Num){static unsigned char i=0;DataPort=0; //清空数据,防止有交替重影LA TCH1=1; //段锁存LA TCH1=0;DataPort=dofly_WeiMa[i+FirstBit]; //取位码LA TCH2=1; //位锁存LA TCH2=0;DataPort=TempData[i]; //取显示数据,段码LA TCH1=1; //段锁存LA TCH1=0;i++;if(i==Num)i=0;}/*------------------------------------------------定时器初始化子程序------------------------------------------------*/void Init_Timer0(void){TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响//TH0=0x00; //给定初值//TL0=0x00;EA=1; //总中断打开ET0=1; //定时器中断打开TR0=1; //定时器开关打开}/*------------------------------------------------定时器中断子程序------------------------------------------------*/void Timer0_isr(void) interrupt 1{TH0=(65536-2000)/256; //重新赋值2msTL0=(65536-2000)%256;Display(0,8);}#include"display.h"#include"delay.h"#define DataPort P0 //定义数据端口程序中遇到DataPort 则用P0 替换//sbit LA TCH1=P2^0;//定义锁存使能端口段锁存//sbit LA TCH2=P2^3;// 位锁存unsigned char code dofly_DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9 unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码unsigned char TempData[8]; //存储显示值的全局变量/*------------------------------------------------显示函数,用于动态扫描数码管输入参数FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示如输入0表示从第一个显示。
Num表示需要显示的位数,如需要显示99两位数值则该值输入2------------------------------------------------*/void Display(unsigned char FirstBit,unsigned char Num){static unsigned char i=0;DataPort=0; //清空数据,防止有交替重影LA TCH1=1; //段锁存LA TCH1=0;DataPort=dofly_WeiMa[i+FirstBit]; //取位码LA TCH2=1; //位锁存LA TCH2=0;DataPort=TempData[i]; //取显示数据,段码LA TCH1=1; //段锁存LA TCH1=0;i++;if(i==Num)i=0;}/*------------------------------------------------定时器初始化子程序------------------------------------------------*/void Init_Timer0(void){TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响//TH0=0x00; //给定初值//TL0=0x00;EA=1; //总中断打开ET0=1; //定时器中断打开TR0=1; //定时器开关打开}/*------------------------------------------------定时器中断子程序------------------------------------------------*/void Timer0_isr(void) interrupt 1{TH0=(65536-2000)/256; //重新赋值2msTL0=(65536-2000)%256;Display(0,8);}/*-----------------------------------------------名称:IIC协议PCF8591 AD/DA转换论坛:编写:shifang修改:无内容:使用4路AD中的1路检测外部模拟量输入------------------------------------------------*/#include <reg52.h>#include "i2c.h"#include "delay.h"#include "display.h"#define AddWr 0x90 //写数据地址#define AddRd 0x91 //读数据地址extern bit ack;unsigned char ReadADC(unsigned char Chl);bit WriteDAC(unsigned char dat);/*------------------------------------------------主程序------------------------------------------------*/main(){unsigned char num=0;Init_Timer0();while (1) //主循环{num=ReadADC(0);TempData[0]=dofly_DuanMa[num/100];TempData[1]=dofly_DuanMa[(num%100)/10]; TempData[2]=dofly_DuanMa[(num%100)%10];//主循环中添加其他需要一直工作的程序DelayMs(100);}}/*------------------------------------------------读AD转值程序输入参数Chl 表示需要转换的通道,范围从0-3返回值范围0-255------------------------------------------------*/unsigned char ReadADC(unsigned char Chl){unsigned char V al;Start_I2c(); //启动总线SendByte(AddWr); //发送器件地址if(ack==0)return(0);SendByte(0x40|Chl); //发送器件子地址if(ack==0)return(0);Start_I2c();SendByte(AddWr+1);if(ack==0)return(0);V al=RcvByte();NoAck_I2c(); //发送非应位Stop_I2c(); //结束总线return(V al);}/*------------------------------------------------写入DA转换数值输入参数:dat 表示需要转换的DA数值,范围是0-255 ------------------------------------------------*//*bit WriteDAC(unsigned char dat){Start_I2c(); //启动总线SendByte(AddWr); //发送器件地址if(ack==0)return(0);SendByte(0x40); //发送器件子地址if(ack==0)return(0);SendByte(dat); //发送数据if(ack==0)return(0);Stop_I2c();}*/。