用51做的16*16點陣顯示屏幕(ptotues仿真)
阿新 • • 發佈:2018-12-20
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仿真)