找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4297|回复: 6
收起左侧

51单片机16*16点阵显示汉字程序流程图Proteus仿真图

[复制链接]
ID:723681 发表于 2022-8-2 16:50 | 显示全部楼层 |阅读模式
包括原理图 程序 仿真以及流程图
可以通过按键控制点阵显示内容的快慢和方向

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
51hei.gif

主程序流程图
51hei.png

按键流程图
51hei.png

显示流程图
51hei.png

单片机源程序如下:

  1. //宏定义
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. #define zishu 5                        //字数

  5. //包含头文件
  6. #include <reg51.h>
  7. #include <intrins.h>
  8. #include <math.h>

  9. uchar i,flag,j,k;
  10. uint X=0;
  11. uchar KEY_NUM=0;
  12. uchar speed=10;                 //初始速度
  13. bit pause=0;                 //暂停变量,为1时是暂停

  14. //管脚定义

  15. //595
  16. sbit SI=P0^6;//数据脚
  17. sbit SCK=P0^5;//上升沿时数据寄存器的数据移位。QA-->QB-->QC-->...-->QH;下降沿移位寄存器数据不变
  18. sbit RCK=P0^4;//上升沿时移位寄存器的数据进入数据存储寄存器,下降沿时存储寄存器数据不变。通常我将
  19.                                   //RCK置为低电平,当移位结束后,在RCK端产生一个正脉冲(5V时,大于几十纳秒就行了。我
  20.                                   //通常都选微秒级),更新显示数据。
  21. sbit SI0=P0^3;//
  22. sbit SCK0=P0^2;//
  23. sbit RCK0=P0^1;
  24. sbit SI1=P2^1;
  25. sbit RCK1=P2^2;
  26. sbit SCK1=P2^0;
  27. sbit SI2=P2^4;
  28. sbit RCK2=P2^5;
  29. sbit SCK2=P2^3;
  30. sbit KEY_=P3^2;                  //切换方向
  31. sbit KEY_ADD=P1^0;          //加速
  32. sbit KEY_DEC=P1^1;          //减速
  33. sbit KEY_PAUSE=P1^2;  //暂停
  34. //函数声明
  35. void Init595_l1();
  36. void Init595_l2();
  37. void Init595_c1();
  38. void Init595_c2();
  39. void Write_byte595_l1(uchar temp);
  40. void Write_byte595_l2(uchar temp);
  41. void Write_byte595_c1(uchar temp);
  42. void Write_byte595_c2(uchar temp);
  43. void delay(uint z);

  44. //汉字数组
  45. uchar code H1[]=                                                                                                //左移 逐字
  46. {
  47. 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" ",0*/
  48. 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,/*" ",1*/

  49. ^^^^^^^^^^^^省略见附件^^^^^^^
  50. };
  51. uchar code a[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
  52. uchar code b[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
  53. uchar code c[]={0x20,0x40,0x60,0x80};

  54. void T0_time() interrupt 1                 //定时器0
  55. {
  56.         TH0=0x3c;
  57.         TL0=0xb0;
  58.         if(KEY_==0)
  59.         {
  60.                 KEY_NUM++;
  61.                 if(KEY_NUM>=2)
  62.                 {
  63.                         KEY_NUM=0;
  64.                         TR0=0;
  65.                         pause=0;
  66.                         flag++;
  67.                         if(flag>=6)                  //切换模式
  68.                         {
  69.                                 flag=1;
  70.                         }
  71.                         Write_byte595_l1(0xff);
  72.                         Write_byte595_l2(0xff);
  73.                         Write_byte595_c1(0x00);
  74.                         Write_byte595_c2(0x00);
  75.                         i=1;X=0;j=0;k=0;
  76.                 }
  77.         }
  78.         if(KEY_ADD==0)                                   //加速按键
  79.         {
  80.                 speed-=2;                                   //速度变量减2(速度变量越小速度越快)
  81.                 if(speed<2)                                   //最小减到2
  82.                 speed=2;
  83.                 TR0=0;
  84.         }
  85.         if(KEY_DEC==0)                                          //减速按键
  86.         {
  87.                 speed+=2;
  88.                 if(speed>20)
  89.                 speed=20;
  90.                 TR0=0;
  91.         }
  92.         if(KEY_PAUSE==0)                                        //暂停按键
  93.         {
  94.                 pause=!pause;                                        //变量为1时进入暂停状态
  95.                 TR0=0;
  96.         }
  97. }

  98. void display()                                   //显示函数
  99. {
  100.         if(flag==1)                                                   //左移函数
  101.         {
  102.                 for(k=0;k<speed;k++)                                  //更改speed能改变速度
  103.                 {
  104.                         for(i=1;i<17;i++)                                                                                 //一个for循环,分别选中16个列
  105.                         {  
  106.                                 if(flag==1)
  107.                                 {
  108.                                         Write_byte595_l1(0xff);
  109.                                         Write_byte595_l2(0xff);
  110.                                         if(i<9)
  111.                                         {
  112.                                                 Write_byte595_c1(a[i-1]);
  113.                                                 Write_byte595_c2(0x00);
  114.                                         }
  115.                                         else
  116.                                         {
  117.                                                 Write_byte595_c2(a[i-9]);
  118.                                                 Write_byte595_c1(0x00);
  119.                                         }
  120.                                         Write_byte595_l1(H1[i*2-2+2*X]);
  121.                                         Write_byte595_l2(H1[i*2-1+2*X]);                        //显示内容
  122.                                         delay(7);
  123.                                 }
  124.                                 if(KEY_&&KEY_ADD&&KEY_DEC&&KEY_PAUSE==1) TR0=1;
  125.                         }
  126.                 }
  127.         }                                 
  128.         if(flag==2)                                                    //右移函数
  129.         {
  130.                 for(k=0;k<speed;k++)
  131.                 {  
  132.                         for(i=1;i<17;i++)                                                                                 //一个for循环,分别选中16个列
  133.                         {  
  134.                                 if(flag==2)
  135.                                 {
  136.                                         Write_byte595_l1(0xff);
  137.                                         Write_byte595_l2(0xff);
  138.                                         if(i<9)
  139.                                         {
  140.                                                 Write_byte595_c1(a[i-1]);
  141.                                                 Write_byte595_c2(0x00);
  142.                                         }
  143.                                         else
  144.                                         {
  145.                                                 Write_byte595_c2(a[i-9]);
  146.                                                 Write_byte595_c1(0x00);
  147.                                         }
  148.                                         Write_byte595_l2(H2[i*2-1-2*X+32*(zishu+1)]);                   //32乘以要显示的汉字加1
  149.                                         Write_byte595_l1(H2[i*2-2-2*X+32*(zishu+1)]);                   //32乘以要显示的汉字加1
  150.                                         delay(7);
  151.                                 }
  152.                                 if(KEY_&&KEY_ADD&&KEY_DEC&&KEY_PAUSE==1) TR0=1;
  153.                         }
  154.                 }
  155.         }                                 
  156.        
  157.         if(flag==3)                                                          // 上移函数
  158.         {
  159.                 for(k=0;k<speed;k++)
  160.                 {  
  161.                         for(i=1;i<17;i++)                                                                                 //一个for循环,分别选中16个列
  162.                         {        
  163.                                 if(flag==3)
  164.                                 {
  165.                                         Write_byte595_c1(0x00);
  166.                                         Write_byte595_c2(0x00);
  167.                                         if(i<9)
  168.                                         {
  169.                                                 Write_byte595_l1(b[i-1]);
  170.                                                 Write_byte595_l2(0xff);
  171.                                         }
  172.                                         else
  173.                                         {
  174.                                                 Write_byte595_l2(b[i-9]);
  175.                                                 Write_byte595_l1(0xff);
  176.                                         }
  177.                                         Write_byte595_c1(H3[i*2-2+2*X]);
  178.                                         Write_byte595_c2(H3[i*2-1+2*X]);
  179.                                         delay(7);
  180.                                 }
  181.                                 if(KEY_&&KEY_ADD&&KEY_DEC&&KEY_PAUSE==1) TR0=1;
  182.                         }
  183.                 }
  184.         }                                                       
  185.         if(flag==4)                                                         //下移函数
  186.         {
  187.                 for(k=0;k<speed;k++)
  188.                 {  
  189.                         for(i=1;i<17;i++)                                                                                 //一个for循环,分别选中16个列
  190.                         {        
  191.                                 if(flag==4)
  192.                                 {
  193.                                         Write_byte595_c1(0x00);
  194.                                         Write_byte595_c2(0x00);
  195.                                         if(i<9)
  196.                                         {
  197.                                                 Write_byte595_l1(b[i-1]);
  198.                                                 Write_byte595_l2(0xff);
  199.                                         }
  200.                                         else
  201.                                         {
  202.                                                 Write_byte595_l2(b[i-9]);
  203.                                                 Write_byte595_l1(0xff);
  204.                                         }
  205.                                         Write_byte595_c1(H4[i*2-2-2*X+32*(zishu+1)]);                          //32乘以要显示的汉字加1
  206.                                         Write_byte595_c2(H4[i*2-1-2*X+32*(zishu+1)]);                          //32乘以要显示的汉字加1
  207.                                         delay(7);
  208.                                 }
  209.                                 if(KEY_&&KEY_ADD&&KEY_DEC&&KEY_PAUSE==1) TR0=1;
  210.                         }
  211.                 }
  212.         }                                    
  213.        
  214.         if(pause==0)                                   //非暂停状态时,正常控制X变量加,也就是正常移动显示
  215.         {
  216.                 X++;                                                                                                                //显示左移
  217.                 if(X==16+16*zishu)                                                                                                        //16加16乘以要显示的汉字数
  218.                 X=0;                                                                                                        //从头开始
  219.         }
  220. }

  221. void dis_zhuzi()                                                          //逐字显示函数
  222. {
  223.         uchar zancun;                                                          //暂存变量
  224.         if(flag==5)                                  //逐字显示
  225.         {
  226.                 for(j=1;j<(zishu+2);j++)                                   //字数+2(加1时是正好都显示,为了显示完显示一个空格,所以此处加2)
  227.                 {
  228.                         if(pause!=0)                                                  //暂停状态时
  229.                         {
  230.                                 j=zancun;                                                  //将暂存里的数值复制给j(j的值会在上面的for循环里循环变大,在暂停状态时,不想让显示继续,所以这里会将暂停前的j值复制回来)
  231.                         }
  232.                         zancun=j;                                                           //正常显示时保存j值到暂存变量中,用于暂停后停止显示
  233.                         for(k=0;k<(speed*4);k++)                           //调速
  234.                         {  
  235.                                 for(i=1;i<17;i++)                                                                                 //一个for循环,分别选中16个列
  236.                                 {  
  237.                                         if(flag==5)
  238.                                         {
  239.                                                 Write_byte595_l1(0xff);
  240.                                                 Write_byte595_l2(0xff);
  241.                                                
  242.                                                 if(i<9)
  243.                                                 {
  244.                                                         Write_byte595_c1(a[i-1]);
  245.                                                         Write_byte595_c2(0x00);
  246.                                                 }
  247.                                                 else
  248.                                                 {
  249.                                                         Write_byte595_c2(a[i-9]);
  250.                                                         Write_byte595_c1(0x00);
  251.                                                 }
  252.                                                 Write_byte595_l1(H1[i*2-2+0x20*j]);
  253.                                                 Write_byte595_l2(H1[i*2-1+0x20*j]);                        //显示内容
  254.                                                 delay(7);
  255.                                         }
  256.                                         if(KEY_&&KEY_ADD&&KEY_DEC&&KEY_PAUSE==1) TR0=1;
  257.                                 }
  258.                         }                                       
  259.                
  260.                         Write_byte595_c1(0x00);
  261.                         Write_byte595_c2(0x00);
  262.                         Write_byte595_l1(0xff);
  263.                         Write_byte595_l2(0xff);
  264.                         delay(10);
  265.                 }
  266.        
  267.         }
  268. }

  269. //主函数
  270. void main()
  271. {
  272.         EA=1;
  273.         TMOD=0x01;
  274.         TH0=0x3c;
  275.         TL0=0xb0;
  276.         ET0=1;
  277.         TR0=1;
  278.         //595c初始化
  279.         Init595_l1();
  280.         Init595_l2();
  281.         Init595_c1();
  282.         Init595_c2();
  283.         //循环演示
  284.         while(1)          //循环
  285.         {  
  286.                 display();                 //调用显示函数
  287.                 dis_zhuzi();         //调用逐字显示函数
  288.         }
  289. }

  290. //初始化595
  291. void Init595_l1()
  292. {
  293.         flag=1;
  294.         SI=1;
  295.         SCK=0;
  296.         RCK=0;
  297. }
  298. void Init595_l2()
  299. {
  300.         SI0=1;
  301.         SCK0=0;
  302.         RCK0=0;
  303. }
  304. void Init595_c1()
  305. {
  306.         SI1=1;
  307.         SCK1=0;
  308.         RCK1=0;
  309. }
  310. void Init595_c2()
  311. {
  312.         SI2=1;
  313.         SCK2=0;
  314.         RCK2=0;
  315. }

  316. void Write_byte595_l1(uchar temp)                //写数据到595
  317. {
  318.         uchar i,data_=temp;
  319.                                                 //关闭列选
  320.         for(i=0;i<8;i++)                                //传值8位
  321.         {
  322.                 if(data_&0x01==0x01)                //判断低位为1
  323.                 {
  324.                         SI=1;                                        //数据脚就写入1
  325.                 }
  326.                 else                                                 //判断低位为0
  327.                 {
  328.                         SI=0;                                        //数据脚写入0
  329.                 }
  330.                 //产生一个上升沿
  331.                 SCK=0;
  332.                 SCK=1;
  333.                 SCK=0;
  334.                 data_>>=1;                                        //将要写入的数据右移一位
  335.         }
  336.         RCK=0;//显示数据
  337.         RCK=1;
  338.         RCK=0;
  339. }
  340. void Write_byte595_c1(uchar temp)                //写数据到595
  341. {
  342.         uchar i,data_=temp;
  343.                                                 //关闭列选
  344.         for(i=0;i<8;i++)                                //传值8位
  345.         {
  346.                 if(data_&0x01==0x01)                //判断低位为1
  347.                 {
  348.                         SI1=1;                                        //数据脚就写入1
  349.                 }
  350.                 else                                                 //判断低位为0
  351.                 {
  352.                         SI1=0;                                        //数据脚写入0
  353.                 }
  354.                 //产生一个上升沿
  355.                 SCK1=0;
  356.                 SCK1=1;
  357.                 SCK1=0;
  358.                 data_>>=1;                                        //将要写入的数据右移一位
  359.         }
  360.         RCK1=0;//显示数据
  361.         RCK1=1;
  362.         RCK1=0;
  363. }
  364. void Write_byte595_l2(uchar temp)                //写数据到595
  365. {
  366.         uchar i,data_=temp;
  367.                                                 //关闭列选
  368.         for(i=0;i<8;i++)                                //传值8位
  369.         {
  370.                 if(data_&0x01==0x01)                //判断低位为1
  371.                 {
  372.                         SI0=1;                                        //数据脚就写入1
  373.                 }
  374.                 else                                                 //判断低位为0
  375.                 {
  376.                         SI0=0;                                        //数据脚写入0
  377.                 }
  378.                 //产生一个上升沿
  379.                 SCK0=0;
  380.                 SCK0=1;
  381.                 SCK0=0;
  382.                 data_>>=1;                                        //将要写入的数据右移一位
  383.         }
  384.         RCK0=0;//显示数据
  385.         RCK0=1;
  386.         RCK0=0;
  387. }
  388. void Write_byte595_c2(uchar temp)                //写数据到595
  389. {
  390.         uchar i,data_=temp;
  391.                                                 //关闭列选
  392.         for(i=0;i<8;i++)                                //传值8位
  393.         {
  394.                 if(data_&0x01==0x01)                //判断低位为1
  395.                 {
  396.                         SI2=1;                                        //数据脚就写入1
  397.                 }
  398.                 else                                                 //判断低位为0
  399.                 {
  400.                         SI2=0;                                        //数据脚写入0
  401.                 }
  402.                 //产生一个上升沿
  403.                 SCK2=0;
  404.                 SCK2=1;
  405.                 SCK2=0;
  406.                 data_>>=1;                                        //将要写入的数据右移一位
  407.         }
  408.         RCK2=0;//显示数据
  409.         RCK2=1;
  410.         RCK2=0;
  411. }

  412. void delay(uint z)           //延时函数
  413. {
  414.         uint x,y;
  415.         for(x=z;x>0;x--)
  416.                 for(y=7;y>0;y--);
  417. }
复制代码

Keil代码与Proteus8.8 7.5仿真下载:
16点阵.zip (888.79 KB, 下载次数: 141)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:262 发表于 2022-8-4 02:24 | 显示全部楼层
好资料,51黑有你更精彩!!!
回复

使用道具 举报

ID:992298 发表于 2022-11-27 09:51 | 显示全部楼层
51有你更精彩
回复

使用道具 举报

ID:320306 发表于 2022-12-26 16:50 | 显示全部楼层
亲测能用  感谢楼主
回复

使用道具 举报

ID:1061679 发表于 2023-1-28 18:07 | 显示全部楼层

51有你更精彩
回复

使用道具 举报

ID:889178 发表于 2023-2-3 21:56 | 显示全部楼层
太好了,我一直只懂一些段码的基础东西,先收藏了,有时间慢慢学习。
回复

使用道具 举报

ID:894420 发表于 2023-4-3 14:43 | 显示全部楼层

太好了,我一直只懂一些段码的基础东西,先收藏了,有时间慢慢学习。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表