壹拾叁:数码管的显示

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_17017545/article/details/81323839

#数码管的结构与原理
七段发光二极管简称数码管
七段发光管分别称为a、b、c、d、e、f、g,构成字形“8”,七段式发光管名称就是由此而来的,数码管分为共阴极和共阳极两种。
通常有的产品还附带有一个小数点,如图dp断控制,故有人叫其为八段式发光二极管。
这里写图片描述

在共阴极数码管中,如果a、b、c为高电平,其他段为低电平,即1110000,则显示数字“7”。
在共阳极数码管中刚好相反,即数码管显示端数据位0001111时,则显示数据“7”。
这里写图片描述

#课程实验
这里写图片描述

C代码

******************************************************************/	
*   【课程14】 ****数码管的显示***********
*   【说  明】 ****
*   【描  述】 ****数码管的静态扫描,显示(0~F)16个字符
******************************************************************/   
#include<reg51.h>		//51头文件,

//---------常用的两个宏定义-------------- 
#define uint8	unsigned char
#define uint16  unsigned int

//---------数码管位选定义----------------
sbit smg_A1 = P2^0;
sbit smg_A2 = P2^1;

//------------数码管段选显示数据-------------------
uint8 SEG_Data[16]={~0x3F,~0x06,~0x5B,~0x4F,~0x66,~0x6D,~0x7D,
~0x07,~0x7F,~0x6F,~0x77,~0x7C,~0x39,~0x5E,~0x79,~0x71};
// 例:0x3F转为二进制:0011 1111,取反为:1100 0000,
//这里数码管的八段ABC从低位P0.1、P0.2、P0.3一一对应,显示为数字“0”,(共阳极)

//------------函数的声明-----------------
void DelayMS(uint16 dly);

//-------------主函数--------------------
void main(void)
{
	uint8 i;
	
	smg_A1 = 1;		//打开第一个数码管的位选
	smg_A2 = 1;     //打开第二个数码管的位选
	while(1)
	{
//两个数码管显示不一样的数据(动态显示,切换)	
//缩短延时时间,然后在两个数码管之间迅速切换,人眼感觉不到,看到的是显示数字“12”
		smg_A1 = 0;         //关闭第一个数码管
		smg_A2 = 0;         //关闭第二个数码管
		P0 = SEG_Data[1];   //将先显示“1”的数据传给P0口
		smg_A1 = 1;         //打开第一个数码管的位选,显示“1”
		DelayMS(20);        //延时20ms
		
		smg_A1 = 0;         //关闭第一个数码管
		smg_A2 = 0;         //关闭第二个数码管
		P0 = SEG_Data[2];   //将先显示“2”的数据传给P0口
		smg_A2 = 1;         //打开第二个数码管的位选,显示“2”
		DelayMS(20);	    //延时20ms
//两个数码管显示一样的数据(静态显示)	
/*
		for(i=0;i<16;i++)
		{
			P0 = SEG_Data[i];//段选数据
			DelayMS(1000);
		} 
*/	
	}		
}
/********************************************************
** 名称 :void DelayMS(uint16 dly)
** 功能 :毫秒级延时(24M的晶振)
** 入口参数 :dly  用户的延时参数   
** 出口参数 :无   
*********************************************************/
void DelayMS(uint16 dly)
{
	uint16 x,y;
	for(x=dly;x>0;x--)
		for(y=247;y>0;y--);
}

//位选:选择控制哪个数码管,即相当于使能某个数码管。
//段选:即选择数码管的哪一段亮,然后显示出想要的数字。

#思维扩展1
这里写图片描述

**SPI(Serial Peripheral Interface,串行外围接口)**是由Motorola公司提出的一种同步串行外围接口,SPI是一种全双工的同步串行接口,一个SPI总线可以连接多个主机和多个从机,但是在同一时刻只允许一个主机操作总线。
1.SPI总线接口中具体接口信号描述如下:
MISO(Master In Slave Out)
主机输入、从机输出信号
MOSI(Master Out Slave In)
主机输出、从机输入信号
SCK(Serial Clock)
串行时钟信号
SS(Slave Select)
从机选择信号

注: LSB:least significant bit 表示二进制数据的最低位 MSB : most significant bit 表示二进制数据的最高位

这里写图片描述

代码

******************************************************************/ 	
*   【课程14】 ****数码管的显示***********
*   【说  明】 ****动态扫描数码管		
*   【描  述】 ****动态扫描数码管,并使用单片机与595通信
******************************************************************/ 
#include<reg51.h>		//51头文件,

//---------常用的两个宏定义-------------- 
#define uint8	unsigned char
#define uint16  unsigned int

/*--595功能脚定义--*/
sbit Sck=P2^4;
sbit nCS=P3^7;
sbit Rck=P2^0;
sbit Mosi=P2^6;

/*--数码管位码定义--*/
sbit smgA1=P0^0;
sbit smgA2=P0^3;
sbit smgA3=P0^4;
sbit smgA4=P0^5;

//------------数码管段选显示数据-------------------十六进制数 0-F
uint8 SEG_Data[17]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,
0x01,0x19,0x11,0xc1,0x63,0x85,0x61,0x71,0xff};
//0x03二进制位 0000 0011 
//这里数码管的八段ABC从高位QA、QB、QC一一对应,显示为数字“0”,(共阳极)这里数组与上个程序不同

/********************************************************
** 名称 :void DelayMS(uint16 dly)
** 功能 :毫秒级延时(24M的晶振)
** 入口参数 :dly  用户的延时参数   
** 出口参数 :无   
*********************************************************/
void DelayMS(uint16 dly)
{
	uint16 x,y;
	for(x=dly;x>0;x--)
		for(y=124;y>0;y--);
}

/*******************************************
函数名:SMG_Disp(uint8 Data)
功能:驱动数码管  
入口参数:uint8 Data 数码管要显示的数  
出口参数:无 
********************************************/
void SMG_Disp(uint8 Data)
{	
	uint8 i,temp;
	nCS=0;
	Rck=0;
	temp=SEG_Data[Data];
	for(i=0;i<8;i++)  //循环八次,依次送出数码管段码的八位
	{
		
		Sck=0;			//上升沿送出一位
		Mosi=temp&0x01; //先送出低位
		Sck=1;	
		temp=temp>>1;	//右移送出高位
	}
		Rck=1;			//上升沿输出锁存
}
/*******************************************
函数名:void SMG_Disp2(uint8 count)
功能:驱动两位数码管  
入口参数:uint8 count 数码管要显示的数  
出口参数:无 
********************************************/
void SMG_Disp2(uint8 count)
{
	uint8 num_ge,num_shi;

	num_shi = count / 10;   //取十位数
	num_ge = count % 10;    //取个位数
	SMG_Disp(16);           //数据中第16个为 0xff,代表全黑
	smgA2=1;
	smgA1=0;	     	    //点亮第一个数码管		
	SMG_Disp(num_shi); 		//显示十位数		
	DelayMS(10);

	SMG_Disp(16);
	smgA1=1;
	smgA2=0;
	SMG_Disp(num_ge); 		//显示个位数	
	DelayMS(10);	
}
//PNP三极管的基极为低电平时三极管导通
//当P0^0(smgA1)输出0(低)时,三极管导通,下方为VDD 3.3V,A1端为高电平(即片选信号)


/*******************************************
函数名:void SMG_Disp4(uint16 count)
功能:驱动四位数码管  
入口参数:uint16 count 数码管要显示的数  
出口参数:无 
********************************************/
void SMG_Disp4(uint16 count)
{
	uint8 num_one,num_ten,num_hundred,num_thousand;

	num_thousand = count / 1000;        //提取千位
	num_hundred = (count % 1000)/ 100;  //提取百位
	num_ten = (count % 100) / 10;       //提取十位
	num_one = count % 10;               //提取个位
	
	SMG_Disp(16);                      //全黑
	smgA4 = 1;
	smgA3 = 1;		
	smgA2 = 1;
	smgA1 = 0;			//	点亮第一个数码管(千位)	
	SMG_Disp(num_thousand); 				
	DelayMS(15);

	SMG_Disp(16);
	smgA4 = 1;
	smgA3 = 1;
	smgA1 = 1;
	smgA2 = 0;			//	点亮第二个数码管(百位)
	SMG_Disp(num_hundred); 				
	DelayMS(15);


	SMG_Disp(16);
	smgA4 = 1;		
	smgA2 = 1;
	smgA1 = 1;
	smgA3 = 0;			//	点亮第三个数码管(十位)		
	SMG_Disp(num_ten); 				
	DelayMS(5);
	
	SMG_Disp(16);
	smgA3 = 1;		
	smgA2 = 1;
	smgA1 = 1;
	smgA4 = 0;			//	点亮第四个数码管(个位)		
	SMG_Disp(num_one); 				
	DelayMS(5);
}

//从main函数处开始执行
void main()
{	
	uint16 x,y;	
	x = y = 0;
	while(1)
	{
		SMG_Disp4(x);
		y++;				//延时的作用
		if(y==10)
		{
			y=0;
			x++;
			if(x==9999)		
				x=0;
		}	
	}
}

猜你喜欢

转载自blog.csdn.net/qq_17017545/article/details/81323839