75HC595是一片具有8位串行输入/并行输出移位寄存器,利用三个端口,就可以驱动8位数码管,本文在显示的同时,外加一个51单片机IO口,将8位独立按键复用。
74HC595驱动数码管不再累述,请查看规格书理解底层代码,仿真电路图如下:
按键识别思路:利用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);
}
}
仿真结果如下 :