第一次写博客,来试试水。正好前几天搞一个单片机的仿真拿来分享
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硬件图:
原文地址:https://www.cnblogs.com/jxlk233/p/10146190.html
时间: 2024-11-09 10:00:39