首页 > 其他分享 >实验二 数码管的静态和动态显示方法、矩阵式键盘扫描

实验二 数码管的静态和动态显示方法、矩阵式键盘扫描

时间:2024-11-16 22:43:11浏览次数:3  
标签:动态显示 delayms LED 矩阵式 void SEG 数码管 按键

本文主要介绍了课本第5章第3、7节数码管与矩阵式键盘接口设计的实验,本节内容更侧重对原理的理解,可能会出简答题

LED数码管的显示原理

静态显示

当LED位于静态显示时,无论多少位LED数码管都处于同时显示的状态,但1位数码管独占1个IO口

实验一

#include <reg51.h>
#define uchar unsigned char

#define seg P0
sbit button = P3^2;

uchar mode = 0;

void delayms(uchar ms) {
    uchar i;
    while(ms--) {
        for(i = 0; i < 120; i++);
    }
}

void check_button()
{
    if(button == 0) {
        delayms(10);  // 按键消抖
        if(button == 0) {  // 确认按键状态
            mode++;
            if(mode > 3) {
                mode = 1;
            }
            while(button == 0);  // 等待按键释放
        }
    }
}

void seg_mode()
{
    switch(mode)
    {
        case 0:
            seg = 0x03;  // 显示0
            break;
        case 1:
            seg = 0x9F;  // 显示1
            break;
        case 2:
            seg = 0x25;  // 显示2
            break;
        case 3:
            seg = 0x0D;  // 显示3
            break;
    }
}

void main()
{
    while(1) {
        check_button();
        seg_mode();
    }
}

 动态显示

动态显示的核心是通过快速轮流显示每个位,并利用人眼的视觉暂留效应让多个数码管看起来像是同时显示各自的内容。

视觉暂留效应
  • 人眼有一个“视觉暂留时间”,大约是 0.1 秒以内。当图像在短时间内变化得足够快时,人眼无法分辨出变化,而会认为它们是同时显示的。
  • 动态显示利用这一效应,在不同的数码管之间快速切换,使人感到它们都同时在显示数字。
步骤与过程
  1. 分时点亮

    • 对于一个多位数码管,按顺序点亮每一位。例如,如果有 4 个数码管(显示 4 位数字),程序会按顺序依次点亮第 1 位、第 2 位、第 3 位、第 4 位。
    • 只点亮一个数码管,并在显示完数字后迅速切换到下一个数码管。
  2. 快速刷新

    • 每个位显示的时间非常短,通常是几毫秒(例如每个位 2 ms)。4 个数码管全显示完一轮后,立刻开始下一轮。
    • 由于切换速度快,人眼会觉得 4 个数码管是同时显示的。
void delay(uint t)
{
    uchar i;
    while(t--)for(i=0;i<200;i++);
}

void main(){
    uchar i,j = 0x80;
    while(1)
    {
        for(i=0;i<8;i++){
            j = _crol_(j,1);
            P0 = discode[i];
            P2 = j;
            delay(1);
    }
}

位选码和段选码 

矩阵式键盘的接口设计 

原理:键盘矩阵中无按键按下时,行线处于高电平状态;当有按键按下时,行线电平状态将由与此行线相连的列线的电平决定。如果列线的电平为低,则行线电平为低,反之亦然。

【课本例题逻辑】假设以行扫描为例:

  1. 逐行拉低行线
    • 将 R1~R4 设置为输出,并逐行拉低(例如,先让 R1 为低电平,其余为高电平)。
  2. 逐列检测
    • 读取 C1~C4 的电平状态。如果某列检测到低电平,说明当前激活行对应的按键被按下。
    • 例如,R1 为低电平,C2 为低电平,表示 R1 和 C2 的交点(按键 “2”)被按下。
  3. 重复扫描
    • 逐行重复上述过程,直到扫描完整个键盘矩阵。
#include <reg51.h>
#define uchar unsigned char 
#define ucode unsigned code 

#define SEG P0		 //定义IO口
#define BUTTON P2
sbit LED = P3^7;	 

//延时函数
void delayms(uchar ms) {
    uchar i;
    while(ms--) {
        for(i = 0; i < 120; i++);
    }
}

//读键值函数
char getKey(void) {
    uchar temp, row, column, i;
    uchar ColumnCode[4] = {0xef, 0xdf, 0xbf, 0x7f};  // 列扫描
    BUTTON = 0x0f;  // 低四位输入状态
    temp = BUTTON & 0x0f;

    if (temp != 0x0f) { // 检测到按键
        delayms(5); // 消抖
        temp = BUTTON & 0x0f;
        
        if (temp != 0x0f) {
            switch(temp) {
                case 0x07: row = 3; break;
                case 0x0b: row = 2; break;
                case 0x0d: row = 1; break;
                case 0x0e: row = 0; break;
                default: return -1; // 未识别的行
            }
            for (i = 0; i < 4; i++) {
                BUTTON = ColumnCode[i]; // 列扫描
                temp = BUTTON & 0x0f; // 读按键状态
                if (temp != 0x0f) { // 检测按键
                    column = i;
                    return (row * 4 + column); // 计算按键编号0~15
                }
            }
        }
    }
    return -1; // 没有按键被按下
}


void begin(void){   //数码管显示闪烁“8”
    SEG = 0x00;	 
	delayms(2000);
	SEG = 0xFF;
	delayms(2000); 	
}

void right(void){	//数码管闪烁显示“P”
	SEG = 0x8C;	  
	delayms(2000);
	SEG = 0xFF; 
	delayms(2000); 
}	

void wrong(void){	//数码管闪烁显示“E”
	SEG = 0x86;	  
	delayms(2000);
	SEG = 0xFF; 
	delayms(2000); 
}	

void main(void)
{	
	int tempkey;
	LED = 1;   //LED灭,表示上锁
	begin();
	begin();	
	SEG = 0xBF;	  //数码管显示“-”,进入待机状态
 	
   	while(1)
	{
		tempkey = getKey();
		
		if (tempkey == 6) {  // 如果密码输入正确
			LED = 0;	  // LED亮
			right();
			right();
			SEG = 0xBF;
			LED = 1;	  // 进入待机状态
		} 
		else if (tempkey >= 0 && tempkey < 16) { // 有效按键
			LED = 1;	  // LED灭
			wrong();
			wrong();
			SEG = 0xBF;	  // 进入待机状态
		} else {
			SEG = 0xBF;	 //保持待机状态
		}
	}
}

按键函数逻辑

  1. 行扫描检测按键按下
    • 通过读取行的电平状态,确定按下按键所在的行。
  2. 列扫描确认具体按键
    • 逐列拉低列线,读取行的状态变化,确认按下按键所在的列。
  3. 按键编号计算
    • 按键编号 = 行编号 * 4 + 列编号。
  4. 返回按键编号
    • 返回按键的编号(0~15);若无按键按下,返回 -1

标签:动态显示,delayms,LED,矩阵式,void,SEG,数码管,按键
From: https://blog.csdn.net/Astro_1999/article/details/143823554

相关文章

  • 基于STM32通过TM1637驱动4位数码管详细解析(可直接移植使用)
    目录1. 单位数码管概述2. 对应编码2.1 共阳数码管2.2 共阴数码管3. TM1637驱动数码管3.1 工作原理3.1.1 读键扫数据3.1.2 显示器寄存器地址和显示模式3.2 时序3.2.1 指令数据传输过程(读案件数据时序)3.2.2 写SRAM数据地址自动加1模式3.2.3 ......
  • Qt/C++地图高级绘图/指定唯一标识添加删除修改/动态显示和隐藏/支持天地图高德地图百
    一、前言说明已经有了最基础的接口用来添加覆盖物,而且还有通过进入覆盖物模式动态添加覆盖物的功能,为什么还要来个高级绘图?因为又有新的需求,给钱就搞,一点底线都没有。无论哪个地图厂家,提供的接口都是没有唯一标识参数的,也就类似于学号,这就是需要自己主动定一个属性用来存储唯一标......
  • 38、基于AT89C52的VIM-332-DP笔段式液晶动态显示proteus仿真设计
    一、仿真原理图:二、仿真效果:三、相关代码:/************************************************************************************** *FunctionName   :DisplayM *Description    : *******************************************************......
  • 51单片机实现数码管显示
    51单片机实现数码管显示本次的实现效果方式采用模拟进行,芯片为AT89C51,开发软件为keil5,proteus上代码代码如下:#include<reg51.h>voiddelay(unsignedinti);//延时函数unsignedinti=0;voidmain(){unsignedcharbutton=0,flag=0;unsignedchardigitC......
  • FPGA实例——数码管(下)
    前言:上一篇文章的话是介绍了关于数码管的基础知识和静态数码管的verilog代码,那本章的话将去介绍如何实现动态数码管以及它的verilog代码和展示动态数码管:简易计数器:这里的话主要去介绍一个简易的计数器,由按键控制开始和结束,每秒自加1,从0计到9999,计满后清零动态数码管显示......
  • 2、51单片机实现数码管的数值显示
    2.1、实验目的8位共阴数码管显示8位以内的数字2.2、实验环境普中51开发板(stc89c52、74HC245、74HC138、8位共阴数码管)2.3、实验代码#include<reg52.h> #include<intrins.h> typedefunsignedcharu8; typedefunsignedintu16;staticu8digital_buffer[8]......
  • 基于Arduino的数码管显示变阻器模拟量读取值
    题目要求采集变阻器模拟量信号在数码管中显示,要求有二位小数电路连接数码管连接:数码管的七个段(a-g)分别连接到Arduino的引脚2到8。数码管的小数点(dp)连接到Arduino的引脚9。数码管的4个控制引脚连接到Arduino的引脚10到11。变阻器连接:变阻器的模拟输出引脚连接到Arduin......
  • Proteus中数码管动态扫描显示不全(已解决)
    前言我是直接把以前写的51数码管程序复制过来的,当时看的郭天祥的视频,先送段选,消隐后送位选,最后来个1ms的延时。代码在Proteus中数码管静态是可以的,动态显示出了问题——显示不全,我在网上搜的说是Proteus的Bug,需要先送位选再送段选,我试了试也不行。最后在我多次实验下......
  • 抗干扰数显LED显示屏驱动芯片/数码管驱动控制器-VK1628 SOP28
    VK1628是一种带键盘扫描接口的数码管或点阵LED驱动控制专用芯片,内部集成有3线串行接口、数据锁存器、LED驱动、键盘扫描等电路。SEG脚接LED阳极,GRID脚接LED阴极,可支持13SEGx4GRID、12SEGx5GRID、11SEGx6GRID、10SEGx7GRID的点阵LED显示面板,最大支持10x2按键。适用于要求可......
  • 【STM32 Blue Pill编程实例】-4位7段数码管使用
    4位7段数码管使用文章目录4位7段数码管使用1、7段数码介绍2、硬件准备与接线3、模块配置4、代码实现在本文中,我们将介绍如何将STM32BluePill开发板与4位7段数码管连接,并在STM32CubeIDE中对其进行编程。在文章中首先将介绍4位7段数码管及其与......