1. 程式人生 > >用51做的16*16點陣顯示屏幕(ptotues仿真)

用51做的16*16點陣顯示屏幕(ptotues仿真)

pan bit arp sharp image 再次 按鍵消抖 for 描述

第一次寫博客,來試試水。正好前幾天搞一個單片機的仿真拿來分享

技術分享圖片

16*16的點陣顯示屏,按下開始按鍵後,在顯示屏上輪流顯示“字符串1”字樣。再次按下開始按鍵後,顯示屏上無任何顯示。按下切換後能顯示“字符串2”字樣等(可以設計很多切換字符串)。且啟動消隱的過程顯示清晰無異樣。

/* ***************************************************** */
// 作  者:lk			系統時鐘 : 11.0592MHZ      
// 版  本:V1.2       		生成日期 : 2018-12-01	   					
// 簡單描述 : 用8255和74ls154驅動16*16點陣,
// 字幕軟件:Copyleft采用縱向取模,字節倒序,字體:宋體12
//switch按鍵切換字符組,start按鍵用來啟動和關閉點陣顯示。
/* ***************************************************** */
#include<reg51.h>
#include<intrins.h>
#include<absacc.h>
#define uchar unsigned char
#define uint unsigned int
	
//PA,BP,PC端口地址及命令定義 按鍵定義
#define PA XBYTE[0x0000]
#define PB XBYTE[0x0001]
#define PC XBYTE[0x0002]
#define COM XBYTE[0x0003]

sbit sz_anji = P3^3;    //切換按鍵
sbit ks_anji = P3^2;		//開關按鍵
sbit switch_154 = P3^0;					//74ls154譯碼開關
uchar shuzu=0;				  	//當前數組號
uchar BR=0;				  	//跳出信號
uint qh=0;						//切換數組按鍵變量
uchar dz_start = 0;									//啟動標誌位
uchar data Row_Data[32];  			//發送4片LED屏數據
uchar code Word_Set1[][32]= 			//待顯示文字的點陣
{
{/*--  文字:  電  --*/
/*--  宋體12;  此字體下對應的點陣為:寬x高=16x16   --*/
0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0xFF,0x88,0x88,0x88,0x88,0xF8,0x00,0x00,0x00,
0x00,0x00,0x1F,0x08,0x08,0x08,0x08,0x7F,0x88,0x88,0x88,0x88,0x9F,0x80,0xF0,0x00},
{/*--  文字:  信  --*/
/*--  宋體12;  此字體下對應的點陣為:寬x高=16x16   --*/
0x00,0x80,0x60,0xF8,0x07,0x00,0x04,0x24,0x24,0x25,0x26,0x24,0x24,0x24,0x04,0x00,
0x01,0x00,0x00,0xFF,0x00,0x00,0x00,0xF9,0x49,0x49,0x49,0x49,0x49,0xF9,0x00,0x00},
/*省略一部分字符代碼*/};

void delay(uint x)					//延時函數
{
	uchar i;
	while(x--)
		for(i=0; i<120; i++);
}

void clear(void)      //清屏函數
{
	switch_154 = 1;		//關閉列譯碼器
	PA = 0xff;			  //清零上8行數據
	PB = 0xff;			  //清零下8行數據
	switch_154 = 0;		//打開列譯碼器	
}

void switch_sz(uint xh)     //切換按鍵判斷函數
{
	uint x;
	for(x=0;x<xh;xh++)
	{
		if(!sz_anji)
		{
			delay(10);	//按鍵消抖
		 if(!sz_anji)
			{
				TR0 = 0;					//關閉定時器不再刷新
				clear();					//消隱
				qh++;		shuzu=qh%3;  //獲取當前數組號
				 BR=1;
			  while(!sz_anji);		//按鍵彈起後	
			}		 		
		}			
	}
}


//定時器0中斷,在主程序的延時時期內以1ms的間隔動態顯示每列數據
void led_disply_control() interrupt 1
{
		uchar i;
		TH0 = ~1000/256;						
		TL0 = ~1000%256;						
		switch_154 = 1;					//關閉列譯碼器
		i = (P1+1) & 0X0F;			//列號遞增
		PA = ~Row_Data[i];			//發送上8行數據
		PB = ~Row_Data[i+16];		//發送下8行數據
		P1 = i;									//列譯碼
		switch_154 = 0;					//打開列譯碼器	
}

//按鍵外部中斷處理程序
void Key_Down() interrupt 0
{
	TR0 = 0;								//關閉定時器刷新
	EX0 = 0;								//關閉外部中斷
	
	delay(10);								//按鍵消抖
	if(!ks_anji)									//按鍵按下
	dz_start = !dz_start;			//改變啟動狀態位	
	
	TR0 = 1;						  //打開定時器繼續刷新
	EX0 = 1;							//開啟外部中斷
}

void main ()			
{
	uchar i,K;								//刷新變量
	uchar qs,mw;					//數組起始,末尾位
	
	//8255工作方式選擇PA,PB均輸出,工作方式0
	COM = 0x80;
	TMOD = 0x01;
	TH0 = ~1000/256;						
	TL0 = ~1000%256;	
	IT0 = 1;							//下降沿觸發
	IE = 0x83;
	P1 = 0xFF;
	sz_anji = 1;

	while(1)
	{
		if(dz_start)						//是否start
		{
			BR=0;
			switch(shuzu)					//數組起始和末尾值
			{
				case 0: qs=0;  mw=5;  break;
				case 1: qs=5;  mw=13; break;
				case 2: qs=13; mw=15; break;
				default: qs=0; mw=5;  break;				
			}			
			
			for(K=qs;K<mw;K++)			//顯示一串字符
			{			
			if(BR) break;				//如果按鍵切換了就跳出重取緩沖值
			for(i=0;i<32;i++)	Row_Data[i]=Word_Set1[K][i];				//裝入一個字符的緩沖值
			while(!dz_start)			//啟動定時器顯示時檢測start按鍵,無start一直在這;
			clear();							//點陣消隱,緩沖裝空值	
			TR0 = 1;						  //使能定時器中斷
			switch_sz(300);					//按鍵一直在判斷,大約耗時0.5s。此時定時器刷新一個字符
			TR0 = 0;			
			P2=0xff;					    //點陣消隱
			}
		}
	}
}

註釋寫的很清楚了,只是代碼是由原來一個8*8的靜態輸出的代碼改的沒花多少重新搞刷新算法(之前實驗的動態刷新protues跑起來會卡)

下面是protues硬件圖:

技術分享圖片 技術分享圖片 技術分享圖片

技術分享圖片 技術分享圖片 技術分享圖片

用51做的16*16點陣顯示屏幕(ptotues仿真)