包括原理图 程序 仿真以及流程图
可以通过按键控制点阵显示内容的快慢和方向
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
主程序流程图
按键流程图
显示流程图
单片机源程序如下:
- //宏定义
- #define uchar unsigned char
- #define uint unsigned int
- #define zishu 5 //字数
- //包含头文件
- #include <reg51.h>
- #include <intrins.h>
- #include <math.h>
- uchar i,flag,j,k;
- uint X=0;
- uchar KEY_NUM=0;
- uchar speed=10; //初始速度
- bit pause=0; //暂停变量,为1时是暂停
- //管脚定义
- //595
- sbit SI=P0^6;//数据脚
- sbit SCK=P0^5;//上升沿时数据寄存器的数据移位。QA-->QB-->QC-->...-->QH;下降沿移位寄存器数据不变
- sbit RCK=P0^4;//上升沿时移位寄存器的数据进入数据存储寄存器,下降沿时存储寄存器数据不变。通常我将
- //RCK置为低电平,当移位结束后,在RCK端产生一个正脉冲(5V时,大于几十纳秒就行了。我
- //通常都选微秒级),更新显示数据。
- sbit SI0=P0^3;//
- sbit SCK0=P0^2;//
- sbit RCK0=P0^1;
- sbit SI1=P2^1;
- sbit RCK1=P2^2;
- sbit SCK1=P2^0;
- sbit SI2=P2^4;
- sbit RCK2=P2^5;
- sbit SCK2=P2^3;
- sbit KEY_=P3^2; //切换方向
- sbit KEY_ADD=P1^0; //加速
- sbit KEY_DEC=P1^1; //减速
- sbit KEY_PAUSE=P1^2; //暂停
- //函数声明
- void Init595_l1();
- void Init595_l2();
- void Init595_c1();
- void Init595_c2();
- void Write_byte595_l1(uchar temp);
- void Write_byte595_l2(uchar temp);
- void Write_byte595_c1(uchar temp);
- void Write_byte595_c2(uchar temp);
- void delay(uint z);
- //汉字数组
- uchar code H1[]= //左移 逐字
- {
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" ",0*/
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" ",1*/
- ^^^^^^^^^^^^省略见附件^^^^^^^
- };
- uchar code a[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
- uchar code b[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
- uchar code c[]={0x20,0x40,0x60,0x80};
- void T0_time() interrupt 1 //定时器0
- {
- TH0=0x3c;
- TL0=0xb0;
- if(KEY_==0)
- {
- KEY_NUM++;
- if(KEY_NUM>=2)
- {
- KEY_NUM=0;
- TR0=0;
- pause=0;
- flag++;
- if(flag>=6) //切换模式
- {
- flag=1;
- }
- Write_byte595_l1(0xff);
- Write_byte595_l2(0xff);
- Write_byte595_c1(0x00);
- Write_byte595_c2(0x00);
- i=1;X=0;j=0;k=0;
- }
- }
- if(KEY_ADD==0) //加速按键
- {
- speed-=2; //速度变量减2(速度变量越小速度越快)
- if(speed<2) //最小减到2
- speed=2;
- TR0=0;
- }
- if(KEY_DEC==0) //减速按键
- {
- speed+=2;
- if(speed>20)
- speed=20;
- TR0=0;
- }
- if(KEY_PAUSE==0) //暂停按键
- {
- pause=!pause; //变量为1时进入暂停状态
- TR0=0;
- }
- }
- void display() //显示函数
- {
- if(flag==1) //左移函数
- {
- for(k=0;k<speed;k++) //更改speed能改变速度
- {
- for(i=1;i<17;i++) //一个for循环,分别选中16个列
- {
- if(flag==1)
- {
- Write_byte595_l1(0xff);
- Write_byte595_l2(0xff);
- if(i<9)
- {
- Write_byte595_c1(a[i-1]);
- Write_byte595_c2(0x00);
- }
- else
- {
- Write_byte595_c2(a[i-9]);
- Write_byte595_c1(0x00);
- }
- Write_byte595_l1(H1[i*2-2+2*X]);
- Write_byte595_l2(H1[i*2-1+2*X]); //显示内容
- delay(7);
- }
- if(KEY_&&KEY_ADD&&KEY_DEC&&KEY_PAUSE==1) TR0=1;
- }
- }
- }
- if(flag==2) //右移函数
- {
- for(k=0;k<speed;k++)
- {
- for(i=1;i<17;i++) //一个for循环,分别选中16个列
- {
- if(flag==2)
- {
- Write_byte595_l1(0xff);
- Write_byte595_l2(0xff);
- if(i<9)
- {
- Write_byte595_c1(a[i-1]);
- Write_byte595_c2(0x00);
- }
- else
- {
- Write_byte595_c2(a[i-9]);
- Write_byte595_c1(0x00);
- }
- Write_byte595_l2(H2[i*2-1-2*X+32*(zishu+1)]); //32乘以要显示的汉字加1
- Write_byte595_l1(H2[i*2-2-2*X+32*(zishu+1)]); //32乘以要显示的汉字加1
- delay(7);
- }
- if(KEY_&&KEY_ADD&&KEY_DEC&&KEY_PAUSE==1) TR0=1;
- }
- }
- }
-
- if(flag==3) // 上移函数
- {
- for(k=0;k<speed;k++)
- {
- for(i=1;i<17;i++) //一个for循环,分别选中16个列
- {
- if(flag==3)
- {
- Write_byte595_c1(0x00);
- Write_byte595_c2(0x00);
- if(i<9)
- {
- Write_byte595_l1(b[i-1]);
- Write_byte595_l2(0xff);
- }
- else
- {
- Write_byte595_l2(b[i-9]);
- Write_byte595_l1(0xff);
- }
- Write_byte595_c1(H3[i*2-2+2*X]);
- Write_byte595_c2(H3[i*2-1+2*X]);
- delay(7);
- }
- if(KEY_&&KEY_ADD&&KEY_DEC&&KEY_PAUSE==1) TR0=1;
- }
- }
- }
- if(flag==4) //下移函数
- {
- for(k=0;k<speed;k++)
- {
- for(i=1;i<17;i++) //一个for循环,分别选中16个列
- {
- if(flag==4)
- {
- Write_byte595_c1(0x00);
- Write_byte595_c2(0x00);
- if(i<9)
- {
- Write_byte595_l1(b[i-1]);
- Write_byte595_l2(0xff);
- }
- else
- {
- Write_byte595_l2(b[i-9]);
- Write_byte595_l1(0xff);
- }
- Write_byte595_c1(H4[i*2-2-2*X+32*(zishu+1)]); //32乘以要显示的汉字加1
- Write_byte595_c2(H4[i*2-1-2*X+32*(zishu+1)]); //32乘以要显示的汉字加1
- delay(7);
- }
- if(KEY_&&KEY_ADD&&KEY_DEC&&KEY_PAUSE==1) TR0=1;
- }
- }
- }
-
- if(pause==0) //非暂停状态时,正常控制X变量加,也就是正常移动显示
- {
- X++; //显示左移
- if(X==16+16*zishu) //16加16乘以要显示的汉字数
- X=0; //从头开始
- }
- }
- void dis_zhuzi() //逐字显示函数
- {
- uchar zancun; //暂存变量
- if(flag==5) //逐字显示
- {
- for(j=1;j<(zishu+2);j++) //字数+2(加1时是正好都显示,为了显示完显示一个空格,所以此处加2)
- {
- if(pause!=0) //暂停状态时
- {
- j=zancun; //将暂存里的数值复制给j(j的值会在上面的for循环里循环变大,在暂停状态时,不想让显示继续,所以这里会将暂停前的j值复制回来)
- }
- zancun=j; //正常显示时保存j值到暂存变量中,用于暂停后停止显示
- for(k=0;k<(speed*4);k++) //调速
- {
- for(i=1;i<17;i++) //一个for循环,分别选中16个列
- {
- if(flag==5)
- {
- Write_byte595_l1(0xff);
- Write_byte595_l2(0xff);
-
- if(i<9)
- {
- Write_byte595_c1(a[i-1]);
- Write_byte595_c2(0x00);
- }
- else
- {
- Write_byte595_c2(a[i-9]);
- Write_byte595_c1(0x00);
- }
- Write_byte595_l1(H1[i*2-2+0x20*j]);
- Write_byte595_l2(H1[i*2-1+0x20*j]); //显示内容
- delay(7);
- }
- if(KEY_&&KEY_ADD&&KEY_DEC&&KEY_PAUSE==1) TR0=1;
- }
- }
-
- Write_byte595_c1(0x00);
- Write_byte595_c2(0x00);
- Write_byte595_l1(0xff);
- Write_byte595_l2(0xff);
- delay(10);
- }
-
- }
- }
- //主函数
- void main()
- {
- EA=1;
- TMOD=0x01;
- TH0=0x3c;
- TL0=0xb0;
- ET0=1;
- TR0=1;
- //595c初始化
- Init595_l1();
- Init595_l2();
- Init595_c1();
- Init595_c2();
- //循环演示
- while(1) //循环
- {
- display(); //调用显示函数
- dis_zhuzi(); //调用逐字显示函数
- }
- }
- //初始化595
- void Init595_l1()
- {
- flag=1;
- SI=1;
- SCK=0;
- RCK=0;
- }
- void Init595_l2()
- {
- SI0=1;
- SCK0=0;
- RCK0=0;
- }
- void Init595_c1()
- {
- SI1=1;
- SCK1=0;
- RCK1=0;
- }
- void Init595_c2()
- {
- SI2=1;
- SCK2=0;
- RCK2=0;
- }
- void Write_byte595_l1(uchar temp) //写数据到595
- {
- uchar i,data_=temp;
- //关闭列选
- for(i=0;i<8;i++) //传值8位
- {
- if(data_&0x01==0x01) //判断低位为1
- {
- SI=1; //数据脚就写入1
- }
- else //判断低位为0
- {
- SI=0; //数据脚写入0
- }
- //产生一个上升沿
- SCK=0;
- SCK=1;
- SCK=0;
- data_>>=1; //将要写入的数据右移一位
- }
- RCK=0;//显示数据
- RCK=1;
- RCK=0;
- }
- void Write_byte595_c1(uchar temp) //写数据到595
- {
- uchar i,data_=temp;
- //关闭列选
- for(i=0;i<8;i++) //传值8位
- {
- if(data_&0x01==0x01) //判断低位为1
- {
- SI1=1; //数据脚就写入1
- }
- else //判断低位为0
- {
- SI1=0; //数据脚写入0
- }
- //产生一个上升沿
- SCK1=0;
- SCK1=1;
- SCK1=0;
- data_>>=1; //将要写入的数据右移一位
- }
- RCK1=0;//显示数据
- RCK1=1;
- RCK1=0;
- }
- void Write_byte595_l2(uchar temp) //写数据到595
- {
- uchar i,data_=temp;
- //关闭列选
- for(i=0;i<8;i++) //传值8位
- {
- if(data_&0x01==0x01) //判断低位为1
- {
- SI0=1; //数据脚就写入1
- }
- else //判断低位为0
- {
- SI0=0; //数据脚写入0
- }
- //产生一个上升沿
- SCK0=0;
- SCK0=1;
- SCK0=0;
- data_>>=1; //将要写入的数据右移一位
- }
- RCK0=0;//显示数据
- RCK0=1;
- RCK0=0;
- }
- void Write_byte595_c2(uchar temp) //写数据到595
- {
- uchar i,data_=temp;
- //关闭列选
- for(i=0;i<8;i++) //传值8位
- {
- if(data_&0x01==0x01) //判断低位为1
- {
- SI2=1; //数据脚就写入1
- }
- else //判断低位为0
- {
- SI2=0; //数据脚写入0
- }
- //产生一个上升沿
- SCK2=0;
- SCK2=1;
- SCK2=0;
- data_>>=1; //将要写入的数据右移一位
- }
- RCK2=0;//显示数据
- RCK2=1;
- RCK2=0;
- }
- void delay(uint z) //延时函数
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=7;y>0;y--);
- }
复制代码
Keil代码与Proteus8.8 7.5仿真下载:
16点阵.zip
(888.79 KB, 下载次数: 147)
|