首页技术单片机汇编程序100例?单片机程序设计范例汇总

单片机汇编程序100例?单片机程序设计范例汇总

编程之家2026-05-20754次浏览

大家好,今天小编来为大家解答单片机汇编程序100例这个问题,单片机程序设计范例汇总很多人还不知道,现在让我们一起来看看吧!

单片机汇编程序100例?单片机程序设计范例汇总

8051单片机的汇编程序编程问题!!!

既然向我求助,那我就写一下大概的思路和C语言程序,至于汇编语言,兄弟可自己由C语言翻译,我今天的确没太有时间.

周期为2个ms的方波,也就是说半个周期为1ms,也就是说,P1.2每1ms翻转一次;

同理,P1.3每3.5ms翻转一次,因为只能用一个定时器,所以,取1ms和3.5ms的最大公约数,是0.5ms,也就是说,让定时器0.5ms中断一次,然后每两个中断,翻转一次P1.2,每7个中断翻转一次P1.3;

这就是编程思路,那么我们来看具体的编程细节;

6Mhz,也就是指令周期是2us,0.5ms需要250个计数,250<256,为了速度和效率,我们让定时器1工作在自动重载模式下,也就是模式2;

C语言整个程序编程如下;

单片机汇编程序100例?单片机程序设计范例汇总

#include<reg52.h>

bit P1_2_Turn_Cnt= 0;//----用于P1.2的计数翻转,因为只有两次,大可不必用unsigned char类型的

unsigned char P1_3_Turn_Cnt= 0;//----用于P1.3的计数翻转,因为要7次,所以用unsigned char

sbit P1_3= P1^3;

sbt P1_2= P1^2;

void main(void)

{

//----初始化定时器,工作在模式2,自动重载,开中断,每0.5ms中断一次

TH1= 256- 250;//----设置定时器,250 X 2us= 500us= 0.5ms

TL1= 256-250;

TMOD= 0x20;//----定时器/计数器1工作在模式2下;

ET1= 1;//----开定时器1中断

TR1= 1;//-----启动定时器

EA= 1;//----开总中断

while(1);//----定时器初始化完成,方波工作在定时器内部完成;

}

void ISR_Timer1(void) interrupt 3

{

P1_2_Turn_Cnt=~P1_2_Turn_Cnt;//---P1_2翻转计数,由于初始化为0,所以第1次会翻转为1;

//---由此推论,奇数次翻转后状态为1,偶数次中断会翻转为

//---0,所以当P1_2_Turn_Cnt= 0时,P1_2翻转.

if(P1_2_Turn_Cnt== 0)

{

P1_2=~P1_2;

}

P1_3_Turn_Cnt++;

if(P1_3_Turn_Cnt>= 7)

{

P1_3_Turn_Cnt= 0;

P1_3=~P1_3;

}

}

以上就是这个程序实现的全部过程,你可以自己手动翻译成汇编语言,也可以用Keil的Debug模式自动翻译,因为我时间有限,所以就不给你翻译了,请见谅!

单片机汇编语言的几个疑问

1、如果程序代码空间不紧张的话,建议你全部使用LJMP,或者如果跳转的目标段程序相隔很近,也可以使用SJMP。个人认为AJMP最麻烦:其机器码所标注的地址位从A10到A0,计11位,000H~7FFH,也就是说跳转到的地址与当前地址的A10到A0必须一样,比如:

原来AJMP地址为:07F8H,目标地址:07F0H,如果调试软件修改后,变为

AJMP地址为:0800H,目标地址:07F8H,A11不一样,不在一页范围,此时还得将其改成LJMP,否则编译出错。其实就省了一个字节,执行时间上都是2个机器周期,没区别,所以犯不上。如果像此例,使用SJMP倒是个较好的选择,只是要求你对代码间的间隔有数才行。

总之,尽量用LJMP吧。

2、二者区别其实就是转移的目标是绝对地址,还是针对当前转移指令所在地址的相对偏移量

【绝对转移】51中只有AJMP、LJMP是绝对转移指令,都是直接跳转到固定地址。我们平时写的比如LJMP MAIN语句,源程序中并未表示出这一点,假设MAIN标志的程序段是从0102H开始的,此句编译后的机器码是02 01 02,02代表LJMP跳转,后两个字节0102则为目标地址,由于使用了2个字节指明目标地址,所以其范围就是整个64K的空间,没有限制;AJMP在这一点上就要差些,只能在所在的2K页内跳转。

【相对转移】剩下的转移指令都是相对转移指令,包括SJMP,它们是以当前语句的下一条语句所在地址为准,PC值向前或向后偏移数个字节地址开始执行,偏移量范围从-128到+127,以补码方式存在。比如

ORG 0100H

NO1: CLR A

SJMP NO1

编译后地址及机器码:

0100H: 0E4H(CLR A)

0101H: 80H 0FDH(SJMP NO1,从0103跳回0100,倒退3字节,3的补码即取反+1=FDH

0103H: 00H

3、要想能高效的调试大的汇编程序,首先要求程序本身的编制应该规范。关于这一点我有些感触,就算是经验吧,供参考(我曾经用汇编做过50多K机器码的程序)。

单片机的执行其实是单一线程的,一般只有两种情况会偏离原来的流程,一种是中断服务子程序,注意别忘了使用RETI;还有就是普通子程序,别忘了使用RET;再加上注意出栈、入栈操作,而且该操作因成对并保证先进后出原则,这样的话才真正做到模块化编程,调试时才能不理睬其它部份,单独调试某个模块,提高效率。这一点C语言就比较好,以函数方式实现,少写括号编译通不过,不像汇编,少些个RET照样能通过。

另外,编写程序时应养成一种习惯:对程序体中的寄存器操作尽量不要直接使用其地址,比如:MOV 30H,A,这里直接写30H不好,因为大的汇编程序对寄存器地址的调整是很常见的现象,一旦修改,程序中每个地方都要改,容易遗漏,一旦遗漏,非常难找原因的。可以用EQU伪指令对其定义,程序体中使用。同样,这一点C语言要好的多,至少不需要去分配寄存器了。

还有一个最容易出错的地方,就是关于标志位C:比如CJNE指令,它的判断是会影响C标志位的,如果程序后面有对C标志位判断的语句又没有考虑这种情况,问题极难查。很多人包括我自己会忽略这种细节。这类问题只能靠细致了。

最后谈谈调试

调试过程一般都是逐个模块(子程序)分别调试,完成一个再检查下一个,不能指望一上来就正确。调试完后还要多次、多人测试,自己有时形成了固定思维,发现不了问题。

终极方法:分部仿真设断点甚至于单步执行。对一些外部输入可以采用到断电后修改寄存器数值的方法来模拟。当然最理想的情况是不用,只是初期恐怕是免不了的。比如对上面所说的C标志位问题,我个人当初几乎都是这样找出的问题

大的汇编程序的调试确实比较麻烦,首先要求你对软件流程很清晰,对单片机的运行模式也要很了解。至于你现在的程序如果有问题,我建议还是采用仿真设断点的方式来找问题,尤其是如果搞单片机的时间不长的话,这样其实可能更快些。

希望所说能对你有所帮助。

单片机交通灯的汇编程序

NAME T3;I/O口扩展实验一

PORT EQU 0CFA0H;片选地址CS0

CSEG AT 0000H

LJMP START

CSEG AT 4100H

START: MOV A,#11H;两个红灯亮,黄灯、绿灯灭

ACALL DISP;调用273显示单元(以下雷同)

ACALL DE3S;延时3秒

LLL: MOV A,#12H;东西路口绿灯亮;南北路口红灯亮

ACALL DISP

ACALL DE10S;延时10秒

MOV A,#10H;东西路口绿灯灭;南北路口红灯亮

ACALL DISP

MOV R2,#05H;R2中的值为黄灯闪烁次数

TTT: MOV A,#14H;东西路口黄灯亮;南北路口红灯亮

ACALL DISP

ACALL DE02S;延时0.2秒

MOV A,#10H;东西路口黄灯灭;南北路口红灯亮

ACALL DISP

ACALL DE02S;延时0.2秒

DJNZ R2,TTT;返回TTT,使东西路口;黄灯闪烁五次

MOV A,#11H;两个红灯亮,黄灯、绿灯灭

ACALL DISP

ACALL DE02S;延时0.2秒

MOV A,#21H;东西路口红灯亮;南北路口绿灯亮

ACALL DISP

ACALL DE10S;延时10秒

MOV A,#01H;东西路口红灯亮;南北路口绿灯灭

ACALL DISP

MOV R2,#05H;黄灯闪烁五次

GGG: MOV A,#41H;东西路口红灯亮;南北路口黄灯亮

ACALL DISP

ACALL DE02S;延时0.2秒

MOV A,#01H;东西路口红灯亮;南北路口黄灯灭

ACALL DISP

ACALL DE02S;延时0.2秒

DJNZ R2,GGG;返回GGG,使南北路口;黄灯闪烁五次

MOV A,#03H;两个红灯亮,黄灯、绿灯灭

ACALL DISP

ACALL DE02S;延时0.2秒

JMP LLL;转LLL循环

DE10S: MOV R5,#100;延时10秒

JMP DE1

DE3S: MOV R5,#30;延时3秒

JMP DE1

DE02S: MOV R5,#02;延时0.2秒

DE1: MOV R6,#200

DE2: MOV R7,#126

DE3: DJNZ R7,DE3

DJNZ R6,DE2

DJNZ R5,DE1

RET

DISP: MOV DPTR,#PORT;273显示单元

CPL A

MOVX@DPTR,A

RET

END

你看看行不行如果不行你自己再稍微改一下吧反正大概就这些了

希望对你能有所帮助。

关于单片机汇编程序100例的内容到此结束,希望对大家有所帮助。

php数组求和函数?php处理数组的常用函数关系数据库管理系统(深信服终端安全管理系统)