(51单片机)习题:74HC595数码管8位显示与8位独立按键复用

     75HC595是一片具有8位串行输入/并行输出移位寄存器,利用三个端口,就可以驱动8位数码管,本文在显示的同时,外加一个51单片机IO口,将8位独立按键复用。

     74HC595驱动数码管不再累述,请查看规格书理解底层代码,仿真电路图如下:

(51单片机)习题:74HC595数码管8位显示与8位独立按键复用_第1张图片

 按键识别思路:利用74HC595驱动的8个位码端口,给按键依次发送低电平,当8个按键有按下时,检测P3.7,如为0,则进行识别,并将键值输出至数码管显示。

头文件、变量声明、IO口定义如下:

/******************************************************************
使用8个595输出端口+一个单片机IO口P3.7,利用两个数码管输出键值1-8
思路:使用动态扫描的间隙,去给按键写0,判断IO口,识别键值
******************************************************************/
#include
#include
typedef unsigned char uint8;
typedef unsigned int uint16;
typedef unsigned long uint32;
sbit Latch_clk = P2^0;   //595的第12脚锁存
sbit Shift_clk = P2^1;   //595的第11脚移位
sbit data_in = P2^2;     //595的第14脚串行输入
sbit key_IO = P3^7;      //一个IO口
/*****************************变量声明*****************************/
uint8 code duanma[19]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x89,0x7f,0xbf}; 
uint8 code wei_dat[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};       //定义八位数码管位选数据数组
uint8 key_scan();

595的驱动底层函数:

/***************************写入数据函数******************************
*函数名称:Write_INT16_74hc595
*函数功能:两片595级联输出16位数据函数
*函数调用:Write_INT16_74hc595(uint16 Data); 
*参数列表:Data
*返 回 值:无
*结    果:把 16 Data  数据输出到两片595芯片输出引脚
*备    注:
*********************************************************************/
void Write_INT16_74hc595(uint16 Data)
{
  uint8 i=0;
	for(i=0;i<16;i++)
	{
   data_in  =  (Data<

74HC595驱动共阳数码管,在指定位置输出一个几位数函数:

/*************************74hc595驱动数码管输出函数***************************
*函数名称:Disp_smg_74HC595_number
*函数功能:74HC595驱动共阳数码管,在指定位置输出一个几位数
*函数调用:Disp_smg_74HC595_number(uint8 x_smg,uint8 count_smg,uint32 number,uint16 time) ; 
*参数列表:x_smg(位置),count_smg(几位数),number(数字),time(延时)
*返 回 值:无
*结    果:在数码管指定位上显示数字
*备    注:
***************************************************************************/
void Disp_smg_74HC595_number(uint8 x_smg,uint8 count_smg,uint32 number,uint16 time)  //在数码管第二号位置, 写一个6位数
{
uint8 i=0;	
uint8 number1[8];      //定义一个存储八位数的每一位的数字用的数组
uint8 code duanma[19]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x89,0x7f,0xbf}; //共阳段码
uint8 code wei_dat[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};       //定义八位数码管位选数据数组

number1[0] = number % 10;            //个位        
number1[1] = number % 100 / 10;      //十位  

	for(i=0;i < count_smg;i++)
	{		
		  Write_INT16_74hc595( duanma[number1[count_smg-1-i]] *256  +  wei_dat[x_smg-1+i] );
			delay_100us(time);	 
	}
}
/******************************数码管上显示横杠*******************************
*函数名称:HG_74HC595
*函数功能:74HC595驱动共阳数码管,在指定位置输出一个横杠
*函数调用:HG_74HC595(uint8 x_smg,uint8 time); 
*参数列表:x_smg(位置),time(延时)
*返 回 值:无
*结    果:在数码管某个位上显示横杠
*备    注:
***************************************************************************/
void HG_74HC595(uint8 x_smg,uint8 time)
{
  Write_INT16_74hc595( duanma[18] *256  +  wei_dat[x_smg-1]  ); //duanma[18] 或	  0xbf    //数码管段选显示 "-" 段码数据			 
  delay_100us(time);	
}	
/******************************数码管上显示点*******************************
*函数名称:XSD_74HC595
*函数功能:74HC595驱动共阳数码管,在指定位置输出一个点
*函数调用:XSD_74HC595(uint8 x_smg,uint8 time); 
*参数列表:x_smg(位置),time(延时)
*返 回 值:无
*结    果:在数码管某个位上显示小数点
*备    注:
***************************************************************************/
void XSD_74HC595(uint8 x_smg,uint8 time)
{
  Write_INT16_74hc595( duanma[17] *256  +  wei_dat[x_smg-1]  ); //duanma[17] 或	  0x7f    //数码管段选显示 "." 段码数据			 
  delay_100us(time);	
}		

延时函数

/***************************************************************************
*函数名称:delay
*函数功能:延时函数
*函数调用:delay(uint16 x_ms); 
*参数列表:x_ms
*返 回 值:无
*结    果:延迟时间= * x_ms(毫秒)
*备    注:
***************************************************************************/
	void delay(uint16 X_ms)  //延迟  X_ms*1  毫秒
{
   uint16 m,n;
	  for(m=X_ms;m>0;m--)
		 for(n=114;n>0;n--);  
}	
/***************************************************************************
*函数名称:delay_100us
*函数功能:延时函数
*函数调用:delay(uint16 x_100us); 
*参数列表:x_100us
*返 回 值:无
*结    果:延迟时间=100* x_100us(微秒)
*备    注:
***************************************************************************/
void delay_100us(uint16 x_100us) //延迟  x_100*100  微秒
{
   uint16 i,j;
  	for(i=x_100us;i>0;i--)
		 for(j=11;j>0;j--);	  
}	

按键扫描:

/*******************************按键识别**********************************
*函数名称:key_scan
*函数功能:写入16位数据,识别出键值
*函数调用:key_scan(); 
*参数列表:
*返 回 值:key_num
*结    果:识别出8个键值
*备    注:
*************************************************************************/
uint8 key_scan()
{
	
	static uint8 key_num=0;
	key_IO = 1;
	
	Write_INT16_74hc595(0xfffe);
  if(key_IO == 0)
		key_num = 1;
	
	Write_INT16_74hc595(0xfffd);
  if(key_IO == 0)
		key_num = 2;
	
	Write_INT16_74hc595(0xfffb);
  if(key_IO == 0)
		key_num = 3;
	
	Write_INT16_74hc595(0xfff7);
  if(key_IO == 0)
		key_num = 4;
	
	Write_INT16_74hc595(0xffef);
  if(key_IO == 0)
		key_num = 5;
	
	Write_INT16_74hc595(0xffdf);
  if(key_IO == 0)
		key_num = 6;
	
	Write_INT16_74hc595(0xffbf);
  if(key_IO == 0)
		key_num = 7;
  
	Write_INT16_74hc595(0xff7f);
  if(key_IO == 0)
		key_num = 8;
	
	return key_num;
}

main主程序:

/******************************main主程序**********************************/
void main()
{
		
	while(1)
   {			 				
				Disp_smg_74HC595_number(7,2,key_scan(),5);														
	 }	 
}

仿真结果如下 :

(51单片机)习题:74HC595数码管8位显示与8位独立按键复用_第2张图片

你可能感兴趣的:(51单片机,嵌入式硬件,单片机)