51单片机独立按键汇编源代码
我的51单片机之 按键 的 C语言与汇编的编程
P1=0xFF; P3=0xFF; while(1) {
if(KINT0==0) {
LD1=0; } if(KINT1==0) {
LD2=0; } if(KT0==0) {
LD3=0; } if(KT1==0) {
LD4=0; } if(KA2==0) {
LD5=0;
} if(KA1==0) {
KINT0 EQU P3.2; KINT1 EQU P3.3; KT0 EQU P3.4; KT1 EQU P3.5; KA2 EQU P3.6; KA1 EQU P3.7; LD1 EQU P1.0; LD2 EQU P1.1; LD3 EQU P1.2; LD4 EQU P1.3; LD5 EQU P1.4; LD6 EQU P1.5;
LD6=0; } } }
四、独立按键汇编程序: ;**************************************************************** ;每个独立铵键用一只指示灯指示;按复位键可熄灭,made by luqichao ;**************************************************************** ORG 0000H AJMP MAIN ORG 0030H
//字形码:0--f 及小数点
unsigned char code AscLed[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
//
{ 0 , 1, 2 , 3 , 4 , 5, 6, 7, 8, 9 }
void main() {
start: LED2=0; //亮数码管 P3=0xFF; KH1=0; if(KL1==0){LEDCODE=AscLed[1];goto start;};//k1 if(KL2==0){LEDCODE=AscLed[2];goto start;};//k2 if(KL3==0){LEDCODE=AscLed[5];goto start;};//k5 KH2=0; if(KL1==0){LEDCODE=AscLed[3];goto start;};//k3 if(KL2==0){LEDCODE=AscLed[4];goto start;};//k4 if(KL3==0){LEDCODE=AscLed[6];goto start;};//k6 KH3=0; if(KL1==0){LEDCODE=AscLed[7];goto start;};//k7 if(KL2==0){LEDCODE=AscLed[8];goto start;};//k8 if(KL3==0){LEDCODE=AscLed[9];goto start;};//k9
C51矩阵键盘汇编语言源代码
C51矩阵键盘汇编语言源代码/************************************************************** ******************;* 描述: *;* lcd1602显示遥控键值读取器 *;* lcd1602显示遥控器接p3.2 *;* 喇叭接p1.5 继电器接p1.4 *;* 17(40h)键按下,继电器吸合。
19(04h)键按下,继电器关闭。
*;* 连接方法:使用红外功能时 J1跳线短接 **************************************************************** *****************/;-----------------------------------------------IRCOM EQU 20H ;20H-23H IR使用X EQU 26H ;LCD 地址变量IRIN EQU P3.2BEEP EQU P1.5RELAY EQU P1.4RS EQU P2.6RW EQU P2.5EN EQU P2.7;------------------------------------------------ORG 0000HJMP MAIN;------------------------------------------------MAIN:MOV SP,#40HMOV A,#00HMOV R0,#20HLOOP0: MOV @R0,A ;20H-26H清零INC R0CJNE R0,#27H,LOOP0SETB IRINCALL SET_LCDCALL MENU1LOOP1:CALL IR_INCALL IR_SHOWMOV A,22HCJNE A,#40H,LOOP2 ;K17键按下CLR RELAY ;继电器吸合LOOP2: CJNE A,#04H,LOOP3 ;K19键按下SETB RELAY ;继电器关闭LOOP3: JMP LOOP1;----------------------------------------------------- ; LCD 初始化设置;----------------------------------------------------- SET_LCD:CLR ENCALL INIT_LCD ;初始化 LCDCALL DELAY1MOV DPTR,#INFO1 ;指针指到显示信息1MOV A,#1 ;显示在第一行CALL LCD_SHOWMOV DPTR,#INFO2 ;指针指到显示信息2MOV A,#2 ;显示在第二行CALL LCD_SHOWRET;----------------------------------------------------- INIT_LCD: ;8位I/O控制 LCD 接口初始化MOV A,#38H ;双列显示,字形5*7点阵CALL WCOMCALL DELAY1MOV A,#38H ;双列显示,字形5*7点阵CALL WCOMCALL DELAY1MOV A,#38H ;双列显示,字形5*7点阵CALL WCOMCALL DELAY1MOV A,#0CH ;开显示,关光标,CALL WCOMCALL DELAY1MOV A,#01H ;清除 LCD 显示屏CALL WCOMCALL DELAY1RET;---------------------------------------------------- LCD_SHOW: ;在LCD的第一行或第二行显示信息字符CJNE A,#1,LINE2 ;判断是否为第一行LINE1: MOV A,#80H ;设置 LCD 的第一行地址CALL WCOM ;写入命令CALL CLR_LINE ;清除该行字符数据MOV A,#80H ;设置 LCD 的第一行地址CALL WCOM ;写入命令JMP FILLLINE2: MOV A,#0C0H ;设置 LCD 的第二行地址CALL WCOM ;写入命令CALL CLR_LINE ;清除该行字符数据MOV A,#0C0H ;设置 LCD 的第二行地址CALL WCOMFILL: CLR A ;填入字符MOVC A,@A+DPTR ;由消息区取出字符CJNE A,#0,LC1 ;判断是否为结束码RETLC1: CALL WDATA ;写入数据INC DPTR ;指针加1JMP FILL ;继续填入字符RET;--------------------------------------------------- CLR_LINE: ;清除该行 LCD 的字符MOV R0,#24CL1: MOV A,#' 'CALL WDATADJNZ R0,CL1RET;---------------------------------------------------- MENU1: ;LCD 显示工作菜单信息MOV DPTR,#MENU2MOV A,#1 ;在第一行显示信息CALL LCD_SHOWRETMENU2: DB " Red Control ",0;----------------------------------------------------- INFO1: DB " ",0 ;LCD 第一行显示信息INFO2: DB " IR-CODE: --H ",0 ;LCD 第二行显示信息;-----------------------------------------------------;----------------------------------------------------- ; 写指令、数据使能子程序;----------------------------------------------------- WCOM:MOV P0,A ;写指令使能CLR RS ;RS=L,RW=L,D0-D7=指令码,E=高脉冲CLR RWSETB ENCALL DELAY0CLR ENRETWDATA:MOV P0,A ;写数据使能SETB RS ;RS=H,RW=L,D0-D7=数据,E=高脉冲CLR RWSETB ENCALL DELAY0CLR ENRETDELAY0: MOV R7,#250 ;延时500微秒DJNZ R7,$RET;---------------------------------------------------;在 LCD 第二行显示字符;A=ASC DATA, B=LINE X POS;--------------------------------------------------- LCDP2: ;在LCD的第二行显示字符PUSH ACC ;MOV A,B ;设置显示地址ADD A,#0C0H ;设置LCD的第二行地址CALL WCOM ;写入命令POP ACC ;由堆栈取出ACALL WDATA ;写入数据RET;--------------------------------------------------- ; IR 译码子程序;--------------------------------------------------- IR_IN:MOV R0,#IRCOMI1: JNB IRIN,I2 ;等待 IR 信号出现JMP I1I2: MOV R4,#20I20: CALL DELDJNZ R4,I20JB IRIN,I1 ;确认IR信号出现I21: JB IRIN,I3 ;等 IR 变为高电平CALL DELJMP I21I3: MOV R3,#0 ;8位数清为0LL: JNB IRIN,I4 ;等 IR 变为低电平CALL DELJMP LLI4: JB IRIN,I5 ;等 IR 变为高电平CALL DELJMP I4I5: MOV R2,#0 ;0.14ms 计数L1: CALL DELJB IRIN, N1 ;等 IR 变为高电平;IR=0,检查R2中的计数值MOV A,#8CLR CSUBB A,R2 ;判断高低位;IF C=0 BIT=0MOV A,@R0RRC AMOV @R0,A ;处理完一位INC R3CJNE R3,#8,LL ;需处理完8位MOV R3,#0INC R0CJNE R0,#24H,LL ;收集到4字节了JMP OKN1: INC R2CJNE R2,#30,L1 ;0.14ms 计数过长则时间到自动离开OK: RET;--------------------------------------------------------------------IR_SHOW:MOV A,22HCPL A ;将22H取反后和23H比较CJNE A,23H,IR_SHOW1 ;如果不等表示接收数据发生错误,放弃。
51C语言源代码
闪烁灯[实验要求]点亮与单片机P1.0口相连的发光二极管,延时0.2S,然后熄灭,延时0.2S,再点亮,如此循环下去。
[实验目的]初步了解单片机IO口输出高低电平的作用,延时函数的时间估算。
[硬件电路][源代码]#include<reg51.h>/**********************************************************上面这行是一个"文件包含"处理。
所谓"文件包含"是指一个文件将另外一个文件的内容全部包含进来这里的程序虽然只写了一行,但C编译器在处理的时候却要处理几十或几百行,这里包含reg51.h的目的在于本程序要使用P1这个符号,而P1是在reg51.h这个头文件中定义的。
大家可以在编译器目录下面用记事本打开这个文件看看。
*********************************************************/sbit P1_0=P1^0; //定义IO口这步的目的是让编//译器知道P1_0代表的就是单片机的P1.0口void delay02s(void) //延时0.2秒子程序{unsigned char i,j,k; //定义3个无符号字符型变量。
for(i=20;i>0;i--) //三个FOR循环用来延时,这里为for(j=20;j>0;j--) //什么是0.2S大家可以用WAVE for(k=248;k>0;k--); //高断点仿真一下,就可知道大概 } //是0.2S了。
void main(void) //每一个C语言程序有且只有一个主函数,{while(1) //循环条件永远为真,以下程序一直执行下去。
{P1_0=0; // I/O口P1.0输出低电平,小灯被点亮。
delay02s(); //延时经过0.2秒。
P1_0=1; // I/O口P1.0输出高电平,小灯熄灭。
基于51单片机按键 长按短按效果 源程序
基于51单片机按键长按短按效果源程序[复制链接] *实验名称:多位数按键加减**晶振:12MHZ*内容:按键加减数字,多个数码管显示,使用定时器做数码管动态扫描**并区别长按短按效果,完全可以应用的实际生产中** ---------------------------------------------------------------*/#include<reg52.h> //包含头文件,一般情况不需要改动,//头文件包含特殊功能寄存器的定义sbit KEY_ADD=P3^3; //定义按键输入端口S17sbit KEY_DEC=P3^2; //S18#define DataPort P1 //定义数据端口程序中遇到DataPort则用P1替换sbit LATCH1=P2^0;//定义锁存使能端口段锁存sbit LATCH2=P2^1;//位锁存sbit P35 = P3^5;//这是为了关闭开发板上的点阵实际应用去掉unsigned char code HEYAO_DuanMa[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//显示段码值89unsigned char code HEYAO_WeiMa[]={0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80};//分别对应相应的数码管点亮,即位码unsigned char TempData[8]={0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF};//存储显示值的全局变量void DelayUs2x(unsigned char t);//函数声明void DelayMs(unsigned char t);void Init_Timer0(void);void Display(unsigned char FirstBit,unsigned char Num);/*------------------------------------------------主函数------------------------------------------------*/void main (void){unsigned char num=0,key_press_num;P35=0; //这是为了关闭开发板上的点阵实际应用去掉KEY_ADD=1; //按键输入端口电平置高KEY_DEC=1;Init_Timer0();while(1) //主循环{if(!KEY_ADD) //如果检测到低电平,说明按键按下{DelayMs(10); //延时去抖,一般10-20msif(!KEY_ADD) //再次确认按键是否按下,没有按下则退出{while(!KEY_ADD){key_press_num++;DelayMs(10); //10x200=2000ms=2sif(key_press_num==200) //大约2s{key_press_num=0; //如果达到长按键标准//则进入长按键动作while(!KEY_ADD) //这里用于识别是否按//键还在按下,如果按//下执行相关动作,否则退出{if(num<99) //加操作num++;//即时把显示数据处理,如果去掉下面2//句处理信息,实际上看不到渐变效果,//而是看到跳变效果//用户可以自行屏蔽测试//分解显示信息,如要显示68,则=6 68%10=8TempData[0]=HEYAO_DuanMa[num/10];TempData[1]=HEYAO_DuanMa[num%10];DelayMs(50);//用于调节长按循环操作//的速度,可以自行调整此值以便达到最佳效果}}}key_press_num=0;//防止累加造成错误识别if(num<99) //加操作num++;}}if(!KEY_DEC) //如果检测到低电平,说明按键按下{DelayMs(10); //延时去抖,一般10-20msif(!KEY_DEC) //再次确认按键是否按下,没有//按下则退出{while(!KEY_DEC){key_press_num++;DelayMs(10);if(key_press_num==200) //大约2s{key_press_num=0;while(!KEY_DEC){if(num>0) //减操作num--;//分解显示信息,如要显示68,则=6 68%10=8TempData[0]=HEYAO_DuanMa[num/10];TempData[1]=HEYAO_DuanMa[num%10];DelayMs(50);//用于调节长按循环操作的速度}}}key_press_num=0;//防止累加造成错误识别if(num>0) //减操作num--;}}//分解显示信息,如要显示68,则=6 68%10=8TempData[0]=HEYAO_DuanMa[num/10];TempData[1]=HEYAO_DuanMa[num%10];// Display(0,8); //显示全部8位//主循环中添加其他需要一直工作的程序}}/*------------------------------------------------uS延时函数,含有输入参数unsigned char t,无返回值unsigned char是定义无符号字符变量,其值的范围是0~255这里使用晶振12M,精确延时请使用汇编,大致延时xx如下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);}}显示函数,用于动态扫描数码管输入参数FirstBit表示需要显示的第一位,如赋值2表示从第三个数码管开始显示如输入0表示从第一个显示。
51单片机键盘接口电路(含源程序)
51单片机键盘接口电路(含源程序)键盘是由若干按钮组成的开关矩阵,它是单片机系统中最常用的输入设备,用户能通过键盘向计算机输入指令、地址和数据。
一般单片机系统中采和非编码键盘,非编码键盘是由软件来识别键盘上的闭合键,它具有结构简单,使用灵活等特点,因此被广泛应用于单片机系统。
按钮开关的抖动问题组成键盘的按钮有触点式和非触点式两种,单片机中应用的一般是由机械触点组成的。
在下图中,当开<键盘结构图>< P> 图1 < P> 图2关S未被按下时,P1。
0输入为高电平,S闭合后,P1。
0输入为低电平。
由于按钮是机械触点,当机械触点断开、闭合时,会有抖动动,P1。
0输入端的波形如图2所示。
这种抖动对于人来说是感觉不到的,但对计算机来说,则是完全能感应到的,因为计算机处理的速度是在微秒级,而机械抖动的时间至少是毫秒级,对计算机而言,这已是一个“漫长”的时间了。
前面我们讲到中断时曾有个问题,就是说按钮有时灵,有时不灵,其实就是这个原因,你只按了一次按钮,可是计算机却已执行了多次中断的过程,如果执行的次数正好是奇数次,那么结果正如你所料,如果执行的次数是偶数次,那就不对了。
为使CPU能正确地读出P1口的状态,对每一次按钮只作一次响应,就必须考虑如何去除抖动,常用的去抖动的办法有两种:硬件办法和软件办法。
单片机中常用软件法,因此,对于硬件办法我们不介绍。
软件法其实很简单,就是在单片机获得P1。
0口为低的信息后,不是立即认定S1已被按下,而是延时10毫秒或更长一些时间后再次检测P1。
0口,如果仍为低,说明S1的确按下了,这实际上是避开了按钮按下时的抖动时间。
而在检测到按钮释放后(P1。
0为高)再延时5-10个毫秒,消除后沿的抖动,然后再对键值处理。
不过一般情况下,我们常常不对按钮释放的后沿进行处理,实践证明,也能满足一定的要求。
当然,实际应用中,对按钮的要求也是千差万别,要根据不一样的需要来编制处理程序,但以上是消除键抖动的原则。
51单片机汇编指令大全
51汇编指令大全Rn: 表示当前寄存器区的8个工作寄存器R0~R7Ri: 表示当前寄存器区的R0或R1,可作地址指针即间址寄存器(i=0或1)@: 为间接寄存器或基址寄存器的前缀.Direct: 表示8位内部数据存储单元的地址.它可以是内部RAM的单元地址0~127.特殊功能寄存器SFR的地址(128~255)或名称,A: 累加器ACC.B: .特殊功能寄存器B,用于MUL和DIV指令中.C: 进位位Cy.#data: 表示包含在指令中的单字节(8位)立即数.如果用16位进制表示,后缀字母为”H”,数据范围00~0FFH,不得一字母开头;如果用16进制表示无须任何后缀,但必须在0~255之间.#data16: 表示包含在指令中的双字节(16位)立即数.Adda16: 表示16位的目的地址.用于LCALL和LJMP指令中,目的地址范围是从0000H~FFFFH的整个64KB存储地址空间.Adda11: 表示11位的目的地址.用于ACALL和AJMP的指令中,目的地址必须和下一条指令第一个字节同处一页.Rel: 表示8位带符号的相对偏移量.用语SJMP和所有的条件转移指令中.偏移量相对于下一条指令的第一个字节计算,在-128~+127范围内取值.DPTR: 为数据指针,可用作16位的地址寄存器./: 加在位操作的前面,表示对该位进行非运算.bit: 表示内部可寻址位或特殊功能寄存器中的直接寻址位.“(x): 寄存器或地址单元中的内容.((x)): 有x见解寻址的单元中的内容.<-: 表示将箭头右边的内容传送至箭头的左边.$: 当前指令的地址.单片机指令系统(一) 内部数据传送指令(1) 以累加器A为目的的传送指令:MOV A, #data ;(A)<-dataMOV A, direct ;(A)<-(direct)MOV A, Rn ;(A)<-(Rn)MOV A, @Ri ;(A)<- ((Ri))(2) 以通用寄存器Rn为目的的传送指令:MOV Rn, A ;(Rn)<-(A)MOV Rn, direct ; (Rn)<(direct)-MOV Rn, #data: ; (Rn)<-(data)(3) 以直接地址为目的的传送指令:MOV direct, A ;(direct)<-(A)MOV direct, Rn ; (direct)<-(Rn)MOV direct, direct2 ; (direct)<-(direct2)MOV direct, @Ri ; (direct)<-((Rn))MOV direct, #data ; (direct)<-data(4) 以寄存器间接地址为目的的传送指令:MOV @Ri, A ;((Ri))<-(A)MOV @Ri, direct ;((Ri))<-(direct)MOV @Ri, #data ;((Ri))<-data(二) 数据指针赋值指令(16位数据传送指令)MOV DPTR, #data16;(三) 片外数据传送指令MOVX A, @Ri ;(A)<-((Ri))片外MOVX A, @DPTR ;(A)<-((DPTR))片外MOVX @Ri, A ;((Ri))片外<-(A)MOVX @DPTR, A ;((DPTR))片外<-(A)(四) ROM数据访问指令(查表指令)MOVC A, @A+DPTR ;(A)<-((A)+(DPTR))romMOVC A, @A+PC ;(PC)<-(PC)+1,(A)<-((A)+(PC))rom (五) 堆栈操作指令PUSH direct ;(SP)<-(SP)+1,(SP)<-(direct)堆栈指针先加1,将数据压入栈顶POP direct ;(direct)<-(SP),(SP)<-(SP)-1将数据从栈顶弹出存入direct,SP再减1(六) 数据交换指令(1)整字节(8位)交换指令:XCH A, Rn ;A和Rn中的数互换XCH A, direct ;A和direct单元中的数互换XCH A, @Ri ;A和Ri间址单元中的数互换(2)半字节交换指令:XCHD A, @Ri ;A的低4位Ri间接单元的低4位互换,高4位不动(3)累加器高低半字节交换指令:SWAP A, ;A的高4位(D7~D4)和低4位(D3~D0)互换(七) 加法指令(1)不带Cy加法指令:ADD A, Rn ;(A)<-(A)+(Rn)ADD A, direct ; (A)<-(A)+(direct)ADD A, @Ri ; (A)<-(A)+((Ri))ADD A, #data ; (A)<-(A)+data(2)带进位加法指令:ADDC A, Rn ;(A)<-(A) +Cy+(Rn)ADDC A, direct ; (A)<-(A) +Cy+(direct)ADDC A, @Ri ; (A)<-(A) +Cy+((Ri))ADDC A, #data ; (A)<-(A) +Cy+data(3)加1指令:INC A, ;(A)<-(A)+1INC Rn ;(Rn)<-(Rn)+1INC @Ri ;((Ri))<-((Ri))+1INC direct ;(direct)<-(direct)+1INC DPTR ;(FPTR)<-(DPTR)+1(八) 减法指令(1)带进位减法指令:SUBB A, Rn ;(A)<-(A) -Cy-(Rn)SUBB A, direct ; (A)<-(A) -Cy-(direct)SUBB A, @Ri ; (A)<-(A) -Cy-((Ri))SUBB A, #data ; (A)<-(A) -Cy-data(2)减1指令:DEC A ;(A)<-(A)-1DEC direct ;(direct)<-(durect)-1DEC Rn ;(Rn)<-(Rn)-1DEC @Ri ;((Ri))<-((Ri))-1(九) 乘除指令(1)乘法指令MUL AB ;(B)(A)<-(A)*(B)指令功能是把累加器A和特殊功能寄存器B中两个8位无符号整数相乘,并把积的高8位字节存入B寄存器,低8位字节存入累加器A.(2)除法指令DIV AB ;A/B,商存入A,余数存入B指令的功能是把累加器A中的8位无符号整数除以寄存器B中的8位无符号整数商的整数部分存入累加器A中,余数保留在B中.(十) 十进制调整指令DA A(十一) 逻辑运算指令(1) 逻辑与运算指令:ANL A, Rn ;(A)<-(A)∧(Rn)ANL A, direct ; (A)<-(A)∧(direct)ANL A, @Ri ; (A)<-(A)∧((Ri))ANL A, #data ; (A)<-(A)∧dataANL direct, A ;(direct)<-(A)∧(direct)ANL direct, #data;(direct<-(direct)∧data(2) 逻辑或运算指令:ORL A, Rn ;(A)<-(A)∨(Rn)ORL A, direct ; (A)<-(A)∨(direct)ORL A, @Ri ; (A)<-(A)∨((Ri))ORL A, #data ; (A)<-(A)∨dataORL direct, A ;(direct)<-(A)∨(direct)ORL direct, #data; (direct)<-(direct)∨data(3) 逻辑异或运算指令:XRL A, Rn ;(A)<-(A)⊙(Rn)XRL A, direct ; (A)<-(A)⊙(direct)XRL A, @Ri ; (A)<-(A)⊙((Ri))XRL A, #data ; (A)<-(A)⊙dataXRL direct, A ;(direct)<-(A)⊙(direct)XRL direct, #data; (direct)<-(direct)⊙data(4) 累加器清0和去反指令CLR A ;(A)<-0 (累加器清0指令)CLR A ;(A)<-(A) (累加器取反指令)(5) 累加器移位指令:不带进位Cy循环左移: RL A ;Dn+1<-Dn,D0<-D7D7D6D5D4D3D2D1D0不带进位Cy循环右移: RR A :Dn+1->Dn,D0<-D7D7D6D5D4D3D2D1D0带进位Cy循环左移: RLC A ;Cy<-D7,Dn+1<-Dn,D0<-CyD7D6D5D4D3D2D1D0带进位Cy循环右移: RRC A ;Cy->D7,Dn+1->Dn,D0->Cy(十二) 控制转移指令[1] 无条件转移指令:(1) 长转移指令LJMP addr16 ;(PC)<-addr16(2) 绝对转移指令AJMP addr11 ;(PC)<-(PC)+2,(PC)10~0<-addr11(3) 短转移指令SJMP rel ;(PC)<-(PC)+2+rel(4) 变址寻址转移指令JMP @A+DPTR ;(PC)<-(A)+(DPTR)[2] 条件转移指令:(1) 累加器判0转移指令:JZ rel ;如果(A)=0,跳转到目标语句,否则顺序执行JNZ rel ;如果(A)≠0,跳转到目标语句,否则顺序执行(2) 比较转移指令:CJNZ A, #data, rel ;如果(A)≠data,则跳转到目标语句,否则程序顺序执行CJNZ A direct, rel ; 如果(A)≠(direct),则跳转到目标语句,否则程序顺序执行CJNZ Rn #data, rel ; 如果(A)≠data,则跳转到目标语句,否则程序顺序执行CJNZ @Ri #data, rel ; 如果(A)≠data,则跳转到目标语句,否则程序顺序执行(3) 循环控制转移指令:DJNZ Rn, rel ;(Rn)先减1,如减1后(Rn)≠0,则跳转到目标语句;否则顺序执行DJNZ firect, rel ; (direct)先减1,如减1后(direct)≠0,则跳转到目标语句;否则顺序执行(十三) 子程序调用和返回指令(1) 绝对调用指令:ACALL addr11(2) 长调用指令:LCALL addr16(3) 返回指令:RET 子程序返回RETI 中断服务程序返回(十四) 空操作指令NOP 空操作指令是一条特殊指令,单片机在执行该指令时不进行任何操作,只是消耗1个机器周期的时间,所以该指令长用于延时程序.软件陷阱程序等(十五) 位操作类指令(1) 位传送指令:MOV C,bit ;(Cy)<-(bit),bit位的状态不变MOV bit,C ; (bit) <- (Cy),Cy位的状态不变(2) 位置位和复位指令:SETB C ;(Cy)<-1SETB bit ;(bit)<-1CLR C ;(Cy)<-0CLR bit ;(bit)<-0(3) 位运算指令:ANL C,bit ;(Cy)<-(Cy)∧(bit),Cy位和bit位相与,结果赋给Cy ANL C,/bit ;(Cy)<-(Cy)∧(bit),Cy位和bit位相与,结果赋给CyORL C,bit ;(Cy)<-(Cy)∨(bit),Cy位和bit位相或,结果赋给Cy ORL C,/bit ;(Cy)<-(Cy) ∨(bit),Cy位和bit位相或,结果赋给CyCPL C ; (Cy)<-(Cy),Cy位取反CPL bit ;(bit)<-(bit),bit位取反(4) 位测试转移指令:(1) 以Cy位状态为条件的转移指令JC rel ;如果Cy位=1,跳转到目标语句,否则顺序执行JNC rel ;如果Cy位=0,跳转到目标语句,否则顺序执行(2) 以指定位状态为条件的转移指令:JB bit, rel ;如果bit=1,跳转到目标语句,否则顺序执行JNB bit, rel ;如果bit=0,跳转到目标语句,否则顺序执行JBC bit, rel ;如果bit=1,跳转到目标语句,同时将bit位清0;否则顺序执行。
基于51单片机按键长按短按效果源程序
基于51单片机按键长按短按效果源程序[复制链接]* 实验名称:多位数按键加减** 晶振:12MHZ* 内容:按键加减数字,多个数码管显示,使用定时器做数码管动态扫描** 并区别长按短按效果,完全可以应用的实际生产中** ---------------------------------------------------------------*/#include<reg52.h> //包含头文件,一般情况不需要改动,//头文件包含特殊功能寄存器的定义sbit KEY_ADD=P3^3; //定义按键输入端口S17sbit KEY_DEC=P3^2; //S18#define DataPort P1 //定义数据端口程序中遇到DataPort 则用P1 替换sbit LATCH1=P2^0;//定义锁存使能端口段锁存sbit LATCH2=P2^1;// 位锁存sbit P35 = P3^5;//这是为了关闭开发板上的点阵实际应用去掉unsigned char code HEYAO_DuanMa[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};// 显示段码值0123456789unsigned char code HEYAO_WeiMa[]={0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80};//分别对应相应的数码管点亮,即位码unsigned char TempData[8]={0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF};//存储显示值的全局变量void DelayUs2x(unsigned char t);//函数声明void DelayMs(unsigned char t);void Init_Timer0(void);void Display(unsigned char FirstBit,unsigned char Num);/*------------------------------------------------主函数------------------------------------------------*/void main (void){unsigned char num=0,key_press_num;P35=0; //这是为了关闭开发板上的点阵实际应用去掉KEY_ADD=1; //按键输入端口电平置高KEY_DEC=1;Init_Timer0();while (1) //主循环{if(!KEY_ADD) //如果检测到低电平,说明按键按下DelayMs(10); //延时去抖,一般10-20msif(!KEY_ADD) //再次确认按键是否按下,没有按下则退出{while(!KEY_ADD){key_press_num++;DelayMs(10); //10x200=2000ms=2sif(key_press_num==200) //大约2s{key_press_num=0; //如果达到长按键标准//则进入长按键动作while(!KEY_ADD) //这里用于识别是否按//键还在按下,如果按//下执行相关动作,否则退出{if(num<99) //加操作num++;//即时把显示数据处理,如果去掉下面2//句处理信息,实际上看不到渐变效果,//而是看到跳变效果//用户可以自行屏蔽测试//分解显示信息,如要显示68,则68/10=6 68%10=8 TempData[0]=HEYAO_DuanMa[num/10];TempData[1]=HEYAO_DuanMa[num%10];DelayMs(50);//用于调节长按循环操作//的速度,可以自行调整此值以便达到最佳效果}}}key_press_num=0;//防止累加造成错误识别if(num<99) //加操作num++;}}if(!KEY_DEC) //如果检测到低电平,说明按键按下{DelayMs(10); //延时去抖,一般10-20msif(!KEY_DEC) //再次确认按键是否按下,没有//按下则退出{while(!KEY_DEC)key_press_num++;DelayMs(10);if(key_press_num==200) //大约2s{key_press_num=0;while(!KEY_DEC){if(num>0) //减操作num--;//分解显示信息,如要显示68,则68/10=6 68%10=8 TempData[0]=HEYAO_DuanMa[num/10];TempData[1]=HEYAO_DuanMa[num%10];DelayMs(50);//用于调节长按循环操作的速度}}}key_press_num=0;//防止累加造成错误识别if(num>0) //减操作num--;}}//分解显示信息,如要显示68,则68/10=6 68%10=8 TempData[0]=HEYAO_DuanMa[num/10];TempData[1]=HEYAO_DuanMa[num%10];// Display(0,8); //显示全部8位//主循环中添加其他需要一直工作的程序}}/*------------------------------------------------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);}}/*------------------------------------------------显示函数,用于动态扫描数码管输入参数FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示如输入0表示从第一个显示。
51单片机16键电子琴汇编程序
KEYL EQU 30H ; 定义KEYL变量,用于键盘扫描KEYR EQU 31H ; 定义KEYR变量,用于键盘扫描VAL EQU 32H ; 定义键值变量VALORG 00HJMP START ; 主程序入口ORG 0BHJMP INT_T0 ; Timer 0中断入口START:MOV TMOD,#01H ; Timer 0作定时器,模式1LSCAN: ; 键盘按键判断MOV P2,#0F0H ; 列全为1L1: ; 判断第1行JNB P2.0,L2CALL DELAYJNB P2.0,L2MOV KEYL,#00HJMP RSCANL2: ; 判断第2行JNB P2.1,L3CALL DELAYJNB P2.1,L3MOV KEYL,#01HJMP RSCANL3: ; 判断第3行JNB P2.2,L4CALL DELAYJNB P2.2,L4MOV KEYL,#02HJMP RSCANL4: ; 判断第4行JNB P2.3,L1CALL DELAYJNB P2.3,L1MOV KEYL,#03HRSCAN:MOV P2,#0FH ; 键盘行输出1C1: ; 判断第1列JNB P2.4,C2MOV KEYR,#00HJMP CALCUC2: ; 判断第2列JNB P2.5,C3MOV KEYR,#01HJMP CALCUC3: ; 判断第3列JNB P2.6,C4MOV KEYR,#02HJMP CALCUC4: ; 判断第4列JNB P2.7,C1MOV KEYR,#03HCALCU: ; 计算按键号MOV A,KEYLMOV B,#04HMUL ABADD A,KEYRMOV VAL,AMOV DPTR,#TABLE ; 装表MOV B,#2MUL ABMOV R1,AMOVC A,@A+DPTR ; 把表中计数初始值装入累加器AMOV TH0,AINC R1MOV A,R1MOVC A,@A+DPTRMOV TL0,AMOV IE,#82H ; 使能Timer 0中断SETB TR0 ; 启动TimerW0: ; 等待按键释放MOV A,P2CJNE A,#0FH,W1CLR TR0 ; TRO清0JMP LSCANW1:MOV A,P2CJNE A,#0F0H,W2MOV P0,#00HCLR TR0JMP LSCANW2:JMP W0;Timer 0中断服务程序,输出某一频率的方波.INT_T0:MOV DPTR,#TABLEMOV A,VALMOV B,#2MUL ABMOV R1,AMOVC A,@A+DPTRMOV TH0,AINC R1MOV A,R1MOVC A,@A+DPTRMOV TL0,ACPL P1.0 ; 清P1.0口RETIDELAY:MOV R6,#10D1:MOV R7,#250DJNZ R7,$DJNZ R6,D1RETTABLE: ; 16个琴键发音频率的计数初始值DW 64021,64103,64260,64400DW 64524,64580,64684,64777DW 64820,64898,64968,65030DW 65058,65110,65157,65178END。
基于51单片机按键长按短按效果源程序
基于51单片机按键长按短按效果源程序[复制链接]* 实验名称:多位数按键加减** 晶振:12MHZ* 内容:按键加减数字,多个数码管显示,使用定时器做数码管动态扫描** 并区别长按短按效果,完全可以应用的实际生产中** ---------------------------------------------------------------*/#include<reg52.h> //包含头文件,一般情况不需要改动,//头文件包含特殊功能寄存器的定义sbit KEY_ADD=P3^3; //定义按键输入端口S17sbit KEY_DEC=P3^2; //S18#define DataPort P1 //定义数据端口程序中遇到DataPort 则用P1 替换sbit LATCH1=P2^0;//定义锁存使能端口段锁存sbit LATCH2=P2^1;// 位锁存sbit P35 = P3^5;//这是为了关闭开发板上的点阵实际应用去掉unsigned char code HEYAO_DuanMa[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};// 显示段码值0123456789unsigned char code HEYAO_WeiMa[]={0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80};//分别对应相应的数码管点亮,即位码unsigned char TempData[8]={0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF};//存储显示值的全局变量void DelayUs2x(unsigned char t);//函数声明void DelayMs(unsigned char t);void Init_Timer0(void);void Display(unsigned char FirstBit,unsigned char Num);/*------------------------------------------------主函数------------------------------------------------*/void main (void){unsigned char num=0,key_press_num;P35=0; //这是为了关闭开发板上的点阵实际应用去掉KEY_ADD=1; //按键输入端口电平置高KEY_DEC=1;Init_Timer0();while (1) //主循环{if(!KEY_ADD) //如果检测到低电平,说明按键按下DelayMs(10); //延时去抖,一般10-20msif(!KEY_ADD) //再次确认按键是否按下,没有按下则退出{while(!KEY_ADD){key_press_num++;DelayMs(10); //10x200=2000ms=2sif(key_press_num==200) //大约2s{key_press_num=0; //如果达到长按键标准//则进入长按键动作while(!KEY_ADD) //这里用于识别是否按//键还在按下,如果按//下执行相关动作,否则退出{if(num<99) //加操作num++;//即时把显示数据处理,如果去掉下面2//句处理信息,实际上看不到渐变效果,//而是看到跳变效果//用户可以自行屏蔽测试//分解显示信息,如要显示68,则68/10=6 68%10=8 TempData[0]=HEYAO_DuanMa[num/10];TempData[1]=HEYAO_DuanMa[num%10];DelayMs(50);//用于调节长按循环操作//的速度,可以自行调整此值以便达到最佳效果}}}key_press_num=0;//防止累加造成错误识别if(num<99) //加操作num++;}}if(!KEY_DEC) //如果检测到低电平,说明按键按下{DelayMs(10); //延时去抖,一般10-20msif(!KEY_DEC) //再次确认按键是否按下,没有//按下则退出{while(!KEY_DEC)key_press_num++;DelayMs(10);if(key_press_num==200) //大约2s{key_press_num=0;while(!KEY_DEC){if(num>0) //减操作num--;//分解显示信息,如要显示68,则68/10=6 68%10=8 TempData[0]=HEYAO_DuanMa[num/10];TempData[1]=HEYAO_DuanMa[num%10];DelayMs(50);//用于调节长按循环操作的速度}}}key_press_num=0;//防止累加造成错误识别if(num>0) //减操作num--;}}//分解显示信息,如要显示68,则68/10=6 68%10=8 TempData[0]=HEYAO_DuanMa[num/10];TempData[1]=HEYAO_DuanMa[num%10];// Display(0,8); //显示全部8位//主循环中添加其他需要一直工作的程序}}/*------------------------------------------------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);}}/*------------------------------------------------显示函数,用于动态扫描数码管输入参数FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示如输入0表示从第一个显示。
51单片机应用实例及源代码 推荐1
1.闪烁灯1.实验任务如图4.1.1所示:在P1.0端口上接一个发光二极管L1,使L1在不停地一亮一灭,一亮一灭的时间间隔为0.2秒。
2.电路原理图图4.1.13.系统板上硬件连线把“单片机系统”区域中的P1.0端口用导线连接到“八路发光二极管指示模块”区域中的L1端口上。
4.程序设计内容(1).延时程序的设计方法作为单片机的指令的执行的时间是很短,数量大微秒级,因此,我们要求的闪烁时间间隔为0.2秒,相对于微秒来说,相差太大,所以我们在执行某一指令时,插入延时程序,来达到我们的要求,但这样的延时程序是如何设计呢?下面具体介绍其原理:如图4.1.1所示的石英晶体为12MHz,因此,1个机器周期为1微秒机器周期微秒MOV R6,#20 2个 2D1: MOV R7,#248 2个 2 2+2×248=498 20× DJNZ R7,$ 2个2×248 (498DJNZ R6,D1 2个2×20=4010002因此,上面的延时程序时间为10.002ms。
由以上可知,当R6=10、R7=248时,延时5ms,R6=20、R7=248时,延时10ms,以此为基本的计时单位。
如本实验要求0.2秒=200ms,10ms×R5=200ms,则R5=20,延时子程序如下:DELAY: MOV R5,#20D1: MOV R6,#20D2: MOV R7,#248DJNZ R7,$DJNZ R6,D2DJNZ R5,D1RET(2).输出控制如图1所示,当P1.0端口输出高电平,即P1.0=1时,根据发光二极管的单向导电性可知,这时发光二极管L1熄灭;当P1.0端口输出低电平,即P1.0=0时,发光二极管L1亮;我们可以使用SETB P1.0指令使P1.0端口输出高电平,使用CLR P1.0指令使P1.0端口输出低电平。
5.程序框图如图4.1.2所示图4.1.26.汇编源程序ORG 0START: CLR P1.0LCALL DELAYSETB P1.0LCALL DELAYLJMP STARTDELAY: MOV R5,#20 ;延时子程序,延时0.2秒D1: MOV R6,#20D2: MOV R7,#248DJNZ R7,$DJNZ R6,D2DJNZ R5,D1RETEND7. C语言源程序#include <AT89X51.H>sbit L1=P1^0;void delay02s(void) //延时0.2秒子程序{unsigned char i,j,k;for(i=20;i>0;i--)for(j=20;j>0;j--)for(k=248;k>0;k--);}void main(void) {while(1){L1=0;delay02s();L1=1;delay02s();}2.模拟开关灯1.实验任务如图4.2.1所示,监视开关K1(接在P3.0端口上),用发光二极管L1(接在单片机P1.0端口上)显示开关状态,如果开关合上,L1亮,开关打开,L1熄灭。
51单片机C语言程序设计源代码
新概念51单片机C语言教程----入门、提高、开发、拓展全攻略郭天祥编著电子工业出版社例2.2.1编写程序,点亮第一个发光二极管(part2_1.c P27)#include <reg52.h> //52系列单片机头文件sbit led1=P1^0; //声明单片机P1口的第一位void main() //主函数{led1=0; /*点亮第一个发光二极管*/}例2.2.2编写程序,点亮P1口的若干二极管(part2_2.c P39)#include <reg52.h> //52系列单片机头文件void main() //主函数{P1=0xaa;//while(1);}例2.5.1利用for语句延时特性,编写第一个发光二极管以间隔1S亮灭闪动的程序(part2_3.c P42)#include <reg52.h> //52系列单片机头文件#define uint unsigned int //宏定义sbit led1=P1^0; //声明单片机P1口的第一位uint i,j;void main() //主函数{while(1) //大循环{led1=0; /*点亮第一个发光二极管*/for(i=1000;i>0;i--) //延时for(j=110;j>0;j--);led1=1; /*关闭第一个发光二极管*/for(i=1000;i>0;i--) //延时for(j=110;j>0;j--);}}- 2 - 例2.6.1编写程序使第一个发光二极管以间隔500ms亮灭闪动。
(part2_4.c P48)#include <reg52.h> //52系列单片机头文件#define uint unsigned int //宏定义sbit led1=P1^0; //声明单片机P1口的第一位void delay1s(); //声明子函数void main() //主函数{while(1) //大循环{led1=0; /*点亮第一个发光二极管*/delay1s(); //调用延时子函数led1=1; /*关闭第一个发光二极管*/delay1s(); //调用延时子函数}}void delay1s() //子函数体{uint i,j;for(i=500;i>0;i--)for(j=110;j>0;j--);}例2.7.1编写程序使第一个二极管以亮200ms、灭800ms的方式闪动。
(完整版)51单片机汇编指令(全)
指令中常用符号说明Rn当前寄存器区的8个工作寄存器R0~R7(n=0~7)Ri当前寄存器区可作为地址寄存器的2个工作寄存器R0和R1(i=0,1)Direct8位内部数据寄存器单元的地址及特殊功能寄存器的地址#data表示8位常数(立即数)#data16表示16位常数Add16表示16位地址Addr11表示11位地址Rel8位代符号的地址偏移量Bit表示位地址@间接寻址寄存器或基址寄存器的前缀( )表示括号中单元的内容(( ))表示间接寻址的内容指令系统数据传送指令(8个助记符)助记符中英文注释MOV Move 移动MOV A , Rn;Rn→A,寄存器Rn的内容送到累加器AMOV A , Direct;(direct)→A,直接地址的内容送AMOV A ,@ Ri;(Ri)→A,RI间址的内容送AMOV A , #data;data→A,立即数送AMOV Rn , A;A→Rn,累加器A的内容送寄存器RnMOV Rn ,direct;(direct)→Rn,直接地址中的内容送RnMOV Rn , #data;data→Rn,立即数送RnMOV direct , A;A→(direct),累加器A中的内容送直接地址中MOV direct , Rn;(Rn)→direct,寄存器的内容送到直接地址MOV direct , direct;(direct)→direct,直接地址的内容送到直接地址MOV direct , @Ri;((Ri))→direct,间址的内容送到直接地址MOV direct , #data;8位立即数送到直接地址中MOV @Ri , A;(A)→@Ri,累加器的内容送到间址中MOV @Ri , direct;direct→@Ri,直接地址中的内容送到间址中MOV @Ri , #data; data→@Ri ,8位立即数送到间址中MOV DPTR , #data16;data16→DPTR,16位常数送入数据指针寄存器,高8位送入DPH,低8位送入DPL中(单片机中唯一一条16位数据传送指令)(MOV类指令共16条)MOVC Move Cod 查表指令MOVC A , @A+PC;PC+1→PC,(A+PC)→AMOVC A , @A+DPTR;(A+DPTR) →A(MOVC类指令共两条)MOVX Move External 与外部数据寄存区传送数据MOVX A , @DPTR;(DPTR)→A,DPTR间址单元内容送AMOVX @DPTR , A;A→(DPTR),A中内容送入DPTR间址单元MOVX A , @Ri;(Ri)→A,Ri间址单元内容送AMOVX @Ri , A;A→(Ri),A中内容送Ri间址单元(MOVX类指令4条)XCH Exchange 交换指令XCH A , Rn;Rn←→A , Rn的内容与A的内容交换XCH A , Direct; Direct ←→A ,直接地址的内容与A的内容交换XCH A , @Ri;(Ri)←→A ,间址的内容与A的内容交换XCHD Exchange Decimal十进制交换XCHD A , @Ri;(Ri.3~Ri.0) ←→A.3~A.0,间址内容低四位与A中内容低四位交换SWAP Swap 交换SWAP A;A.3~A.0←→ A.7~A.4 , A中低四位与高四位内容交换PUSH Push 入栈PUSH direct;SP+1→SP , (direct)→(SP);直接地址内容压入堆栈顶POP Pop 出栈POP direct;(SP)→(direct) , SP-1→SP;堆栈内容弹出到直接地址●算术运算类指令(7个助记符)ADD Add 加法运算ADD A , Rn;A + Rn→A , A与Rn的内容相加,结果送到A中ADD A , direct;(direct)+A→A,A与直接地址的内容相加,结果送到A中ADD A , @Ri;((Ri))+A→A, A与间址中的内容相加,结果送到A中ADD A , #data;data+A→A,A与立即数相加,和送入AADDC ADD with Carry 带进位加法ADDC A , Rn;A + Rn+CY→A , A与Rn的内容、进位状态相加,结果送到A中ADDC A , direct;(direct)+A+CY→A,A与直接地址的内容、进位状态相加,结果送到A中ADDC A , @Ri;((Ri))+A+CY→A, A与间址中的内容、进位状态相加,结果送到A中ADDC A , #data;data+A+CY→A,A与立即数、进位状态相加,和送入ASUBB Subbtract with Borrow 带进位减法SUBB A , Rn;A-Rn-CY→A,A减寄存器Rn的内容及进位标志,结果送ASUBB A , direct; A-(direct)-CY→A,A直接地址的内容及进位标志,结果送ASUBB A , @Ri; A-((Ri))-CY→A,A间址的内容及进位标志,结果送ASUBB A , #data; A-data-CY→A,A立即数及进位标志,结果送AMUL Multiply 乘法指令MUL AB;A x B→B和A,结果16位,高8位存入B,低8位存入A;若结果大于FFH,则将溢出标志OV置1DIV Divide 除法指令DIV AB;A÷B 商→A,余数→B;若除数为0,结果不确定,则将溢出标志OV置1INC Increment 加1指令INC A;A+1→A,A加1,结果放在AINC Rn; Rn +1→ Rn, Rn加1,结果放在RnINC direct; (direct)+1→ direct,直接地址的内容加1,结果放在该地址中INC @Ri;((Ri))+1→( Ri),间址中的内容加1,结果放在该间址中INC DPTR;(DPTR)+1→DPTR,数据指针内容加1,结果放在数据指针寄存器(DPTR)中DEC Decrement 减1指令INC A;A-1→A,A减1,结果放在AINC Rn; Rn -1→ Rn, Rn减1,结果放在RnINC direct; (direct)-1→ direct,直接地址的内容减1,结果放在该地址中INC @Ri;((Ri))-1→( Ri),间址中的内容减1,结果放在该间址中DA Decimal Adjust 十进制加法调整指令DA A;在加法指令后,把A中二进制码自动调整为BCD码;DA A只能更跟在ADD或ADDC加法指令后,不适用于减法●逻辑运算指令(9个助记符)ANL Logical And 逻辑与运算ANL A , Rn; (A)与(Rn)→A, A的内容与Rn中的内容相与,结果放在A中ANL A , direct; (A)与(direct)→A, A的内容与直接地址中的内容相与,结果放在A中ANL A , @Ri; (A)与((Ri))→A, A的内容与间址的内容相与,结果放在A中ANL A , #data; (A)与(data)→A, A的内容与立即数相与,结果放在A中ANL direct , A; (direct)与(A)→direct, 直接地址中的内容相与A的内容相与,结果放在直接地址中ANL direct , #data;(direct)与#data→direct, 直接地址中的内容相与立即数相与,结果放在直接地址中ORL Logical OR 逻辑或运算ORL A , Rn; (A) 或(Rn)→A, A的内容与Rn中的内容相或,结果放在A中ORL A , direct; (A) 或(direct)→A, A的内容与直接地址中的内容相或,结果放在A中ORL A , @Ri; (A) 或((Ri))→A, A的内容与间址的内容相或,结果放在A中ORL A , #data; (A) 或(data)→A, A的内容与立即数相或,结果放在A中ORL direct , A; (direct) 或A)→direct, 直接地址中的内容相与A的内容相或,结果放在直接地址中ORL direct , #data;(direct) 或#data→direct, 直接地址中的内容相与立即数相或,结果放在直接地址中XRL Logical exclusive or 逻辑异或运算ORL A , Rn; (A) 异或(Rn)→A, A的内容与Rn中的内容相异或,结果放在A中ORL A , direct; (A) 异或(direct)→A, A的内容与直接地址中的内容相异或,结果放在A中ORL A , @Ri; (A) 异或((Ri))→A, A的内容与间址的内容相异或,结果放在A中ORL A , #data; (A) 异或(data)→A, A的内容与立即数相异或,结果放在A中ORL direct , A; (direct) 或A)→direct, 直接地址中的内容相与A的内容相异或,结果放在直接地址中ORL direct , #data;(direct) 异或#data→direct, 直接地址中的内容相与立即数相异或,结果放在直接地址RL Rotate Left 循环左移指令RL A;每执行一次,A中的内容左移一位RR Rotate Right 循环右移指令RR A;每执行一次,A中的内容右移一位RLC Rotate Left with the Carry flag 带进位循环左移指令RLC A;每执行一次,CY和A中的内容左移一位RRC Rotate Right with the Carry flag带进位循环又移指令RRC A;每执行一次,CY和A中的内容右移一位注意:循环移位指令只能对A中的内容进行移位操作CPL Complement 取反指令(求补指令)CPL A;累加器内容按位取反,0变1,1变0CLR Clear 清零指令CLR A;累加器清零(A各位全变为0)●控制转移指令(9个助记符)LJMP Long Jump 长跳转指令LJMP add16;add16→PC,无条件跳转到add16地址,可在64KB范围内转移AJMP Absolute Jump 绝对跳转指令AJMP add11;add11→PC,无条件跳转到add11地址,可在2KB范围内转移SJMP Short Jump 短跳转指令SJMP rel;PC+2+rel→PC,rel是偏移量,8位有符号数(-127~127),可向前后跳转±128个地址单元JMP Jump 跳转指令JMP @A+DPTR;A+DPTR→PC,属于散转指令,无条件转向A与DPTR内容相加后形成的新地址JZ Jump if acc is Zero累加器为零转移JZ rel;A=0转向PC+2+rel→PC,A≠0,顺序执行JNZ Jump if acc is Not Zero累加器不为零转移JNZ rel;A≠0转向PC+2+rel→PC,A=0,顺序执行CJNE Compare and Jump if Not Equal比较不相等则转移CJNE A , direct , rel;A≠(direct)转向PC+3+rel→PC,否则顺序执行(PC+3 →PC);(A)>(direct)CY=0, (A)<(direct)CY=1CJNE A , #data , rel;A≠(data)转向PC+3+rel→PC,否则顺序执行(PC+3 →PC);(A)>(data)CY=0,( A)<(data)CY=1CJNE Rn , #data , rel; Rn≠(data)转向PC+3+rel→PC,否则顺序执行(PC+3 →PC); (Rn) >(data)CY=0, (Rn) <(data)CY=1CJNE @Ri , #data , rel;((Ri))≠(data)转向PC+3+rel→PC,否则顺序执行(PC+3 →PC); ((Ri))>(data)CY=0, ((Ri)) <(data)CY=1DJNE Decrement and Jump if Not Zero 减1不为0则转移DJNE Rn , rel;Rn-1→Rn, Rn≠0转向PC+2+rel→PC,否则顺序执行(PC+2→PC)DJNZ direct , rel;(direct-1)→direct, direct≠0转向PC+2+rel→PC,否则顺序执行(PC+2→PC)LCALL Long Call 长条用指令LCALL addr16;调用程序入口地址为addr16的之程序ACALL Absolute Call短调用ACALL addr11;调用程序入口地址为addr11的之程序RET ReturnRET;放在子程序最后,使程序准确返回到主程序断点处RETI Return from InterruptRETI;中断返回指令,能清楚优先级状态NOP No Operation 空操作指令NOP;空操作,产生一个机器周期延时●位操作指令MOV Move 数据传送指令MOV C , bit;(bit)→C,寻址位的状态送入CMOV bit , C;(C)→bit,C的转态送入地址中CLR Clear 清零指令CLR C;0→C,清零累加器CLR bit;清零直接寻址位CPL Complement 取反指令(求补指令)CPL C;c取反CPL bit;直接寻址位取反SETB Set Bit 置位SETB C;C置1SETB bit;直接寻址位置1ANL And Logical 与逻辑运算ANL C , bit;直接寻址位与C相与,结果放在CANL C , /bit; 直接寻址位与非C相与,结果放在CORL OR Logical 或逻辑运算ORL C , bit;直接寻址位与C相或,结果放在CORL C , /bit; 直接寻址位与非C相或,结果放在CJC Jump if Carry is set 进位位为1则转移JC rel;C=1,转向PC+2+rel→PC,否则顺序执行PC+2→PCJNC Jump if Carry is Not set 进位位为不为1则转移JNC rel;C=0,转向PC+2+rel→PC,否则顺序执行PC+2→PCJB Jump if Bit is set 进位位为1则转移JB bit , rel;(bit)=1,转向PC+3+rel→PC,否则顺序执行PC+3→PCJNB Jump if Bit is Not set 进位位为1则转移JNB bit , rel;(bit)=0,转向PC+3+rel→PC,否则顺序执行PC+3→PCJBC Jump if Bit is set and Clear bit指定位等于1转移并清该位JBC bit , rel; (bit)=1,转向PC+3+rel→PC,同时0→bit否则顺序执行PC+3→PC伪指令ORG Origin 代码起始地址指令ORG 0000HMOV A , #0010H;这条指令从0000H这个地址单元开始写起END End 汇编程序结束指令END;汇编指令结束DB字节定义伪指令ORG 1000HDB 01H , 02H;则(1000H)=01H,(1001H)=02HORG 1100HDB ‘01’;则(1100H)=30H,30H是0的ASCII码,(1101H)=31H,31H是1的ASCII码DW双字节定义伪指令ORG 2000HDW 2546H , 0178H; (2000H)=25H, (2001H)=46H, (2002H)=01H, (2003H)=78H,EQU数据赋值伪指令X EQU n;将n的值赋给xBIT位数据赋值伪指令y BIT b;y是用户定义标号,b为0或1MACRO宏指令宏指令名MACRO 形式参数······代码段······ENDM;宏指令定义结束寻址方式及相关的存储空间寻址方式寻址范围寄存器寻址R0~R7A 、B、C(CY)、AB(双字节)、DPTR(双字节)、PC(双字节)直接寻址内部RAM低128字节特殊功能寄存器内部RAM位寻区的128个位特殊功能寄存器中可寻址的位寄存器间接寻址内部数据存储器RAM【@R0,@R1,@SP(仅PUSH,POP)】内部数据存储器单元的低4位(@R0,@R1)外部RAM或I/O口(@R0,@R1,@DPTR)立即寻址程序存储器(常数)程序存储器(@A+PC,@A+DPTR)基寄存器加变址寄存器间接寻址。
51单片机常见汇编程序实验代码
51单片机常见汇编程序实验代码1. 将片外8000H-80FFH单元写入数据AB 32. 将片内RAM20H单元中数据在数码管上显示出来 (3)3. 将片内ARM30H-40H单元清零 54. 将六位数显示在数码管上 55. 8255并口芯片的应用:交通灯控制系统的设计 (6)6. 将交通灯点亮 (7)7. AD转换实验 (8)8. DA转换实验 (10)9. 定时器的应用 ·· 1110. 开关控制LED的亮灭及速度 1211. 计数器实验 (12)12. 串并转换实验 · 1413. 直流电机速度检测1514. 8255PB外接8个开关,编程将开关状态显示在数码管上(串并转换动态扫描方式)17 15. P3.4接开关K,编程将开关拨动次数,通过串并转换的方式进行显示1816. 比较片内RAM30H、31H两个单元值的大小,将较大的数显示在数码管上1917. 单片机P1口接8个开关,编程将开关状态显示在数码管上(串并转换动态扫描方式) (21)18. 将片内50H单元的值显示在数码管上2219. 开关K1接P1.0,K2接P1.1,编程实现当按下K1时在数码管上显示50H单元的值,按下K2在数码管上显示51H单元的值231. 将片外8000H-80FFH单元写入数据ABORG 0000H ;程序从0000H开始执行AJMP MAIN ;跳转到主程序ORG 0030H ;以免覆盖中断MAIN: MOV SP,#60H; 避免堆栈和工作寄存器区冲突MOV DPTR,#8000HMOV R0,#0LOOP: MOV A,#0ABHMOVX @DPTR,AINC DPTRINC R0CJNE R0,#0,LOOP ; 判断AJMP $; 等待END ;调试-视图-M存储器(输入X:8000H)2. 将片内RAM20H单元中数据在数码管上显示出来ORG 0000H ;程序从0000H开始执行AJMP MAIN ;跳转到主程序ORG 0030H ;以免覆盖中断MAIN: MOV SP,#60H ;避免堆栈和工作寄存器区冲突MOV DPTR,#0E100H ;指向命令口MOV A,#03H ;PA、PB口输出MOVX @DPTR,A ;所有并口显示程序先进行8155初始化MOV 20H,#34HMOV A,20HACALL CHAILOOP: MOV R0,#10H ;第一个显示数的送R0MOV R1,#2 ;显示2个数MOV R2,#1 ;从倒数第一个数码管开始显示ACALL DISPLAYLJMP LOOP ;判断CHAI: MOV B,#10HDIV ABMOV 10H,BMOV 11H,ARETDISPLAY: MOV A,@R0MOV 0FH,#8ACALL P164ACALL PBITACALL DELAYMOV A,#0MOVX @DPTR,AINC R0DJNZ R1,DISPLAYRETP164: MOV DPTR,#TABMOVC A,@A+DPTRP164_1: RRC AMOV R3,AMOV ACC.0,CANL A,#0FDHMOV DPTR,#0E102HMOVX @DPTR,AORL A,#0FEHMOVX @DPTR,AMOV A,R3DJNZ 0FH,P164_1MOV 0FH,#8RETPBIT: MOV DPTR,#0E101HMOV A,R2MOVX @DPTR,ARL AMOV R2,ARETDELAY: MOV R6,#4DEL: MOV R7,#250DJNZ R7,$DJNZ R6,DELRETTAB: DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0H DB 0FEH,0F6H,0EEH,3EH,9CH,7AH,9EH,8EHEND3. 将片内ARM30H-40H单元清零ORG 0000H ;程序从0000H开始执行AJMP MAIN ;跳转到主程序ORG 0030H ;以免覆盖中断MAIN: MOV SP,#60H ;避免堆栈和工作寄存器区冲突MOV R0,#30HMOV A,#0LOOP: MOV @R0,AINC R0CJNE R0,#41H,LOOP ;判断AJMP $ ;等待END ;D:30H4. 将六位数显示在数码管上ORG 0000H ;程序从0000H开始执行AJMP MAIN ;跳转到主程序ORG 0030H ;以免覆盖中断MAIN: MOV SP,#60H ;避免堆栈和工作寄存器区冲突MOV DPTR,#0E100H ;指向命令口MOV A,#03H ;PA、PB口输出MOVX @DPTR,A ;所有并口显示程序先进行8155初始化LOOP: MOV R0,#10H ;第一个显示数的送R0MOV 10H,#0HMOV 11H,#3HMOV 12H,#1HMOV 13H,#2HMOV 14H,#1HMOV 15H,#1HMOV R1,#6 ;显示6个数MOV R2,#1 ;从倒数第一个数码管开始显示ACALL DISPLAYLJMP LOOPDISPLAY: MOV A,@R0MOV 0FH,#8ACALL P164ACALL PBITACALL DELAYMOV A,#0MOVX @DPTR,AINC R0DJNZ R1,DISPLAYRETP164: MOV DPTR,#TABMOVC A,@A+DPTRP164_1: RRC AMOV R3,AMOV ACC.0,CANL A,#0FDHMOV DPTR,#0E102HMOVX @DPTR,AORL A,#0FEHMOVX @DPTR,AMOV A,R3DJNZ 0FH,P164_1MOV 0FH,#8RETPBIT: MOV DPTR,#0E101HMOV A,R2MOVX @DPTR,ARL AMOV R2,ARETDELAY: MOV R6,#4DEL: MOV R7,#250DJNZ R7,$DJNZ R6,DELRETTAB: DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0HDB 0FEH,0F6H,0EEH,3EH,9CH,7AH,9EH,8EHEND5. 8255并口芯片的应用:交通灯控制系统的设计ORG 0000HAJMP STARTORG 0030HSTART: MOV DPTR,#0AC03HMOV A,#80HMOVX @DPTR,A //8155初始化(所有并口显示中都要先8155初始化)MOV R5,#0F0HACALL DENGMOV R1,#20ACALL DELAYMOV R0,#1LOOP01: MOV R5,#5AHACALL DENGMOV R1,#100ACALL DELAYDJNZ R0,LOOP01MOV R0,#3 // LED_2闪烁次数LOOP02: MOV R5, #0FAHACALL DENGMOV R1,#10ACALL DELAYMOV R5,#50HACALL DENGMOV R1,#10ACALL DELAYDJNZ R0,LOOP02MOV R5,#0A5HACALL DENGMOV R1,#100ACALL DELAYMOV R0,#3LOOP03: MOV R5, #0F5HACALL DENGMOV R1,#10ACALL DELAYMOV R5,#0A0HACALL DENGMOV R1,#10ACALL DELAYDJNZ R0,LOOP03AJMP LOOP01DENG: MOV DPTR,#0AC00H //8155 PA口输出MOV A,R5MOVX @DPTR,A //8155 PA口送出显示参数RET //100ms延时子程序DELAY: MOV R7,#200DEL: MOV R6,#229DJNZ R6,$DJNZ R7,DELDJNZ R1,DELAYRETEND6. 将交通灯点亮ORG 0000HAJMP STARTORG 0030HSTART: MOV DPTR,#0AC03HMOV A,#80HMOV DPTR,#0AC00HMOV A,#05AHMOVX @DPTR,AAJMP $END7. AD转换实验ORG 0000AJMP STARTORG 000BHAJMP INT_0ORG 0030H START: MOV SP,#60HMOV TMOD,#01HMOV TH0,#4BHMOV TL0,#0FDHMOV R4,#2SETB EASETB ET0SETB TR0MOV DPTR,#0E100HMOV A,#3MOVX @DPTR,AMOV 22H,#9MOV 23H,#0MOV 24H,#8MOV 25H,#0 LOOP: MOV R0,#20HMOV R1,#6MOV R2,#1ACALL DISPLAYSJMP LOOPINT_0: MOV TH0,#4BHMOV TL0,#0FDHDJNZ R4,EXITPUSH ACCPUSH DPHPUSH DPLMOV DPTR,#0A000HMOVX A,@DPTRMOV B,#10HDIV ABMOV 21H,AMOVX @DPTR,AMOV R4,#2POP DPLPOP DPHPOP ACCEXIT: RETIDISPLAY: MOV A,@R0MOV 0FH,#8ACALL P164ACALL PBITACALL DELAYMOV A,#0MOVX @DPTR,AINC R0DJNZ R1,DISPLAYRETP164: MOV DPTR,#TABMOVC A,@A+DPTRP164_1: RRC AMOV R3,AMOV ACC.0,CANL A,#0FDHMOV DPTR,#0E102HMOVX @DPTR,AORL A,#0FEHMOVX @DPTR,AMOV A,R3DJNZ 0FH,P164_1MOV 0FH,#8RETPBIT: MOV DPTR,#0E101HMOV A,R2MOVX @DPTR,ARL AMOV R2,ARETDELAY: MOV R6,#4DEL: MOV R7,#250DJNZ R7,$DJNZ R6,DELRETTAB: DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0H DB 0FEH,0F6H,0EEH,3EH,9CH,7AH,9EH,8EHEND8. DA转换实验ORG 0000SJMP STARTORG 0030HSTART: MOV SP,#60HMOV A,#0LOOP1: MOV DPTR,#0B000HMOVX @DPTR,AACALL XSACALL DELAYINC ACJNE A,#0FFH,LOOP1LOOP2: MOV DPTR,#0B000HMOVX @DPTR,AACALL XSACALL DELAYDEC ACJNE A,#0,LOOP2SJMP LOOP1XS: PUSH ACCMOV DPTR,#TABMOV B,#51DIV ABMOV R1,AXCH A,BMOV B,#5DIV ABMOVC A,@A+DPTRMOV R4,#8ACALL S164MOV A,R1MOVC A,@A+DPTRMOV R4,#8ACALL S164MOV A,#0CLR CMOV R4,#16ACALL S164POP ACCRETS164: RRC AMOV P1.0,CCLR P1.1SETB P1.1DJNZ R4,S164RETDELAY: MOV R7,#200DEl: MOV R6,#229DJNZ R6,$DJNZ R7,DELRETTAB: DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0H DB 0FEH,0F6H,0EEH,3EH,9CH,7AH,9EH,8EHEND9. 定时器的应用ORG 0000HAJMP STARTORG 00BHAJMP INT_0ORG 0030HSTART: MOV TMOD,#01HMOV TH0,#4BHMOV TL0,#0FDHMOV R0,#20MOV R1,#0SETB ET0SETB TR0SETB EAAJMP $INT_0: MOV TH0,#4BHMOV TL0,#0FDHDJNZ R0,EXITMOV R0,#20MOV A,R1MOV DPTR,#TABMOVC A,@A+DPTRMOV P1,AINC R1CJNE R1,#8,EXITMOV R1,#0EXIT: RETITAB: DB 0FFH,0FAH,0F5H,0AFH,05FH,0AAH,55H,0H,0FFH END10. 开关控制LED的亮灭及速度ORG 0000H ;程序从0000H开始执行AJMP START ;跳转到主程序ORG 0030H ;以免覆盖中断START: MOV R4,#1 ;立即数传送到累加器LOOP: CLR P3.3 ;进位标志位清零LOOP1: JNB P3.5,LOOP ;直接寻址位为0则转移JB P3.4,LOOP2 ;直接寻址位为1则转移JNB P3.4,$INC R4 ;寄存器增1LOOP2: CPL P3.3 ;累加器求反MOV A,R4 ;寄存器内容传送到累加器AMOV R5,A ;累加器内容传送到累加器ACALL DELAY ;调用延时函数AJMP LOOP1 ;循环DELAY: MOV R6,#200DEL: MOV R7,#229DJNZ R7,$DJNZ R6,DEL ;寄存器减1,不为0则转移DJNZ R5,DELAYRET ;子程序返回END11. 计数器实验ORG 0000SJMP STARTORG 001BHLJMP INT_1START: MOV SP,#60HMOV R5,#20MOV TMOD,#15HMOV TH1,#4BHMOV TL1,#0FDHMOV TH0,#0MOV TL0,#0SETB ET1SETB EASETB TR1SETB TR0MOV DPTR,#0E100HMOV A,#3MOVX @DPTR,ALOOP: MOV R0,#50H;MOV R1,#4LCALL DISPLAYSJMP LOOPINT_1: MOV TH1,#4BHMOV TL1,#0FDHDJNZ R5,CONMOV R5,#20PUSH ACCPUSH BMOV A,TL0MOV B,#10HDIV ABMOV 50H,BMOV 51H,AMOV A,TH0MOV B,#10HDIV ABMOV 52H,BMOV 53H,AMOV TH0,#0MOV TL0,#0POP BPOP ACCCON: RETIDISPLAY: MOV A,@R0MOV 0FH,#8ACALL P164ACALL PBITACALL DELAYMOV A,#0MOVX @DPTR,AINC R0DJNZ R1,DISPLAYRETP164: MOV DPTR,#TABMOVC A,@A+DPTR P164_1: RRC AMOV R3,AMOV ACC.0,CANL A,#0FDHMOV DPTR,#0E102HMOVX @DPTR,AORL A,#0FEHMOVX @DPTR,ADJNZ 0FH,P164_1MOV 0FH,#8RETPBIT: MOV DPTR,#0E101HMOV A,R2MOVX @DPTR,ARL AMOV R2,ARETDELAY: MOV R6,#4DEL: MOV R7,#250DJNZ R7,$DJNZ R6,DELRETTAB: DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0H DB 0FEH,0F6H,0EEH,3EH,9CH,7AH,9EH,8EHEND12. 串并转换实验ORG 0000SJMP STARTORG 0030HSTART: MOV SP,#60HMOV R1,#0MOV DPTR,#TABLOOP: MOV A,#0CLR CMOV R4,#24ACALL S164MOV A,R1MOVC A,@A+DPTRMOV R4,#8ACALL S164INC R1MOV R5,#10ACALL DELAYCJNE R1,#10,EXITMOV R1,#0EXIT: SJMP LOOPS164: RRC AMOV P1.0,CCLR P1.1SETB P1.1DJNZ R4,S164RETDELAY: MOV R6,#200DEL: MOV R7,#230DJNZ R7,$DJNZ R6,DELDJNZ R5,DELAYRETTAB: DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0H, 0FEH,0F6H END13. 直流电机速度检测ORG 0000HAJMP MAINORG 001BHAJMP INT_1ORG 0030HMAIN: MOV SP,#60HMOV TMOD,#15HMOV TH1,#4BHMOV TL1,#0FDHMOV R0,#20MOV TH0,#0MOV TL0,#0SETB ET1SETB EASETB TR0SETB TR1MOV R2,#00HUP: MOV A,R2MOV DPTR,#0A000H //注意片选接YC2,非YC3MOVX @DPTR,AMOV R5,#1ACALL DELAY ;100msINC R2CJNE R2,#0FFH,UPDOWN:MOV A,R2MOV DPTR,#0A000HMOVX @DPTR,AMOV R5,#1ACALL DELAY ;100msDEC R2CJNE R2,#00H,DOWNAJMP UPINT_1: MOV TH1,#4BHMOV TL1,#0FDHDJNZ R0,EXITMOV R0,#20PUSH ACCPUSH DPHPUSH DPLMOV A,TL0ACALL XSMOV TL0,#0MOV A,TH0ACALL XSMOV TH0,#0POP DPLPOP DPHPOP ACCEXIT: RETIXS: MOV DPTR,#TAB;MOV A,R2MOV B,#10 ;显示10进制数DIV ABXCH A,B;MOV DPTR,#TABMOVC A,@A+DPTRACALL FSXCH A,B;MOV DPTR,#TABMOVC A,@A+DPTRACALL FSRETFS: MOV R1,#8YW:RRC AMOV P1.0,CCLR P1.1SETB P1.1DJNZ R1,YWRETDELAY:MOV R6,#200DEL:MOV R7,#230DJNZ R7,$DJNZ R6,DELDJNZ R5,DELAYRETTAB:DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0HDB 0FEH,0F6H,0EEH,3EH,9CH,7AH,9EH,8EHEND14. 8255PB外接8个开关,编程将开关状态显示在数码管上(串并转换动态扫描方式)ORG 0000AJMP STARTORG 0030HSTART: MOV DPTR,#0AC03HMOV A, #82HMOVX @DPTR, AMOV DPTR,#0E100HMOV A,#3MOVX @DPTR,ALOOP: MOV DPTR,#0AC01HMOVX A,@DPTRMOV B,#10HDIV ABMOV 10H,BMOV 11H,AMOV R0,#10HMOV R1,#2MOV R2,#1ACALL DISPLAYSJMP LOOPDISPLAY:MOV A,@R0MOV 0FH,#8ACALL P164ACALL PBITACALL DELAYMOV A,#0MOVX @DPTR,AINC R0DJNZ R1,DISPLAYRETP164: MOV DPTR,#TABMOVC A,@A+DPTRP164_1: RRC AMOV R3,AMOV ACC.0,CANL A,#0FDHMOV DPTR,#0E102HMOVX @DPTR,AORL A,#0FEHMOVX @DPTR,ADJNZ 0FH,P164_1MOV 0FH,#8RETPBIT: MOV DPTR,#0E101HMOV A,R2MOVX @DPTR,ARL AMOV R2,ARETDELAY: MOV R6,#4DEL: MOV R7,#250DJNZ R7,$DJNZ R6,DELRETTAB:DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0HDB 0FEH,0F6H,0EEH,3EH,9CH,7AH,9EH,8EHEND15. P3.4接开关K,编程将开关拨动次数,通过串并转换的方式进行显示ORG 0000SJMP STARTORG 0030HSTART: MOV SP,#60HMOV R5,#0LOOP: JB P3.4,$ACALL DELAYJB P3.4,LOOPINC R5ACALL XSLOOP1: JNB P3.4,$ACALL DELAYJNB P3.4,LOOP1INC R5ACALL XSSJMP LOOPDELAY: MOV R7,#200DEL: MOV R6,#229DJNZ R6,$DJNZ R7,DELRETXS: MOV DPTR,#TABMOV A,R5MOV B,#10HMOV R1,AMOV A,BMOVC A,@A+DPTRMOV R4,#8ACALL S164MOV A,R1MOVC A,@A+DPTRMOV R4,#8ACALL S164MOV A,#0CLR CMOV R4,#16ACALL S164RETS164: RRC AMOV P1.0,CCLR P1.1SETB P1.1DJNZ R4,S164RETTAB: DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0HDB 0FEH,0F6H,0EEH,3EH,9CH,7AH,9EH,8EHEND16. 比较片内RAM30H、31H两个单元值的大小,将较大的数显示在数码管上ORG 0000SJMP STARTORG 0030HSTART: MOV SP,#60HMOV DPTR,#0E100HMOV A,#3MOVX @DPTR,AMOV 30H,#06H ;随便赋两个值,显示较大的MOV 31H,#11HMOV A,30HSUBB A,31HJC SMALLMOV B,#10HMOV A,30HDIV ABMOV 30H,BMOV 31H,ABIG: MOV R0,#30HMOV R1,#2MOV R2,#1ACALL DISPLAYSJMP BIG SMALL: MOV B,#10HMOV A,31HDIV ABMOV 30H,BMOV 31H,ASMALL1:MOV R0,#30HMOV R1,#2MOV R2,#1ACALL DISPLAYSJMP SMALL1 DISPLAY:MOV A,@R0MOV 0FH,#8ACALL P164ACALL PBITACALL DELAYMOV A,#0MOVX @DPTR,AINC R0DJNZ R1,DISPLAYRETP164: MOV DPTR,#TABMOVC A,@A+DPTR P164_1: RRC AMOV R3,AMOV ACC.0,CANL A,#0FDHMOV DPTR,#0E102HMOVX @DPTR,AORL A,#0FEHMOVX @DPTR,AMOV A,R3DJNZ 0FH,P164_1MOV 0FH,#8RETPBIT: MOV DPTR,#0E101HMOV A,R2MOVX @DPTR,ARL AMOV R2,ARETDELAY: MOV R6,#4DEL: MOV R7,#250DJNZ R7,$DJNZ R6,DELRETTAB:DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0HDB 0FEH,0F6H,0EEH,3EH,9CH,7AH,9EH,8EHEND17. 单片机P1口接8个开关,编程将开关状态显示在数码管上(串并转换动态扫描方式)ORG 0000HSJMP STARTORG 0030HSTART: MOV SP,#60HMOV DPTR,#0E100HMOV A,#3MOVX @DPTR,ALOOP: MOV A,P1MOV B,#10HDIV ABMOV 20H,BMOV 21H,AMOV R0,#20HMOV R1,#2MOV R2,#1ACALL DISPLAYAJMP LOOPDISPLAY:MOV A,@R0MOV 0FH,#8ACALL P164ACALL PBITACALL DELAYMOV A,#0MOVX @DPTR,AINC R0DJNZ R1,DISPLAYRETP164: MOV DPTR,#TABMOVC A,@A+DPTRP164_1: RRC AMOV R3,AMOV ACC.0,CANL A,#0FDHMOV DPTR,#0E102HMOVX @DPTR,AORL A,#0FEHMOVX @DPTR,AMOV A,R3DJNZ 0FH,P164_1MOV 0FH,#8RETPBIT: MOV DPTR,#0E101HMOV A,R2MOVX @DPTR,ARL AMOV R2,ARETDELAY: MOV R6,#4DEL: MOV R7,#250DJNZ R7,$DJNZ R6,DELRETTAB:DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0H DB 0FEH,0F6H,0EEH,3EH,9CH,7AH,9EH,8EHEND18. 将片内50H单元的值显示在数码管上ORG 0000HSJMP STARTORG 0030HSTART: MOV SP,#60HMOV DPTR,#0E100HMOV A,#3MOVX @DPTR,ALOOP: MOV A,P1MOV B,#10HDIV ABMOV 20H,BMOV 21H,AMOV R0,#20HMOV R1,#2MOV R2,#1ACALL DISPLAYAJMP LOOPDISPLAY:MOV A,@R0MOV 0FH,#8ACALL P164ACALL PBITACALL DELAYMOV A,#0MOVX @DPTR,AINC R0DJNZ R1,DISPLAYRETP164: MOV DPTR,#TABMOVC A,@A+DPTRP164_1: RRC AMOV R3,AMOV ACC.0,CANL A,#0FDHMOV DPTR,#0E102HMOVX @DPTR,AORL A,#0FEHMOVX @DPTR,AMOV A,R3DJNZ 0FH,P164_1MOV 0FH,#8RETPBIT: MOV DPTR,#0E101HMOV A,R2MOVX @DPTR,ARL AMOV R2,ARETDELAY: MOV R6,#4DEL: MOV R7,#250DJNZ R7,$DJNZ R6,DELRETTAB:DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0HDB 0FEH,0F6H,0EEH,3EH,9CH,7AH,9EH,8EHEND19. 开关K1接P1.0,K2接P1.1,编程实现当按下K1时在数码管上显示50H单元的值,按下K2在数码管上显示51H单元的值ORG 0000SJMP STARTORG 0030HSTART: MOV SP,#60HMOV DPTR,#0E100HMOV A,#3MOVX @DPTR,AMOV 50H,#18H ;50H,51H 随便赋两个值MOV 51H,#22HLOOP:JB P1.0,D50JB P1.1,D51SJMP LOOPD51: MOV R0,#10HMOV R1,#2MOV R2,#1MOV A,51HMOV B,#10HDIV ABMOV 10H,BMOV 11H,AACALL DISPLAYSJMP LOOPD50: MOV R0,#10HMOV R1,#2MOV R2,#1MOV A,50HMOV B,#10HDIV ABMOV 10H,BMOV 11H,AACALL DISPLAYSJMP LOOPDISPLAY:MOV A,@R0MOV 0FH,#8ACALL P164ACALL PBITACALL DELAYMOV A,#0MOVX @DPTR,AINC R0DJNZ R1,DISPLAYRETP164:MOV DPTR,#TABMOVC A,@A+DPTRP164_1:RRC AMOV R3,AMOV ACC.0,CANL A,#0FDHMOV DPTR,#0E102HMOVX @DPTR,AORL A,#0FEHMOVX @DPTR,AMOV A,R3DJNZ 0FH,P164_1MOV 0FH,#8RETPBIT:MOV DPTR,#0E101HMOV A,R2MOVX @DPTR,ARL AMOV R2,ARETDELAY:MOV R6,#4DEL:MOV R7,#250DJNZ R7,$DJNZ R6,DELRETTAB:DB 0FCH,60H,0DAH,0F2H,66H,0B6H,0BEH,0E0H DB 0FEH,0F6H,0EEH,3EH,9CH,7AH,9EH,8EHEND。
51单片机C语言程序设计源代码
新概念51单片机C语言教程----入门、提高、开发、拓展全攻略郭天祥编著电子工业出版社例2.2.1编写程序,点亮第一个发光二极管(part2_1.c P27)#include <reg52.h> //52系列单片机头文件sbit led1=P1^0; //声明单片机P1口的第一位void main() //主函数{led1=0; /*点亮第一个发光二极管*/}例2.2.2编写程序,点亮P1口的若干二极管(part2_2.c P39)#include <reg52.h> //52系列单片机头文件void main() //主函数{P1=0xaa;//while(1);}例2.5.1利用for语句延时特性,编写第一个发光二极管以间隔1S亮灭闪动的程序(part2_3.c P42)#include <reg52.h> //52系列单片机头文件#define uint unsigned int //宏定义sbit led1=P1^0; //声明单片机P1口的第一位uint i,j;void main() //主函数{while(1) //大循环{led1=0; /*点亮第一个发光二极管*/for(i=1000;i>0;i--) //延时for(j=110;j>0;j--);led1=1; /*关闭第一个发光二极管*/for(i=1000;i>0;i--) //延时for(j=110;j>0;j--);}}- 2 -例2.6.1编写程序使第一个发光二极管以间隔500ms亮灭闪动。
(part2_4.c P48)#include <reg52.h> //52系列单片机头文件#define uint unsigned int //宏定义sbit led1=P1^0; //声明单片机P1口的第一位void delay1s(); //声明子函数void main() //主函数{while(1) //大循环{led1=0; /*点亮第一个发光二极管*/delay1s(); //调用延时子函数led1=1; /*关闭第一个发光二极管*/delay1s(); //调用延时子函数}}void delay1s() //子函数体{uint i,j;for(i=500;i>0;i--)for(j=110;j>0;j--);}例2.7.1编写程序使第一个二极管以亮200ms、灭800ms的方式闪动。
MCS-51单片机汇编语言编程实例
例3
步进电机
任务2:定时器中断实现演示程序
TIME: CJNE R2,#0,TIM0 ;R2不等于0则是慢速,跳转 ;;;;;;;快速,60转/分 MOV TH0,#5BH MOV TL0,#0F0H SETB TR0 MOV R1,#0H TIM1: CJNE R1,#1H,TIM1 SJMP TIM2 ;;;;;;;;慢速,10转/分 TIM0: MOV R3,#2H TIM4: MOV TH0,#0H MOV TL0,#0H SETB TR0 MOV R1,#0H
0000H 90H R1 , #100 R0 , #100 R0 , LOOP1 R1 , LOOP1 LOOP
例2 跑马灯
任务:D1,D2,D3循环亮灭, D1 →D2→D3 ↑ ↓ 一个时间只有一个亮, 每个1秒转换一次。
VCC
VCC
VCC
1
1
D1
D2
D3
2
2
R1
R2
R3 1 2 3 P1.0 P1.1 P1.2 89C51
例1
方波产生
任务:从P1.0引脚输出一个方波
VCC
D0
R1 1 P1.0 89C51
2
1
程序1:
LOOP:
ORG CPL SJMP
0000H 90H LOOP
机器码 0000 0001 0002 0003 0004
B2 90 80 FC --
程序2:加软延时 ORG LOOP: CPL MOV MOV LOOP1: DJNZ DJNZ SJMP
L1:
例3
任务:主程序
51按键程序
#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intunsigned char code dis[]={"Hello World!"};unsigned char code dis1[]={"KEY:"};unsigned char code dis2[]={"TIME:"};uchar key_val[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G'};uchar codekey_code[]={0x77,0x7B,0x7D,0x7E,0xB7,0xBB,0xBD,0xBE,0xD7,0xDB,0xDD,0xDE,0xE7,0xEB,0xED,0 xEE};uchar key,x,count;uint time=0;sbit U3_DS=P1^5;sbit U3_STCP=P1^4;sbit U3_SHCP=P1^3;sbit U4_DS=P1^2;sbit U4_STCP=P1^1;sbit U4_SHCP=P1^0;void delay(unsigned int n);//74HC595void U3_595(unsigned char num){unsigned char count1;for (count1=0;count1<=7;count1++){if ((num&0x80)==0x80)//最高位为1,则向SDATA_595发送1{U3_DS=1;}else{U3_DS=0;}U3_SHCP=0;U3_SHCP=1;num<<=1;//左移}U3_STCP=0;U3_STCP=1;}void U4_595(unsigned char num)//发送指令到RS,RW,E(4,5,6位) {unsigned char count2;for (count2=0;count2<=7;count2++){if((num&0x80)==0x80){U4_DS=1;}else{U4_DS=0;}U4_SHCP=0;U4_SHCP=1;num<<=1;}U4_STCP=0;U4_STCP=1;}//LCD延时子程序n=1时延时1msvoid delay(unsigned int n){unsigned int i;for(;n>0;n--)for(i=0;i<255;i++)_nop_();}//写指令到LCDvoid wcmd(unsigned char cmd){U4_595(0x00);U3_595(cmd);U4_595(0x40);U4_595(0x00);}//写要显示的数据到LCDvoid wdat(unsigned char dat){U4_595(0x10);U3_595(dat);U4_595(0x50);U4_595(0x10);}//初始化LCDvoid init(){wcmd(0x38);//设置8位总线双行显示,5*7点阵delay(20);wcmd(0x0C);//开显示,开光标,不闪烁delay(20);wcmd(0x06);//读写字符时地址加1delay(20);wcmd(0x01);//清屏delay(20);wcmd(0x80+2);for(x=0;x<12;x++) //第一行显示hello world! wdat(dis[x]);delay(20);wcmd(0xC2);for(x=0;x<4;x++)//第二行显示按键和次数wdat(dis1[x]);wcmd(0xC8);for(x=0;x<5;x++)wdat(dis2[x]);TMOD=0x01;//中断设置TH0=0x3C;//定时初值设置TL0=0xB0;EA=1;//开中断ET0=1;//定时器0中断允许}//键盘扫描子程序uchar keyscan(void){unsigned char hang,lie,keycode; char i;P0=0xf0;hang=P0;if((hang&0xf0)!=0xf0) //有键按下?{delay(50); //去抖动hang=P0;if((hang&0xf0)!=0xf0) //有键按下{P0=0x0f;lie=P0;keycode=hang|lie; //获得键码for(i=15;i>=0;i--){if(keycode==key_code[i]) //查找键码{key=i;return(key);}}}}elseP0=0xff; //按键弹起则关闭定时器TR0=0;count=0;return (16);}}void keydown() //判断按键按下和显示程序{P0=0xf0;if((P0&0xf0)!=0xf0){TR0=1; //开启定时器while(P0!=0xf0)keyscan(); //获得键码if(count<30){time++;count=0;}else //超过1.5秒计数2次{time+=2;count=0;}wcmd(0xC6); //设置键值显示位置wdat(key_val[16-key]);wcmd(0xCD); //设置次数显示位置if(time<10)wdat(0x30+time);if(time>9&&time<100){wdat(0x30+time/10);wdat(0x30+time%10);if(time>99&&time<1000){wdat(0x30+time/100);wdat(0x30+time/10-(time/100)*10); wdat(0x30+time%10);}}}//中断函数void timer() interrupt 1{TH0=0x3C;TL0=0xB0;count++;}void main(void){init();for(;;){keydown();}}。
基于51单片机按键长按短按效果源程序
基于51单片机按键长按短按效果源程序基于51单片机按键长按短按效果源程序[复制链接]* 实验名称:多位数按键加减** 晶振:12MHZ* 内容:按键加减数字,多个数码管显示,使用定时器做数码管动态扫描** 并区别长按短按效果,完全可以应用的实际生产中** ---------------------------------------------------------------*/#include //包含头文件,一般情况不需要改动,//头文件包含特殊功能寄存器的定义sbit KEY_ADD=P3^3; //定义按键输入端口S17sbit KEY_DEC=P3^2; //S18#define DataPort P1 //定义数据端口程序中遇到DataPort 则用P1 替换sbit LATCH1=P2^0;//定义锁存使能端口段锁存sbit LATCH2=P2^1;// 位锁存sbit P35 = P3^5;//这是为了关闭开发板上的点阵实际应用去掉unsigned char code HEYAO_DuanMa[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};// 显示段码值0123456789unsigned char code HEYAO_WeiMa[]={0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80};//分别对应相应的数码管点亮,即位码unsigned char TempData[8]={0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF};//存储显示值的全局变量void DelayUs2x(unsigned char t);//函数声明void DelayMs(unsigned char t);void Init_Timer0(void);void Display(unsigned char FirstBit,unsigned char Num); /*------------------------------------------------主函数------------------------------------------------*/void main (void){unsigned char num=0,key_press_num;P35=0; //这是为了关闭开发板上的点阵实际应用去掉KEY_ADD=1; //按键输入端口电平置高KEY_DEC=1;Init_Timer0();while (1) //主循环{if(!KEY_ADD) //如果检测到低电平,说明按键按下DelayMs(10); //延时去抖,一般10-20msif(!KEY_ADD) //再次确认按键是否按下,没有按下则退出{ while(!KEY_ADD){key_press_num++;DelayMs(10); //10x200=2000ms=2sif(key_press_num==200) //大约2s{key_press_num=0; //如果达到长按键标准//则进入长按键动作while(!KEY_ADD) //这里用于识别是否按//键还在按下,如果按//下执行相关动作,否则退出{if(num<99) //加操作num++;//即时把显示数据处理,如果去掉下面2//句处理信息,实际上看不到渐变效果,//而是看到跳变效果//用户可以自行屏蔽测试//分解显示信息,如要显示68,则68/10=6 68%10=8 TempData[0]=HEYAO_DuanMa[num/10];TempData[1]=HEYAO_DuanMa[num%10];DelayMs(50);//用于调节长按循环操作//的速度,可以自行调整此值以便达到最佳效果}}}key_press_num=0;//防止累加造成错误识别if(num<99) //加操作num++;}}if(!KEY_DEC) //如果检测到低电平,说明按键按下{DelayMs(10); //延时去抖,一般10-20msif(!KEY_DEC) //再次确认按键是否按下,没有//按下则退出{while(!KEY_DEC)key_press_num++;DelayMs(10);if(key_press_num==200) //大约2s{key_press_num=0;while(!KEY_DEC){if(num>0) //减操作num--;//分解显示信息,如要显示68,则68/10=6 68%10=8 TempData[0]=HEYAO_DuanMa[num/10];TempData[1]=HEYAO_DuanMa[num%10];DelayMs(50);//用于调节长按循环操作的速度}}}key_press_num=0;//防止累加造成错误识别if(num>0) //减操作num--;}}//分解显示信息,如要显示68,则68/10=6 68%10=8 TempData[0]=HEYAO_DuanMa[num/10];TempData[1]=HEYAO_DuanMa[num%10];// Display(0,8); //显示全部8位//主循环中添加其他需要一直工作的程序}}/*------------------------------------------------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);}}/*------------------------------------------------显示函数,用于动态扫描数码管输入参数FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示如输入0表示从第一个显示。