74HC595驱动2位数码管代码实现和注意事项

Posted perseverance52

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了74HC595驱动2位数码管代码实现和注意事项相关的知识,希望对你有一定的参考价值。

74HC595驱动2位数码管

  • 驱动芯片:74HC595,74LS595,
  • 单片机:AT89C52,或者STC89C52都可以

实例代码

#include <STC89C5xRC.H>
//#include<reg52.h>
#include "intrins.h"

sbit ST=P2^0;
sbit SH=P2^2;
sbit DS=P2^1;

typedef unsigned int u16;	  //对数据类型进行声明定义
typedef unsigned char u8;

#define duanxuan P0
#define keyboard P1
u8 code smgduan[10]=// {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};//共阳数码管段码
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //共阴数码管段码
u8 duanZhi[]= {0,0};//数码管显示位数的数值数组
static u8 gewei, shiwei,num;

void SendTo595(u8 byteData);

void display();
void delay(int s)
{
    u16 i,j;
    for(i=0; i<s; i++)            //延时函数
        for(j=114; j>0; j--);
}
void main()
{
    P2=0xff;
    while(1)
    {
        display();
    }

}
/***********************************************************
*函数名		:SendTo595
*功能		:串行发送8个比特(一个字节)的数据给595,再并行输出
*参数		:byteData
************************************************************/
void SendTo595(u8 byteData)
{
    char i=0;
//    P2=duanMa[n];
    ST = 0;   //ST //先拉低,为后面的上升沿做准备
    for(i; i<8; i++)
    {
        //  SH = 0;//先拉低,
//        if(byteData&0x80)DS=1;
//        else DS=0;
        DS = (byteData&0x80)?1:0;
        byteData = byteData <<1;		//该字节右移一位
        SH = 1;//上升沿,让串行输入时钟变为高电平,并延时2个时钟周期
        _nop_();
        _nop_();
        SH = 0;        //上升沿,让串行输入时钟变为高电平,并延时2个时钟周期
    }
		/*位移寄存器数据准备完毕,转移到存储寄存器*/
    ST =1;//上升沿,让存储寄存器时钟变为高电平,并延时2个时钟周期
    _nop_();
    _nop_();
    ST = 0;

    //    SH = 0; //变为低电平,为下次准备
    //   byteData=byteData <<1;
}
void display()
{
    gewei = 97%10;
    shiwei = 97/10;
    duanZhi[0]=smgduan[shiwei];
    duanZhi[1]=smgduan[gewei];

    P26=0x01;
    P25=0x00;//先让十位先显示
    SendTo595(duanZhi[0]);//如果采用共阳就取反
    delay(20);//该延时不能少,根据实际显示效果调整,已调好。

    P25=0x01;
    P26=0x00;//显示个位
    SendTo595(duanZhi[1]); //送段码
    delay(20);
//消隐
    P25=0x01;
    P26=0x01;

}

我在调试的过程中进入了一个误区,数码管闪屏现象,在函数SendTo595()在多位数码管显示的时候,注意调整位与位显示的时间间隔。由于一开始没发现这个问题,导致,每次显示不正常,其实是显示时间没有调整好,看到的视觉效果就是字符显示不全,一直困惑了很久,后来在每个位发送完之后,调整延时时间,发现显示是完整的,才找到问题的所在,数码管闪烁的另外一个原因是由于显示的函数放置的位置不理导致的,应该挨着显示调用的地方,因为程序指令要执行一定的周期。

 SendTo595(duanZhi[1]); //发送段码显示
 delay(20);//对于多位数码管显示,该延时需要自行调整长短。

主要是学习74HC595,8位移位寄存器的原理和代码实现方法。

/***********************************************************
*函数名		:SendTo595
*功能		:串行发送8个比特(一个字节)的数据给595,再并行输出
*参数		:byteData
************************************************************/
void SendTo595(u8 byteData)
{
    char i=0;
//    P2=duanMa[n];
    ST = 0;   //ST //先拉低,为后面的上升沿做准备
    for(i; i<8; i++)
    {
        //  SH = 0;//先拉低,
//        if(byteData&0x80)DS=1;
//        else DS=0;
        DS = (byteData&0x80)?1:0;
        byteData = byteData <<1;		//该字节右移一位
        SH = 1;//上升沿,让串行输入时钟变为高电平,并延时2个时钟周期
        _nop_();
        _nop_();
        SH = 0;        //上升沿,让串行输入时钟变为高电平,并延时2个时钟周期
    }
		/*位移寄存器数据准备完毕,转移到存储寄存器*/
    ST =1;//上升沿,让存储寄存器时钟变为高电平,并延时2个时钟周期
    _nop_();
    _nop_();
    ST = 0;

    //    SH = 0; //变为低电平,为下次准备
    //   byteData=byteData <<1;
}

以上是关于74HC595驱动2位数码管代码实现和注意事项的主要内容,如果未能解决你的问题,请参考以下文章

Arduino UNO + 74HC595联级+数码管实现00-99循环计数显示+ Proteus仿真

Arduino 74HC595驱动数码管0-9循环显示+Proteus仿真

Arduino UNO + 74HC595联级+数码管实现0000-9999循环计数显示+ Proteus仿真

51单片机8x8矩阵键盘+数码管+74HC595+Proteus仿真

基于51单片机定时器计数+2片74HC595联级+8位数码管时钟+按键修改时间

Arduino UNO+DS1302+74HC595联级+8位数码管时钟+Proteus仿真(修复篇)