找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1730|回复: 1
收起左侧

单片机16x16点阵显示汉字程序 左右移动,可快慢,暂停

[复制链接]
ID:412177 发表于 2022-11-21 11:53 | 显示全部楼层 |阅读模式
  1. #include<reg52.h>
  2. #define uint                 unsigned int
  3. #define u16                 unsigned int
  4. #define uchar         unsigned char
  5. #define u8                         unsigned char
  6. sbit H_stcp                          =         P2^6;                //输出时钟线
  7. sbit H_shcp                          =         P2^7;   //HC595芯片输入时钟线
  8. sbit H_ds                            =         P2^5;                //数据线

  9. sbit HC138_A0                 =         P2^0;        //
  10. sbit HC138_A1                 =         P2^1;        //
  11. sbit HC138_A2                 =         P2^2;        //
  12. sbit HC138_A3                 =         P2^3;        //


  13. u16 volatile W_BCNT;                //显示字标志
  14. u8 volatile W_LCNT;                //显示位移标志
  15. u8 speed=5;                //移动速度

  16. #define WORDNUM   8
  17. unsigned char code Word[WORDNUM][32] = {
  18. {0x00,0x00,0x31,0x2A,0x24,0x20,0x2F,0x20,0xE6,0x11,0x08,0xC4,0x3F,0x10,0x08,0x04,
  19. 0x00,0x06,0x88,0x00,0x07,0x01,0xC1,0x21,0x4D,0x11,0x81,0x01,0xEE,0x00,0x0C,0x02},/*"您",3*/

  20. {0x00,0x02,0x02,0x22,0x22,0x2A,0x26,0x22,0x63,0xA2,0x26,0x2A,0x22,0x22,0x02,0x02,
  21. 0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0xFF,0x20,0x20,0x20,0x20,0x20,0x20,0x00},/*"辛",4*/

  22. {0x00,0x21,0x21,0x21,0x21,0xF9,0x21,0x21,0x2F,0x21,0x21,0xF9,0x21,0x21,0x21,0x21,
  23. 0x00,0x00,0x00,0x00,0x3F,0x22,0x22,0x22,0xE2,0x22,0x22,0x22,0x3F,0x00,0x00,0x00},/*"苦",5*/

  24. {0x00,0x00,0x00,0x40,0x60,0x50,0x48,0x44,0x47,0x40,0x40,0x40,0x40,0x40,0x40,0x00,
  25. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x01,0x02,0x00,0x00,0x00,0x00,0x00},/*"了",6*/

  26. /*--  文字:  军  --*/
  27. /*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
  28. {0x00,0x00,0x78,0x44,0x4B,0x70,0x49,0x44,0x00,0x07,0x34,0x2F,0xE4,0x37,0x08,0x04,
  29. 0x00,0x10,0x90,0x90,0xFF,0x90,0x90,0x50,0x00,0xFF,0x91,0xFC,0x90,0xF8,0x06,0x01},

  30. /*--  文字:  放  --*/
  31. /*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
  32. {0x00,0x08,0x08,0x0F,0x08,0x08,0xE8,0x1B,0x04,0x12,0x13,0x12,0x52,0x9F,0x10,0x10,
  33. 0x00,0x01,0x02,0x84,0x68,0x10,0x68,0x84,0x02,0x01,0xFC,0x02,0x04,0xF0,0x0C,0x02},

  34. {0x00,0x60,0x50,0x44,0x44,0x44,0x44,0x44,0x45,0x5C,0x46,0x45,0x44,0x44,0x60,0x10,
  35. 0x00,0x08,0x08,0x48,0x48,0x48,0x48,0x48,0xFF,0x48,0x48,0x48,0xC8,0x48,0x08,0x08},





  36. {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,
  37. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCC,0x00,0x00,0x00},/*"!",7*/






  38. };


  39. unsigned char  WordTemp[32] = {
  40. 0x01,0x01,0x61,0x71,0x19,0x0D,0x05,0xFF,0xFF,0x01,0x7D,0x7C,0x44,0x47,0x47,0x40,
  41. 0x02,0x06,0x0C,0x18,0x70,0xE4,0x86,0xFF,0xFF,0x00,0x7C,0x7E,0x43,0xC3,0xC2,0x00,
  42. };

  43. /*************************/
  44. //延时函数
  45. /*************************/
  46. void delay_ms(uint xms)
  47. {
  48.     uint i, j;
  49.     for(i = xms; i > 0; i--)
  50.             for(j = 118; j > 0; j--);
  51. }

  52. #define HC595_QA        0x80
  53. #define HC595_QB        0x20
  54. #define HC595_QC        0x04
  55. #define HC595_QD        0x01
  56. #define HC595_QE        0x10
  57. #define HC595_QF        0x40
  58. #define HC595_QG        0x02
  59. #define HC595_QH        0x08
  60. void sendbyte_All(u8 group1,u8 group2)      //利用HC595输出
  61. {
  62.         u8 z;
  63.         for(z = 0; z < 8; z++)                 //循环8次移入数据
  64.         {
  65.                 H_shcp = 0;
  66.                 switch(z)
  67.                 {
  68.                         case 0:H_ds = group2 & HC595_QH;break;
  69.                         case 1:H_ds = group2 & HC595_QG;break;
  70.                         case 2:H_ds = group2 & HC595_QF;break;
  71.                         case 3:H_ds = group2 & HC595_QE;break;
  72.                         case 4:H_ds = group2 & HC595_QD;break;
  73.                         case 5:H_ds = group2 & HC595_QC;break;
  74.                         case 6:H_ds = group2 & HC595_QB;break;
  75.                         case 7:H_ds = group2 & HC595_QA;break;
  76.                 }
  77.                 H_shcp = 1;              //上升沿输入数据
  78.         }
  79.         for(z = 0; z < 8; z++)                 //循环8次移入数据
  80.         {
  81.                 H_shcp = 0;
  82.                 switch(z)
  83.                 {
  84.                         case 0:H_ds = group1 & HC595_QH;break;
  85.                         case 1:H_ds = group1 & HC595_QG;break;
  86.                         case 2:H_ds = group1 & HC595_QF;break;
  87.                         case 3:H_ds = group1 & HC595_QE;break;
  88.                         case 4:H_ds = group1 & HC595_QD;break;
  89.                         case 5:H_ds = group1 & HC595_QC;break;
  90.                         case 6:H_ds = group1 & HC595_QB;break;
  91.                         case 7:H_ds = group1 & HC595_QA;break;
  92.                 }
  93.                 H_shcp = 1;              //上升沿输入数据
  94.         }

  95.         H_stcp = 0;
  96.         H_stcp = 1;                //上升沿使数据并行输出
  97. }
  98. void HC138Out(u8 i,u8 l)
  99. {
  100.         u8 j;
  101.         switch(i)
  102.         {
  103.                 case  7:j=5;break;
  104.                 case  6:j=2;break;
  105.                 case  5:j=1;break;
  106.                 case  4:j=7;break;
  107.                 case  3:j=0;break;
  108.                 case  2:j=6;break;
  109.                 case  1:j=4;break;
  110.                 case  0:j=3;break;
  111.         }
  112.         HC138_A0 = j&0x01;
  113.         HC138_A1 = j&0x02;
  114.         HC138_A2 = j&0x04;
  115.         if(l)
  116.                 HC138_A3=0;
  117.         else
  118.                 HC138_A3=1;
  119. }

  120. void WordDisplay(u8 *word)
  121. {
  122.         uchar i;
  123.         for(i = 0; i < 8; i++)  
  124.         {  
  125.                 sendbyte_All(0,0); //消影
  126.                 HC138Out(i,0);
  127.                 sendbyte_All(*(word+i),*(word+i+8)); //输出信息
  128.         }
  129.         for(i = 0; i < 8; i++)  
  130.         {  
  131.                 sendbyte_All(0,0); //消影
  132.                 HC138Out(i,1);
  133.                 sendbyte_All(*(word+i+16),*(word+i+24)); //输出信息
  134.         }
  135. }

  136. /*********************定时器0、定时器1初始化******************/
  137. void time0_init()         
  138. {
  139.         TMOD = 0x01;                    //设置定时器0为工作模式1 (16-bit)
  140.         TL0 = 15536;                    //给定时器低位赋初始值                65536-15536=50000us=50ms,即50ms一个中断
  141.         TH0 = 15536 >> 8;               //给定时器高位赋初始值
  142.         TR0 = 1;                        //开启定时器0
  143.         ET0 = 1;                        //允许定时器0中断
  144.         EA = 1;                         //开启全局中断
  145. }

  146. //按键
  147. sbit Key1=P1^3;                                 //设置键
  148. sbit Key2=P1^4;                                 //加按键
  149. sbit Key3=P3^2;                                 //减按键
  150. sbit Key4=P3^3;                                 //交通管制键
  151. //========================================================================
  152. // 函数: u8 Key_Scan()
  153. // 应用: temp=u8 Key_Scan();
  154. // 描述: 按键扫描并返回按下的键值
  155. // 参数: NONE
  156. // 返回: 按下的键值
  157. // 版本: VER1.0
  158. // 日期: 2015-05-29
  159. // 备注: 该函数带松手检测,按下键返回一次键值后返回0,直至第二次按键按下
  160. //========================================================================
  161. u8 Key_Scan()
  162. {         
  163.         static u8 key_up=1;//按键按松开标志
  164.         if(key_up&&(Key1==0||Key2==0||Key3==0||Key4==0))
  165.         {
  166.                 delay_ms(10);//去抖动
  167.                 key_up=0;
  168.                 if(Key1==0)                        return 1;
  169.                 else if(Key2==0)return 2;
  170.                 else if(Key3==0)return 3;
  171.                 else if(Key4==0)return 4;
  172.         }
  173.         else if(Key1==1&&Key2==1&&Key3==1&&Key4==1)
  174.                 key_up=1;            
  175.          return 0;// 无按键按下
  176. }

  177. void main()
  178. {
  179.         uchar key_can;         //按键值
  180.         uchar mode=0;         //模式
  181.         uchar modej=0;         //模式
  182.         uchar i;
  183.         time0_init();
  184.         while(1)
  185.         {
  186.                 key_can=Key_Scan();
  187.                 if(1==key_can)
  188.                 {
  189.                         TR0 = 1;              //开启定时器0
  190.                         if(modej)                                                        //判断暂停标志,此处处理是为了防止暂停再启动方向会变
  191.                         {
  192.                                 modej=0;                                
  193.                                 mode++;
  194.                                 if(mode>=2)
  195.                                 {
  196.                                         mode=0;
  197.                                 }
  198.                         }
  199.                         mode++;
  200.                         if(mode>=2)
  201.                         {
  202.                                 mode=0;
  203.                         }
  204.                 }
  205.                 if(2==key_can)
  206.                 {
  207.                         TR0 = 0;              //关闭定时器0,暂停
  208.                         modej=1;                                                        //暂停标志
  209.                 }
  210.                 if(4==key_can)
  211.                 {
  212.                         speed+=1;                                                        //速度加1
  213.                 }
  214.                 if(3==key_can)
  215.                 {
  216.                         speed-=1;                                                        //速度减1
  217.                         if(speed==0)
  218.                                 speed=1;
  219.                 }
  220.                 if(1==mode)//往右移
  221.                 {
  222.                         for(i = 0; i < 16-W_LCNT; i++)  
  223.                         {
  224.                                 WordTemp[i]=Word[W_BCNT][i+W_LCNT];
  225.                         };
  226.                         for(i = 0; i <W_LCNT ; i++)  
  227.                         {
  228.                                 WordTemp[i+16-W_LCNT]=Word[W_BCNT+1][i];
  229.                         };
  230.                         for(i = 16; i < 32-W_LCNT; i++)  
  231.                         {
  232.                                 WordTemp[i]=Word[W_BCNT][i+W_LCNT];
  233.                         };
  234.                         for(i = 16; i <16+W_LCNT ; i++)  
  235.                         {
  236.                                 WordTemp[i+16-W_LCNT]=Word[W_BCNT+1][i];
  237.                         };
  238.                 }
  239.                         
  240.                 if(0==mode)//往左移
  241.                 {
  242.                         for(i = 0; i < 16-W_LCNT; i++)  
  243.                         {
  244.                                 WordTemp[i+W_LCNT]=Word[W_BCNT][i];
  245.                         };
  246.                         for(i = 0; i < W_LCNT ; i++)  
  247.                         {
  248.                                 WordTemp[i]=Word[W_BCNT+1][16-W_LCNT+i];
  249.                         };
  250.                         for(i = 16; i < 32-W_LCNT; i++)  
  251.                         {
  252.                                 WordTemp[i+W_LCNT]=Word[W_BCNT][i];
  253.                         };
  254.                         for(i = 16; i <16+W_LCNT ; i++)  
  255.                         {
  256.                                 WordTemp[i]=Word[W_BCNT+1][16-W_LCNT+i];
  257.                         };
  258.                 }
  259.                 WordDisplay(WordTemp);
  260.         }
  261. }

  262. /*********************定时器0中断服务程序************************/
  263. void time0_int() interrupt 1  
  264. {                                                   
  265.         static uchar volatile value;                         //定时10ms中断一次
  266.         TL0 = 15536;                    //给定时器低位重装初始值                65536-15536=50000us=50ms,即50ms一个中断
  267.         TH0 = 15536 >> 8;               //给定时器高位重装初始值
  268.         value ++;
  269.         if(value >= speed)
  270.         {
  271.                 value = 0;
  272.                 W_LCNT++;
  273.                 if(W_LCNT >= 16)
  274.                 {
  275.                         W_LCNT=0;
  276.                         W_BCNT++;
  277.                         if(W_BCNT >= (WORDNUM-1))
  278.                         {
  279.                                 W_BCNT=0;
  280.                         }
  281.                 }
  282.                
  283.         }
  284. }
复制代码
回复

使用道具 举报

ID:262 发表于 2022-11-21 15:18 | 显示全部楼层
电路是如何连接的?楼主能介绍一下吗?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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