标题:
单片机16x16点阵显示汉字程序 左右移动,可快慢,暂停
[打印本页]
作者:
想后看开
时间:
2022-11-21 11:53
标题:
单片机16x16点阵显示汉字程序 左右移动,可快慢,暂停
#include<reg52.h>
#define uint unsigned int
#define u16 unsigned int
#define uchar unsigned char
#define u8 unsigned char
sbit H_stcp = P2^6; //输出时钟线
sbit H_shcp = P2^7; //HC595芯片输入时钟线
sbit H_ds = P2^5; //数据线
sbit HC138_A0 = P2^0; //
sbit HC138_A1 = P2^1; //
sbit HC138_A2 = P2^2; //
sbit HC138_A3 = P2^3; //
u16 volatile W_BCNT; //显示字标志
u8 volatile W_LCNT; //显示位移标志
u8 speed=5; //移动速度
#define WORDNUM 8
unsigned char code Word[WORDNUM][32] = {
{0x00,0x00,0x31,0x2A,0x24,0x20,0x2F,0x20,0xE6,0x11,0x08,0xC4,0x3F,0x10,0x08,0x04,
0x00,0x06,0x88,0x00,0x07,0x01,0xC1,0x21,0x4D,0x11,0x81,0x01,0xEE,0x00,0x0C,0x02},/*"您",3*/
{0x00,0x02,0x02,0x22,0x22,0x2A,0x26,0x22,0x63,0xA2,0x26,0x2A,0x22,0x22,0x02,0x02,
0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0xFF,0x20,0x20,0x20,0x20,0x20,0x20,0x00},/*"辛",4*/
{0x00,0x21,0x21,0x21,0x21,0xF9,0x21,0x21,0x2F,0x21,0x21,0xF9,0x21,0x21,0x21,0x21,
0x00,0x00,0x00,0x00,0x3F,0x22,0x22,0x22,0xE2,0x22,0x22,0x22,0x3F,0x00,0x00,0x00},/*"苦",5*/
{0x00,0x00,0x00,0x40,0x60,0x50,0x48,0x44,0x47,0x40,0x40,0x40,0x40,0x40,0x40,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x01,0x02,0x00,0x00,0x00,0x00,0x00},/*"了",6*/
/*-- 文字: 军 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
{0x00,0x00,0x78,0x44,0x4B,0x70,0x49,0x44,0x00,0x07,0x34,0x2F,0xE4,0x37,0x08,0x04,
0x00,0x10,0x90,0x90,0xFF,0x90,0x90,0x50,0x00,0xFF,0x91,0xFC,0x90,0xF8,0x06,0x01},
/*-- 文字: 放 --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/
{0x00,0x08,0x08,0x0F,0x08,0x08,0xE8,0x1B,0x04,0x12,0x13,0x12,0x52,0x9F,0x10,0x10,
0x00,0x01,0x02,0x84,0x68,0x10,0x68,0x84,0x02,0x01,0xFC,0x02,0x04,0xF0,0x0C,0x02},
{0x00,0x60,0x50,0x44,0x44,0x44,0x44,0x44,0x45,0x5C,0x46,0x45,0x44,0x44,0x60,0x10,
0x00,0x08,0x08,0x48,0x48,0x48,0x48,0x48,0xFF,0x48,0x48,0x48,0xC8,0x48,0x08,0x08},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCC,0x00,0x00,0x00},/*"!",7*/
};
unsigned char WordTemp[32] = {
0x01,0x01,0x61,0x71,0x19,0x0D,0x05,0xFF,0xFF,0x01,0x7D,0x7C,0x44,0x47,0x47,0x40,
0x02,0x06,0x0C,0x18,0x70,0xE4,0x86,0xFF,0xFF,0x00,0x7C,0x7E,0x43,0xC3,0xC2,0x00,
};
/*************************/
//延时函数
/*************************/
void delay_ms(uint xms)
{
uint i, j;
for(i = xms; i > 0; i--)
for(j = 118; j > 0; j--);
}
#define HC595_QA 0x80
#define HC595_QB 0x20
#define HC595_QC 0x04
#define HC595_QD 0x01
#define HC595_QE 0x10
#define HC595_QF 0x40
#define HC595_QG 0x02
#define HC595_QH 0x08
void sendbyte_All(u8 group1,u8 group2) //利用HC595输出
{
u8 z;
for(z = 0; z < 8; z++) //循环8次移入数据
{
H_shcp = 0;
switch(z)
{
case 0:H_ds = group2 & HC595_QH;break;
case 1:H_ds = group2 & HC595_QG;break;
case 2:H_ds = group2 & HC595_QF;break;
case 3:H_ds = group2 & HC595_QE;break;
case 4:H_ds = group2 & HC595_QD;break;
case 5:H_ds = group2 & HC595_QC;break;
case 6:H_ds = group2 & HC595_QB;break;
case 7:H_ds = group2 & HC595_QA;break;
}
H_shcp = 1; //上升沿输入数据
}
for(z = 0; z < 8; z++) //循环8次移入数据
{
H_shcp = 0;
switch(z)
{
case 0:H_ds = group1 & HC595_QH;break;
case 1:H_ds = group1 & HC595_QG;break;
case 2:H_ds = group1 & HC595_QF;break;
case 3:H_ds = group1 & HC595_QE;break;
case 4:H_ds = group1 & HC595_QD;break;
case 5:H_ds = group1 & HC595_QC;break;
case 6:H_ds = group1 & HC595_QB;break;
case 7:H_ds = group1 & HC595_QA;break;
}
H_shcp = 1; //上升沿输入数据
}
H_stcp = 0;
H_stcp = 1; //上升沿使数据并行输出
}
void HC138Out(u8 i,u8 l)
{
u8 j;
switch(i)
{
case 7:j=5;break;
case 6:j=2;break;
case 5:j=1;break;
case 4:j=7;break;
case 3:j=0;break;
case 2:j=6;break;
case 1:j=4;break;
case 0:j=3;break;
}
HC138_A0 = j&0x01;
HC138_A1 = j&0x02;
HC138_A2 = j&0x04;
if(l)
HC138_A3=0;
else
HC138_A3=1;
}
void WordDisplay(u8 *word)
{
uchar i;
for(i = 0; i < 8; i++)
{
sendbyte_All(0,0); //消影
HC138Out(i,0);
sendbyte_All(*(word+i),*(word+i+8)); //输出信息
}
for(i = 0; i < 8; i++)
{
sendbyte_All(0,0); //消影
HC138Out(i,1);
sendbyte_All(*(word+i+16),*(word+i+24)); //输出信息
}
}
/*********************定时器0、定时器1初始化******************/
void time0_init()
{
TMOD = 0x01; //设置定时器0为工作模式1 (16-bit)
TL0 = 15536; //给定时器低位赋初始值 65536-15536=50000us=50ms,即50ms一个中断
TH0 = 15536 >> 8; //给定时器高位赋初始值
TR0 = 1; //开启定时器0
ET0 = 1; //允许定时器0中断
EA = 1; //开启全局中断
}
//按键
sbit Key1=P1^3; //设置键
sbit Key2=P1^4; //加按键
sbit Key3=P3^2; //减按键
sbit Key4=P3^3; //交通管制键
//========================================================================
// 函数: u8 Key_Scan()
// 应用: temp=u8 Key_Scan();
// 描述: 按键扫描并返回按下的键值
// 参数: NONE
// 返回: 按下的键值
// 版本: VER1.0
// 日期: 2015-05-29
// 备注: 该函数带松手检测,按下键返回一次键值后返回0,直至第二次按键按下
//========================================================================
u8 Key_Scan()
{
static u8 key_up=1;//按键按松开标志
if(key_up&&(Key1==0||Key2==0||Key3==0||Key4==0))
{
delay_ms(10);//去抖动
key_up=0;
if(Key1==0) return 1;
else if(Key2==0)return 2;
else if(Key3==0)return 3;
else if(Key4==0)return 4;
}
else if(Key1==1&&Key2==1&&Key3==1&&Key4==1)
key_up=1;
return 0;// 无按键按下
}
void main()
{
uchar key_can; //按键值
uchar mode=0; //模式
uchar modej=0; //模式
uchar i;
time0_init();
while(1)
{
key_can=Key_Scan();
if(1==key_can)
{
TR0 = 1; //开启定时器0
if(modej) //判断暂停标志,此处处理是为了防止暂停再启动方向会变
{
modej=0;
mode++;
if(mode>=2)
{
mode=0;
}
}
mode++;
if(mode>=2)
{
mode=0;
}
}
if(2==key_can)
{
TR0 = 0; //关闭定时器0,暂停
modej=1; //暂停标志
}
if(4==key_can)
{
speed+=1; //速度加1
}
if(3==key_can)
{
speed-=1; //速度减1
if(speed==0)
speed=1;
}
if(1==mode)//往右移
{
for(i = 0; i < 16-W_LCNT; i++)
{
WordTemp[i]=Word[W_BCNT][i+W_LCNT];
};
for(i = 0; i <W_LCNT ; i++)
{
WordTemp[i+16-W_LCNT]=Word[W_BCNT+1][i];
};
for(i = 16; i < 32-W_LCNT; i++)
{
WordTemp[i]=Word[W_BCNT][i+W_LCNT];
};
for(i = 16; i <16+W_LCNT ; i++)
{
WordTemp[i+16-W_LCNT]=Word[W_BCNT+1][i];
};
}
if(0==mode)//往左移
{
for(i = 0; i < 16-W_LCNT; i++)
{
WordTemp[i+W_LCNT]=Word[W_BCNT][i];
};
for(i = 0; i < W_LCNT ; i++)
{
WordTemp[i]=Word[W_BCNT+1][16-W_LCNT+i];
};
for(i = 16; i < 32-W_LCNT; i++)
{
WordTemp[i+W_LCNT]=Word[W_BCNT][i];
};
for(i = 16; i <16+W_LCNT ; i++)
{
WordTemp[i]=Word[W_BCNT+1][16-W_LCNT+i];
};
}
WordDisplay(WordTemp);
}
}
/*********************定时器0中断服务程序************************/
void time0_int() interrupt 1
{
static uchar volatile value; //定时10ms中断一次
TL0 = 15536; //给定时器低位重装初始值 65536-15536=50000us=50ms,即50ms一个中断
TH0 = 15536 >> 8; //给定时器高位重装初始值
value ++;
if(value >= speed)
{
value = 0;
W_LCNT++;
if(W_LCNT >= 16)
{
W_LCNT=0;
W_BCNT++;
if(W_BCNT >= (WORDNUM-1))
{
W_BCNT=0;
}
}
}
}
复制代码
作者:
heicad
时间:
2022-11-21 15:18
电路是如何连接的?楼主能介绍一下吗?
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1