8*8全彩点阵的使用

最近用6块8*8全彩点阵做了一个16*24的全彩屏,每个点可以显示7种颜色,这个可以实现一些好玩的功能,比如俄罗斯方块。


一、原理

1. 点阵屏的16行使用2个74hc138组成4-16译码,之后用三极管9012驱动,用100的限流电阻

2. 点阵屏的24列使用9个74hc595驱动,第一个595驱动第一列8*8点阵的红led,第二个595驱动第一列8*8点阵的绿led,第三个595驱动第一列8*8点阵的蓝led,以此类推,使用100的限流电阻

3. GND与VCC之间接入104瓷片电容与470uF 16V电解电容,增加抗干扰能力

4. 使用74hc245驱动595,提高驱动能力,这样单片机的IO口通过245就可以一次驱动一行的9个595了

5. 点阵的行用高电位,列用低电位


二、接口

1. A、B、C、D为行选线

2. G为屏使能线,接在74hc138上

3. CLK、LATCH、DATA为595驱动线,分别为输入触发、输出触发、串行数据输入

4. GND、VCC


三、实物图



四、代码

1. 头文件

#ifndef __RGBDZH_H__
#define __RGBDZH_H__

#include <reg51.h>
#include <intrins.h>

#define BLOCK_ROW_COUNT					2
#define BLOCK_COL_COUNT					3
#define PIXEL_ROW_COUNT					(BLOCK_ROW_COUNT*8)
#define PIXEL_COL_COUNT					(BLOCK_COL_COUNT*8)

/*颜色定义*/
#define NONE		0x00
#define RED			0x01
#define GREEN 	0x02
#define BLUE		0x04
#define YELLOW	(RED|GREEN)
#define PURPLE	(RED|BLUE)
#define LBLUE		(GREEN|BLUE)
#define WHITE		(RED|GREEN|BLUE)

// 端口定义
/*行选*/
sbit A_Port = P1^0;
sbit B_Port = P1^1;
sbit C_Port = P1^2;
sbit D_Port = P1^3;
/*使能*/
sbit En_Port = P1^4;
/*输入触发*/
sbit Clk_Port = P1^5;
/*输出触发*/
sbit Latch_Port = P1^6;
/*串口输入*/
sbit Data_Port = P1^7;

// 接口函数
void Lcd_Init();

void Lcd_Clear();

void Lcd_Refresh();

void Lcd_SetPixel( unsigned char x, unsigned char y, unsigned char color);

unsigned char Lcd_GetPixel( unsigned char x, unsigned char y);

#endif

2. 源文件

#include "RGBDZh.h"

// 开启:一次扫描1*24
// 关闭:一次扫描1*8, 一行分三次扫描
#define ENABLE_ROW_SCAN

#define COLOR_BASE_COUNT				3
#define CACHE_DATA_SIZE					(PIXEL_ROW_COUNT*BLOCK_COL_COUNT*COLOR_BASE_COUNT)

static unsigned char xdata cache_data[CACHE_DATA_SIZE];
static unsigned char xdata cur_row = 0;
#ifndef ENABLE_ROW_SCAN
static unsigned char xdata cur_block = 0;
#endif

void Lcd_Init()
{
	Lcd_Clear();
}

void Lcd_Clear()
{
	unsigned int i;
	for( i = 0; i < CACHE_DATA_SIZE; i ++)
		cache_data[i] = 0xff;
	cur_row = 0;
#ifndef ENABLE_ROW_SCAN
	cur_block = 0;
#endif
}

void Lcd_Refresh()
{
	char i, j;
	
	/*74HC595*/
	/*串入数据*/
	for( i = BLOCK_COL_COUNT * COLOR_BASE_COUNT - 1; i >= 0; i --)
	{
		unsigned char buff = cache_data[BLOCK_COL_COUNT * COLOR_BASE_COUNT * cur_row + i];
		
		for( j = 0; j < 8; j ++)
		{
#ifndef ENABLE_ROW_SCAN
			if( i / COLOR_BASE_COUNT != cur_block)
				Data_Port = 1;
			else
#endif
				if(( buff & 0x01) == 0x01)
				Data_Port = 1;
			else
				Data_Port = 0;
			
			Clk_Port = 0;
			_nop_();
			_nop_();
			Clk_Port = 1;
			_nop_();
			_nop_();
			
			buff >>= 1;
		}
	}
	
	/*并出数据*/
	Latch_Port = 0;
	_nop_();
	_nop_();
	Latch_Port = 1;
	_nop_();
	_nop_();
	Latch_Port = 0;
	_nop_();
	_nop_();
	
	/*74HC138*/
	/*显示数据*/
	En_Port = 1;
	A_Port = cur_row & 0x01;
	B_Port = ( cur_row >> 1) & 0x01;
	C_Port = ( cur_row >> 2) & 0x01;
	D_Port = ( cur_row >> 3) & 0x01;
	En_Port = 0;
	
#ifndef ENABLE_ROW_SCAN
	cur_block ++;
	if( cur_block >= BLOCK_COL_COUNT)
	{
#endif
		cur_row ++;
		if( cur_row >= PIXEL_ROW_COUNT)
			cur_row = 0;
		
#ifndef ENABLE_ROW_SCAN
		cur_block = 0;
	}
#endif
}

void Lcd_SetPixel( unsigned char x, unsigned char y, unsigned char color)
{
	unsigned int offset;
	unsigned char mask;
	
	if( x >= PIXEL_COL_COUNT || y >= PIXEL_ROW_COUNT)
		return;
	
	offset = BLOCK_COL_COUNT * COLOR_BASE_COUNT * y + x / 8 * COLOR_BASE_COUNT;
	mask = 0x01 << ( 7 - x % 8);
	
	// Red
	cache_data[offset] |= mask;
	if( color & RED)
		cache_data[offset] &= ~mask;
	
	// Green
	cache_data[offset + 1] |= mask;
	if( color & GREEN)
		cache_data[offset + 1] &= ~mask;
	
	// Blue
	cache_data[offset + 2] |= mask;
	if( color & BLUE)
		cache_data[offset + 2] &= ~mask;
}

unsigned char Lcd_GetPixel( unsigned char x, unsigned char y)
{
	unsigned char r = NONE;
	unsigned int offset;
	unsigned char mask;
	
	if( x >= PIXEL_COL_COUNT || y >= PIXEL_ROW_COUNT)
		return r;
	
	offset = BLOCK_COL_COUNT * COLOR_BASE_COUNT * y + x / 8 * COLOR_BASE_COUNT;
	mask = 0x01 << ( 7 - x % 8);
	
	// Red
	if(( cache_data[offset] & mask) == 0x00)
		r |= RED;
	
	// Green
	if(( cache_data[offset + 1] & mask) == 0x00)
		r |= GREEN;
	
	// Blue
	if(( cache_data[offset + 2] & mask) == 0x00)
		r |= BLUE;
	
	return r;
}

五、测试代码

#include "RGBDZh.h"

int main()
{
	unsigned char index = 0;
	
	Lcd_Init();
	
	TMOD = 0x01;
	TH0 = 0xfc;
	TL0 = 0x66;
	TR0 = 1;
	EA = 1;
	ET0 = 1;
	
	while(1)
	{
		unsigned char colors[7] = { RED, GREEN, BLUE, YELLOW, PURPLE, LBLUE, WHITE};
		unsigned int i;
		
		for( i = 0; i < 16 * 24; i ++)
		{
			Lcd_SetPixel( i % 24, i / 24, colors[index++]);
			if( index >= 7)
				index = 0;
			
			{
				unsigned int j;
				for(j=0;j<5000;j++);
			}
		}
		
		Lcd_Clear();
	}
	
	return 0;
}

void disp() interrupt 1 using 3
{
	TH0 = 0xfc;
	TL0 = 0x66;
	
	Lcd_Refresh();
}


请移步www.yintju03.com/blog

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值