LED点阵

LED显示的原理就是利用扫描把把要显示内容在点阵上扫描过去(说得有点简单啊)。大的显示屏需要扫描更多的行数和一次点亮更多的LED,所以一般需要借助一些数字芯片来扫描,如74154 4-16译码器和74154移位寄存器。

74154带有使能端,可以利用这个来消除移位过程中产生的鬼影。在使用74154的时候有个细节需要注意 一下,有些人会直接对管脚进行++操作,这在有些时候是可以的,但是遇到像我上次LED流水灯实验就会发生错误了(详见《做LED流水灯时犯的一个小错误》)。

LED点阵显示可以分为静态的和动态的,先发一下静态的代码。

#include "stc12c5a.h"
#include "delay.h"
#include "config.h"
#include "chinese.h"//取模方式为行列式取模,从左上到左下,再从右下到右下
#define A P2    //选择行,仅低四位有效
#define DATA P1 //数据发送口,本程序仅低四位有效
#define HZ 32	 //定义一个汉字字模的字节数
sbit EN_n = P3^3;//使能端
sbit CLK = P3^4; //时钟信号

void Send_4Byte(uchar *Byte)//发送四个相距16个字节的数据
{
	uchar i = 0,j = 0;
	uchar temp = 0;
	for(i=0;i<8;i++)
	{
		temp = 0;
        for(j=0;j<4;j++)
        {
            if((*(Byte+16*j))&(1<<i)) temp |= 1<<j;//获得相距16个字节4个数据的第i位数据
        }
		CLK = 0;
		DATA = temp;//发送数据
		CLK = 1;//上升沿发送一位数据
	}
}

void main()
{
	uchar i = 0;
	uchar *start;
	uchar move = 0;
	/***初始化*****/
	A = 0;
	EN_n = 1;
	start = *chinese;
	/**************/
	while(1)
	{
		for(i=0;i<16;i++)
		{
			EN_n = 1;//关闭显示
			A = 15 - i;//选择行(自上向下扫描)
			Send_4Byte(start+i);
			EN_n = 0;//打开显示
			delay_ms(1);
		}
	}
}

动态显示即实现内容的移动。我采用的是将原数据左移,再从后面数据取前N位补在低位。当显示完一个点阵的宽度(即半个字)后,起始点直接跳到下个点阵。看代码。


#include "stc12c5a.h"
#include "delay.h"
#include "config.h"
#include "chinese.h"//取模方式为行列式取模,从左上到左下,再从右下到右下
#define SPEED 8
#define A P2    //选择行,仅低四位有效
#define DATA P1 //数据发送口,本程序仅低四位有效
#define HZ 32	 //定义一个汉字字模的字节数
sbit EN_n = P3^3;//使能端
sbit CLK = P3^4; //时钟信号

void Send_4Byte(uchar *Byte,uchar move)//发送四个相距16个字节的数据,move为位移量,原先变量左移move位,后move位补上后16字节的前move位
{
	uchar i = 0,j = 0;
	uchar temp = 0;
	for(i=0;i<8;i++)
	{
		temp = 0;
		if(i>=move)
		{
			//发送原数据低位数据
			for(j=0;j<4;j++)
			{
				if((*(Byte+16*j))&(1<<i-move)) temp |= 1<<j;
			}
		}
		else
		{
			//发送后续数据的高位
			for(j=0;j<4;j++)
			{
				if((*(Byte+16+16*j))&(1<<(i+8-move))) temp |= 1<<j;
			}
		}
		CLK = 0;
		DATA = temp;
		CLK = 1; //上升沿
	}
}

void main()
{
	uchar i = 0;
	uchar *start;
	uint count = 0;//计数变量
	uchar move = 0;//位移控制变量
	unsigned long length= sizeof(chinese);
	/***初始化*****/
	A = 0;
	EN_n = 1;
	start = *chinese;//设置起点
	/**************/
	while(1)
	{
		/*****速度控制******/
		count++;
		if(!(count%SPEED))
		{
			move = ++move%8;
			if(count>=8*SPEED)
			{
				start += 16;
				if(start-*chinese==length-2*HZ)	start = chinese;
				count =0;
			}
		}
		/******************/
		for(i=0;i<16;i++)
		{
			EN_n = 1;//关闭显示
			A = 15 - i;//选择行(自上向下扫描)
			Send_4Byte(start+i,move);
			EN_n = 0;//打开显示
			delay_ms(1);
		}
	}
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值