ORG 0000H ; 指定地址 0001--1
LJMP MAIN ; 长转移 0010--2
ORG 0080H ; 0011--3
MAIN: MOV P1,#0DBH ;11011011--零为亮 0100--4
ACALL DELay ; 短调用 0101--5
MOV P1,#06DH ;01101101 0110--6
ACALL DELay ; 0111--7
MOV P1,#0B6H ;10110110 1000--8
ACALL DELay ; 1001--9
AJMP MAIN ; 1010--A
delay: mov r7,#255 ;延时子程序 共1us 1011--B
d1: mov r6,#255 ; 255us 1100--C
d2: djnz r6,d2 ;255*255*2us 1101--D
djnz r7,d1 ;255*2us 1110--E
ret ;子程序结束 1111--F
end
ORG 0000H ; 12个时钟周期等于1个机器周期 12/时钟频率
LJMP MAIN ; mov单周期,djnz双周期
ORG 0080H ; 1-8:P1口 9:RST复位 10-17:P3口 18:XTAL2出 19:XTAL1片内时钟振荡器入
MAIN: MOV P1,#0FEH ;11111110--零为亮 20:VSS 21-28:P2口 29:PSEN 30:ALE/PROG 31:EA/VPP
ACALL DELay ; 39-32:P0口 40:VCC
MOV P1,#0FDH ;11111101 12,13:外部中断0/1 14,15:计时器0/1
ACALL DELay ;
MOV P1,#0FBH ;11111011
ACALL DELay ;
MOV P1,#0F7H ;11110111
ACALL DELay ;
MOV P1,#0EFH ;11101111
ACALL DELay ;
MOV P1,#0DFH ;11011111
ACALL DELay ;
MOV P1,#0BFH ;10111111
ACALL DELay ;
MOV P1,#07FH ;01111111
ACALL DELay ;
AJMP MAIN ;(2kb内)无条件跳转
delay: mov r7,#100 ;延时子程序 1us
d1: mov r6,#100 ;100us
d2: djnz r6,d2 ;100*100*2us
djnz r7,d1 ;100*2us
ret
end
ORG 0000H
LJMP START
ORG 0080H
START: ;MOV P1,#0FFH; 开关闭合,一开始开关都为高,选中哪位哪位给低
MOV P0,#0FFH; led全闭
MAIN: MOV A,P1
CPL A ;取反
CJNE A,#01H,NXET1;比较00000001不相等转移
MOV P0,#0FEH
LJMP MAIN
NXET1: CJNE A,#02H,NXET2;比较是否相等00000010
MOV P0,#0FDH
LJMP MAIN
NXET2:CJNE A,#04H,NXET3;00000100
MOV P0,#0FCH
LJMP MAIN
NXET3:CJNE A,#08H,NXET4; 00001000
MOV P0,#0FBH
LJMP MAIN
NXET4: CJNE A,#010H,NXET5;00010000 16
MOV P0,#0FAH
LJMP MAIN
NXET5: CJNE A,#020H,NXET6; 00100000 32
MOV P0,#0F9H
LJMP MAIN
NXET6:CJNE A,#040H,NXET7;01000000 64
MOV P0,#0F8H
LJMP MAIN
NXET7:CJNE A,#080H,NXET ;10000000 128
MOV P0,#0F7H ;00001000
LJMP MAIN
NXET: MOV P0,#0FFH;00000000
LJMP MAIN
END
设计要求:
(1)选择函数发生器输出TTL信号输入单片机的某I/O口,经单片机分频后从另一I/O口输出,I/O分配自定,分频比范围1-10,要求分频比在程序中可进行设置;
(2)实现2位10进制有符号数(0-49)的加、减运算,按键K1选择加,按键K2选择或运算,LED指示运算结果。采用仿真器仿真运行,数据输入采用存储器直接置数,存储器分配自定。画出程序设计流程图,程序必须加以注释。
分频 (P1.0主函数TTL输入 2khz 5v,P0.0输出)
ORG 0000H ; N个周期2N个边沿 N个正边沿 N个负边沿
LJMP MAIN ;
ORG 0080H ;
MAIN: MOV P1,#0FFH ;11111111
LOOP1: JB P1.0,LOOP1;检测下降沿,JB直接寻址位为一则转移否则顺延
INC A ;检测到一个下降沿
ACALL CHECK
LOOP2: JNB P1.0,LOOP2;检测上升沿JNB直接寻址位为0则转移否则顺延
INC A ;检测到一个上升沿
ACALL CHECK
AJMP LOOP1
CHECK: CJNE A,#02H,D1;检测到的周期个数与设定的分频系数比较,2分频,不相等转移
CLR A ;进位标志位清0
CPL P0.0 ;直接寻址位取反
D1: RET
END
加减运算,p1接led 从上到下 位数从低到高 开关p2.7左低减 右高加
ORG 0000H ------ADD,SUBB,JB,JNB,
LJMP MAIN
ORG 0080H
MAIN:
MOV R2,#22H ;参与加减的数可更改
MOV R3,#05H ;参与加减的数可更改
MOV A,#31H ;十进制的49
CHECK1: ;判断R2是否>49 acc.7 为1则>49
SUBB A,R2 ;带借位 A=A-R2-cy
JNB Acc.7,CHECK2 ;为0转 否则顺延
LJMP LOOP1
CHECK2: ;判断R3是否>49 acc.7 为1则>49
SUBB A,R3 ;带借位 A=A-R3-cy
JB Acc.7,LOOP1 ;为1转 否则顺延
LOOP:
JB P2.7,ADD1 ;P2.7为高电平,则作加运算,反之则作减运算
LJMP SUBB1
ADD1: MOV A,R2 ;加
ADD A,R3
CPL A ;结果取反 led低电平亮
MOV P1,A
LJMP LOOP
SUBB1: MOV A,R2 ;减
SUBB A,R3 ;A=R2-R3
JB Acc.7,SUBB2 ;R2>R3顺序 否则跳
CPL A
MOV P1,A
LJMP LOOP
SUBB2: MOV A,R3
SUBB A,R2 ;r3-r2
SETB Acc.7 ;直接置1
CPL A ;取反
MOV P1,A
LJMP LOOP
RET
LOOP1:MOV P1,#00H ;如果参与运算的数大于49,则让所有的LED均亮
RET
END
10进制计数器(0-9),间隔1秒(软件延时)自动加1,并将计数值显示在一位数码管上(P0连接一位数码管)
ORG 0000H ;
LJMP MAIN ;
MAIN: MOV P2,#0FEH ; 11111110????这句不懂什么意思
MOV R1,#00
MOV DPTR,#0080H ; 便于将表中数读出
MOV A,R1
LOOP1: CJNE A,#0AH,LOOP ; 比较数(1010)是否相等,不相等跳转
MOV R1,#00 ; 此时A>10 重新赋0给A
MOV A,R1
LOOP: MOVC A,@A+DPTR ;将表中读出的数赋给A
MOV P0,A ;在数码管显示
ACALL DELay ;调用延时子程序
INC R1 ;延时1s后,寄存器加一
MOV A,R1
ACALL LOOP1 ;加一后进行比较
DElay: MOV R7,#10 ;延时子程序约 0.996s 1us 12mhz
DEL1: MOV R6,#200 ;1us
DEL2: MOV R5,#248 ;1us
DJNZ R5,$ ;248*200*10*2us
DJNZ R6,DEL2 ;200*10*2us
DJNZ R7,DEL1 ;10*2us
RET
ORG 0080H ; 数码管显示表
DB 28H,7EH,0A2H,62H,74H,61H,21H,7AH,20H,60H; 0-9
END
ORG 0000H ; ------延时,数码管
LJMP MAIN ;
ORG 0080H ;
MAIN: MOV P0,#028H ; 数码管显示0 (可以改为其他数值)
MOV P2,#0FEH; 11111110(第一个数码管亮)
ACALL DELay ; 调用延时程序
LOOP: MOV A,P2 ;
RL A ; 循环左移
MOV P2,A ;
ACALL DELay ; 调用子程序
AJMP LOOP;
DElay: MOV R7,#10 ;延时子程序 约0.996s 1us
DEL1: MOV R6,#200 ;1us
DEL2: MOV R5,#248; 1us
DJNZ R5,$; 248*200*10*2us
DJNZ R6,DEL2;200*10*2us
DJNZ R7,DEL1;10*2us
RET
END
ORG 0000H ;程序的初始位置
LJMP MAIN ;跳到程序的起始位置
ORG 0100H
MAIN: MOV DPTR,#TABLE ; 将表文件头的地址赋给基址
MOV R3,#00H ; 将R3置0
MOV P2,#0FEH ; 11111110
LOOP1:
MOV A,#00H
MOV A,R3 ; 将R3置给A
MOVC A,@A+DPTR ;基址加变址查表内容赋给A
MOV P0,#0FFH
MOV P0,A ;将A给P0口
INC R3
acall delay
MOV A,P2
RL A ;循环左移
MOV P2,#0FFH
MOV P2,A
CJNE R3,#8,LOOP1; 当0-7都赋完值(8次)顺序执行 否则跳转
AJMP MAIN
DELAY: MOV R7,#20
DEL1: MOV R6,#50
DEL2: DJNZ R6,DEL2
DJNZ R7,DEL1
RET
TABLE: DB 028H,07EH,0A2H,62H,74H,61H,21H,7AH ;0-7
END
(备用)
ORG 0000H ;程序的初始位置
LJMP MAIN ;跳到程序的起始位置
ORG 0100H
MAIN:
MOV P2,#0FEH ;
MOV P0,#028H; 最左边一个显示0
ACALL DEALY
MOV P0, #0FFH
MOV P2,#0FDH ;
MOV P0,#07EH;第二个显示1
ACALL DEALY
MOV P0, #0FFH
MOV P2,#0FBH ;
MOV P0,#0A2H;第三个显示2
ACALL DEALY
MOV P0, #0FFH
MOV P2,#0F7H ;
MOV P0,#062H;第四个显示3
ACALL DEALY
MOV P0, #0FEH
MOV P2,#0EFH ;
MOV P0,#074H;第五个显示4
ACALL DEALY
MOV P0, #0FFH
MOV P2,#0DFH ;
MOV P0,#61H;第六个显示5
ACALL DEALY
MOV P0, #0FFH
MOV P2,#0BFH ;
MOV P0,#21H;第七个显示6
ACALL DEALY
MOV P0, #0FFH
MOV P2,#07FH ;
MOV P0,#7AH;第八个显示7
ACALL DEALY
AJMP MAIN
DELAY: MOV R7,#20
DEL1: MOV R6,#50
DEL2:DJNZ R6,DEL2
DJNZ R7,DEL1
RET
END
通过K01(JP37)产生外部中断请求(/INT0)信号,K02产生外部中断请求(/INT1)信号,在对应的中断服务程序实现在一位数码管上显示中断源编号(0或1)。
(按键K01接 P3.2 按键K02 接P3.3) 这里跳沿触发
ORG 0000H -----外部中断0,外部中断1
LJMP MAIN
ORG 0003H ;外部中断口0的地址入口
LJMP INT_0 ;长调用外部中断0
ORG 0013H ;外部中断口1的地址入口
LJMP INT_1 ; 长调用外部中断1
ORG 0080H
MAIN: MOV SP,#30H ;堆栈指针 保护断点
SETB EA ;打开中断总开关
SETB EX0 ;打开外部中断0
SETB EX1 ;打开外部中断1
SETB IT0 ; 跳沿触发
SETB IT1 ; 跳沿触发
SJMP $ ;跳转到本指令起始位置开始执行,即循环执行等待中断
INT_0: CLR EX0 ;保护过程,关外部中断0
PUSH PSW ;现场保护
PUSH ACC ; 压入数据进RAM
SETB EX0 ; 打开外部中断0
LCALL DELAY ;调用延时10ms,去抖动
JB P3.2,RETURN1 ;若K0为高电平则跳出 中断低有效
MOV P0,#28H ;否则数码管显示0
RETURN1: CLR EX0; 保护过程,关外部中断0
POP ACC ;现场恢复
POP PSW
SETB EX0
RETI
INT_1:CLR EX1 ;关外部中断1
PUSH PSW ;现场保护
PUSH ACC
SETB EX1 ; 打开外部中断1
LCALL DELAY ; 调用延时10ms,去抖动
JB P3.3,RETURN2 ;若K1为高电平则跳出
MOV P0,#7EH ;否则会数码管显示1
RETURN2: CLR EX1
POP ACC ;现场恢复
POP PSW
SETB EX1
RETI
DELAY:MOV R7,#100 ;延时子程序 约0.1s 0.5us 这时为24MHz
D1: MOV R6,#100; 0.5us
D2: DJNZ R6,D2;100*100*1
DJNZ R7,D1;100*1
RET
END
设计一个10进制计数器(0-9),选择一个按键(K01-K04任选)产生外部中断信号/INT0(或/INT1),每按一次计数器加1,并将计数值显示在一位数码管上
(按键接P3.2 P0数码管 ) 这里电平触发
ORG 0000H ;程序的初始位置 -------外部中断0
LJMP MAIN ;跳到程序的起始位置
ORG 0003H ;外部中断程序0入口
LJMP INT ;跳到中断程序的起始位置
ORG 0100H
MAIN: CLR IT0 ;采用低电平触发
SETB EX0 ;允许外部中断0中断
SETB EA ;开启总中断
MOV R3,#00H ;将R3置0
MOV DPTR,#TABLE ;将表文件头的地址赋给基址
LOOP: MOV A,R3 ;将R3置给A
MOVC A,@A+DPTR ;基址加变址查表内容赋给A
MOV P0,A ;将A给P0口
AJMP LOOP
DELAY: MOV R7,#25 ;延时程序
LOOP3: MOV R6,#50 ;
LOOP2: MOV R5,#50
LOOP1: DJNZ R5,LOOP1
DJNZ R6,LOOP2
DJNZ R7,LOOP3
RET
INT: ACALL DELAY ;中断程序
LOOP4: JNB P3.2,LOOP4 ;去抖动
INC R3 ;R3加一
CJNE R3,#10,RETURN ;若R3不为10则转移 ,相等则顺序执行置0 JNB直接寻址位为0则转移
MOV R3,#0 ;将R3置0 JB 直接寻址位为1则转移
RETURN: RETI
TABLE: DB 028H,07EH,0A2H,62H,74H,61H,21H,7AH,20H,60H
END ;程序结束
ORG 0000H; 程序入口
LJMP MAIN
ORG 000BH; T0的中断入口
LJMP ITOP; 转T0中断处理子程序IT0P
ORG 0080H
MAIN: MOV P0,#7FH ; 先亮第一盏灯 01111111
MOV A,P0
MOV SP,#60H ; 保护断点
MOV B,#14H ; 一次定时50ms,一共循环20次
MOV TMOD,#01H ; 采用定时器T0,方式1
MOV TL0,#0B0H ; 给T0设初值15536 (12Mhz 50ms)
MOV TH0,#3CH ;
SETB ET0;允许T0中断
SETB EA;总中断允许
SETB TR0;启动T0计数
HERE: SJMP HERE
ITOP: MOV TL0,#0B0H;进入T0中断服务子程序,给T0重新装入初值
MOV TH0,#3CH ;
DJNZ B,RETURN;B为中断次数计数器,B减1非0则中断返回
CLR TR0 ;1s定时时间到,停止T0工作
MOV R3,#01H ;1s定时完成时,就将R3值设为01H,作为标志
RR A ; A右移
MOV P0,A
MOV B,#14H ;定时50ms,一共循环20次
SETB TR0;重新启动T0计数
RETURN: RETI
END
(拓展部分)时间间隔0.5~2秒可调,时间步进为0.2秒,采用按键(K01
~K04任选一个)产生外部中断信号,作为时间间隔选择输入,中断服务程序调
整时间间隔。(P1接led 按键接P3.2) -----外部中断0,定时器T0
ORG 0000H
RESET: LJMP MAIN
ORG 0003H;外部中断0入口
LJMP INT
ORG 000BH; 定时器/计数器T0中断入口
LJMP IT0P
ORG 0100H
MAIN: MOV SP,#60H
MOV R4,#10 ;
MOV R3,#10 ;
MOV P1,#0FEH ; 11111110点亮一个led
MOV TMOD,#01H ;T0为方式1定时
MOV TL0,#0B0H ; 10110000 初值15536
MOV TH0,#3CH ; 00111100
CLR IT0 ;电平触发
SETB EX0 ;允许外部中断0中断
SETB ET0 ;允许T0中断
SETB EA ;总中断允许
SETB TR0 ; 启动T0计数
SETB PX0 ;外部中断0优先级
CLR PT0 ;定时器/计数器T0优先级 置0
HERE: SJMP HERE
IT0P: MOV TL0,#0B0H ;T0中断程序 初值15536 (12Mhz 50ms)
MOV TH0,#3CH ;一次50ms 共十次 即间隔0.5s(可改)移位led
DJNZ R4,RETURN ; R4=10减一不为0转移
MOV B,R3 ;
MOV R4,B ;R4=10
MOV A,P1
RL A ;循环左移
MOV P1,A
RETURN: RETI
DELAY: MOV R7,#25 ;延时程序 (12MHz 延时约0.1s)
D1: MOV R6,#200 ;
DJNZ R6,$ ;200*25*2us
DJNZ R7,D1 ;25*2us
RET
INT: ACALL DELAY ;外部中断0程序 延时约0.1s
LOOP4: JNB P3.2,LOOP4 ; 为低电平跳出
ACALL DELAY ;再延时约0.1s 共0.2s
LOOP5: JNB P3.2,LOOP5 ;去抖动
INC R3
INC R3
INC R3
INC R3
CJNE R3,#42,RETURN1 ; (42-10=32 32/4=8 判断是否循环了八个led)
/*改为:INC R3 CJNE R3,#18,RETURN1;*/
MOV R3,#10
RETURN1: RETI
END
(方式2:8位自动重装 led轮流显示)(P0接led) —方式2 定时器T0
ORG 0000H;程序入口
LJMP MAIN
ORG 000BH;T0的中断入口
LJMP ITOP; 转T0中断处理子程序IT0P
ORG 0080H
MAIN: MOV P0,#7FH; 先亮第一盏灯
MOV A,P0
MOV SP,#60H
MOV B,#50H ; 一次定时250μs,一共循环50*80次 共1s
MOV TMOD,#02H ; 采用定时器T0,方式2
MOV TL0,#06H ;初值为6 (12MHz 下 250us 初值计算公式)
MOV TH0,#06H;
SETB ET0; 允许T0中断
SETB EA; 总中断允许
SETB TR0;启动T0计数
HERE: SJMP HERE
ITOP: DJNZ B,RETURN;B为中断次数计数器,B减1非0则中断返回(循环80次)
MOV B,#50H
INC R4
CJNE R4,#32H,RETURN ;将R4与50比较 (循环50次)
RR A ; A右移
MOV P0,A
MOV B,#50H ;开始新一轮
MOV R4,#00H ;(寄存器R4一开始为0否?)
RETURN: RETI
END
P0.0输出频率为1KHz的矩形波信号(方式1)T=1ms 500Us半周期
ORG 0000H ----定时器T0
LJMP MAIN
ORG 000BH ;T0的中断入口
LJMP IT0P
ORG 0080H; 主程序入口
MAIN: MOV SP,#60H
MOV TMOD,#01H ;设置T0在方式1定时
MOV TH0,#0FEH; 设初始值65036 500us(12Mhz)
MOV TL0,#0CH
SETB EA ;总中断允许
SETB ET0;允许T0中断
SETB TR0 ;启动T0
HERE: SJMP HERE
IT0P: MOV TL0,#0CH ;进入T0中断服务子程序,给T0重新装入初始值
MOV TH0,#0FEH
CPL P0.0 ;反转
RETI
END
(方式2)P0.0输出频率为1KHz的矩形波信号 精确----定时器T0
ORG 0000H
LJMP MAIN
ORG 000BH;T0的中断入口
LJMP IT0P
ORG 0080H
MAIN: MOV SP,#60H
MOV B,#5 ;循环次数为5次
MOV TMOD,#02H ;T0在方式2定时
MOV TL0,#156 ;设初始值 100us
MOV TH0,#156
SETB EA ;打开中断开关
SETB ET0 ;允许T0中断
SETB TR0 ;启动T0
SETB P0.0
HERE: SJMP HERE
IT0P: DJNZ B,RETURN
MOV B,#5
CPL P0.0
RETURN:RETI
END
//低电平亮
//脉冲信号测量:被测信号频率范围为1~10KHz,采用定时/计数器实时检测信号频率,测试结果可观察 (P2位选 P0 段选)信号发生器接p3.5 t1计数
#include <reg52.h>
int Show_Num[5] = {0};
int counter = 0;
char Led[10] = {0X28,0X7E,0XA2,0X62,0X74,0X61,0X21,0X7A,0X20,0X60}; 0-9 共阳
void Time_Start(void)
{ TMOD = 0X51; // T0方式1 定时计数, T1方式1计数 定时1s时 20次50ms
ET0 = 1; //打开T0中断
ET1 = 1; 打开T1中断
TH0 = 0X3C; 设置定时器/计数器0的初始值。(65536-50000)/256=60
TL0 = 0XAF; ((65536-50000)%256)=176 )
TH1 = TL1 = 0;设置定时器/计数器1的初始值
TR0 = 1; 定时器0运行控制位
TR1 = 1; 定时器1运行控制位
}
void delayms(int a) ;延时程序
{ int z;
for( a=12; a > 0; a--)
{ for( z = 121; z>0; z--);
}}
void Show_Led_7(unsigned int k)//75693
{ //通过七段数码管显示频率,该子函数经软件仿真,无问题
Show_Num[0] = k % 10;
Show_Num[1] = (k % 100 )/10;
Show_Num[2] = (k % 1000 )/100;
Show_Num[3] = (k % 10000 )/1000;
Show_Num[4] = k / 10000;
P2 = 0XFE; P0 = Led[Show_Num[4]]; delayms(1); //高位
P2 = 0XFD; P0 = Led[Show_Num[3]]; delayms(1);
P2 = 0XFB; P0 = Led[Show_Num[2]]; delayms(1);
P2 = 0XF7; P0 = Led[Show_Num[1]]; delayms(1);
P2 = 0XEF; P0 = Led[Show_Num[0]]; delayms(1);
}void main(void)
{ int F_TH = 0,F_TL = 0; 能否把以下F_TH直接换成TH1, F_TL换成TL1
unsigned int Frequency ;
Time_Start();
EA = 1; 开总中断
while(1)
{ if(counter >= 20 )
{
TR1 = 0;
TR0 = 0;
F_TH = TH1;
F_TL = TL1;
counter = 0;
TH1 = TL1 = 0;
TR1 = 1;
TR0 = 1;
Frequency = (int) (F_TH * 256 + F_TL);
}
Show_Led_7(Frequency); }}
void Time_interrupt0() interrupt 1 //外部中断0程序
{//TR1 = 1;
TH0 = 0X3C; 1s到了 再赋初值
TL0 = 0XAF;
counter++; 计满了65536一次
}
/*void Time_interrupt1() interrupt 3 ; 外部中断1程序 可删
{ //报错
P1 = 0X10; P0 = 0XA1; //输出ERROR}*/
XCH 交换 XCHD交换低半字节
SWAP 累加器高低半字节交换
SUBB (带借位)减
INC 加一 DEC 减一
MUL AB 结果为BA(B高A低)
DIV AB (A商B余)
DA A 十进制调整
ANL 与
ORL 或
XRL 异或
CLR 清0
CPL 求反
RL 循环左移 RR循环右移
JZ 为0转移 JNZ 非0转移
CJNE 比较不相等转移
DJNZ 减一不为0转移
DElay: MOV R7,#10 ;延时子程序约 0.996s 1us
DEL1: MOV R6,#200 ;1us
DEL2: MOV R5,#248 ;1us
DJNZ R5,$ ;248*200*10*2us
DJNZ R6,DEL2 ;200*10*2us
DJNZ R7,DEL1 ;10*2us
RET
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOVC A,@A+DPTR 或MOVC A,@A+PC
DB 28H,7EH,0A2H,62H,74H,61H,21H,7AH,20H,60H; 0-9