51單片機教程:51單片機驅動四個8*8點陣,拼湊16*16點陣顯示標準漢字。

看此篇博文之前建議先看博主的上一篇博文: 51單片機教程:8*8 點陣顯示字符、數字、簡單漢字

教你如何用4個8乘8點陣拼成一個16乘16點陣

資料鏈接:點陣16乘16.rar
一、點陣原理
市面上有很多種類的點陣,但是最常用的還是這種8乘8點陣
在這裏插入圖片描述
內部結構如下圖
在這裏插入圖片描述
可以發現點陣就是由led構成,並且有一排是陽極,另一排是陰極,有一排是控制行,另一排是控制列。
打開proteus搜索MATRIX,看到各種型號的點陣,選擇8乘8即可
在這裏插入圖片描述
任意選擇一個顏色的點陣,我們發現引腳沒有做任何標記,默認上排:陰極、控制列;下排:陽極、控制行
(一定要自己測一下,proteus仿真佈置的點陣每次方向都可能發生改變)
在這裏插入圖片描述
什麼意思呢,也就是跟下圖對應關係,只不過引腳位置發生改變
在這裏插入圖片描述

二、4個 “ 2乘2 ” 點陣拼成一個 “ 4乘4” 點陣
我們先從簡單開始理解,首先畫出4個 “2乘2” 點陣
在這裏插入圖片描述
然後把上下方向的陰極控制列連接起來
把左右方向的陽極控制行連接起來
就拼成了一個4*4點陣
在這裏插入圖片描述
二、4個 “ 8乘8 ” 點陣拼成一個 “ 16乘16” 點陣
注意:proteus的點陣真的很難用,找不到方向,得自己測
測量兩個內容:控制列還是控制行、陰極還是陽極
在這裏插入圖片描述

三、仿真:依次顯示 “化作塵”,間隔爲1秒

這裏使用了74hc138與74hc595,不瞭解原理的自行百度,不做講解
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
對應代碼:

/*
hc595與hc138控制8*8點陣
一開始寫這個程序的時候,程序運行佔用存儲空間超過了128b
錯誤:
點陣(四)16乘16.C(98): error C249: 'DATA': SEGMENT TOO LARGE

導致程序無法運行,原因是數組佔用了大量的內存
後來在數組名前加了code解決了這個問題
意思是把數組存儲到程序存儲區4kb而不是  data區128b
*/

#include <regx51.h>

sbit SH_CP = P3^0;
sbit DS = P3^1;
sbit ST_CP = P3^2;

//不需要改變的數組保存到code程序存儲區
unsigned char code b[3][32] = {
/*--  文字:  化  --*/
/*--  宋體12;  此字體下對應的點陣爲:寬x高=16x16   --*/
0x10,0x01,0x10,0x01,0x10,0x21,0x08,0x11,0x08,0x09,0x0C,0x05,0x0C,0x03,0x0A,0x01,
0x89,0x01,0x48,0x01,0x28,0x01,0x08,0x41,0x08,0x41,0x08,0x41,0x08,0x7E,0x08,0x00,

/*--  文字: 作  --*/
/*--  宋體12;  此字體下對應的點陣爲:寬x高=16x16   --*/
0x90,0x00,0x90,0x00,0x90,0x00,0x88,0x7F,0x48,0x01,0x4C,0x01,0x2C,0x01,0x0A,0x1F,
0x09,0x01,0x08,0x01,0x08,0x01,0x08,0x3F,0x08,0x01,0x08,0x01,0x08,0x01,0x08,0x01,

/*--  文字:  塵  --*/
/*--  宋體12;  此字體下對應的點陣爲:寬x高=16x16   --*/
0x80,0x00,0x80,0x00,0x90,0x04,0x90,0x08,0x88,0x10,0x84,0x20,0x82,0x20,0x00,0x00,
0x80,0x00,0x80,0x00,0xFC,0x1F,0x80,0x00,0x80,0x00,0x80,0x00,0xFF,0x7F,0x00,0x00,
  };

void delayms(unsigned int m)
{
	int i,j;
	for(i=0; i<m; i++)
		for(j=0; j<120; j++);
}

void hc_595(unsigned int temp,unsigned int temp1)	  //595段碼程序
{
	char t;
	bit val;
	for(t=0; t<8; t++)
	{
	   
		val = temp & 0x80;     //第一個數據傳到第一個595輸出
		DS = val;
		SH_CP = 0;;  
		SH_CP = 1;
		temp = temp<<1;
	}
	for(t=0; t<8; t++)
	{
	   
		val = temp1 & 0x80;    //第二個數據傳輸到第二個595輸出
		DS = val;
		SH_CP = 0;;  
		SH_CP = 1;
		temp1 = temp1<<1;
	}
	ST_CP = 0;;   
	ST_CP = 1;	
} 

void hc_138()
{
	unsigned int n,t,i;
	for(i=0; i<3; i++)				  //顯示3個漢字
	{
		for(t=0; t<30; t++)			   //用來延時1秒
		{
			for(n=0; n<16; ++n)		   //一次顯示一個漢字
			{	
				if(n<8)       //第一個138的高電平向下移動
				{
					P3_6 = 1;   //第一個138使能,第二個138不工作
					P2 = n;		   
				}
				else         //第二個138的高電平向下移動
				{
					P3_6 = 0;	 //第二個138使能,第一個138不工作
					P2 = n-8;    
				}
				hc_595(b[i][2*n],b[i][2*n+1]);	 //發送段碼
				delayms(2);
			}
		}
	}
}


void main(void)
{
	while(1)
	{
			hc_138();
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章