Ai8051U学习之旅(3)- 数码管显示
一、前言数码管显示是常见的显示器件,最常用的是家电、消费电子上,学会数码管驱动,对于理解数字显示、定时器运用、IO操作都有帮助,今天就先整理一下数码管学习笔记。二、硬件电路2.1 数码管2.1.1 数码管的基本结构1) 七段数码管:ü最常见的类型,包含7个LED段(a-g),排列成“日”字形。ü额外的小数点(DP)段,共8个控制引脚。ü每个段对应一个LED,通过通电点亮。2) 共阳(Common Anode)与共阴(Common Cathode):ü共阳:所有LED的阳极连接在一起,接高电平(VCC),阴极分别控制。ü共阴:所有LED的阴极连接在一起,接地(GND),阳极分别控制。2.1.2 工作原理1)显示原理:ü通过给不同段通电组合显示数字(如数字“0”需要a、b、c、d、e、f段亮)。ü需配合限流电阻(通常100-500Ω)保护LED。2)编码方式:ü每个数字对应一个二进制或十六进制编码(段码表)。ü例如,共阴数码管显示“0”的段码为 0x3F(二进制 00111111)。2.1.3 驱动方式1、静态驱动:n每个数码管独立连接控制引脚,适合少量显示。n优点:亮度稳定;缺点:占用引脚多。2、动态扫描(多路复用):n多个数码管共用段引脚,通过快速切换公共端分时显示。n优点:节省引脚;缺点:需较高刷新频率(>60Hz)避免闪烁。2.2 数码管驱动电路正常情况下,MCU的驱动电路没有那么大或IO不够多时,就需要外围驱动IC来做数码管的驱动电路,最常用的是串转并芯片,AI8051U开发板上用的是经典的74HC595,如下图:图1 数码管电路图 74HC595是一个8位串行输入、平行输出的位移缓存器:平行输出为三态输出。在SCK的上升沿,单行数据由SDL输人到内部的8位位移缓存器,并由Q7‘输出,而平行输出则是在LCK的上升沿将在8位位移缓存器的数据存人到8位平行输出缓存器。当串行数据输人端OE的控制信号为低使能时,平行输出端的输出值等于平行输出缓存器所存储的值。而当OE为高电位,也就是输出关闭时,平行输出端会维持在高阻抗状态。串行输入,并行输出。表1 74HC595引脚定义三、软件设计 知道了驱动原理,接下来就是根据原理写程序,也就是如果让HC595发数据,如果让数据管显示。先简单的显示12345678 3.1 数码管驱动 Dev_Segled.c/*----------------------------------------------------------------------------------------------------------------------* Copyright(c) 2024, Mark Xu Work Studio R&D Department. All rights reserved.
* 文件名称 : Dev_Segled.c
* 文件版本 : V1.0.0
* 功能描述 : 数码管应用模块
* 创建人员 : Mark Xu
* 创建日期 : 2025/02/17
----------------------------------------------------------------------------------------------------------------------*/
#include "Dev_Segled.h"
//----------------------------------------------------------------------------------------------------------------------
// 配置文件
//----------------------------------------------------------------------------------------------------------------------
#define SEG_COM_MAX (8) //8位数码管
//----------------------------------------------------------------------------------------------------------------------
// 类型重定义
//----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------
// 常量、宏
//----------------------------------------------------------------------------------------------------------------------
U8C segCode[] = { //标准字库
// 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,
//black- H J K L N o P U t G Q r M y
0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46}; //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1
U8C segCom = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //位码
//----------------------------------------------------------------------------------------------------------------------
// 局部变量
//----------------------------------------------------------------------------------------------------------------------
static U8s_u8DisBuff = {1, 2, 3, 4, 5, 6, 7, 8}; //显示缓存
static U8s_u8ComLoopCnt = 0; //轮询值
//----------------------------------------------------------------------------------------------------------------------
// 全局变量
//----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------
// 本地函数声明
//----------------------------------------------------------------------------------------------------------------------
/*----------------------------------------------------------------------------------------------------------------------
* 函数名称 :void Segled_Init(void)
* 功能描述 :数码管程序初始化
* 入口参数 :无
* 出口参数 :无
* 备注说明 :无
----------------------------------------------------------------------------------------------------------------------*/
void Segled_Init(void)
{
}
/*----------------------------------------------------------------------------------------------------------------------
* 函数名称 :void HC595_SendDat(U8 i_Dat)
* 功能描述 :传输数据
* 入口参数 :i_Dat - 要传输的8位数据
* 出口参数 :无
* 备注说明 :无
----------------------------------------------------------------------------------------------------------------------*/
void HC595_SendDat(U8 i_Dat)
{
U8 i;
for (i=0; i<8; i++)
{
if (i_Dat & 0x80) //先传输高位
{
HC595_DAT_HI();
}
else
{
HC595_DAT_LO();
}
i_Dat <<= 1;
HC595_SRCLK_HI();
HC595_SRCLK_LO();
}
}
/*----------------------------------------------------------------------------------------------------------------------
* 函数名称 :void Segled_AllOff(void)
* 功能描述 :关闭数码管
* 入口参数 :无
* 出口参数 :无
* 备注说明 :无
----------------------------------------------------------------------------------------------------------------------*/
void Segled_AllOff(void)
{
U8 i = 0;
for (i=0; i<SEG_COM_MAX; i++)
{
s_u8DisBuff = 0x00;
}
} Dev_Segled.h/*----------------------------------------------------------------------------------------------------------------------
* Copyright(c) 2025, Mark Xu Work Studio R&D Department. All rights reserved.
* 文件名称 : Dev_Segled.h
* 文件版本 : V1.0.0
* 功能描述 : 数码管功能头文件
* 创建人员 : Mark Xu
* 创建日期 : 2025/02/17
----------------------------------------------------------------------------------------------------------------------*/
#ifndef __DEV_SEGLED_H__
#define __DEV_SEGLED_H__
#include "includes.h"
//----------------------------------------------------------------------------------------------------------------------
// 常量、宏
//----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------
// 类型重定义
//----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------
// 全局变量
//----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------
// 全局函数
//----------------------------------------------------------------------------------------------------------------------
#if (DEV_SEGLED_EN)
extern void Segled_Init(void);
extern void Segled_DeInit(void);
extern void Segled_PollProc(void);
#else
#define Segled_Init()
#define Segled_DeInit()
#define Segled_PollProc()
#endif
#endif //#ifndef __DEV_SEGLED_H__
在主程序中调用void Segled_PollProc(void);这个函数即可,如下所示:
1、为了简单期间,直接在main函数中轮询调用,当然设计了标志,每1ms调用一次
2、存在缺点:如果大循环中存在的事件比较大,浪费的时间比较久,则可能影响数码管的显示效果,这时可能需要抢占式任务或直接在定时器中调用
3、下步计划:试一下RTC,作一个小闹钟,配合按键等,可以直接用 今天实验的工程,所有源文件均在工程中,
注意:工程名没有更改,当然这个不影响实验的结果{:4_167:}
页:
[1]