【C51单片机】LED胸牌设计(仿真)

1、功能描述

设计16*64LED点阵屏,制作胸牌,显示如下效果,并且让字体有滚动效果(字体从下到上、从上到下、从左到右、从右到左显示)

2、PROTEUS中设计的电路图

3、源代码(代码中有详细注释)

#include <reg51.h>
#include <intrins.h>
sbit OE=P1^0;//锁存
sbit EN=P1^1;//行选输出允许
//阴码,按行取模,低位在前
unsigned char code font[][32]={
{0x00,0x03,0x00,0x03,0x00,0x0F,0x00,0x0F,0x00,0x3C,0x00,0x3C,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0x00,0x3C,0x00,0x3C,0x00,0x0F,0x00,0x0F,0x00,0x03,0x00,0x03},/*"C:\Users\FUTURE\Desktop\箭头.bmp",0*/

{0x40,0x00,0x80,0x00,0x80,0x00,0xFF,0x7F,0x20,0x00,0x20,0x00,0x20,0x00,0xE0,0x0F,
0x20,0x08,0x20,0x08,0x20,0x08,0x10,0x08,0x10,0x08,0x08,0x08,0x04,0x05,0x02,0x02},/*"方",0*/

{0x00,0x00,0x3C,0x1E,0x7E,0x3F,0xFE,0x7F,0xFE,0x7F,0xFE,0x7F,0xFE,0x7F,0xFE,0x3F,
0xFC,0x1F,0xF8,0x1F,0xF0,0x0F,0xE0,0x07,0xC0,0x03,0xC0,0x01,0x80,0x00,0x00,0x00},/*"C:\Users\FUTURE\Desktop\心.bmp",0*/

{0x08,0x00,0x10,0x20,0xFE,0x1E,0x00,0x02,0x44,0x02,0x28,0x02,0xFF,0x7E,0x10,0x12,
0x10,0x12,0xFE,0x12,0x10,0x12,0x54,0x12,0x92,0x12,0x11,0x11,0x14,0x11,0x88,0x10},/*"新",0*/

{0xC0,0x00,0xE0,0x00,0xF0,0x00,0xF8,0x00,0x7C,0x00,0x3E,0x00,0xFE,0x7F,0xFF,0xFF,
0xFF,0xFF,0xFE,0x7F,0x3E,0x00,0x7C,0x00,0xF8,0x00,0xF0,0x00,0xE0,0x00,0xC0,0x00},/*"C:\Users\FUTURE\Desktop\箭头(反).bmp",0*/
};
void delay(unsigned int xms)	  
{int i,j;
 for(i=0;i<=xms;i++)
	 for(j=0;j<=110;j++);
}

//从下往上
void downtoup()
{	
 unsigned char i=0,k,m,j,x,y;
 for(i=0;i<16;i++)  //i:16帧
  for(x=0;x<15;x++)	//x:一帧重复显示20次,实际上控制的是上下滚动的速度
	for(k=15-i,m=0;k<16;k++,m++)  //k:第一帧从第15行开始显示,第二帧从第14行开始显示。。。。。。
	                              //m:总是从第0行开始送字模
	{	
		EN=1;//行选输出禁止
		for(j=0,y=0;j<5;j++)  //j:共5个字,一次送一个字的一行
		                      //y:总是从第0列点阵屏开始
		{			
			P0=font[j][2*m];	  //一行的低8位
			P3=y++;	   //指定哪个点阵
			OE=0;	   //更新
			OE=1;  	   //锁存
			
			P0=font[j][2*m+1];	//一行的高8位
			P3=y++;	   //指定哪个点阵
			OE=0;		//更新
			OE=1; 	  //锁存
		}
		
		P2=k;	//设置行选信号
		EN=0;  //行选输出允许
		delay(1);
	}
}

//从上往下
void uptodown()	
{	
 unsigned char i=0,k,m,j,x,y;
 for(i=0;i<16;i++)  //i:16帧
  for(x=0;x<15;x++)	//x:一帧重复显示20次,实际上控制的是上下滚动的速度
	for(k=0,m=15-i;k<=i;k++,m++)  //k:每帧都是从第0行开始显示,第i帧共显示i行
	                              //m:第一帧从第15行开始送字模,第二帧从第14行开始送字模
	{	
		EN=1;//行选输出禁止
		for(j=0,y=0;j<5;j++)  //j:共8个字,一次送一个字的一行
		                      //y:总是从第0列点阵屏开始
		{			
			P0=font[j][2*m];	  //一行的低8位
			P3=y++;	   //指定哪个点阵
			OE=0;	   //更新
			OE=1;  	   //锁存
			
			P0=font[j][2*m+1];	//一行的高8位
			P3=y++;	   //指定哪个点阵
			OE=0;		//更新
			OE=1; 	  //锁存
		}
		
		P2=k;	//设置行选信号
		EN=0;  //行选输出允许
		delay(1);
	}
}

//从右往左,一次移动一个字
void righttoleft()	
{	
 unsigned char i,k,j,x,y;
 for(i=0;i<6;i++)  //i:5帧,,第6帧是让最后显示空白
  for(x=0;x<20;x++)	//x:一帧重复显示20次,实际上控制的是上下滚动的速度
	for(k=0;k<16;k++)  //k:每帧16行都要显示
	{	
		EN=1;//行选输出禁止
		for(j=i,y=0;j<5;j++)  //j:一帧显示i~7这几个字
		{			
			P0=font[j][2*k];	  //一行的低8位
			P3=y++;	   //指定哪个点阵
			OE=0;	   //更新
			OE=1;  	   //锁存
			
			P0=font[j][2*k+1];	//一行的高8位
			P3=y++;	   //指定哪个点阵
			OE=0;		//更新
			OE=1; 	  //锁存
		}
		while(y<10)  //一帧显示i~7这几个字后,剩下的送字模0x00,即:不显示
		{			
			P0=0x00;	  //一行的低8位
			P3=y++;	   //指定哪个点阵
			OE=0;	   //更新
			OE=1;  	   //锁存
			
			P0=0x00;	//一行的高8位
			P3=y++;	   //指定哪个点阵
			OE=0;		//更新
			OE=1; 	  //锁存
		} 
		P2=k;	//设置行选信号
		EN=0;  //行选输出允许
		delay(1);
	}
}

//从左往右,一次移动一个字
void lefttoright()	
{	
 unsigned char i,k,j,x,y;
 for(i=0;i<6;i++)  //i:5帧,,第6帧是让最后显示空白
  for(x=0;x<15;x++)	//x:一帧重复显示20次,实际上控制的是上下滚动的速度
	for(k=0;k<16;k++)  //k:每帧16行都要显示
	{	
		EN=1;//行选输出禁止
		y=0;
		while(y<2*i)  //一帧先0~i-1这几个字不显示,所以送字模0x00
		{			
			P0=0x00;	  //一行的低8位
			P3=y++;	   //指定哪个点阵
			OE=0;	   //更新
			OE=1;  	   //锁存
			
			P0=0x00;	//一行的高8位
			P3=y++;	   //指定哪个点阵
			OE=0;		//更新
			OE=1; 	  //锁存
		} 
		for(j=0;j<5-i;j++)  //j:一帧显示0~8-i这几个字
		{			
			P0=font[j][2*k];	  //一行的低8位
			P3=y++;	   //指定哪个点阵
			OE=0;	   //更新
			OE=1;  	   //锁存
			
			P0=font[j][2*k+1];	//一行的高8位
			P3=y++;	   //指定哪个点阵
			OE=0;		//更新
			OE=1; 	  //锁存
		}
	
		P2=k;	//设置行选信号
		EN=0;  //行选输出允许
		delay(1);
	}
}

//从右往左,一次移动半个字
void righttoleft_half()	
{	
 unsigned char i,k,j,x,y;
 for(i=0;i<11;i++)  //i:16帧
  for(x=0;x<15;x++)	//x:一帧重复显示20次,实际上控制的是上下滚动的速度
	for(k=0;k<16;k++)  //k:每帧16行都要显示
	{	
		EN=1;//行选输出禁止
		for(j=i,y=0;j<10;j++)  //j:一帧显示16-i个半字
		{			
			P0=font[j/2][2*k+j%2];	  //送半字
			P3=y++;	   //指定哪个点阵
			OE=0;	   //更新
			OE=1;  	   //锁存
		}
		while(y<11)  //剩下的i个半字送0x00,即:不显示
		{			
			P0=0x00;	  //一行的低8位
			P3=y++;	   //指定哪个点阵
			OE=0;	   //更新
			OE=1;  	   //锁存
			
	//	P0=0x00;	//一行的高8位
		//	P3=y++;	   //指定哪个点阵
	//		OE=0;		//更新
	//		OE=1; 	  //锁存
		}  
		P2=k;	//设置行选信号
		EN=0;  //行选输出允许
		delay(1);
	}
}

//从左往右,一次移动半个字
void lefttoright_half()	
{	
 unsigned char i,k,j,x,y;
 for(i=0;i<11;i++)  //i:10帧	  16
  for(x=0;x<15;x++)	//x:一帧重复显示20次,实际上控制的是上下滚动的速度
	for(k=0;k<16;k++)  //k:每帧16行都要显示
	{	
		EN=1;//行选输出禁止
		y=0;
		while(y<i)  //先送i个0x00,即:不显示
		{			
			P0=0x00;	  //一行的低8位
			P3=y++;	   //指定哪个点阵
			OE=0;	   //更新
			OE=1;  	   //锁存
			
		}  
		for(j=0;j<10-i;j++)  //j:一帧显示16-i个半字
		{			
			P0=font[j/2][2*k+j%2];	  //送半字
			P3=y++;	   //指定哪个点阵
			OE=0;	   //更新
			OE=1;  	   //锁存
		}
	
		P2=k;	//设置行选信号
		EN=0;  //行选输出允许
		delay(1);
	}
}

void bink(){
	unsigned char i,j,k,n=0;
	while(n<15){
	for(i=0;i<16;i++)  //按行,共16行,一次点亮所有8个字的一行
	{	
		EN=1;//行选输出禁止
		for(j=0,k=0;j<5;j++)  //共8个字,一次送一个字的一行
		{			
			P0=font[j][2*i];	  //一行的低8位
			P3=k++;	   //指定哪个字
			OE=0;	   //更新
			OE=1;  	   //锁存
			
			P0=font[j][2*i+1];	//一行的高8位
			P3=k++;	   //指定哪个字
			OE=0;		//更新
			OE=1; 	  //锁存
		}	
		P2=i;	//设置行选信号
		EN=0;  //行选输出允许
		delay(1);
		}
	n++;
	}

}
void main()
{
 int i=0;	

 while(1){
	downtoup();
	while(i<3){
 	bink();
	delay(400);
	i++;	
 	}
	i=0; 
  	uptodown();
 	righttoleft();
  	lefttoright();	
 	righttoleft_half();
  	lefttoright_half();
	while(i<3){
 	bink();
	delay(400);
	i++;	
 	}

 	}
}

4、实验效果  

由于不能上传视频,所以我将效果视频上传至优酷,请点击观看------->LED胸牌效果视频

问题咨询及项目源码请加群:

QQ群

名称:IT项目交流群

群号:245022761

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值