16*16点阵滚动汉字,74hc595+74hc164芯片驱动 阳极数据 阴极扫描 数据横向左高位 扫描从上到下
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include <reg51.h>
- #include <intrins.h>
- #define DATAOUT P2 //P2 use as data, you can change
- #define SPEED 13
- void ymove(char dir,unsigned char *ptr,char speed);
- void xmove(char dir,unsigned char *ptr,char n,char speed);
- void delay(unsigned int a);
- void display();
- void displaytime(char time);
- void init164();
- sbit ADATA= DATAOUT^0;
- sbit ASCK= DATAOUT^1;
- sbit LATCH= DATAOUT^2;
- sbit BDATA= DATAOUT^3;
- sbit BCLK= DATAOUT^4;
- code unsigned char xin[32]={
- 0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x38, //心
- 0x1F,0x7C,0x3F,0xFE,0x3F,0xFE,0x3F,0xFE,
- 0x1F,0xFC,0x0F,0xF8,0x07,0xF0,0x03,0xE0,
- 0x01,0xC0,0x00,0x80,0x00,0x00,0x00,0x00};
- code unsigned char zhong[32]={
- 0x01,0x00,0x01,0x00,0x01,0x04,0x7F,0xFE, //中
- 0x41,0x04,0x41,0x04,0x41,0x04,0x41,0x04,
- 0x7F,0xFC,0x41,0x04,0x01,0x00,0x01,0x00,
- 0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00};
-
- code unsigned char guo[32]={
- 0x00,0x04,0x7F,0xFE,0x40,0x24,0x5F,0xF4, //国
- 0x41,0x04,0x41,0x04,0x41,0x44,0x4F,0xE4,
- 0x41,0x04,0x41,0x44,0x41,0x24,0x41,0x04,
- 0x5F,0xF4,0x40,0x04,0x7F,0xFC,0x40,0x04};
- code unsigned char dui[32]={
- 0x7C,0x40,0x44,0x40,0x48,0x40,0x48,0x40, //队
- 0x50,0x40,0x48,0x40,0x48,0x40,0x44,0xA0,
- 0x44,0xA0,0x44,0xA0,0x69,0x10,0x51,0x10,
- 0x42,0x08,0x44,0x06,0x48,0x04,0x00,0x00};
-
- code unsigned char jia[32]={
- 0x10,0x00,0x10,0x00,0x10,0x04,0x12,0x7E, //加
- 0xFF,0x44,0x12,0x44,0x12,0x44,0x12,0x44,
- 0x12,0x44,0x22,0x44,0x22,0x44,0x22,0x44,
- 0x22,0x44,0x4A,0x7C,0x84,0x44,0x00,0x00};
- code unsigned char you[32]={
- 0x00,0x40,0x40,0x40,0x30,0x40,0x10,0x44, //油
- 0x87,0xFE,0x64,0x44,0x24,0x44,0x0C,0x44,
- 0x14,0x44,0x27,0xFC,0xE4,0x44,0x24,0x44,
- 0x24,0x44,0x24,0x44,0x27,0xFC,0x24,0x04 };
- code unsigned char gth[32]={
- 0x00,0x00,0x01,0x80,0x03,0xC0,0x03,0xC0, //!
- 0x03,0xC0,0x03,0xC0,0x03,0xC0,0x01,0x80,
- 0x01,0x80,0x01,0x80,0x00,0x00,0x01,0x80,
- 0x03,0xC0,0x01,0x80,0x00,0x00,0x00,0x00};
- unsigned char idata buffer[32];
- void main(void)
- {
- unsigned char i;
- init164();
- while(1)
- {
- for(i=0;i<32;i++)
- buffer[i]=xin[i];
- displaytime(1);
-
- xmove(1,zhong,3,SPEED);
- displaytime(1);
- ymove(1,0,SPEED);
- ymove(1,jia,SPEED);
- ymove(1,you,SPEED);
- ymove(1,0,SPEED);
- xmove(0,jia,3,SPEED);
- ymove(0,gth,SPEED);
- ymove(0,0,SPEED);
- xmove(1,xin,1,SPEED);
- }
- }
- /************* 子函数 ******************/
- void delay(unsigned int a)
- {
- while(a--);
- }
- void display()
- {
- unsigned char hang,ib,k,tmp;
- DATAOUT= 0x0;
- BDATA = 0;
- for(hang=0;hang<16;hang++)
- {
- ASCK =0;
- LATCH=0;
- BCLK =0;
- for(ib=0;ib<2;ib++)
- {
- tmp = buffer[hang*2+ib];
- for(k=0;k<8;k++)
- {
- tmp <<=1;
- ASCK =0;
- ADATA =CY;
- ASCK =1;
- }
- }
- DATAOUT|=0x14;
- //LATCH=1;
- //BCLK=1;
- BDATA=1;
- }
- delay(64);
- ASCK =0;
- ASCK =1;
- }
- void displaytime(char time)
- {
- unsigned char i;
- while(time--)
- {
- i=130;
- while(i--)
- display();
- }
- }
- void init164()
- {
- char i;
- BDATA=1;
- for(i=0;i<16;i++)
- {
- BCLK =0;
- BCLK =1;
- }
- }
- void xmove(char dir,unsigned char *ptr,char n,char speed)
- { /* 方向 n是要移动的汉字个数 移动速度*/
- unsigned char i=0, ib=0;
- unsigned int tmp=0, speedm=0;
- unsigned char buffer2[16]; //半个汉字的缓存
- n*=2; //左半字和右半字,所以要x2
- for(i=0;i<16;i++) //清零
- buffer2[i]=0;
- if(dir == 1)
- {
- /**** 向左移动 ****/
- for(n;n>0;n--)
- {
- if(ptr != 0)
- {
- tmp = n%2; //判断是左半字还是右半字
- for(i=0;i<16;i++)
- buffer2[i]=ptr[i*2+tmp];
-
- if(tmp) //tmp为1时,将地址指向下一个汉字
- ptr+=32;
- }
-
- for(tmp=8;tmp>0;tmp--) //要移动8列
- {
- ib=0;
- for(i=0;i<16;i++)
- { //要移16行,共16个字节
-
- buffer[ib] <<=1; //移第一个半字
- if(buffer[ib+1] & 0x80)
- buffer[ib]++;
- ib++;
-
- buffer[ib]<<=1; //移后半字
- if(buffer2[i] & 0x80)
- buffer[ib]++;
- ib++;
-
- buffer2[i]<<=1; //缓冲左半字向左移一位
- }
-
- speedm=speed; //更新点阵
- while(speedm--)
- display();
- }
- }
- }
- //--------------------------------------------------//
- else
- {
- /****** 向右移动 ******/
- for(n;n>0;n--)
- {
- if(ptr != 0)
- {
- tmp = (n+1) % 2 ; //判断左半字还是右半字
- for(i=0;i<16;i++)
- buffer2[i]=ptr[i*2+tmp];
-
- if(tmp == 0) //tmp为0时,将地址指向下一个汉字
- ptr+=32;
- }
-
- for(tmp=8;tmp>0;tmp--) //要移动8列
- {
- ib=0;
- for(i=0;i<16;i++)
- { //要移16行,共16个字节
-
- buffer[ib+1] >>= 1; //移右半字
- if(buffer[ib] & 0x01)
- buffer[ib+1] |=0x80 ;
-
- buffer[ib] >>= 1; //移左半字
- if(buffer2[i] & 0x01)
- buffer[ib] |= 0x80;
- ib+=2;
-
- buffer2[i] >>=1; //下个汉字的右半字向右移一位
- }
-
- speedm=speed;
- while(speedm--) //更新点阵
- display();
- }
-
- }
- }
- }
- void ymove(char dir,unsigned char *ptr, char speed)
- { //dir=1上移动,dir=0为下移动
- char i=0, j=0, ib=0;
- unsigned int tmp=0, speedm=0;
- if(dir==0)
- {
- /**** 向下移 ****/
- ib=31;
- for(i=16;i>0;i--) //下移16行
- {
- for(j=29;j>-1;j--)
- buffer[j+2]=buffer[j]; //将上一行的内容复制到下一行
-
- if(ptr==0)
- { //移空时,buffer的首行用0移入
- buffer[0]=0;
- buffer[1]=0;
- }
- else
- { //否则,处理buffer的首行元素
- buffer[1]=ptr[ib];
- buffer[0]=ptr[ib-1];
- ib=ib-2;
- }
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
16x16点阵.rar
(50.5 KB, 下载次数: 23)
|