《蓝桥杯CT107D单片机竞赛板》:数码管模块

Posted 是七喜呀!

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《蓝桥杯CT107D单片机竞赛板》:数码管模块相关的知识,希望对你有一定的参考价值。

数码管模块

实验简介

软件控制,实现数码的静态和动态显示效果

实验原理图

实验原理

  • 数码管介绍:LED数码管为单片机中的显示器之一,有共阳和共阴数码管,CT107D单片机中所用的为共阳数码管, 即7段数码管(a,b,c,d,e,f,g)和一个小数点(dp)的共8个管脚有一端共同接到VCC上。CT107D单片机上有两个多位数码管(4位一体),两个4位一体的多位数码管内部的公共端(com)是独立的,公共端又叫做“位选线”,而负责显示什么数字的段线(a,b,c,d,e,f,g)和小数点(dp)全部是连在一起的,独立的公共端控制哪一位数码管亮(选择哪一位亮的过程我们称之为“位选”),而显示亮什么内容(亮什么内容这个过程我们称之为“段选”)

  • 基本原理:数码管显示有两种显示方式,静态显示方式和动态显示方式。静态显示的主要特征为:每个数码管的段选必须接一个8位数据线来保持显示的字形码。送入一次字形码后,显示字形可一直保持,直到送入新字形码为止。因此我们也就知道了静态显示的显示弊端所在,要么只显示一位数码管,否则多位数码管同时显示时,必须显示相同内容。而动态显示,则是一定程度上弥补了静态显示的显示弊端。

  • 实现须知:动态显示,利用减少段选线,分开位选线,利用位选线不同时选择通断,改变段选数据来实现的。利用人眼的视觉暂留现象,即光对视网膜所产生的视觉在光停止作用后,仍保留一段时间的现象,正常情况人眼只能分辨变化超过 24ms 间隔的运动。根据锁存器的芯片手册,锁存端LE得为高电平,即得控制Y7C,Y6C为高电平,下图知Y7C,受Y7控制,Y6C,受Y6控制,WR输入固定为低电平(0),了解数字电路中或非门知识,我们得使得Y6,Y7输出低电平,才能使的Y6C,Y7C输出高电平,而Y6,Y7为74HC138芯片(38译码器)的两个个管脚,查阅对应芯片手册可知,其真值表满足C = 1,B = 1,A = 0(Y6),C = 1,B = 1,A = 1(Y7)(对应管脚P27,P26,P25),使得Y6,Y7输出低电平,同时我们得保证管脚P2的其他的管脚(0~4)保持原来的状态。


实验程序

静态显示

	//config.h--用于声明头文件,声明函数,声明一些经常使用的变量或难书写的语句
	#ifndef _CONFIG_H
	#define _CONFIG_H
	#include <STC15F2K60S2.H>//对应芯片函数头文件,定义了一些特殊功能寄存器
	
	//typedef unsigned char uchar;
	#define uchar unsigned char
	
	#endif
//main.c文件
#include "config.h"

//共阳数码管0~9的段选码
uchar smgduan[] = 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90;

void led_init()//LED初始化为全部不亮

	P2 = (P2 & 0x1f) | 0x80;//初始化锁存器的Y4C
	P0 = 0xff;


void closeBeep()

	P2 = (P2 & 0x1f) | 0xa0;  //开启译码器的Y6端口,同时不改变其他管脚状态
	P0 &= 0xaf;//1010 1111//关闭蜂鸣器和继电器,P06和P04端口分贝输入,输出低电平
	P2 &= 0x1f;//关闭译码器	


void digDisplay()

	//Y6C输入高电平,选中位选,使得1,3,5,7个数码管亮,给对应管脚高电平即可
	P2 = (P2 & 0x1f) | 0xc0;
	P0 = 0x55; //0101 0101

	//Y7C输入高电平,选中段选,使得1,3,5,7数码管输出4 个 1,1的共阳数码管码值为0xf9
    P2 = (P2 & 0x1f) | 0xe0;
	P0 = 0xf9;//1111 1001



void main()

	led_init();	
	closeBeep();
	digDisplay();	

	while(1); 

动态显示

数码管从左往右依次显示数字

//config.h--用于声明头文件,声明函数,声明一些经常使用的变量或难书写的语句
#ifndef _CONFIG_H
#define _CONFIG_H
#include <STC15F2K60S2.H>//对应芯片函数头文件,定义了一些特殊功能寄存器
#include<intrins.h>//使用_nop_()函数所需的头文件
//typedef unsigned char uchar;
#define uchar unsigned char

void Delay300ms();		//@12.000MHz

#endif
//main.c文件--8个数码管从左往右依次显示,0~7八个数字
#include "config.h"

//共阳数码管0~9的段选码
uchar smgduan[] = 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90;

//共阳数码管1 ~ 8的位选码
uchar smgwei[] = 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80;


void led_init()//LED初始化为全部不亮

	P2 = (P2 & 0x1f) | 0x80;
	P0 = 0xff;


void closeBeep()

	P2 = (P2 & 0x1f) | 0xa0;  //开启译码器的Y6端口,同时不改变其他管脚状态
	P0 &= 0xaf;//1010 1111//关闭蜂鸣器和继电器,P06和P04端口分贝输入,输出低电平
	P2 &= 0x1f;//关闭译码器	


void digDisplay()

	uchar i;
	for (i = 0; i < 8; i++)
	
		//位选,单次选中一个数码管
		P2 = (P2 & 0x1f) | 0xc0;
		P0 = smgwei[i];
		
		
		//段选
		P2 = (P2 & 0x1f) | 0xe0;
		P0 = smgduan[i];
		
		
		//消隐,给足显示的时间
		Delay300ms();
		
		//初始化
		P2 = P2 & 0x1f;
		P0 = 0x00;
		



void main()

	led_init();	
	closeBeep();
	
	while(1)
	
	
	  digDisplay();	
	 


void Delay300ms()		//@12.000MHz

	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 14;
	j = 174;
	k = 224;
	do
	
		do
		
			while (--k);
		 while (--j);
	 while (--i);


8个数码管同时显示不同的数字

//在上面的基础上,主要改动的代码部分,config.h文件里面对延时3000u函数进行声明一下即可
void digDisplay()

	uchar i;
	for (i = 0; i < 8; i++)
	
		//位选,单次选中一个数码管
		P2 = (P2 & 0x1f) | 0xc0;
		P0 = smgwei[i];
		
		
		//段选
		P2 = (P2 & 0x1f) | 0xe0;
		P0 = smgduan[i];

		//给足显示的时间
		Delay3000us();
		
		//端口初始化,不弄也可以,下次进入循环时也会自动改变
		P2 = P2 & 0x1f;
		P0 = 0x00;

		



void main()

	led_init();	
	closeBeep();
	
	while(1)
	
	  digDisplay();	
	 


void Delay3000us()		//@12.000MHz

	unsigned char i, j;

	i = 36;
	j = 1;
	do
	
		while (--j);
	 while (--i);


8位数码管显示输入的内容

  • config.h文件不变
//main.c文件--8个数码管显示输入的内容
#include "config.h"

//共阴数码管段选码
uchar smgduan[] =                       //标准字库
//   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

//共阳数码管1 ~ 8的位选码
uchar smgwei[] = 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80;
	
uchar tab[8];//全局变量存储即将要显示的内容

	
void led_init()//LED初始化为全部不亮

	P2 = (P2 & 0x1f) | 0x80;
	P0 = 0xff;


void closeBeep()

	P2 = (P2 & 0x1f) | 0xa0;  //开启译码器的Y6端口,同时不改变其他管脚状态
	P0 &= 0xaf;//1010 1111//关闭蜂鸣器和继电器,P06和P04端口分别输入,输出低电平
	P2 &= 0x1f;//关闭译码器	


void digDisplay(uchar pos, letter)//数码管的哪一位,显示什么字母(letter)

	//Y6C输入高电平,选中一个位选,给对应管脚高电平即可
	P2 = (P2 & 0x1f) | 0xc0;
	P0 = smgwei[pos - 1];

	//Y7C输入高电平,选中段选,注意共阳数码管使用共阴数码管的码值需要加个取反符号
    P2 = (P2 & 0x1f) | 0xe0;
	P0 = ~smgduan[letter];
	
	//消隐
	Delay3000us();
	P2 &= 0x1f;//P27 ~ P25清零
	P0 = 0xff;



void display()

	uchar i;
	for (i = 0; i < 8; i++)
	
	digDisplay(i + 1, tab[i]);
	


void display_ds(uchar p1, p2, p3, p4, p5, p6, p7, p8)

	tab[0] = p1;
	tab[1] = p2;
	tab[2] = p3;
	tab[3] = p4;
	tab[4] = p5;
	tab[5] = p6;
	tab[6] = p7;
	tab[7] = p8;


void main()

	led_init();	
	closeBeep();
	
	while(1) 
    
		display();//显示进行初始化
		display_ds(2, 0, 2, 2, 0, 1, 2, 0);//显示:2022年01月20号
    


void Delay3000us()		//@12.000MHz

	unsigned char i, j;

	i = 36;
	j = 1;
	do
	
		while (--j);
	 while (--i);

以上是关于《蓝桥杯CT107D单片机竞赛板》:数码管模块的主要内容,如果未能解决你的问题,请参考以下文章

《蓝桥杯CT107D单片机竞赛板》:定时器模块

《蓝桥杯CT107D单片机竞赛板》:矩阵键盘模块

《蓝桥杯CT107D单片机竞赛板》:中断模块

《蓝桥杯CT107D单片机竞赛板》:蜂鸣器模块

《蓝桥杯CT107D单片机竞赛板》:LED模块

《蓝桥杯CT107D单片机竞赛板》:赛前准备工作