包括原理圖 程序 仿真以及流程圖
可以通過按鍵控制點陣顯示內容的快慢和方向
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.gif (148.2 KB, 下載次數: 69)
下載附件
2022-8-4 02:17 上傳
主程序流程圖
51hei.png (10.08 KB, 下載次數: 51)
下載附件
2022-8-4 02:19 上傳
按鍵流程圖
51hei.png (13.74 KB, 下載次數: 58)
下載附件
2022-8-4 02:20 上傳
顯示流程圖
51hei.png (11.17 KB, 下載次數: 58)
下載附件
2022-8-4 02:20 上傳
單片機源程序如下:
- //宏定義
- #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)
2022-8-2 16:46 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|