STC单片机74hc164驱动8位数码管动态显示

芯片介绍

74HC164、74HCT164是8位边沿触发式移位寄存器,串行输入数据,然后并行输出。数据通过两个输入端(DSA 或 DSB)之一串行输入;任一输入端可以用作高电平时使能端,控制另一输入端的数据输入。两个输入端或者连接在一起,或者把不用的输入端接高电平,一定不要悬空。

 

硬件与电原理图

数码显示模块来自淘宝优信电子的数码管模块(因为自己不想动手pcb布局(狗头保命))

电原理图:

由于74hc164是可以进行多联级的,只需要将第二级的74hc164的AB引脚接到第一级Q8引脚即可实现联级。数据传输方式为第一次传输的8位数据为驱动U2的,第二次传输8位数据为驱动U1。如果有3联级或多联级,以此类推。

顺便提一下:此模块数码管为阳极数码管;

编程步骤

将需要显示的数字进行分为千位,百位,十位,个位>>>发送显示千位数据>>>人为延时>>>将数码管选择第一位数据进行发送>>>人为延时>>>发送显示百位的数据>>>人为延时>>>将数码管选择第二位数据进行发送>>>人为延时>>>发送显示十位的数据>>>人为延时>>>将数码管选择第三位数据进行发送>>>人为延时>>>发送显示个位的数据>>>人为延时>>>将数码管选择第四位数据进行发送>>>循环;

数值显示分位代码

首先需要将数据进行分位,如果不进行分为个位,数码管无法将数值进行显示

void DATA_Part(uint byte)
{
    uchar Dat1,Dat2,Dat3,Dat4
    Dat1=byte/1000;    //千位
    Dat2=byte/100%10;  //百位
	Dat3=byte/10%10;   //十位
	Dat4=byte%10;      //个位
}

共阳极数码管0-9显示代码

uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};

共阴极数码管0-9显示代码

uchar code tab[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xff,0xf6};

74hc164驱动显示代码

前4位显示驱动代码

sbit DAT1 = P0^1;
sbit CP1  = P0^0;


void sed_4bit(uint byte)
{
	uchar num,c,Dat1,Dat2,Dat3,Dat4,i=0,b=0,d=0;
	Dat1=byte/1000;
    Dat2=byte/100%10;
	Dat3=byte/10%10;
	Dat4=byte%10;
	i=0;
	b=0;
	d=0;
	for(b=0;b<4;b++)
	{
		switch(i)
		{
			case 0:i=1;num=tab[Dat1];for(c=0;c<8;c++)        
                   {CP1=0;DAT1=num&0x80;CP1=1;num<<=1;}break;
			case 1:i=2;num=tab[Dat2];for(c=0;c<8;c++)    
                   {CP1=0;DAT1=num&0x80;CP1=1;num<<=1;}break;
			case 2:i=3;num=tab[Dat3];for(c=0;c<8;c++) 
                   {CP1=0;DAT1=num&0x80;CP1=1;num<<=1;}break;
			case 3:i=0;num=tab[Dat4];for(c=0;c<8;c++) 
                   {CP1=0;DAT1=num&0x80;CP1=1;num<<=1;}break;
			default:break;
		}

		switch(d)
		{
			case 0:d=1;num=0x01;for(c=0;c<8;c++)
                   {CP1=0;DAT1=num&0x80;CP1=1;num<<=1;}break;
			case 1:d=2;num=0x02;for(c=0;c<8;c++)
                   {CP1=0;DAT1=num&0x80;CP1=1;num<<=1;}break;
			case 2:d=3;num=0x04;for(c=0;c<8;c++)
                   {CP1=0;DAT1=num&0x80;CP1=1;num<<=1;}break;
			case 3:d=0;num=0x08;for(c=0;c<8;c++)
                   {CP1=0;DAT1=num&0x80;CP1=1;num<<=1;}break;
			default:break;
		}
		Delay_ms(2);
	}
}

后4位显示驱动代码

void sed_4bit_late(uint byte)
{
	uchar num,c,Dat1,Dat2,Dat3,Dat4,i=0,b=0,d=0;
	Dat1=byte/1000;
    Dat2=byte/100%10;
	Dat3=byte/10%10;
	Dat4=byte%10;
	i=0;
	b=0;
	d=0;
	for(b=0;b<4;b++)
	{
		switch(i)
		{
			case 0:i=1;num=tab[Dat1];for(c=0;c<8;c++)         
                   {CP1=0;DAT1=num&0x80;CP1=1;num<<=1;}break;
			case 1:i=2;num=tab[Dat2];for(c=0;c<8;c++) 
                   {CP1=0;DAT1=num&0x80;CP1=1;num<<=1;}break;
			case 2:i=3;num=tab[Dat3];for(c=0;c<8;c++) 
                   {CP1=0;DAT1=num&0x80;CP1=1;num<<=1;}break;
			case 3:i=0;num=tab[Dat4];for(c=0;c<8;c++) 
                   {CP1=0;DAT1=num&0x80;CP1=1;num<<=1;}break;
			default:break;
		}

		switch(d)
		{
			case 0:d=1;num=0x10;for(c=0;c<8;c++)
                   {CP1=0;DAT1=num&0x80;CP1=1;num<<=1;}break;
			case 1:d=2;num=0x20;for(c=0;c<8;c++)
                   {CP1=0;DAT1=num&0x80;CP1=1;num<<=1;}break;
			case 2:d=3;num=0x40;for(c=0;c<8;c++)
                   {CP1=0;DAT1=num&0x80;CP1=1;num<<=1;}break;
			case 3:d=0;num=0x80;for(c=0;c<8;c++)
                   {CP1=0;DAT1=num&0x80;CP1=1;num<<=1;}break;
			default:break;
		}
		Delay_ms(2);
	}
}

主函数显示

void main()
{
	uint i=0;
	Function();
	while(1)
	{  	
		sed_4bit(506);
		Delay500us();
		sed_4bit_late(442);
		Delay500us();
	}
}

 

实际效果

 

好的,以下是使用Keil5编写STC单片机74hc164驱动8位数码管动态显示的C语言代码,您可以根据需要进行修改: ``` #include "stc89c52.h" // 定义数码管的8个位选引脚和8个段选引脚 sbit LED_COM1 = P2^0; sbit LED_COM2 = P2^1; sbit LED_COM3 = P2^2; sbit LED_COM4 = P2^3; sbit LED_COM5 = P2^4; sbit LED_COM6 = P2^5; sbit LED_COM7 = P2^6; sbit LED_COM8 = P2^7; sbit LED_A = P3^0; sbit LED_B = P3^1; sbit LED_C = P3^2; sbit LED_D = P3^3; sbit LED_E = P3^4; sbit LED_F = P3^5; sbit LED_G = P3^6; sbit LED_DP = P3^7; // 定义动态显示程序的数组 unsigned char code LED_TAB[]={ 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71 }; // 定义定时器中断计数器 unsigned int count = 0; // 定义动态显示函数 void Display(unsigned char *p); // 定义定时器中断函数 void Timer0_ISR() interrupt 1 { TH0 = 0xFC; // 定时器计数初值 TL0 = 0x67; count++; // 计数器加1 if (count >= 500) // 每隔500ms刷新一次数码管 { count = 0; Display(LED_TAB); // 调用动态显示函数 } } // 主函数 void main() { // 初始化IO口 P2 = 0x00; // P2口设置为输出模式 P3 = 0x00; // P3口设置为输出模式 LED_COM1 = 1; // 数码管关闭 LED_COM2 = 1; LED_COM3 = 1; LED_COM4 = 1; LED_COM5 = 1; LED_COM6 = 1; LED_COM7 = 1; LED_COM8 = 1; LED_A = 0; LED_B = 0; LED_C = 0; LED_D = 0; LED_E = 0; LED_F = 0; LED_G = 0; LED_DP = 0; // 初始化定时器 TMOD = 0x01; // 定时器0,模式1 TH0 = 0xFC; // 定时器计数初值 TL0 = 0x67; ET0 = 1; // 开启定时器中断 TR0 = 1; // 启动定时器 // 主循环 while(1); } // 动态显示函数 void Display(unsigned char *p) { static unsigned char i = 0; i++; if (i > 8) i = 1; switch(i) { case 1: LED_COM1 = 0; LED_COM2 = 1; LED_COM3 = 1; LED_COM4 = 1; LED_COM5 = 1; LED_COM6 = 1; LED_COM7 = 1; LED_COM8 = 1; P3 = *(p + 0); break; case 2: LED_COM1 = 1; LED_COM2 = 0; LED_COM3 = 1; LED_COM4 = 1; LED_COM5 = 1; LED_COM6 = 1; LED_COM7 = 1; LED_COM8 = 1; P3 = *(p + 1); break; case 3: LED_COM1 = 1; LED_COM2 = 1; LED_COM3 = 0; LED_COM4 = 1; LED_COM5 = 1; LED_COM6 = 1; LED_COM7 = 1; LED_COM8 = 1; P3 = *(p + 2); break; case 4: LED_COM1 = 1; LED_COM2 = 1; LED_COM3 = 1; LED_COM4 = 0; LED_COM5 = 1; LED_COM6 = 1; LED_COM7 = 1; LED_COM8 = 1; P3 = *(p + 3); break; case 5: LED_COM1 = 1; LED_COM2 = 1; LED_COM3 = 1; LED_COM4 = 1; LED_COM5 = 0; LED_COM6 = 1; LED_COM7 = 1; LED_COM8 = 1; P3 = *(p + 4); break; case 6: LED_COM1 = 1; LED_COM2 = 1; LED_COM3 = 1; LED_COM4 = 1; LED_COM5 = 1; LED_COM6 = 0; LED_COM7 = 1; LED_COM8 = 1; P3 = *(p + 5); break; case 7: LED_COM1 = 1; LED_COM2 = 1; LED_COM3 = 1; LED_COM4 = 1; LED_COM5 = 1; LED_COM6 = 1; LED_COM7 = 0; LED_COM8 = 1; P3 = *(p + 6); break; case 8: LED_COM1 = 1; LED_COM2 = 1; LED_COM3 = 1; LED_COM4 = 1; LED_COM5 = 1; LED_COM6 = 1; LED_COM7 = 1; LED_COM8 = 0; P3 = *(p + 7); break; default: break; } } ``` 以上是使用Keil5编写STC单片机74hc164驱动8位数码管动态显示的C语言代码,具体实现方式可能会有所不同,仅供参考。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值