基于STC15W204内核为8051的8位单片机,编程驱动8×8单色LED阵列
基于STC15W204内核为8051的8位单片机,编程驱动通过两个串-并变换、SOIC-16封装的74HC595D控制的8×8单色LED阵列。
标签
嵌入式系统
显示
8051
LED阵列
Undefined_User
更新2021-01-03
1041

开发环境的搭建

Keil的下载

Keil软件的官网下载地址如下:

https://www.keil.com/download/product/

FlfqnXYd3N3eEkjEtsHaZCOKn5z1

由不同版本的文字提示可知,应下载C51(development tools for all 8051 devices)。并且,要获得Keil C51的全部功能,需要current license,否则只能运行其Lite/Evaluation edition。

 

STC-ISP烧录软件的下载

使用STC-ISP软件进行烧录。STC-ISP6.87S版本(来自STC公司)的官网下载地址如下:

http://www.stcmcudata.com/STCISP/stc-isp-15xx-v6.87S.zip

(若使用Google Chrome打开,会有安全警告)

 

硬件介绍

LED阵列

LED阵列是由发光二极管与限流电阻有规律地排布而成,示意图如下。FrMH5QK00vvcNapGojroTjvQncR7

发光二极管的亮灭通过ROW与COL的电平关系决定,仅当ROW为HIGH且COL为LOW时,二极管导通。

此外,LED阵列还包括两颗串-并变换、SOIC-16封装的74HC595D,、2颗0603封装的电源去耦电容、2个5管脚直插的连接器,示意图如下。

FliglZhxk84Q9bSbBGMwWrpXhoFW

其中第一个74HC595D的输出通过npn型三极管S9013的基级与集电极与COL耦合(如下图),第二个74HC595D的输出直接耦合ROW。

可知,第一个74HC595D的输出C通过三极管后反相后得到COL,即当C为1,ROW为1时,有COL为LOW,ROW为HIGH,此时发光二极管导通。

 

8051最小系统

8051最小系统(下文简称为最小系统)的主要硬件包括:基于STC的STC15W204内核为8051的8位单片机,MicroUSB供电并基于沁恒的CH340E(USB转UART), LED灯(电源状态指示)。

最小系统的电路原理图如下:

FpU6nXqsWMJEUD1_5tiz9fqJwa2R

最小系统的3D效果图的俯视图如下:

FomYGM0S68AAnY3r0lKL-mo49U8w

 

连接

由于软件部分是基于王安然老师提供的全亮测试工程,故保留了王安然老师对寄存器与引脚的分配。

 

代码部分:

sbit SRCLK=P5^4;

sbit RCLK=P3^3;

sbit SER=P5^5;

 

参照阵列与最小系统的原理图,将二者引脚通过杜邦线连接。

FliglZhxk84Q9bSbBGMwWrpXhoFW

 

可知,阵列的P1的1号引脚(3V3)应与最小系统的VCC相连,阵列P1的2号引脚(GND)应与最小系统的GND相连,阵列P1的3号引脚(SER1)应与最小系统的P55相连,阵列P1的4号引脚(SCK)应与最小系统的P54相连,阵列P1的5号引脚(RCK)应与最小系统的P33相连。

 

软件部分

亮灯控制

为避免对角线所在矩形上的其他LED被点亮,采取逐行刷新的方式来进行控制。首先以实验的方式来确定两位16进制的数分别是如何对应行与列的。

代码部分:

void main()
{			
	while(1)
	{
        Hc595OneRow(0x12,0x41); // row:0x12   col:0x41
        }
}

所调用函数的代码:

void Hc595OneRow(u8 R, u8 C)
{
	u16 cnt;
	SRCLK=0;
	RCLK=0;
	for(cnt=0;cnt<16;cnt++)
		{
			if (cnt<=7)
			{
			SER=R>>7;
		  R<<=1;
			}
			else
			{
			SER=C>>7;
		  C<<=1;
			}
			SRCLK=1;
			_nop_();
			_nop_();
			SRCLK=0;
		}
			_nop_();
			RCLK=1;
			_nop_();
			_nop_();
			RCLK=0;			
}

其中,u8是变量类型,定义代码:

typedef unsigned char u8;

LED点亮效果如图:

FqL-9MyYThZN-DODsBt7VT_yrP6a

则可知,两位十六进制与LED点阵的对应关系如下图:

FrUgX_CqWvUx-JXC3Z11Wof7Kv6J

 

部分函数与代码

void Hc595OneRow(unsigned char R, unsigned char C)

代码:

void Hc595OneRow(u8 R, u8 C)
{
	u16 cnt;
	SRCLK=0;
	RCLK=0;
	for(cnt=0;cnt<16;cnt++)
		{
			if (cnt<=7)
			{
			SER=R>>7;
		  R<<=1;
			}
			else
			{
			SER=C>>7;
		  C<<=1;
			}
			SRCLK=1;
			_nop_();
			_nop_();
			SRCLK=0;
		}
			_nop_();
			RCLK=1;
			_nop_();
			_nop_();
			RCLK=0;			
}

代码解释:为避免亮灯对角线所在矩形区域灯的误亮,决定采取逐行点亮的方式。第一个74HC595D的串口输入每读取十六个二进制数据(即四个16进制数据),分别分配到第一个与第二个74HC595D的并行输出,确定某一行灯的亮灭,并视其余诸行为灭。由于各行灯的亮灭间隔很短以及大脑的视觉暂离效应,不同行该亮的灯看起来同时一直再亮。

 

void Hc595RowScanUp(unsigned char dat[8],unsigned int m)

代码:

void Hc595RowScanUp(u8 dat[8],u16 m)
{
	u16 i;
	u8 row=0x80;
		for(i=0;i<8;i++)
		{   	 
			
			Hc595OneRow(row,dat[(i-m)%8]);            //if -m, the pic rises; if +m, the pic falls
			
			RCLK=1;
			_nop_();
			_nop_();
			RCLK=0;
			
			row>>=1;                                  //row is initialized as 0x80 && row>>=1, means the pic is scanned row by row from bottom to top 
		}
}

代码解释:将图案进行单行扫描。可在main函数值里与循环结合实现逐行扫描。

 

代码:

while(1)
	{ 
		for (cnt=0;cnt<4000;cnt++)
		{
			Hc595RowScanUp(rising_one_col,m);
			s++;
			if(s==250)
			{
				 if(m==7) m=0;
				 else m++;
				 s=0;
			}
		}

代码解释:将图案进行逐行扫描,并实现上升的效果。对于每个图案:每经过250次单行扫描,开始扫描下一行。形成一个完整周期需要250乘8=2000个单行扫描周期。当每个图案被完整扫描4000次后,开始扫描下个图案。

 

完整的main.c

代码:

#include "stc15w204.h"		
#include<intrins.h>
//#include "shifting_up.h"

typedef unsigned int u16;	 
typedef unsigned char u8;


sbit SRCLK=P5^4;
sbit RCLK=P3^3;
sbit SER=P5^5;


/*-------------------------Elevator Simulation-----------------------*/
//--------------------------------ONE----------------------------------
u8 rising_one_col[]={0x00,0xE0,0x40,0x60,0x40,0x1F,0x0E,0x04};
u8 falling_one_col[]={0x00,0xE0,0x40,0x60,0x40,0x04,0x0E,0x1F};
//--------------------------------TWO----------------------------------
u8 rising_two_col[]={0xF0,0x20,0x40,0x90,0x60,0x1F,0x0E,0x04};
u8 falling_two_col[]={0xF0,0x20,0x40,0x90,0x60,0x04,0x0E,0x1F};
//-------------------------------THREE---------------------------------
u8 rising_three_col[]={0x60,0x90,0x40,0x90,0x60,0x1f,0x0e,0x04};
u8 falling_three_col[]={0x60,0x90,0x40,0x90,0x60,0x04,0x0E,0x1F};
//--------------------------------FOUR---------------------------------
u8 rising_four_col[]={0x40,0x40,0xf8,0x50,0x60,0x5f,0x0e,0x04};
u8 falling_four_col[]={0x40,0x40,0xf8,0x50,0x60,0x44,0x0E,0x1F};
//--------------------------------FIVE---------------------------------
u8 rising_five_col[]={0xe0,0x80,0xe0,0x20,0xe0,0x1f,0x0e,0x04};
u8 falling_five_col[]={0xe0,0x80,0xe0,0x20,0xe0,0x04,0x0E,0x1F};
////--------------------------------SIX----------------------------------
//u8 rising_six_col[]={0xe0,0xa0,0xe0,0x20,0xe0,0x1f,0x0e,0x04};
//u8 falling_six_col[]={0xe0,0xa0,0xe0,0x20,0xe0,0x04,0x0E,0x1F};
////--------------------------------SEVEN--------------------------------
//u8 rising_seven_col[]={0x00,0x80,0x80,0x80,0xe0,0x1f,0x0e,0x04};
//u8 falling_seven_col[]={0x00,0x80,0x80,0x80,0xe0,0x04,0x0E,0x1F};
////--------------------------------EIGHT--------------------------------
//u8 rising_eight_col[]={0xe0,0xa0,0xe0,0xa0,0xe0,0x1f,0x0e,0x04};
//u8 falling_eight_col[]={0xe0,0xa0,0xe0,0xa0,0xe0,0x04,0x0E,0x1F};
////--------------------------------NINE---------------------------------
//u8 rising_nine_col[]={0xe0,0x80,0xe0,0xa0,0xe0,0x1f,0x0e,0x04};
//u8 falling_nine_col[]={0xe0,0x80,0xe0,0xa0,0xe0,0x04,0x0E,0x1F};




/*-----------generate one row at one time------------*/
void Hc595OneRow(u8 R, u8 C)
{
	u16 cnt;
	SRCLK=0;
	RCLK=0;
	for(cnt=0;cnt<16;cnt++)
		{
			if (cnt<=7)
			{
			SER=R>>7;
		  R<<=1;
			}
			else
			{
			SER=C>>7;
		  C<<=1;
			}
			SRCLK=1;
			_nop_();
			_nop_();
			SRCLK=0;
		}
			_nop_();
			RCLK=1;
			_nop_();
			_nop_();
			RCLK=0;			
}
void Hc595RowScanUp(u8 dat[8],u16 m)
{
	u16 i;
	u8 row=0x80;
		for(i=0;i<8;i++)
		{   	 
			
			Hc595OneRow(row,dat[(i-m)%8]);            //if -m, the pic rises; if +m, the pic falls
			
			RCLK=1;
			_nop_();
			_nop_();
			RCLK=0;
			
			row>>=1;                                  //row is initialized as 0x80 && row>>=1, means the pic is scanned row by row from bottom to top 
		}
}

	void Hc595RowScanDown(u8 dat[8],u16 m)
{
	u16 i;
	u8 row=0x80;
		for(i=0;i<8;i++)
		{   	 
			
			Hc595OneRow(row,dat[(i+m)%8]);            //if -m, the pic rises; if +m, the pic falls
			
			RCLK=1;
			_nop_();
			_nop_();
			RCLK=0;
			
			row>>=1;                                   //row is initialized as 0x80 && row>>=1, means the pic is scanned row by row from bottom to top 
		}
}

	void main()
{			
	u16 m=0,s=0; 
	u16 cnt;
	while(1)
	{ 
		for (cnt=0;cnt<4000;cnt++)
		{
			Hc595RowScanUp(rising_one_col,m);
			s++;
			if(s==250)
			{
				 if(m==7) m=0;
				 else m++;
				 s=0;
			}
		}
		//rising one
		for (cnt=0;cnt<4000;cnt++)
		{
			Hc595RowScanUp(rising_two_col,m);
			s++;
			if(s==250)
			{
				 if(m==7) m=0;
				 else m++;
				 s=0;
			}
		}
		//rising two
		for (cnt=0;cnt<4000;cnt++)
		{
			Hc595RowScanUp(rising_three_col,m);
			s++;
			if(s==250)
			{
				 if(m==7) m=0;
				 else m++;
				 s=0;
			}
		}
		//rising three
		for (cnt=0;cnt<4000;cnt++)
		{
			Hc595RowScanUp(rising_four_col,m);
			s++;
			if(s==250)
			{
				 if(m==7) m=0;
				 else m++;
				 s=0;
			}
		}
		//rising four
		for (cnt=0;cnt<4000;cnt++)
		{
			Hc595RowScanUp(rising_five_col,m);
			s++;
			if(s==250)
			{
				 if(m==7) m=0;
				 else m++;
				 s=0;
			}
		}
		//rising five
//		for (cnt=0;cnt<4000;cnt++)
//		{
//			Hc595RowScanUp(rising_six_col,m);
//			s++;
//			if(s==250)
//			{
//				 if(m==7) m=0;
//				 else m++;
//				 s=0;
//			}
//		}
//		//rising six
//		for (cnt=0;cnt<4000;cnt++)
//		{
//			Hc595RowScanUp(rising_seven_col,m);
//			s++;
//			if(s==250)
//			{
//				 if(m==7) m=0;
//				 else m++;
//				 s=0;
//			}
//		}
//		//rising seven
//		for (cnt=0;cnt<4000;cnt++)
//		{
//			Hc595RowScanUp(rising_eight_col,m);
//			s++;
//			if(s==250)
//			{
//				 if(m==7) m=0;
//				 else m++;
//				 s=0;
//			}
//		}
//		//rising eight
//		for (cnt=0;cnt<4000;cnt++)
//		{
//			Hc595RowScanUp(rising_nine_col,m);
//			s++;
//			if(s==250)
//			{
//				 if(m==7) m=0;
//				 else m++;
//				 s=0;
//			}
//		}
//		//rising nine
//		for (cnt=0;cnt<4000;cnt++)
//		{
//			Hc595RowScanDown(falling_nine_col,m);
//			s++;
//			if(s==250)
//			{
//				 if(m==7) m=0;
//				 else m++;
//				 s=0;
//			}
//		}
//		//falling nine
//		for (cnt=0;cnt<4000;cnt++)
//		{
//			Hc595RowScanDown(falling_eight_col,m);
//			s++;
//			if(s==250)
//			{
//				 if(m==7) m=0;
//				 else m++;
//				 s=0;
//			}
//		}
//		//falling eight
//		for (cnt=0;cnt<4000;cnt++)
//		{
//			Hc595RowScanDown(falling_seven_col,m);
//			s++;
//			if(s==250)
//			{
//				 if(m==7) m=0;
//				 else m++;
//				 s=0;
//			}
//		}
//		//falling seven
//		for (cnt=0;cnt<4000;cnt++)
//		{
//			Hc595RowScanDown(falling_six_col,m);
//			s++;
//			if(s==250)
//			{
//				 if(m==7) m=0;
//				 else m++;
//				 s=0;
//			}
//		}
//		//falling six
		for (cnt=0;cnt<4000;cnt++)
		{
			Hc595RowScanDown(falling_five_col,m);
			s++;
			if(s==250)
			{
				 if(m==7) m=0;
				 else m++;
				 s=0;
			}
		}
		//falling five
		for (cnt=0;cnt<4000;cnt++)
		{
			Hc595RowScanDown(falling_four_col,m);
			s++;
			if(s==250)
			{
				 if(m==7) m=0;
				 else m++;
				 s=0;
			}
		}
		//falling four
		for (cnt=0;cnt<4000;cnt++)
		{
			Hc595RowScanDown(falling_three_col,m);
			s++;
			if(s==250)
			{
				 if(m==7) m=0;
				 else m++;
				 s=0;
			}
		}
		//falling three
		for (cnt=0;cnt<4000;cnt++)
		{
			Hc595RowScanDown(falling_two_col,m);
			s++;
			if(s==250)
			{
				 if(m==7) m=0;
				 else m++;
				 s=0;
			}
		}
		//falling two
		for (cnt=0;cnt<4000;cnt++)
		{
			Hc595RowScanDown(falling_one_col,m);
			s++;
			if(s==250)
			{
				 if(m==7) m=0;
				 else m++;
				 s=0;
			}
		}
		//falling one
	}
}

部分代码被注释的原因:程序数据块太大,已超出片上的ROM。实际上,本人曾尝试CSDN网友提出的解决方案:配置Project->option for target->target选项中memory model 选择compact/large,但并不好用,若要保留数据,应使用外部数据存储器。

 

 

联系作者: 邮箱: 642296016@qq.com

附件下载
led_array_test.rar
项目软件
团队介绍
硬禾训练营(西交利物浦一期)
团队成员
黄世辰 Shichen Huang
西安交通利物浦大学,电子科学与技术专业,大三在读 XJTLU, Electronic Science and Technology from EEE Department, Y3 student
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号