当前位置:   article > 正文

实验二 独立按键控制数码管显示

独立按键控制数码管

仿真图有误还未修改,请自行鉴别
实验二 独立按键控制数码管显示

一、实验目的

1、掌握数码管工作原理

2、掌握独立按键的工作原理

二、实验软硬件

1、Keil uVision4或者Keil uVision5;

2、仿真软件Proteus8,烧录软件stc-isp;

3、普中51开发板;

三、学习内容

1、独立按键的输入原理和编程方法;

2、单片机控制数码管显示的原理,数码管轮流显示同时显示的实现;

3、中断和查询法控制灯的亮灭;

四、实验任务

本次实验需要在proteus上仿真,并烧录到开发板。

任务一:

编写程序,使用独立按键,实现以下功能:

1、按键K3按下,8个LED从左向右形成流水灯的效果,

2、按键K4按下,8个LED从右向左形成流水灯的效果,

任务二:

编写程序,使用中断函数实现以下功能:

1、数码管初始显示值为0。当按键K3按下,使数码管计数,记录按下的次数;

2、 当按键次数达到9时,蜂鸣器报警数码管显示值归0;

**注意:**数码管的驱动方式请查看附带PPT自行设计;

任务三:

编写程序,编写一分钟计时程序,并在数码管显示。使用开发板实现以下功能:

1、使用按键K1 K2 K3,做控制,分别为开始计时、暂停计时、计时清零;

2、开始计时(K1):每次从零开始计时

3、暂停计时(K2):按一次暂停计时,再次按下继续从停止时间计时;

4、计时清零(K3):计时清零,显示00;

任务一

编写程序,使用独立按键,实现以下功能:

1、按键K3按下,8个LED从左向右形成流水灯的效果,

2、按键K4按下,8个LED从右向左形成流水灯的效果,

在这里插入图片描述

由开发板原理图可知K3和K4分别对应单片机P3.2和P3.3单片机

在第一次任务仿真图基础上,稍作修改即可

在这里插入图片描述
用if语句判断K3和K4是否按下,哪一个按下便执行对应的代码块
代码实现如下:

#include <stdio.h>
#include <reg52.h>
typedef unsigned int u16;	 
typedef unsigned char u8;
#define LED P2
/*定义按键控制位*/
sbit K3 = P3^2;
sbit K4 = P3^3;
/*延时函数*/
void delay(unsigned int ms)
{
	u16 i,j;
	for(i=0;i<ms;++i)
		for(j=0;j<110;++j);
}
/*主函数*/
void main()
{
 	u16 i;
    /*左移和右移LED亮灭状态数组*/
	char led_L[] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
	char led_R[] = {0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
	while (1)
	{
		if(K3 == 0)
		{
			for(i=0;i<8;i+=1)
			{
				LED = led_L[i];
				delay(500);
			}	
		}
		if(K4 == 0)
		{
			for(i=0;i<8;i+=1)
			{
				LED = led_R[i];
				delay(500);
			}
		}
	}   
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

任务二

编写程序,使用中断函数实现以下功能:

1、数码管初始显示值为0。当按键K3按下,使数码管计数,记录按下的次数;

2、 当按键次数达到9时,蜂鸣器报警数码管显示值归0;

**注意:**数码管的驱动方式请查看附带PPT自行设计;

根据HC6800-ES V2.0开发板原理图

在这里插入图片描述

74HC573数码管控制驱动电路

在这里插入图片描述

74LS138八选一选择器原理图

可作Proteus仿真图如下:

在这里插入图片描述

数码管显示各部分代码实现详见:从零开始玩转C51之02. 数码管-CSDN博客

中断详解暂时还没写,可移步其他博文。

#include <stdio.h>
#include <intrins.h>
#include <reg52.h>
#define SEG P0
/*定义位选控制位*/
sbit A2=P2^4;
sbit A1=P2^3;
sbit A0=P2^2;

sbit K3 = P3^2;
sbit BEEP = P1^5;
typedef unsigned int u16;	 
typedef unsigned char u8;
/*存储段选数据*/
u8 code SEG_DATA[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,//共阴0 1 2 3 4 5 6 7 8 9
											0x77,0x7c,0x39,0x5e,0x79,0x71};//A B C D E F
/*定义计数变量*/
static u16 cnt=0;
											
/*延时函数*/
void delay(unsigned int ms)
{
	u16 i,j;
	for(i=0;i<ms;++i)
		for(j=0;j<110;++j);
}
/*设置外部中断0*/
void Int0Init()
{
	IT0=1;//跳变沿出发方式(下降沿)
	EX0=1;//打开INT0的中断允许。	
	EA=1;//打开总中断	
}
/*主函数*/
void main()
{
	u16 i,j;
	while (1)
	{
		Int0Init();
		while(1){
			SEG = SEG_DATA[cnt%10];//用取余函数,实现0~9周期显示
			if(cnt%10 ==9)
			{
				do{
					BEEP = ~BEEP;
					delay(1);
				}while(K3);
				if(K3 == 0)
				BEEP = 0;
			}
		}
	}   
}
/*外部中断0的中断函数*/
void Int0()	interrupt 0		
{
	if(K3==0)
	{
		delay(100);//延时消抖,可调节delay时间调整好消抖效果
		if(K3==0)
		{
			cnt++;
		}	
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66

任务三

编写程序,编写一分钟计时程序,并在数码管显示。使用开发板实现以下功能:

1、使用按键K1 K2 K3,做控制,分别为开始计时、暂停计时、计时清零;

2、开始计时(K1):每次从零开始计时

3、暂停计时(K2):按一次暂停计时,再次按下继续从停止时间计时;

4、计时清零(K3):计时清零,显示00;

在这里插入图片描述

#include <stdio.h>
#include <reg52.h>
#include <intrins.h>
#define SEG P0
/*定义位选控制位*/
sbit A2=P2^4;
sbit A1=P2^3;
sbit A0=P2^2;
/*定义按键控制位*/
sbit K1 = P3^1;
sbit K2 = P3^0;
sbit K3 = P3^2;
typedef unsigned int u16;	 
typedef unsigned char u8;
/*存储段选数据*/
u8 code SEG_DATA[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,//共阴0 1 2 3 4 5 6 7 8 9
											0x77,0x7c,0x39,0x5e,0x79,0x71};//A B C D E F
/*定义计时变量*/
u8 gmsec=0;//毫秒级定义
u8 gsec=0;//秒定义
											
/*延时函数*/
void delay(unsigned int ms)
{
	u16 i,j;
	for(i=0;i<ms;++i)
		for(j=0;j<110;++j);
}
void delay10ms(void)   //用于数码管位选扫描显示
{
    unsigned char a,b,c;
    for(c=1;c>0;c--)
        for(b=38;b>0;b--)
            for(a=130;a>0;a--);
}
/*定时器0初始化*/
void time0_init(void)
{
	TMOD|=0X01;//选择为定时器0模式,工作方式1
	TH0=0XDC;	//给定时器赋初值,定时10ms
	TL0=0X00;	
	ET0=1;//打开定时器0中断允许
	EA=1;//打开总中断
	TR0=0;//关闭定时器		
}
void time0_start(void)
{
	TR0=1;//打开定时器	
}
void time0_stop(void)
{
	TR0=0;//关闭定时器
	TH0=0X00;
	TL0=0X00;	
}
/*简易按键扫描*/
void key_scan()
{
	
	if(K1 == 0)//从零开始计时
	{
		time0_start();
		gsec = 0;
	}
	if(K2 == 0)
	{
		delay(1);//按键消抖
		if(K2 == 0)
		{
			TR0=!TR0;//利用取反运算实现暂停和计时
		}
	}
	if(K3 == 0)
	{
		time0_stop();//计时清零,显示00
		gsec = 0;
	}
}
/*动态显示实现两位数显示*/
void display_smg()
{
	u16 i;
	for(i=0;i<2;i++)
		{
		   switch(i)
			{
				case(0):
					A2=0;A1=0;A0=0;
					SEG = SEG_DATA[gsec%10];//显示个位
					break;
				case(1):
					A2=0;A1=0;A0=1;
					SEG = SEG_DATA[gsec/10];//显示十位
					break;
			}
		   delay10ms();
		}
}
/*主函数*/
void main()
{
	time0_init();
	while(1){
		key_scan();
		display_smg();
	}
}
/*定时器0中断函数*/
void time0() interrupt 1 //定时器0中断函数
{
	TH0=0XDC;	//给定时器赋初值,定时10ms
	TL0=0X00;
	gmsec++;//10ms加1次
	if(gmsec==100)//定时1秒
	{
		gmsec=0;
		gsec++;//对秒计数
		if(gsec == 61)
		{	
			gsec = 0;
		}
	}					
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123

虽然代码不是很优雅,但好在能实现功能,等有时间再来优化吧。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/408803
推荐阅读
相关标签
  

闽ICP备14008679号