STC89C51 16*16点阵滚动显示字幕——C语言 源码(字幕内容可以更换)

将16*16点阵看作四个8*8点阵,分别点亮,快速扫描实现字幕显示

数组指针右移实现字幕向左滚动的显示效果

硬件连接:74HC595四片级联,点阵屏的行输入连接HC595第一,二级输出,列输入连接第三,四级输出。74HC595的输入,大家可以根据各自的喜好和习惯连接,然后改掉端口定义。

//定义 74HC595 在电路连接中对应的 STC89C51 I/O口
/*--  当后续电路改变时,只需在此处更换IO口的定义即可,无需再回到函数中改变内容--*/
sbit SER = P0^0; //74HC595 字符输入端 SER
sbit SCK = P0^1; //74HC595 移位寄存器钟控端 SCK
sbit RCK = P0^2; //74HC595 并行输出钟控端 RCK

以下是我写的源码,可供大家参考

初学单片机,16*16点阵是昨天学的,还有很多理解不深刻的地方,或许有跟简单的方法,欢迎各位提出更好的意见或建议

#include <REGX52.H>

//定义一个数组存放需要显示的字符内容
unsigned char code Matrix_led[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/*--  文字:  计  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x02,0x02,0x42,0x33,0x00,0x02,0x02,0x02,0x02,0xFF,0x02,0x02,0x02,0x02,0x02,0x00,
0x00,0x00,0x00,0xFE,0x04,0x08,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,

/*--  文字:  算  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x10,0x20,0xCF,0x4A,0x6A,0x4A,0x4A,0x0A,0x2A,0xCA,0x4A,0x6A,0x4F,0x40,0x40,0x00,
0x08,0x08,0xE9,0xAA,0xBC,0xA8,0xA8,0xA8,0xA8,0xA8,0xBF,0xA8,0xE8,0x08,0x08,0x00,

/*--  文字:  机  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x08,0x08,0x0B,0xFF,0x09,0x08,0x00,0x7F,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,0x00,
0x20,0xC0,0x00,0xFF,0x00,0xC1,0x06,0xF8,0x00,0x00,0x00,0xFC,0x02,0x02,0x1E,0x00,

/*--  文字:  学  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x02,0x0C,0x88,0x69,0x09,0x09,0x89,0x69,0x09,0x09,0x19,0x28,0xC8,0x0A,0x0C,0x00,
0x20,0x20,0x20,0x20,0x20,0x22,0x21,0x7E,0x60,0xA0,0x20,0x20,0x20,0x20,0x20,0x00,

/*--  文字:  院  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x7F,0x44,0x5A,0x61,0x08,0x30,0x24,0x24,0xA4,0x64,0x24,0x24,0x28,0x30,0x00,
0x00,0xFF,0x20,0x10,0xE0,0x01,0x82,0x8C,0xF0,0x80,0x80,0xFC,0x82,0x82,0x8E,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};

//定义 74HC595 在电路连接中对应的 STC89C51 I/O口
/*--  当后续电路改变时,只需在此处更换IO口的定义即可,无需再回到函数中改变内容--*/
sbit SER = P0^0; //74HC595 字符输入端 SER
sbit SCK = P0^1; //74HC595 移位寄存器钟控端 SCK
sbit RCK = P0^2; //74HC595 并行输出钟控端 RCK

//控制四级级联 74HC595 的RCK端
unsigned char _74HC595_RCK_CTRI = 0;


//数组长度
unsigned char length = sizeof(Matrix_led) / sizeof(Matrix_led[0]);

/*------------------------------------------------------------------------------*/
//函数声明: 用户调用函数
/*------------------------------------------------------------------------------*/
void Delay1ms (unsigned char xms);
void Delay10us(unsigned int xus);
void Matrix_Led_Init( void );
void Matrix_Led_Show(unsigned char* Matrix_led_code);
void Matrix_Led_Column(unsigned char col, unsigned char led_code_col, unsigned char k);
void _74HC595_WriteByte(unsigned char led_code_col);

/*------------------------------------------------------------------------------*/
//函数定义
/*------------------------------------------------------------------------------*/
/**
  * @brief   点阵屏初始化
  * @param   无
  * @retval  无
  */
void Matrix_Led_Init( void )
{
	SCK = 1;
	RCK = 1;
}

/**
  * @brief   在16*16点阵屏上显示字符内容
  * @param   无
  * @retval  无
  */
void Matrix_Led_Show(unsigned char* Matrix_led_code)
{
	unsigned char k;
	unsigned char m = 0, //检测字符序列
			            s = 0; //防止指针越界访问
	for(;s <= length - 129; Matrix_led_code++, s++)
	{
		m++;
	    if(m == 17)
		{
			m = 1;
			Matrix_led_code += 16; //数组指针右移,每当连续显示完16帧时,跳过16个字符,跳到下一个字
		}
		for(k = 1; k <= 4; k++)
		{
			unsigned char i, i2;
			for(i = 0; i <= 7;i ++) //循环,依次显示第一列到第八列
			{
				if((i + 8*(k - 1)) % 16 >= 16 - m)
				{
					i2 = i + 8*(k - 1) + 16;//当某一列显示到某个字的最后一列时,跳过16个字节,跳到下一个字
				}
				else
				{
				    i2 = i + 8*(k - 1);
				}
				Matrix_Led_Column(i, Matrix_led_code[i2], k);
			}
		}
	}	
}

/**
  * @brief   在点阵屏指定的一列上显示一个8位字符数据
  * @param   led_cdoe_col 要显示的一个字符数据
  * @param	 col 说明了字符要显示在哪一列的位置上
  * @retval  无
  * @explain 将16*16点阵看作四个8*8点阵,依次分别显示一个屏幕上的内容,并快速刷新
  */
void Matrix_Led_Column(unsigned char col, unsigned char led_code_col, unsigned char k)
{
	unsigned char i;
	if(k == 1){i = 0x00;} //显示左上角
	if(k == 2){i = 0x01;}//显示右上角
	if(k == 3){i = 0x10;}//显示左下角
	if(k == 4){i = 0x11;}//显示右下角
	  
	//选列
	if(i == 0x00 || i == 0x10)
	{
		_74HC595_WriteByte(~0x00);
		_74HC595_WriteByte(~(0x80 >> col));
	 }
	else
	{
		_74HC595_WriteByte(~(0x80 >> col));
		_74HC595_WriteByte(~0x00);
	}
		
	//选行
	if(i == 0x00 || i == 0x01)
	{
		_74HC595_WriteByte(0x00);
		_74HC595_WriteByte(led_code_col);
	}
	else
	{
	    _74HC595_WriteByte(led_code_col);
		_74HC595_WriteByte(0x00);
	}
}

/**
  * @brief   利用74HC595四级级联,将四个字符并行输出。
             每次调用此函数时led_code_col传进一个字符,_74HC595_RCK_CTRI累加计数
             每当函数中传入四个字符时并行输出,_74HC595_RCK_CTRI置0,重新计数
  * @param   led_cdoe_col 一个字符数据
  * @retval  无
  */
void _74HC595_WriteByte(unsigned char led_code_col)
{
	unsigned char i;
	for(i = 0; i <= 7; i++) //将led_code_col传入的字符按位(从低位到高位)放入移位寄存器
	{
		SER = led_code_col & ( 0x01 << i ); //从低位到高位依次读取位数值
		SCK = 0;;;  //控制移位寄存器时钟,将数据送入移位寄存器
	    SCK = 1;  //将 SCK 钟控端复位
	}
	_74HC595_RCK_CTRI ++; //是全局变量
				    	  //控制四级级联的74HC595 RCK端 
		                  //其初值为0,SER端每进入一个字符时,74HC595_RCK_CTRI ++
		                  //当74HC595_RCK_CTRI == 4 时(进入四个字符)
		                  //将RCK 置1,并行输出所有数据
		                  //并将74HC595_RCK_CTRI置0,重新计数
	if(_74HC595_RCK_CTRI >= 4) //当有4个字符数据时
	{
	    RCK = 0;;;     //通过 RCK 控制74HC595并行输出数据
	    RCK = 1;       //RCK复位
	    _74HC595_RCK_CTRI = 0;
	}	
}


void main()
{
	Matrix_Led_Init();//点阵屏初始化
	while(1)
	{
		Matrix_Led_Show(Matrix_led);
	}
}

  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值