STC8H8K系列汇编和C51实战——实现键控不同方式数码管动态显示(C51版和汇编版)


前言

个人对这个实验的汇编部分不太熟悉,逻辑上面可能不太流畅,请各位见谅。


一、实验名称

  1. 巩固和熟练Keil μVision4集成开发环境的使用;
  2. 巩固和熟练EDA工具Proteus仿真环境的使用;
  3. 深入学习C51编程与MCS-51汇编语言;
  4. 学会流程图的画法,了解它在编程设计中的重要作用。

二、实验内容与要求

在Keil μVision2集成开发环境, 分别用C51和MCS-51汇编语言编程,在实验箱上用SW17和SW18(分别对应P3.2和P3.3)两个独立按键状态的四种组合控制实验箱上数码管以四种不同流水方式滚动显示信息:
1) 模式0:SW17和SW18都不按下, 8个数码管从左到右固定显示数字1-8;

2) 模式1:SW17按下,SW18不按下, 8个数码管从左到右依次逐步显示数字1-8, 即1,2, 3,…从左到右是逐步显示出来的,间隔为0.1秒, 直到1-8全部显示后重复这个该显示过程;

3) 模式2:SW17不按下,SW18按下, 8个数码管从右到左依次逐步显示数字1-8, 方式类似模式1,只是方向不同;

4) 模式3:SW17和SW18同时按下, 从最中间两个数码管逐步扩展显示数字2,直到显示8个2,然后重新从中间开始重复以上显示过程。

三、代码

1、51部分

// 文件名称:   实验三51部分
//作者:       不知何人
// 完成日期:   2022.4.16
//内容摘要:   无
//注意:       无
#include<stc8h.h>

void Delay100ms()		//@24.000MHz
{
	unsigned char i, j, k;
	i = 10;
	j = 31;
	k = 147;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void Delay10ms()		//@24.000MHz
{
	unsigned char i, j, k;

	i = 2;
	j = 56;
	k = 172;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void Delay1ms()		//@24.000MHz
{
	unsigned char i, j;

	i = 24;
	j = 85;
	do
	{
		while (--j);
	} while (--i);
}



/*************  本地常量声明    **************/
u8 code t_display[]={                       //标准字库
//   0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
    0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};    //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1

u8 code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};      //位码
u8 code T_COM1[]={0x18,0x3C,0x7E,0xFF};      //位码
void Nixie1()	//数码管显示函数1
{
	u8 i;
	for(i = 0; i < 8; i++)
	{
		P7 = ~T_COM[i];
		P6 =  ~t_display[i + 1];
		Delay1ms();
		P6 = 0xFF;
	}
}

void Nixie2()	//数码管显示函数2
{
	u8 i;
	for(i = 0; i < 8; i++)
	{
		P7 = ~T_COM[i];
		P6 =  ~t_display[i + 1];
		Delay100ms();
		P6 = 0xFF;
	}
}

void Nixie3()//数码管显示函数3
{
	u8 i;
	for(i = 8; i > 0; i--)
	{
		P7 = ~T_COM[i - 1];
		P6 =  ~t_display[i];
		Delay100ms();
		P6 = 0xFF;
	}
}

void Nixie4()//数码管显示函数4
{
	u8 i;
	for(i = 0; i < 4; i++)
	{
		P7 = ~T_COM1[i];
		P6 =  ~t_display[2];
		Delay100ms();
		P6 = 0xFF;

	}
}

void gpio()		//gpio初始化为准双向口,刚开始除了P30,P31其他均为高阻态
{
    P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
    P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
    P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
    P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口
    P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
    P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
    P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口
    P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口
	}

u8 key = -1;
	
void ChooseKey()//通过按键状态确定不同模式
{
	if(P32 != 0 && P33 != 0)
	{
		Delay10ms();	//消抖
		if(P32 != 0 && P33 != 0)
		{
			key = 0;
		}
	}	
	else if(P32 == 0 && P33 != 0)	
	{
		Delay10ms();
		if(P32 == 0 && P33 != 0)
		{
			key = 1;
		}
	}
	else if(P32 != 0 && P33 == 0) 
	{
		Delay10ms();
		if(P32 != 0 && P33 == 0)
		{
			key = 2;
		}
	}
	else if(P32 == 0 && P33 == 0) 
	{
		Delay10ms();
		if(P32 == 0 && P33 == 0)
		{
			key = 3;
		}
	}	
	
	switch(key)//对应模式的数码管显示
	{
		case 0: Nixie1();break;
		case 1: Nixie2();break;
		case 2: Nixie3();break;
		case 3: Nixie4();break;
	}
}
void main()
{
	gpio();
	while(1)
	{
		ChooseKey();
	}
}

2、 汇编部分

// 文件名称:   实验三汇编部分
//作者:       不知何人
// 完成日期:   2022.4.16
//内容摘要:   无
//注意:       无

NIXIE:
	MOV	R2,	#8
	MOV	DPTR, #T_Display1
	MOV R3, #0FEH

NIXIE_LOOP0:
	JNB	P3.2, NIXIE_LOOP1
	JNB	P3.3, NIXIE_LOOP2
	
	MOV	P7,#0FFH
	MOV	A,@R0
	INC	R0
	MOVC A, @A+DPTR
	MOV	P6, A
	MOV A, R3	
	MOV P7, A	;从第1-8位数码管依次导通
	RL A		;循环左移
	MOV R3, A	;下一次P7口的值给R3,下次赋值给P7
	
	LCALL DELAY1MS	;消影,避免上一个数字视觉残留
	DJNZ R2, NIXIE_LOOP0		;点亮一轮以后退出
	RET
	
NIXIE_LOOP1:
	JNB	P3.3, NIXIE_LOOP3
	JB	P3.2, NIXIE_LOOP0
	
	LCALL	DELAY5MS
	
	JNB	P3.3, NIXIE_LOOP3
	JB	P3.2, NIXIE_LOOP0
	MOV	P7,#0FFH
	MOV	A,@R0
	INC	R0
	MOV DPTR, #T_Display2
	MOVC A, @A+DPTR
	MOV	P6, A
	MOV A, R3	
	MOV P7, A	;从第1-8位数码管依次导通
	RR A		;循环右移
	MOV R3, A	;下一次P7口的值给R4,下次赋值给P7
	LCALL DELAY100MS	
	DJNZ R2, NIXIE_LOOP1		;点亮一轮以后退出
	RET
	
NIXIE_LOOP2:
	JB	P3.3, NIXIE_LOOP0
	JNB	P3.2, NIXIE_LOOP3

	LCALL	DELAY5MS
	
	JB	P3.3, NIXIE_LOOP0
	JNB	P3.2, NIXIE_LOOP3
	MOV	P7,#0FFH
	MOV	A,@R0
	INC	R0
	MOV	DPTR, #T_Display3
	MOVC A, @A+DPTR
	MOV	P6, A
	MOV A, R3	
	MOV P7, A	;从第1-8位数码管依次导通
	RL A		;循环左移
	MOV R3, A	;下一次P7口的值给R3,下次赋值给P7
	LCALL DELAY100MS	
	DJNZ R2, NIXIE_LOOP2	;每按个点亮一轮以后退出
	RET
	

NIXIE_LOOP3:
	JB	P3.2, NIXIE_LOOP2
	JB	P3.3, NIXIE_LOOP1
	
	INC A
	MOV	P7,#0FFH
	MOV P6,#0A4H
	
	MOV	P7, #0E7H
	
	LCALL DELAY1000MS
	
	JB	P3.2, NIXIE_LOOP2
	JB	P3.3, NIXIE_LOOP1
	
	MOV	P7, #0C3H
	LCALL DELAY1000MS
	
	JB	P3.2, NIXIE_LOOP2
	JB	P3.3, NIXIE_LOOP1
	
	MOV	P7, #81H
	LCALL DELAY1000MS
	
	JB	P3.2, NIXIE_LOOP2
	JB	P3.3, NIXIE_LOOP1
	
	MOV	P7, #00H
	LCALL DELAY1000MS
	
	RET
	
	T_Display1:                 
	DB 	0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H

	T_Display2:                 
	DB 	0C0H,0F8H,82H,92H,99H,0B0H,0A4H,0F9H,80H
	
	T_Display3:                 
	DB 	0C0H,80H,0F8H,82H,92H,99H,0B0H,0A4H,0F9H
	
DELAY1MS:			;@24.000MHz
	PUSH 30H
	PUSH 31H
	MOV 30H,#32
	MOV 31H,#39
NEXT:
	DJNZ 31H,NEXT
	DJNZ 30H,NEXT
	POP 31H
	POP 30H
	RET

DELAY100MS:			;@24.000MHz
	NOP
	NOP
	PUSH 30H
	PUSH 31H
	PUSH 32H
	MOV 30H,#13
	MOV 31H,#45
	MOV 32H,#212
NEXT1:
	DJNZ 32H,NEXT1
	DJNZ 31H,NEXT1
	DJNZ 30H,NEXT1
	POP 32H
	POP 31H
	POP 30H
	RET

DELAY1000MS:			;@24.000MHz
	NOP
	NOP
	PUSH 30H
	PUSH 31H
	PUSH 32H
	MOV 30H,#122
	MOV 31H,#193
	MOV 32H,#126
NEXT2:
	DJNZ 32H,NEXT2
	DJNZ 31H,NEXT2
	DJNZ 30H,NEXT2
	POP 32H
	POP 31H
	POP 30H
	RET

DELAY5MS:			;@24.000MHz
	NOP
	PUSH 30H
	PUSH 31H
	MOV 30H,#156
	MOV 31H,#212
NEXT3:
	DJNZ 31H,NEXT3
	DJNZ 30H,NEXT3
	POP 31H
	POP 30H
	RET

总结

数码管的使用,关键在于闪烁的频率,频率越快,自然越不晃眼(不像手机的OLED屏幕哈哈哈),当频率越慢的时候,就显示出了流水灯的效果,频率越快就显示是静态的效果了。而想要精确掌握数码管,我们需要很熟练的使用位选段选,这样才能玩出花来。

对汇编不熟悉的朋友(比如我)刚开始会对第二段代码理解有点困难,其实有C语言基础的初学者在大致知道各个指令的功能之后,只需要再查一下if、for、while等语句在汇编中的表示方法就可以很快领悟了。汇编麻烦的是语句太多,过于繁琐,但是效率提升高,至少优化20%-30%,多用于驱动程序处。

主页还有许多汇编、C51、以及Proteus源码和原理图等,这些天就会上传matlab以及Python人工智能算法的代码和资源,现在开始也会陆续有数字图像处理以及单片机作品的展示,全部开源,欢迎各位来看!!!

非常感谢各位观看!!!

系列文章——STC8H8K系列汇编51实战

基于ESP8266与STC单片机的天气时钟(包括DS18B20、TFT、串口、外部中断、ESP8266、STC、API等)

STC8H8K系列汇编和C51实战——实现跑马灯(51版)

STC8H8K系列汇编和C51实战——实现跑马灯(汇编版)

STC8H8K系列汇编和C51实战——实现键控不同方式数码管动态显示(C51版与汇编版)

STC8H8K系列汇编和C51实战——开关控制定时器秒表(C51版)

STC8H8K系列汇编和C51实战——开关控制定时器秒表(汇编版)

STC8H8K系列汇编和C51实战——双中断控制定时器流水灯

STC8H8K系列汇编和C51实战——双中断加减计数器

STC8H8K系列汇编和C51实战——简易频率计

STC8H8K系列汇编和C51实战——秒倒计时器(汇编版)

STC8H8K系列汇编和C51实战——秒倒计时器(51版)

STC8H8K系列汇编和C51实战——秒倒计时器(可自行设定初值)(51版)

STC8H8K系列汇编和C51实战——按键允许按键计数(51版)

STC8H8K系列汇编和C51实战——按键允许按键计数(汇编版)

STC8H8K系列汇编和C51实战——按键允许按键计数(定时器去抖动51版)

STC8H8K系列汇编和C51实战——按键允许按键计数(利用下降沿中断控制)

STC8H8K系列汇编和C51实战——计算机串口控制单片机LED

STC8H8K系列汇编和C51实战——串口发送菜单界面选择不同功能

STC8H8K系列汇编和C51实战——数码管显示ADC、串口显示ADC按键与数值

  • 7
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不知何人

万分感谢诸位观看

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值