标签:src 字体 启动 char s ++ 处理 显示 空值 ima
第一次写博客,来试试水。正好前几天搞一个单片机的仿真拿来分享

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硬件图:


标签:src 字体 启动 char s ++ 处理 显示 空值 ima
原文地址:https://www.cnblogs.com/jxlk233/p/10146190.html