STM32的16X16点阵屏设计(附Proteus仿真文件)

先上文件:https://pan.baidu.com/s/1pB9HZkxn0LEM-tDX2qDNtA 提取码: 4nra

最近单片机课程要做课设,于是本人决定设计一款用STM32F103C8T6驱动的点阵屏,目前方案还在完善,先发一版方案(附简单驱动代码及仿真)

1. 点阵屏

    16X16点阵屏需要由四个8X8点阵屏组成,我用的是共阴极,原理如下:

    COL与ROW分别控制点阵屏的列与行,可以看出,COL置1、ROW置0可以点亮,例如将第一列置1,第一行置0,则左边第一个LED亮。

    如果用IO直接控制点阵屏,4个点阵屏需要占用64个引脚,而且驱动电流也不够。因此本文用74HC595移位寄存器控制列,用74HC138解码器控制行,最终只需占用8个IO,关于这两个芯片的原理,相信大多数同学都知道,后面我也会出文章讲解。

2. 74HC595

    接线图如下:

74HC595
SHCPPA0   
STCPPA1  
DSPA2

    使用两个74HC595级联,每次向U2(第一个)传入16个数据,因为一个74HC595只能寄存8个数据,多余的8个会通过Q7`发送给U3(第二个)。

    如下图所示,DS(PA2)为传入的数据,每次捕捉到SHCP(PA0)的上升沿便会向寄存器写入一个数据,当读到STCP(PA1)上升沿,则输出数据。

void W74HC595_WriteByte(u16 Byte)
{
	u8 i;
	for(i=0;i<16;i++)
	{
		if(Byte & 0x8000>>i) GPIO_SetBits(GPIOA, GPIO_Pin_2);//移位读传入的Byte,1则亮
		else GPIO_ResetBits(GPIOA, GPIO_Pin_2);
		
		GPIO_SetBits(GPIOA, GPIO_Pin_0); //SHCP上升沿将数据写入寄存器
		GPIO_ResetBits(GPIOA, GPIO_Pin_0);
	}
		GPIO_SetBits(GPIOA, GPIO_Pin_1); //STCP上升沿将数据从寄存器输出
		GPIO_ResetBits(GPIOA, GPIO_Pin_1);
}
3. 74HC138

    接线图:

74HC138
A0PA4                              

A1

PA5
A2PA6
E1(第一个)/E3(第二个)PA7
E2PA8

    74HC138读真值表,当E1、E2、E3分别为0、0、1时,解码器工作,否则解码器不工作。

    PA8接E2,可以看出当PA8为1时两个解码器都不工作,用于将数据写入后打开再关闭解码器,有效取消残影。

    PA7接第一个解码器(U4)的E1,接第二个(U5)的E3,当E1=0,第一个解码器工作,当E3=1,第二个解码器工作。

    PA4、PA5、PA6用于输入,电路及代码如下:

void W74HC138_WriteByte(u8 h)
{
	u8 a,b,c;
	switch(h)//笨方法,将16种都列举出来
	{
		case 0: a=1; b=1; c=1; break;
		case 1: a=0; b=1; c=1; break;
		case 2: a=1; b=0; c=1; break;
		case 3: a=0; b=0; c=1; break;
		case 4: a=1; b=1; c=0; break;
		case 5: a=0; b=1; c=0; break;
		case 6: a=1; b=0; c=0; break;
		case 7: a=0; b=0; c=0; break;
		case 8: a=1; b=1; c=1; break;
		case 9: a=0; b=1; c=1; break;
		case 10: a=1; b=0; c=1; break;
		case 11: a=0; b=0; c=1; break;
		case 12: a=1; b=1; c=0; break;
		case 13: a=0; b=1; c=0; break;
		case 14: a=1; b=0; c=0; break;
		case 15: a=0; b=0; c=0; break;
	}
	if(h<=7) //H0-H7
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_7);//使能E3
		GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)(a));
		GPIO_WriteBit(GPIOA, GPIO_Pin_5, (BitAction)(b));
		GPIO_WriteBit(GPIOA, GPIO_Pin_6, (BitAction)(c));//分别写入数据
		GPIO_ResetBits(GPIOA, GPIO_Pin_8);//使能E2,也就是打开138
		GPIO_SetBits(GPIOA, GPIO_Pin_8);//关闭138
	}
	else if(h>=8 && h<=15) //H8-H15
	{
		GPIO_SetBits(GPIOA, GPIO_Pin_7);//使能E1
		GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)(a));
		GPIO_WriteBit(GPIOA, GPIO_Pin_5, (BitAction)(b));
		GPIO_WriteBit(GPIOA, GPIO_Pin_6, (BitAction)(c));//分别写入数据
		GPIO_ResetBits(GPIOA, GPIO_Pin_8);//使能E2,也就是打开138
		GPIO_SetBits(GPIOA, GPIO_Pin_8);//关闭138
	}
	else
	{
		GPIO_SetBits(GPIOA, GPIO_Pin_8);//关闭138
	}
}
4. 控制代码

    本代码由74HC138控制行、74HC595控制列

void Show(u8 h, u16 Byte)//h为行,Byte为该行显示LED的16进制
{
	W74HC595_WriteByte(Byte);
	W74HC138_WriteByte(h);
}

    代码实现了第h行亮的灯为Byte,举个例子:

       Show(1, 0x1081);

        0x1081 = 0001 0000 1000 0001

    因此该代码实现了第1行,第4、9、16个灯亮。

    在主函数中只需While遍历16行即可实现图像的显示。

5. 取字模

    使用PCtoLCD2002取字模,软件也在最上面的链接中一起给出。

    首先左上角新建图像,大小为16X16。

    在模式中,配置如下:

    然后在画布上整自己需要的图案再生成字模,例如我随便生成了一个,复制下来是这样:

{0x80,0x43,0x80,0x42,0x80,0x42,0xC0,0xC2,0x40,0xC4,0x40,0xC4,0x41,0xC4,0x61,0x24},
{0x22,0x28,0x22,0x28,0x26,0x28,0x34,0x38,0x18,0x30,0x18,0x10,0x18,0x00,0x00,0x00}

    将标红的大括号删除即是我们可以使用的字模,程序如下:

u8 showwhat[32] = 
	{0x80,0x43,0x80,0x42,0x80,0x42,0xC0,0xC2,0x40,0xC4,0x40,0xC4,0x41,0xC4,0x61,0x24,
	0x22,0x28,0x22,0x28,0x26,0x28,0x34,0x38,0x18,0x30,0x18,0x10,0x18,0x00,0x00,0x00};
int main(void)
{ 
	u8 i;
	Led_Init();	
	while(1)
	{ 
		i++;
		if(i >= 16) i=0;
		Show(i, showwhat[i*2]<<8|showwhat[i*2+1]);//显示行列
	}		
}

    这样即可实现简单图像的显示,由于仿真频率的问题,显示为一行行显示,实物则不会这样,后续我还会跟进实物,有问题欢迎指出!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值