找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1085|回复: 0
收起左侧

单片机电子贺卡源程序与Proteus仿真原理图

[复制链接]
ID:1086564 发表于 2023-7-3 15:24 | 显示全部楼层 |阅读模式
电子贺卡仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
51hei.gif

单片机电子贺卡源程序如下:
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int  
  5. sbit SPEAK=P2^7;  //定义蜂鸣器输出端口
  6. sbit CS1=P2^4;            
  7. sbit CS2=P2^3;            
  8. sbit RS=P2^2;            
  9. sbit RW=P2^1;            
  10. sbit E=P2^0;
  11. sbit L1=P1^0;
  12. sbit L2=P1^1;

  13. uchar code HZ0[]={

  14. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  15. .................
  16. ...............
  17. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
  18. };



  19. void delayus(uchar delay)
  20. {
  21. uchar i;
  22. for(i=0;i<=delay;i++)
  23. _nop_();
  24. }

  25. void check_busy()
  26. {
  27. uchar a=0;
  28. for(a=0;a<200;a++);                  //此处为延时,一段时间后确保处于空闲状态
  29.                                       //此处为状态查询,查询忙状态,没有使用成功,以后再调试
  30. /*RW=1;
  31. RS=0;                                 
  32. E=1;
  33. while(1)
  34. {
  35.      E=1;
  36.      if(!(P0&0x80))
  37.         break;
  38.             a++;
  39.      if(a>10)
  40.                   break;
  41.             
  42. }        
  43. E=1;*/

  44. }      


  45. void write_cmd(uchar inst)
  46. {
  47. check_busy();
  48. RS=0;
  49. RW=0;
  50. E=1;
  51. P3=inst;
  52. E=0;
  53. _nop_();
  54. }



  55. void write_data(uchar dat)
  56. {
  57. check_busy();
  58. RS=1;
  59. RW=0;
  60. E=1;
  61. P3=dat;
  62. E=0;
  63. _nop_();
  64. }



  65. void LCD_Init()
  66. {
  67. write_cmd(0x30);//30H--基本指令操作?
  68. delayus(4);
  69. write_cmd(0x0c);//开显示,关光标,不闪烁。
  70. delayus(10);
  71. write_cmd(0x01);//清除显示
  72. delayus(10);
  73. write_cmd(0x06);//光标的移动方向左,DDRAM的地址计数器(AC)加1。
  74. delayus(10);
  75. }



  76. void set_xy(uchar x,uchar y)           //x为行,y为列
  77. {
  78. if(y>=64)                            //列地址大于等于64时右屏显示?
  79. {
  80.    CS2=0;                          //低电平选择
  81.         CS1=1;                            //写右屏是左屏关闭,不然两边会同时显示
  82.         y=y-64;
  83. }
  84. else                                 //列地址小于64时左屏显示
  85. {
  86.    CS1=0;                             //同上
  87.         CS2=1;
  88. }
  89. write_cmd(0x40|y);                      //写列地址
  90. _nop_();
  91. write_cmd(0xb8|x);                         //写行地址?
  92. }

  93. //显示函数
  94. void disp_hz(uchar *p)
  95. {
  96. uchar i;
  97. for(i=0;i<128;i++)
  98. {
  99. set_xy(0,i);           
  100. write_data(p[i]);         
  101. set_xy(1,i);        
  102. write_data(p[i+128]);
  103. set_xy(2,i);      
  104. write_data(p[i+256]);

  105. set_xy(3,i);      
  106. write_data(p[i+384]);

  107. set_xy(4,i);        
  108. write_data(p[i+512]);

  109. set_xy(5,i);        
  110. write_data(p[i+640]);

  111. set_xy(6,i);      
  112. write_data(p[i+768]);

  113. set_xy(7,i);        
  114. write_data(p[i+896]);

  115. set_xy(8,i);      
  116. write_data(p[i+1024]);
  117. }
  118. }
  119. void disp_zf(uchar R,uchar L,uchar *p)
  120. {
  121. uchar i;
  122. for(i=0;i<8;i++)
  123. {
  124. set_xy(2*R,8*L+i);               
  125. write_data(p[i]);
  126. set_xy(2*R+1,8*L+i);               
  127. write_data(p[i+8]);
  128. }
  129. }


  130. uchar beat,tl,th,key=0,k=0,temp; //定义节拍和T0初值变量
  131. uchar code TABLE[]={   //音符对应的定时器初值表  
  132. 0xfb,0x04,0xfb,0x90,0xfc,0x09,0xfc,0x44,  
  133. 0xfc,0xac,0xfd,0x09,0xfd,0x34,0xfd,0x82,  
  134. 0xfd,0xc8,0xfe,0x06,0xfe,0x22,0xfe,0x56,   
  135. 0xfe,0x85,0xfe,0x9a,0xfe,0xc1};  
  136. uchar code GRACE[]={   //《奇异恩典》音符码表           
  137. 0x14,0x48,0x62,0x42,0x68,0x54,0x48,0x24,0x18,  
  138. 0x14,0x48,0x62,0x42,0x68,0x54,0x8c,0x88,   
  139. 0x64,0x86,0x62,0x82,0x62,0x48,0x14,0x26,0x42,0x42,0x22,0x18,   
  140. 0x14,0x48,0x62,0x42,0x68,0x54,0x4c,0x48,0x00};  
  141. uchar code JOY[]={     //《欢乐颂》音符码表   
  142. 0x64,0x64,0x74,0x84,0x84,0x74,0x64,0x54,
  143. 0x44,0x44,0x54,0x64,0x66,0x52,0x58,0x64,
  144. 0x64,0x74,0x84,0x84,0x74,0x64,0x54,0x44,
  145. 0x44,0x54,0x64,0x56,0x42,0x48,0x54,0x54,
  146. 0x64,0x44,0x54,0x62,0x72,0x64,0x44,0x54,
  147. 0x62,0x72,0x64,0x54,0x44,0x54,0x18,0x64,
  148. 0x64,0x74,0x84,0x84,0x74,0x64,0x54,0x44,
  149. 0x44,0x54,0x64,0x56, 0x42,0x48,0x00};
  150. uchar code HAPPY[]={   //《生日快乐》音符码表  
  151. 0x82,0x01,0x81,0x94,0x84,0xB4,0xA4,0x04,  
  152. 0x82,0x01,0x81,0x94,0x84,0xC4,0xB4,0x04,   
  153. 0x82,0x01,0x81,0xF4,0xD4,0xB4,0xA4,0x94,
  154. 0xE2,0x01,0xE1,0xD4,0xB4,0xC4,0xB4,0x04,  
  155. 0x82,0x01,0x81,0x94,0x84,0xB4,0xA4,0x04,  
  156. 0x82,0x01,0x81,0x94,0x84,0xC4,0xB4,0x04,  
  157. 0x82,0x01,0x81,0xF4,0xD4,0xB4,0xA4,0x94,  
  158. 0xE2,0x01,0xE1,0xD4,0xB4,0xC4,0xB4,0x04,   
  159. 0x00};   
  160. void Timer0_Initialize();
  161. void delay_10ms();
  162. void Delay(uchar);  
  163. void Key_Scan();
  164. uint a[4]={0,1,2,3};
  165.   void main()
  166.   {  
  167.           uchar m,m1; //定义临时变量      
  168.           uchar *p[3];  
  169.           uchar beat=0;     
  170.           p[0]=GRACE;
  171.           p[1]=JOY;
  172.           p[2]=HAPPY;     
  173.           Timer0_Initialize();         
  174.       while(1)  
  175.       {         
  176.                           Key_Scan();
  177.                         if(key!=3)
  178.                                 TR0=1;
  179.                           switch(key)
  180.                                   {        
  181.                                         P1=0xff;
  182.                                         case 0:
  183.                                                         disp_hz(HZ0 );
  184.                                                         temp=key;
  185.                                                         TR0=1;
  186.                                                         while(*(p[key]+k)!=0) //判断取得的音符码是否为结束码   
  187.                                                         {   
  188.                                                                 beat=*(p[key]+k)&0x0f; //取节拍码   
  189.                                                                 m=_crol_(*(p[key]+k),4)&0x0f; //取音调码   
  190.                                                                 if(beat!=0)
  191.                                                                 {   //判断取得的音调码是否为0     {        //不是,根据取得的音调码计算T0初值      
  192.                                                                         m1=--m*2+1;     
  193.                                                                         m=m*2;     
  194.                                                                         tl=TL0=TABLE[m1];     
  195.                                                                         th=TH0=TABLE[m];     
  196.                                                                
  197.                                                                 }   
  198.                                                                 else
  199.                                                                 {       //取得的节拍码为0,则停止T0      
  200.                                                                         TR0=0;
  201.                                                                 }     
  202.                                                                   Delay(beat);   
  203.                                                                   k++;
  204.                                                                  Key_Scan();
  205.                                                                  delay_10ms();
  206.                                                                  if(temp!=key)break;                                      
  207.                                                         }
  208.                                                         TR0=0;
  209.                                                         k=0;
  210.                                                         break;
  211.                                                 
  212.                                         case 1:
  213.                                                         disp_hz(HZ1 );
  214.                                                             temp=key;
  215.                                                         TR0=1;
  216.                                                         while(*(p[key]+k)!=0) //判断取得的音符码是否为结束码   
  217.                                                         {   
  218.                                                                 beat=*(p[key]+k)&0x0f; //取节拍码   
  219.                                                                 m=_crol_(*(p[key]+k),4)&0x0f; //取音调码   
  220.                                                                 if(beat!=0)
  221.                                                                 {   //判断取得的音调码是否为0     {        //不是,根据取得的音调码计算T0初值      
  222.                                                                         m1=--m*2+1;     
  223.                                                                         m=m*2;     
  224.                                                                         tl=TL0=TABLE[m1];     
  225.                                                                         th=TH0=TABLE[m];     
  226.                                                                
  227.                                                                 }   
  228.                                                                 else
  229.                                                                 {       //取得的节拍码为0,则停止T0      
  230.                                                                         TR0=0;
  231.                                                                 }     
  232.                                                                   Delay(beat);   
  233.                                                                   k++;
  234.                                                                  Key_Scan();
  235.                                                                  delay_10ms();
  236.                                                                  if(temp!=key)break;                                      
  237.                                                         }
  238.                                                         TR0=0;
  239.                                                         k=0;
  240.                                                         break;
  241.                                                 
  242.                                         case 2:
  243.                                                         disp_hz(HZ2 );
  244.                                                         temp=key;
  245.                                                         TR0=1;
  246.                                                         while(*(p[key]+k)!=0) //判断取得的音符码是否为结束码   
  247.                                                         {   
  248.                                                                 beat=*(p[key]+k)&0x0f; //取节拍码   
  249.                                                                 m=_crol_(*(p[key]+k),4)&0x0f; //取音调码   
  250.                                                                 if(beat!=0)
  251.                                                                 {   //判断取得的音调码是否为0     {        //不是,根据取得的音调码计算T0初值      
  252.                                                                         m1=--m*2+1;     
  253.                                                                         m=m*2;     
  254.                                                                         tl=TL0=TABLE[m1];     
  255.                                                                         th=TH0=TABLE[m];     
  256.                                                                
  257.                                                                 }   
  258.                                                                 else
  259.                                                                 {       //取得的节拍码为0,则停止T0      
  260.                                                                         TR0=0;
  261.                                                                 }     
  262.                                                                   Delay(beat);   
  263.                                                                   k++;
  264.                                                                  Key_Scan();
  265.                                                                  delay_10ms();
  266.                                                                  if(temp!=key)break;                                      
  267.                                                         }
  268.                                                         TR0=0;
  269.                                                         k=0;
  270.                                                         break;
  271.                                         case 3:
  272.                                                 TR0=0;break;

  273.                                  }
  274.                         }
  275.                 }
  276.                        
  277.          
  278.          
  279.                   void Timer0_Initialize()
  280.                   {  
  281.                           EA=1;
  282.                           ET0=1;
  283.                           TMOD=0x01;  
  284.                           TR0=1;
  285.                   }  
  286.                   void timer0() interrupt 1 using 1
  287.                   {      
  288.                           TL0=tl;
  289.                           TH0=th;        //重装定时初值      
  290.                           SPEAK=~SPEAK;
  291.                   }           //蜂鸣器控制端口电平取反 }  /************************ 四分之一拍延时函数 ************************/
  292.                   void Delay_Beat()
  293.                   {  
  294.                           uint i;  
  295.                           for(i=0;i<20000;i++);
  296.                   }   
  297.                   void Delay(uchar tt)
  298.                   {  
  299.                            uchar i;  
  300.                            for(i=0;i<tt;i++)     
  301.                            Delay_Beat();  
  302.                    }
  303.                    void delay_10ms()
  304.                    {  
  305.                            int i;  
  306.                            for(i=0;i<200;i++);
  307.                    }  
  308.                    void Key_Scan()
  309.                    {   
  310.                                    uchar i,temp1;        
  311.                                         P1=0xfb;
  312.                                         for(i=0;i<=1;i++)
  313.                                         {
  314.                                                 if(L1==0)
  315.                                                 {
  316.                                                         if(i==0)
  317.                                                                 key=a[i];
  318.                                                         else
  319.                                                                 key=a[i+1];
  320.                                                                
  321.                                                 }
  322.                                                 if(L2==0)
  323.                                                 {   
  324.                                                         if(i==0)
  325.                                                                 key=a[i+1];
  326.                                                         else
  327.                                                                 key=a[i+2];
  328.                                                 }
  329.                                 
  330.                                                 delay_10ms();
  331.                                                 temp1=P1;
  332.                                                 temp1=temp1|0x03;
  333.                                                 temp1=temp1<<1;
  334.                                                 temp1=temp1|0x03;
  335.                                                 P1=temp1;
  336.                                  }
  337.                    }   

复制代码


Keil代码与Proteus仿真下载: 仿真和程序.7z (108.6 KB, 下载次数: 17)

评分

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

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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