include
#include
#include
#include
#include
#define SPEED 2000
#define TIME 1800
#define uint unsigned int
#define uchar unsigned char
#define BLKN 2 //用于点阵列扫描的595的个数
#define TOTAL 26 //待显示的字数
#define CONIO P1
uchar number;//d=0,
uchar control=0,choose,send;
uchar receive_number=3,send_number=0;
bit BUSY;
bit SMB_RW;
uchar hou=0;
uchar min=0;
uchar sec=0;
uchar sg;//时高位
uchar sd;//时低位
uchar fg;//分高位
uchar fd;//分低位
uchar mg;//秒高位
uchar md;//秒低位
sbit CLK=P1^7; //输出脉冲
sbit scyx=P1^6; //复位
sbit led=P0^7;
sbit pcf8563_scl=P0^5;//时钟频率
sbit pcf8563_sda=P0^4;//串行数据传输脚
uchar idata dispram[(BLKN/2)*32]={0};
uchar receive1[3]={0x00,0x00,0x00};//时、分、秒
uchar send1[4]={0x02,0x33,0x25,0x03};//时、分、秒、器件地址
/*********************************字模表***************************************/
uchar code Bmp[][32]={
{0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xF0,0x1C,0x18,0x38,0x1C,0x38,0x0E,0x38,0x0E,
0x78,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x1C,0x1C,0x18,0x07,0xF0,0x00,0x00,0x00,0x00},
/***数字0***/
{0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xC0,0x0F,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,
0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x0F,0xFC,0x00,0x00,0x00,0x00},
/***数字1***/
{0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xF8,0x18,0x1C,0x38,0x1C,0x18,0x1C,0x00,0x38,
0x00,0x70,0x01,0xC0,0x07,0x00,0x0C,0x06,0x3F,0xFC,0x3F,0xFC,0x00,0x00,0x00,0x00},
/***数字2***/
{0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xF0,0x38,0x38,0x38,0x1C,0x00,0x38,0x03,0xF0,
0x03,0xF0,0x00,0x1C,0x00,0x0E,0x38,0x1C,0x38,0x1C,0x0F,0xF0,0x00,0x00,0x00,0x00},
/***数字3***/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0xF0,0x01,0xF0,0x03,0x70,0x0C,0x70,
0x18,0x70,0x30,0x70,0x3F,0xFE,0x00,0x70,0x00,0x70,0x03,0xFE,0x00,0x00,0x00,0x00},
/***数字4***/
{0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xFC,0x18,0x00,0x18,0x00,0x18,0xC0,0x1F,0xF8,
0x18,0x1C,0x00,0x1E,0x10,0x0E,0x38,0x1C,0x38,0x18,0x0F,0xF0,0x00,0x00,0x00,0x00},
/***数字5***/
{0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xF8,0x0C,0x3C,0x18,0x08,0x38,0x00,0x3F,0xF8,
0x7C,0x1C,0x78,0x0E,0x38,0x0E,0x38,0x0E,0x1C,0x1C,0x07,0xF0,0x00,0x00,0x00,0x00},
/***数字6***/
{0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xFE,0x3C,0x0C,0x30,0x18,0x00,0x30,0x00,0x60,
0x00,0xC0,0x01,0xC0,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x00,0x00,0x00,0x00},
/***数字7***/
{0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xF8,0x38,0x0C,0x30,0x0E,0x3C,0x0C,0x1F,0xF8,
0x0F,0xF0,0x38,0x3C,0x30,0x0E,0x70,0x0E,0x38,0x0C,0x0F,0xF0,0x00,0x00,0x00,0x00},
/***数字8***/
{0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xF0,0x38,0x18,0x30,0x0C,0x70,0x0E,0x30,0x0E,
0x38,0x3E,0x1F,0xEE,0x00,0x1C,0x18,0x18,0x3C,0x30,0x1F,0xE0,0x00,0x00,0x00,0x00},
/***数字9***/
{0x00,0x40,0x40,0x40,0x30,0x40,0x10,0x40,0x00,0x48,0x00,0x7C,0xF0,0x40,0x10,0x40,
0x10,0x40,0x10,0x40,0x10,0x40,0x12,0x40,0x14,0x40,0x18,0x44,0x17,0xFE,0x00,0x00},//让
{0x00,0x08,0x3F,0xFC,0x21,0x08,0x21,0x08,0x21,0x08,0x3F,0xF8,0x21,0x08,0x21,0x08,
0x21,0x08,0x3F,0xF8,0x20,0x08,0x02,0x00,0x51,0x88,0x50,0x96,0x90,0x12,0x0F,0xF0},//思
{0x10,0x80,0x10,0xA0,0x20,0x94,0x21,0xFE,0x49,0x10,0xFB,0x10,0x15,0xFC,0x21,0x10,
0x41,0x10,0xFD,0xFC,0x01,0x10,0x01,0x10,0x1D,0x14,0xE1,0xFE,0x41,0x00,0x01,0x00},//维
{0x01,0x20,0x41,0x24,0x2F,0xFE,0x21,0x24,0x01,0x24,0x8F,0xFC,0x49,0x24,0x09,0x20,
0x1F,0xFE,0x29,0x22,0xE1,0x22,0x21,0x2A,0x22,0x24,0x22,0x20,0x24,0x20,0x28,0x20},//沸
{0x00,0x40,0x7A,0x48,0x49,0x50,0x4B,0xFC,0x48,0x80,0x7F,0xFE,0x49,0x10,0x4A,0x0E,
0x4D,0xF4,0x78,0x10,0x49,0x14,0x49,0xFE,0x48,0x04,0x4F,0xE4,0x88,0x14,0x18,0x08},//腾
{0x08,0x00,0x08,0x08,0x08,0xFC,0x7E,0x08,0x08,0x08,0x08,0x08,0xFE,0xF8,0x08,0x88,
0x28,0x80,0x2E,0x84,0x28,0x84,0x28,0x7C,0x28,0x00,0x58,0x06,0x8F,0xFC,0x00,0x00},//起
{0x01,0x00,0x01,0x00,0x01,0x08,0x7F,0xFC,0x01,0x00,0x21,0x10,0x19,0x30,0x09,0x44,
0xFF,0xFE,0x03,0x80,0x05,0x40,0x09,0x30,0x31,0x1E,0xC1,0x04,0x01,0x00,0x01,0x00},//来
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x0C,0x00,0x1E,0x00,0x1E,0x00,0x0C,0x00,0x04,0x00,0x08,0x00,0x10,0x00,0x00,0x00},//,
{0x00,0x40,0x40,0x40,0x30,0x40,0x10,0x40,0x00,0x48,0x00,0x7C,0xF0,0x40,0x10,0x40,
0x10,0x40,0x10,0x40,0x10,0x40,0x12,0x40,0x14,0x40,0x18,0x44,0x17,0xFE,0x00,0x00},//让
{0x20,0x00,0x22,0x04,0x3F,0x7E,0x48,0x44,0x08,0x44,0xFF,0xC4,0x10,0x44,0x14,0x7C,
0x22,0x44,0x42,0x10,0x9F,0xF8,0x10,0x10,0x1F,0xF0,0x10,0x10,0x1F,0xF0,0x10,0x10},//智
{0x08,0x20,0x7E,0xFC,0x08,0x20,0x3E,0xF8,0x08,0x20,0x7E,0xFC,0x08,0x20,0x3F,0xF8,
0x00,0x08,0xFF,0xFE,0x00,0x08,0x3F,0xF8,0x09,0x00,0x28,0xA8,0x48,0x24,0x07,0xE0},//慧
{0x08,0x08,0x0B,0xFC,0x10,0x00,0x20,0x00,0x40,0x00,0x08,0x04,0x17,0xFE,0x30,0x10,
0x50,0x10,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x50,0x10,0x20},//行
{0x00,0x40,0x08,0x40,0x7C,0x40,0x00,0x44,0x05,0xFE,0xFE,0x44,0x10,0x44,0x10,0x44,
0x20,0x44,0x24,0x44,0x42,0x84,0xFE,0x84,0x41,0x04,0x01,0x04,0x02,0x28,0x04,0x10},//动
{0x08,0x00,0x08,0x08,0x08,0xFC,0x7E,0x08,0x08,0x08,0x08,0x08,0xFE,0xF8,0x08,0x88,
0x28,0x80,0x2E,0x84,0x28,0x84,0x28,0x7C,0x28,0x00,0x58,0x06,0x8F,0xFC,0x00,0x00},//起
{0x01,0x00,0x01,0x00,0x01,0x08,0x7F,0xFC,0x01,0x00,0x21,0x10,0x19,0x30,0x09,0x44,
0xFF,0xFE,0x03,0x80,0x05,0x40,0x09,0x30,0x31,0x1E,0xC1,0x04,0x01,0x00,0x01,0x00},//来
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x3C,0x00,0x66,0x00,0x66,0x00,0x66,0x00,0x3C,0x00,0x00,0x00},//.};
uchar code Bmp1[][32]={
{0x01,0x00,0x11,0x00,0x11,0x00,0x11,0x08,0x3F,0xFC,0x21,0x00,0x41,0x00,0x41,0x00,
0x81,0x10,0x3F,0xF8,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x04,0xFF,0xFE,0x00,0x00},
{0x00,0x10,0x1F,0xF8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0xF0,
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10,0x00,0x00},
{0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x88,0x5B,0xFC,0x54,0x88,0x50,0x88,0x90,0x88,
0x10,0x88,0x1F,0xFE,0x10,0x80,0x11,0x40,0x11,0x20,0x12,0x10,0x14,0x0E,0x18,0x04},
{0x00,0x20,0x00,0xF0,0x1F,0x00,0x10,0x00,0x11,0x00,0x11,0x00,0x21,0x04,0x7F,0xFE,
0x01,0x00,0x01,0x00,0x09,0x20,0x09,0x10,0x11,0x08,0x21,0x0C,0x45,0x04,0x02,0x00},
{0x00,0x00,0x38,0x1C,0x44,0x22,0x54,0x2A,0x44,0x22,0x37,0xEC,0x08,0x10,0x10,0x08,
0x2E,0x74,0x20,0x04,0x21,0x84,0x24,0x24,0x13,0xC8,0x08,0x10,0x07,0xE0,0x00,0x00}
};
/*********************************字模表***************************************/
/************系统函数的配置***********/
void sysclk_int(void) //内部晶振
{
OSCICL=0x83;
OSCICN=0xc3; //不分频
CLKSEL=0x00;
}
/*
void delay1(uchar n) //延时程序
{
uchar j;
for(j=0;j
_nop_();
_nop_();
_nop_();
_nop_();
}
}
*/
void delay(uint i) //毫秒延时
{
register uchar j;//
for(;i;i--)
for(j=0;j<255;j++);
}
void SPI_INT(void) //SPI初始化
{
SPI0CFG=0x40;
SPI0CN=0x01; //0000 0001最后一位是SPI使能位 SPI工作在三线主方式
SPI0CKR=0x0f; //SPI 时钟频率设置为100kHz 0x63
IE &= 0xbf; //关闭SPI中断
}
void SMB_INT(void) //SMB初始化
{
SMB0CF=0x5f; //使能SMB 允许时间扩充 定时器2低字节溢出时钟源
SMB0CF|=0x80;
}
void TIME01_INT(void) //定时器初始化
{
TCON=0x10; //定时器0允许
TMOD=0x01; //定时器0在16位工作方式
CKCON &= 0xf8;
CKCON |= 0x01; //定时器0使用系统4分频
TL0=0x03;
TH0=0x03;
IE|=0x02;
}
void TIME2_INT(void) //定时器2用于配置SMB的时钟频率
{
TMR2CN=0x00;
CKCON |= 0x00;
TMR2RLL = 0xef;
TMR2RLH = 0xff;
TMR2L = 0xef;
TMR2H = 0xff;
TMR2CN |= 0x0c;
}
void TIME3_INT(void)//用于I2C的超时检测
{
TMR3CN = 0x00; //定时器3为16位自动重载
CKCON &= ~0x40;
TMR3RLL = 0xaf;
TMR3RLH = 0x57;
TMR3L = 0xaf;
TMR3H = 0x57;
EIE1|=0x00;
TMR3CN |= 0x04;
}
void pio_int(void) // 端口配置
{
XBR0=0x06;
XBR1=0x40;
P0MDIN=0xff; //禁止模拟输入,0为模拟,1为数字
P0MDOUT=0x0d; //0为开漏,1为推挽(ff)
P0SKIP=0x08;
P1MDIN=0xff;
P1MDOUT=0xff; //低四位用于138
P1SKIP=0x00;
P0=0xff;
P1=0xff;
}
/*************呈现各种显示效果的函数集****************/
//void Jump_Word(uchar a) 立即跳显示一个字或一张图案
//void M_Word(uchar a) 卷帘出显示一个字或一张图案
//void M_Words(number) 显示几个交换的字
//void UP_Run(number) 向上滚屏n个字
//void L_Removeout(number) 右入左出n个字
//void M_Black(void) 黑屏
//void R_Removeout(number) 左入右出n个字
/*****************************************************/
/****************立即跳显示一个字或一张图案***************/
void Jump_Word(uchar a)
{register uchar i,q;
for(i=0;i<32;i++)
{
for(q=0;q
//if(i%2)delay(SPEED);
}
}
/****************卷帘出显示一个字或一张图案***************/
void M_Word(uchar a)
{register uchar i,q;
for(i=0;i<32;i++)
{
for(q=0;q
if(i%2)delay(SPEED);
}
}
/****************卷帘出显示number个字***************/
void M_Words(number)
{register uchar i,q,w;
for(w=0;w
for(i=0;i<32;i++)
{
for(q=0;q
}
delay(TIME);
}
}
/****************向上滚屏number个字***************/
void UP_Run(number)
{register uchar i,j,k,q;
for(i=0;i
for(j=0;j<16;j++)
{
for(k=0;k<15;k++)
{
for(q=0;q
dispram[k*2+q*32]=dispram[(k+1)*2+q*32];
dispram[k*2+1+q*32]=dispram[(k+1)*2+1+q*32];
}
}
for(q=0;q
dispram[30+q*32]=Bmp[q+i*BLKN/2][j*2];
dispram[31+q*32]=Bmp[q+i*BLKN/2][j*2+1];
}
delay(2*SPEED);
}
delay(2*TIME);
}
}
/****************左移出显示number个字*******************/
void L_Removeout(number)
{register uchar i,j,k,l,q;
for(i=0;i
for(j=0;j<2;j++)
for(k=0;k<8;k++)
{
for(l=0;l<16;l++)
{
for(q=0;q
dispram[l*2+q*32]=dispram[l*2+q*32]<<1|dispram[l*2+1+q*32]>>7;
if(q==BLKN/2-1)
dispram[l*2+1+q*32]=dispram[l*2+1+q*32]<<1|Bmp[i][l*2+j]>>(7-k);
else
dispram[l*2+1+q*32]=dispram[l*2+1+q*32]<<1|dispram[l*2+(q+1)*32]>>7;
}
}
delay(2*SPEED);
}
}
}
/****************卷帘出黑屏***************/
void M_Black(void)
{register uchar i,q;
for(i=0;i<32;i++)
{
for(q=0;q
if(i%2)delay(SPEED);
}
}
/****************右移出显示number个字*******************/
void R_Removeout(number)
{register uchar i,j,k,l,q;
for(i=0;i
for(j=2;j>0;j--)
for(k=0;k<8;k++)
{
for(l=0;l<16;l++)
{
for(q=0;q
dispram[l*2+1+q*32]=dispram[l*2+1+q*32]>>1|dispram[l*2+q*32]<<7;
if(q==0)
dispram[l*2+q*32]=dispram[l*2+q*32]>>1|Bmp[i][l*2+j-1]<<(7-k);
else
dispram[l*2+q*32]=dispram[l*2+q*32]>>1|dispram[l*2+1+(q-1)*32]<<7;
}
}
delay(2*SPEED);
}
}
}
/*************用于时钟芯片操作的函数集****************/
//void write_pcf8563(void)写时钟芯片
//void read_pcf8563(void)读时钟芯片
/*****************************************************/
void write_pcf8563(void)
{
SPI0CN &=~0x01; //暂时关掉SPI通讯
send =0xa2; //送子器件地址
while(BUSY);
BUSY=1;
SMB_RW=0;control=5;
STA=1; //开始传送
while(BUSY);
SPI0CN |=0x01; //重新开启SPI
}
void read_pcf8563(void) //读当时的时,分,钞
{
SPI0CN &=~0x01;
send =0xa2; //送子器件地址
while(BUSY);
BUSY=1;
SMB_RW=0;
STA=1;
send=0x02;
while(!SI);
BUSY=1;
send=0xa2;
while(BUSY);
BUSY=1;
SMB_RW=1;
STA=1;
while(BUSY);
BUSY=1;
sec=receive1[2]&0x7f;//读秒
min=receive1[1]&0x7f;//读分
hou=receive1[0]&0x3f;//读时
SPI0CN |=0x01;
}
void spit_time(void)//分别计算时、分、秒的各位数字
{
sg=(int)hou/16;
sd=(int)hou%16;
fg=(int)min/16;
fd=(int)min%16;
mg=(int)sec/16;
md=(int)sec%16;
}
void dat_int(void) //数据初始化
{
scyx=1;
CLK=0;
}
void sysclk_int(void);
void delay(unsigned n);
void pio_int(void);
void SPI_INT(void);
void SMB_INT(void);
void dat_int(void);
void TIME01_INT(void);
void TIME2_INT(void);
void TIME3_INT(void);
void write_pcf8563(void);
void read_pcf8563(void);
void spit_time(void);
/**************主函数**************/
void main(void) //主程序
{
register uchar i;
PCA0MD &= ~0x40;// 关闭看门狗
sysclk_int();
OSCICN |= 0x02;
/****************初始化检测pcf8563****************/
while(!pcf8563_sda)
{
XBR1 = 0x40;
pcf8563_scl = 0;
for(i = 0; i < 255; i++);
pcf8563_scl = 1;
while(!pcf8563_scl);
for(i = 0; i < 10; i++);
XBR1 = 0x00;
}
/****************初始化检测pcf8563****************/
pio_int();
TIME01_INT();
TIME2_INT();
TIME3_INT();
SPI_INT(); //SPI0DAT是SPI的数据寄存
SMB_INT();
spit_time();
EIE1|=0x01;
EA=1;
dat_int();
led=0;
TR0=0;
delay(1000);
write_pcf8563();
while(1)
{
TR0=0;
BUSY=0;
read_pcf8563();
spit_time();
TR0=1;
//Jump_Word(sg);
//Jump_Word(sd);
//Jump_Word(fg);
//Jump_Word(fd);
//Jump_Word(md);
//M_Word(md);
M_Word(4);
delay(10*TIME);
M_Words(TOTAL);
UP_Run(TOTAL);
M_Black();
delay(10*TIME);
L_Removeout(TOTAL);
delay(3*TIME);
M_Black();
delay(10*TIME);
R_Removeout(TOTAL);
delay(3*TIME);
}//总while循环的结束
}//main函数的结束
void t0(void) interrupt 1 //定时器0的中断服务程序
{
register uchar m,n=BLKN;
TH0 = 0xfc;
TL0 = 0x18;
m = CONIO;
m = (++m)&0x0f;
for(n=0;n
SPI0DAT = dispram[30-m*2+n];//dispram[((BLKN-)n/2+1)*30-m*2-(n/2)*30+n]
while(!SPIF);
SPIF=0;
}
CONIO &= 0xf0;
CLK = 1;
CONIO |= m;
CLK = 0;
scyx=1;
}
void SMBus_ISR (void) interrupt 7
{
bit FAIL = 0;
if (ARBLOST == 0) //如果赢得总线
{
switch (SMB0CN & 0xF0) //确定中断来源
{
case 0xe0: //主发送方式下产生开始条件
SMB0DAT = send;
SMB0DAT &= 0xFE;
SMB0DAT |= SMB_RW; //对发送的数据进行处理
STA = 0;
break;
case 0xc0: //主方式下发送
if (ACK)
{
if (SMB_RW == 0)
{
if(send_number<=3)
{
if(control==0)
{
SMB0DAT = send;
send_number+=5;
}
else
{
SMB0DAT = send1[send_number];
send_number++;
}
}
else
{
send_number=0;control=0;
STO = 1;
BUSY = 0;
}
}
else {;} //BUSY=0
}
else
{
STO = 1;
STA = 1;
}
break;
case 0x80: //主方式下接收
if (receive_number-1>0) //控制接收3个数据就结束
{
receive1[receive_number-1] = SMB0DAT;
ACK = 1;
receive_number--;
}
else
{
receive1[receive_number-1] = SMB0DAT;
receive_number=3;
BUSY = 0;
ACK = 0;
STO = 1;
}
break;
default:
FAIL = 1;
break;
}
}
else //输掉总线
{
FAIL = 1;
}
if (FAIL) //SMBUS通讯失败后的处理
{
SMB0CF &= ~0x80;
SMB0CF |= 0x80;
STA = 0;
STO = 0;
ACK = 0;
BUSY = 0;
FAIL = 0;
}
SI = 0;
}
void T3_ISR() interrupt 14 //定时器3中断服务程序 用于检测SMBus是否超时
{
SMB0CF &= ~0x80;
SMB0CF |= 0x80;
TMR3CN &=~0x80;
STA = 0;
BUSY = 0;
pcf8563_scl=1;
}
怕有些地方你不知道是怎么来的,所有我就把完整的程序都给你了。你自己取出你所需要的就好了。因为不同的显示效果还是得靠住函数来实现的。
如果住函数没有写好,那么你的移动方式的函数就很难写了的。希望能给楼主一点灵感。呵呵~
我还有几种效果的,但是所有的效果都必须基于我的那种显示方式。你仔细看下,和你的是不是一样的,显示缓存,各种动画效果就是移动的控制方式了
给你借鉴一下,具体的呢还得根据你的硬件来了。
通过撰写代码来实现。
Proteus中只有5×7和8×8等LED点阵,并没有16×16LED点阵,而在实际应用中,要良好地显示一个汉字,则至少需要16×16点阵。下面我们就首先介绍使用8×8点阵构建16×16点阵的方法,并构建一块16×16LED点阵,用于本例的显示任务。
首先,从Proteus元件库中找到“MATRIX-8X8-RED”元器件,并将四块该元器件放入Proteus文档区编辑窗口中。此时需要注意,如果该元器件保持初始的位置(没有转动方向),我们要首先将其左转90°,使其水平放置,那么此时它的左面8个引脚是其行线,右边8个引脚是其列线(当然,如果你是将右转,则右边8个引脚是行线)。
然后我们将四个元器件对应的行线和列线分别进行连接,使每一条行线引脚接一行16个LED,列线也相同。并注意要将行线和列线引出一定长度的引脚,以便下面我们使用。
然后使用以下代码: