⑴ 用汇编语言编程 8051
简单提示一下思路(条件1南北的是绿灯吧),P0口注意上拉电阻的问题,12盏灯,6盏一组,分别接在6个管脚上,开始时东西红灯和南北绿灯亮,定时2s,绿灯灭,点亮黄灯;定时1s,黄灯灭,红灯绿灯按要求变化。如此循环即可。在定时中断服务程序中CPL P0.x ;即可改变灯的亮灭状态。不想用中断也可以用循环延时。
⑵ 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语言整个程序编程如下;
#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模式自动翻译,因为我时间有限,所以就不给你翻译了,请见谅!
⑶ 编写简单的8051汇编语言程序(用KEIL编程环境)
1. ORG 0000H
MOV DPTR,#20H
MOV A,@DPTR
MOV 20H,30H
MOV 30H,A
RET
ORG 0000H
PUSH 20H
PUSH 30H
POP 20H
POP 30H
RET
2. ORG 0000H
MOV A,#34H
ADD A,78H
MOV R2,A
MOV A,12H
ADDC A,56H
MOV R1,A
RET
3. ORG 0000H
MOV R0,#10
MOV DPTR,#2FH
LOOP: INC DPTR
MOV A,@DPTR
CLR A
DJNZ R0,LOOP
RET
4.
DELAY: MOV R0,#4
D1: MOV R1,#297
D2: DJNZ R1,D2
DJNZ R0,D1
RET
⑷ 8051单片机的数字钟汇编程序
ORG 0000H ;程序执行开始地址
LJMP START ;跳到标号START执行
ORG 0003H ;外中断0中断程序入口
LJMP REMO ;外中断0中断返回
ORG 000BH ;定时器T0中断程序入口
LJMP TIME0 ;跳至INTTO执行
ORG 0013H ;外中断1中断程序入口
RETI ;外中断1中断返回
ORG 001BH ;定时器T1中断程序入口
LJMP TIME1 ;跳至TIME1执行
ORG 0023H ;串行中断程序入口地址
RETI ;串行中断程序返回
;
TIME1: RETI
;
TIMEADD EQU 30H;30H做为软件计数缓存
DISP1 EQU 31H;31H做为第一位显示缓存
DISP2 EQU 32H;32H做为第二位显示缓存
DISP3 EQU 33H;33H做为第三位显示缓存
DISP4 EQU 34H;34H做为第四位显示缓存
SECLED EQU P1.0;秒点显示P1.0
HALFSEC EQU 35H;半秒计数缓存
UPKEY BIT P2.7;定义P2.7是UP键
SETKEY BIT P2.0;定义P2.0是SET键
BUZZ BIT P2.5;
;
;第1位使能P2.1
;第2位使能P2.2
;第3位使能P2.3
;第4位使能P2.4
;
ORG 0030H;
;
START:
MOV SP,#5FH;放堆栈
MOV P2,#0FFH;把P2置高
CLR P2.5;把p2.5置0
LCALL BUZZER;发出滴声
LCALL BUZZER;按键滴声
MOV TIMEADD,#0;软件计数器清零
MOV TMOD,#11H;TIME0工作于方式1,TIME1工作于方式1
MOV TH0,#3CH;
MOV TL0,#0B0H;放定时预置数15536
MOV IE,#8BH;开INT0,TIME0,TIME1
MOV IP,#02H;TIME0中断优先
SETB IT0;外部中断0为负跳变方式触发
SETB TR0;开始计数
MOV DISP1,#00H;
MOV DISP2,#00H;
MOV DISP3,#00H;
MOV DISP4,#00H;把所有显示缓存清零
MOV HALFSEC,#00H;把半秒计数缓存清零
MOV DPTR,#TAB;
SCAN:
MOV A,DISP1;把第一位显示缓存送入A
MOVC A,@A+DPTR;查表
SETB P2.4;
CLR P2.1;第一位显示使能
MOV P0,A;查表得到的7段码送给P0去显示
LCALL DELAY;延时
MOV P0,#0FFH;显示一小段时间后关掉7段显示,去显示下一位
MOV A,DISP2;
MOVC A,@A+DPTR;
SETB P2.1;
CLR P2.2;
MOV P0,A;
LCALL DELAY;
MOV P0,#0FFH;
MOV A,DISP3;
MOVC A,@A+DPTR;
SETB P2.2;
CLR P2.3;
MOV P0,A;
LCALL DELAY;
MOV P0,#0FFH;
MOV A,DISP4;
MOVC A,@A+DPTR;
SETB P2.3;
CLR P2.4;
MOV P0,A;
LCALL DELAY;
MOV P0,#0FFH;
JNB SETKEY,ADJUST;按键按下时去调整时间
;以下是进位程序
MOV A,DISP1;把第一位缓存送入A
CJNE A,#10,SCAN;如果第一位不等于10继续扫描
MOV DISP1,#00H;如果第一位等于10了就把第一位清零
INC DISP2;第二位加1
MOV A,DISP2;
CJNE A,#6,SCAN;如果第二位不等于6继续扫描
MOV DISP2,#00H;
INC DISP3;
MOV A,DISP4;
CJNE A,#2,PM;
MOV A,DISP3;
CJNE A,#4,SCAN;
MOV DISP3,#00H;
AJMP DIS4;
PM:
MOV A,DISP3;
CJNE A,#10,SCAN;
MOV DISP3,#00H;
DIS4:
INC DISP4;
MOV A,DISP4;
CJNE A,#3,SCAN;
MOV DISP4,#00H;
AJMP SCAN;
;
DELAY: ;延时子程序
MOV R7,#2
NOP
D1: MOV R6,#2
DJNZ R6,$
DJNZ R7,D1
RET
;
TAB: DB 88H,0EBH,91H,0A1H,0E2H,0A4H,84H,0E9H,80H,0A0H,0C0H,86H,9CH,83H,94H,0D4H,0FFH
;
;
;
;
;下面程序为设置时间用
ADJUST:
LCALL ADJDELAY;
JB SETKEY,SET1;
LCALL BUZZER;按键滴声
JNB SETKEY,$
CLR TR0; 暂时关闭计时
ADJ4:
SETB P2.1;
CLR P2.4;
MOV A,DISP4;
MOVC A,@A+DPTR;
MOV P0,A;显示第四位
JNB SETKEY,ADJ8;如果设置键有动作去调节第3位
JB UPKEY,ADJ4;加键是否按下
LCALL ADJDELAY;
JB UPKEY,ADJ4;延时后再检查加键是否按下
LCALL BUZZER;按键滴声
JNB UPKEY,$;等待加键松开
INC DISP4;第四位加1
MOV A,DISP4;
CJNE A,#3,ADJ4;第四位不等于3转移
MOV DISP4,#00H;第四位等于3清零
AJMP ADJ4;再去显示第四位
ADJ8:
LCALL ADJDELAY;
JB SETKEY,ADJ4;
LCALL BUZZER;按键滴声
JNB SETKEY,$;
ADJ3:
SETB P2.4;
CLR P2.3;
MOV A,DISP3;
MOVC A,@A+DPTR;
MOV P0,A;显示第三位
JNB SETKEY,ADJ7;
JB UPKEY,ADJ3;
LCALL ADJDELAY;
JB UPKEY,ADJ3;
LCALL BUZZER;按键滴声
JNB UPKEY,$;
INC DISP3;第3位加1
MOV A,DISP4;
CJNE A,#2,PM1;
MOV A,DISP3;
CJNE A,#4,ADJ3;第3位不等于4转移
MOV DISP3,#00H;第四位等于3清零
AJMP ADJ3;再去显示第四位
PM1:
MOV A,DISP3;
CJNE A,#10,ADJ3;
MOV DISP3,#00H;
AJMP ADJ3;
SET1:
LCALL BUZZER;按键滴声
LCALL BUZZER;按键滴声
JNB SETKEY,$;
NOP;
MOV HALFSEC,#00H;清零秒针
SETB TR0;
LJMP SCAN;
ADJ7:
LCALL ADJDELAY;
JB SETKEY,ADJ3;
LCALL BUZZER;按键滴声
JNB SETKEY,$;
ADJ2:
SETB P2.3;
CLR P2.2;
MOV A,DISP2;
MOVC A,@A+DPTR;
MOV P0,A;显示第二位
JNB SETKEY,ADJ6;
JB UPKEY,ADJ2;
LCALL ADJDELAY;
JB UPKEY,ADJ2;
LCALL BUZZER;按键滴声
JNB UPKEY,$;
INC DISP2;第2位加1
MOV A,DISP2;
CJNE A,#6,ADJ2;第2位不等于6转移
MOV DISP2,#00H;第2位等于6清零
AJMP ADJ2;再去显示第2位
ADJ6:
LCALL ADJDELAY;
JB SETKEY,ADJ2;
LCALL BUZZER;按键滴声
JNB SETKEY,$;
ADJ1:
SETB P2.2;
CLR P2.1;
MOV A,DISP1;
MOVC A,@A+DPTR;
MOV P0,A;显示第一位
JNB SETKEY,ADJ5;如果SET键有动作转去抖
JB UPKEY,ADJ1;
LCALL ADJDELAY;
JB UPKEY,ADJ1;
LCALL BUZZER;按键滴声
JNB UPKEY,$;
INC DISP1;第1位加1
MOV A,DISP1;
CJNE A,#10,ADJ1;第1位不等于10转移
MOV DISP1,#00H;第1位等于10清零
AJMP ADJ1;再去显示第1位
ADJ5:
LCALL ADJDELAY;
JB SETKEY,ADJ1;
AJMP SET1;
ADJDELAY:;是不是延时40MS?
MOV R7,#200
D3: MOV R6,#100
DJNZ R6,$
DJNZ R7,D3
RET
BUZZER: MOV R6,255;蜂鸣子程序
BUZZ1: CPL BUZZ;
MOV R7,#80;
DJNZ R7,$;
DJNZ R6,BUZZ1;
CLR BUZZ;
RET
;以上为设置时间用
;
REMO:
RETI;
;
;
;
TIME0:; TIME0中断处理程序
MOV TH0,#3CH;
MOV TL0,#0B6H;重新放定时预置数15542,用预置数较正时间。
PUSH ACC;机器周期2
PUSH PSW;机器周期2
INC TIMEADD;软件计数器加1,机器周期1
MOV A,TIMEADD;加1后送给A,机器周期1
CJNE A,#10,T_RET;如果A不等于10跳到T_RET,机器周期2
CPL SECLED;取反秒点LED,软件计数器计时半秒,机器周期1
MOV TIMEADD,#00H;软件计数器清零,机器周期1
INC HALFSEC;秒加1,机器周期1
MOV A,HALFSEC;机器周期1
CJNE A,#120,T_RET;把秒针缓存和120比较,不等跳转T_RET,机器周期2
INC DISP1;第一位显示加1,机器周期1
MOV HALFSEC,#00H;清零秒针,机器周期1
T_RET:
POP PSW
POP ACC
RETI
END
⑸ 8051单片机汇编程序请教
你的第二次修改,还有一处不足:
……
;CLR C
MOV DPTR,#TABLE
LOOP:
CLR A ;这里少了一句,下面每次读出的,
;就不知道是什么了
MOVC A,@A+DPTR
JNZ CONT_P
INC R2
SJMP NEXT
……
可以正常计数的程序如下。
;=========================================
ORG 0H
MOV A,#00H
MOV R2,A
MOV R3,A
MOV R4,A
MOV R6,A
MOV R5,#40
;CLR C
MOV DPTR,#TABLE
LOOP:
CLR A
MOVC A,@A+DPTR
JNZ CONT_P
; CJNE A,#00H,CONT_P
INC R2
SJMP NEXT
CONT_P:
JB ACC.7, CONT_N
INC R3
SJMP NEXT
CONT_N:
INC R4
NEXT:
INC DPTR
DJNZ R5, LOOP
MOV P0,R4
SJMP $
; 实际个数 保存单元 统计个数
;零个数 14 R2 21
;正数个数 19 R3 19
;负数个数: 7 R4 0
;其实是零和负数没有分开统计,请高手指教一下,谢谢!
ORG 400H
TABLE:
DB 01H, 15H, 22H,0FFH, 00H, 02H, 09H,0F9H, 00H, 00H
DB 01H, 15H, 22H,0FFH, 00H, 02H, 09H,0F9H, 00H, 00H
DB 01H, 15H, 22H,0FFH, 00H, 02H, 09H,0F9H, 00H, 00H
DB 02H, 05H, 00H,0FFH, 26H, 34H, 00H, 00H, 00H, 00H
END
⑹ 在keilC中8051汇编程序语言格式
嘿嘿 keilC中8051汇编程序语言格式是:
[ 标号: ] 操作码 操作数,操作数 [;注释]
例如:
MAIN: MOV A,#69H ;将立即数送累加器A。
呵呵 满意 就选满意回答喽
⑺ 求帮修改8051汇编跑马灯程序:
org 0000h ;程序从0000开始运行
Ljmp main
org 0030h
main: ;主程序循环点亮
mov p1,#0FFh
lcall delay ;延时一段时间
loop1: mov a,#0feh ;每次只亮一个灯。
loop: mov p1,a ;输出到p1
lcall delay ; 延时调DELAY时间延时
RL A ;此3句用来点亮P1.2
mov p1,a ;输出到p1
lcall DELAY1 ;延时一段时间
RL A ;此四句用来点亮P1.4因为左移两个
mov p1,a ;输出到p1
lcall DELAY1 ;延时一段时间调DELAY1时间延时
LJMP loop1 ;加这个就循环啦
DELAY1:MOV R4,#25 ;延时子程序,12M晶振延时1.001秒此7句为1S延时子程序供主程序调用
L3: MOV R2 ,#200
L1: MOV R3 ,#248
L2: DJNZ R3 ,L2
DJNZ R2 ,L1
DJNZ R4 ,L3
RET
delay: mov r5,#20 ;延时子程序1闪烁灯调用此7句为延时子程序供主程序调用
d1:mov r6,#20
d2: mov r7,#250
djnz r7,$
djnz r6,d2
djnz r5,d1
ret
end
⑻ 8051的汇编语言程序具有很强的通用性吗
首先汇编语言本身就与通用性不搭界,所以谈不上强通用性
其次8051汇编语言编制的程序只能在
51单片机
平台上运行
第三,每一个8051
汇编语言程序
只对应与其相应的
硬件环境
,否则得不到想要的结果。
⑼ 怎样运行8051单片机汇编程序
如有了源程序,你可以下载个KEIL软件,在软件环境里就可以运行汇编程序了,
如想在硬件上运行,可以把KEIL里编译过的文件通过另一个烧写软件写入单片机里运行
⑽ 8051的汇编语言程序具有很强的通用性吗
首先汇编语言本身就与通用性不搭界,所以谈不上强通用性
其次8051汇编语言编制的程序只能在51单片机平台上运行
第三,每一个8051汇编语言程序只对应与其相应的硬件环境,否则得不到想要的结果。