高级会员
 
主题
帖子
积分3296
阅读权限30
注册时间2010-10-19
最后登录1970-1-1
在线时间 小时
|

楼主 |
发表于 2010-12-5 22:45
|
显示全部楼层
源程序
-----------------------------------------------------------------------------------------------------------------------------------
// 本程序演示 STC12C5A60S2 系列直驱四个8*8LED点阵组成16X16点阵,并显示一个汉字时钟.
// 从右到左流动显示"XX时XX分XX秒"
//编写:桃源客, 日期:2010-9-20
//---------------------------------------------------------------------
#include "STC12C5A60s2.H" //这个头文件在STC官网上下载,是定义增强型单片机STC12C5A的特殊寄存器.
//---------------------------------------------------------------------
typedef unsigned char uchar; //以下两句为定义数据格式.
typedef unsigned int uint;
//以下字模为PC2LCD2000生成,选"逐列,阴码,逆向"方式.
uchar code shuzi[10][4]= //0-9数字字模8X16字阵
{
0x00,0xFE,0x82,0xFE,/*"0",0*/
0x00,0x84,0xFE,0x80,/*"1",0*/
0x00,0xF2,0x92,0x9E,/*"2",0*/
0x00,0x92,0x92,0xFE,/*"3",0*/
0x00,0x1E,0x10,0xFE,/*"4",0*/
0x00,0x9E,0x92,0xF2,/*"5",0*/
0x00,0xFE,0x92,0xF2,/*"6",0*/
0x00,0x02,0x02,0xFE,/*"7",0*/
0x00,0xFE,0x92,0xFE,/*"8",0*/
0x00,0x9E,0x92,0xFE,/*"9",0*/
};
uchar code shi_shuzi[10][4]= //显时0-9数字字模8X16字阵
{
0xFE,0x82,0xFE,0x00,/*0*/
0x84,0xFE,0x80,0x00,/*"1"*/
0xF2,0x92,0x9E,0x00,/*"2*/
0x92,0x92,0xFE,0x00,/*3*/
0x1E,0x10,0xFE,0x00,/*"4",*/
0x9E,0x92,0xF2,0x00,/*5*/
0xFE,0x92,0xF2,0x00,/*"6*/
0x02,0x02,0xFE,0x00,/*"7*/
0xFE,0x92,0xFE,0x00,/*8*/
0x9E,0x92,0xFE,0x00,/*9*/
};
uchar code huhao[][8]={ //流水灯花样.
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"*/
0x03,0x02,0x00,0x00,0x00,0x00,0x00,0x00,/*"*/
0x07,0x06,0x04,0x00,0x00,0x00,0x00,0x00,/*"*/
0x0F,0x0E,0x0C,0x08,0x00,0x00,0x00,0x00,/*"*/
0x1F,0x1E,0x1C,0x18,0x10,0x00,0x00,0x00,/*"*/
0x3F,0x3E,0x3C,0x38,0x30,0x20,0x00,0x00,/*"*/
0x7F,0x7E,0x7C,0x78,0x70,0x60,0x40,0x00,/*"*/
0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,/*"*/
0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"*/
0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,/*"*/
0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,/*"*/
0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,/*"*/
0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,/*"*/
0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,/*"*/
0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,/*"*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,/*"*/
0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,/*"*/
0x7F,0x7E,0x7C,0x78,0x70,0x60,0x40,0x00,/*"*/
0x3F,0x3E,0x3C,0x38,0x30,0x20,0x00,0x00,/*"*/
0x1F,0x1E,0x1C,0x18,0x10,0x00,0x00,0x00,/*"*/
0x0F,0x0E,0x0C,0x08,0x00,0x00,0x00,0x00,/*"*/
0x07,0x06,0x04,0x00,0x00,0x00,0x00,0x00,/*"*/
0x03,0x02,0x00,0x00,0x00,0x00,0x00,0x00,/*"*/
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"*/
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,/*"*/
0x81,0x42,0x24,0x18,0x18,0x24,0x42,0x81,/*"*/
0x01,0x02,0x04,0x08,0x08,0x04,0x02,0x01,/*"*/
0x80,0x40,0x20,0x10,0x10,0x20,0x40,0x80,/*"*/
0x3C,0x42,0x85,0xAD,0xB9,0xA5,0x46,0x3C,/*"*/
0x20,0x24,0x25,0xFE,0xFE,0x25,0x24,0x20,/*"*/
};
uchar code tab[]={0x7f,0xff,0xbf,0xff,0xdf,0xff,0xef,0xff,0xf7,0xff,0xfb,0xff,0xfd,0xff,0xfe, 0xff,
0xff, 0x7f,0xff,0xbf,0xff,0xdf,0xff,0xef,0xff,0xf7,0xff,0xfb,0xff,0xfd,0xff,0xfe };
//16列扫描分时输出,从右到左每次输出1列,低电平有效.
uint i ,speed, k ,j; //定义扫描循环控制变量.
uchar vram[32] ; //显示点阵显示缓冲区
bit SHAN; //以下变量作为时钟计数用
sbit H_KEY=P4^5; //时调整键
sbit M_KEY=P4^6; //分调整键
bit H_TEMP=1; //时调标志位
bit M_TEMP=1; //分调标志位
uchar second=0,minute=0,hour=0;
uchar tim1,tim2; //定义临时变量
void init(); //初始化函数.
#define HAN1 P1 //定义p1口为行0-行7数据口
#define HAN2 P3 //定义p3口为行8-行15数据口
#define LIE1 P2 //定义p2口为列1-行7数据口
#define LIE2 P0 //定义p0口为列8-列15数据口
void delay(uchar delay_time); //延时函数
void display(); //显示函数
//---------------------------------------------------------------------
void main()
{
init(); //初始化STC12C5A60S2的P0-P3端口为强推输出,每端口输出可输出20MA电流,可直驱8X8LED点阵.
while(1)
{
display(); //调用显示函数
}
}
void display()
{
for(j=0;j<4;j++) { vram[28+j]=shuzi[second%10][j];} //秒个位值转字模传vram
for(j=0;j<4;j++) { vram[24+j]=shuzi[second/10][j];} //秒十分值转字模传vram
for(j=0;j<4;j++) { vram[12+j]=shuzi[minute%10][j];} //分个位值转字模传vram
for(j=0;j<4;j++) { vram[8+j]=shuzi[minute/10][j];} //分十值转字模传vram
for(j=0;j<4;j++) { vram[4+j]=shi_shuzi[hour%10][j];} //时个位值转字模传vram
for(j=0;j<4;j++) { vram[j]=shi_shuzi[hour/10][j];} //时十位值转字模传vram
for(j=0;j<8;j++) { vram[16+j]=huhao[second%30][j];}
if(!SHAN) { vram[7]=0x28; vram[8]=0x28; }
for(i=0 ;i <16 ; i++)
{ LIE1=0xff; LIE2=0xff;
HAN1 = vram[ i ] ;
HAN2 = vram[16+i] ;
LIE2=tab[2*i];
LIE1=tab[2*i+1];
delay(20) ;
}
}
//---------------------------------------------------------------------
void delay(uchar t) // 延时函数
{
uchar i; //定义变量
for(;t>0;t--) //如果t大于0,t减1(外层循环)
for(i=124;i>0;i--); //i等于124,如果i大于0,i减1
}
//---------------------------------------------------------------------
/***************************************
函 数 名:init
功 能:初始化函数
说 明:初始化定时器及中断
入口参数:无
返 回 值:无
***************************************/
void init()
{
TMOD=1;TH0=0X3C;TL0=0XB0; //定时器0模式1,50毫秒
ET0=1;TR0=1;EA=1; //开定时器0中断、启动定时器0、开总中断
P4SW=0xff; //定义P4口为I/O口
P0M1=0x00;
P0M0=0xff; //定义P0为强上拉输出.
P1M1=0x00;
P1M0=0xff; //定义P1为强上拉输出.
P2M1=0x00;
P2M0=0xff; //定义P2为强上拉输出.
P3M1=0x00;
P3M0=0xff; //定义P3为强上拉输出.
for(j=0;j<32;j++) vram[j]=0x00; //显示缓冲清0
}
/****************************************************************************
函数功能:定时器中断延时程序 这一段的作用计时用,定时时间为50ms,20次中断计一秒.
入口参数:无
出口参数:无
****************************************************************************/
void timer0(void) interrupt 1
{ uchar tim1,tim2; //定义临时变量
TL0=TL0+0XB0;TH0=0X3C; //重装定时器初值,定时值50ms
tim1++; //每中断一次tim1加1
if(tim1==10) //中断10(0.5秒)
{
SHAN=!SHAN; //闪烁标志取反
tim1=0;tim2++; //tim1清零,tim2加1
if(tim2==2) //到了1秒
{
tim2=0;second++; //tim2清零,秒加1
if(second==60) //如果秒到60
{
second=0;minute++; //秒变0,分加1
if(minute==60) //如果分到60
{
minute=0;hour++; //分变0,时加1
if(hour==24) hour=0; //如果时到24,时变0
}
}
}
}
//以下部分是判断时分调整键是否按下,按下松开后加1.
if (H_KEY==0) //按下时调整键
{H_TEMP=0;}
if(H_KEY==1&H_TEMP==0) //放开时调整键
{
hour++; //时加1
if(hour==24) hour=0; //如果时等于24,时变0
H_TEMP=1;
}
if (M_KEY==0) //按下分调整键
{M_TEMP=0;}
if(M_KEY==1&M_TEMP==0) //放开分调整键.
{
second=0; minute++; //秒清零,时加1
if(minute==60) minute=0; //如果分等于60,分变0
M_TEMP=1;
}
} |
|