找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2239|回复: 0
打印 上一主题 下一主题
收起左侧

51单片机仿真,流水灯、数码管显示时钟、9键计算机的实现

[复制链接]
跳转到指定楼层
楼主

1. 利用proteus把所需要的器件画出来,把它们的端口引脚定义好连起来。
2. 流水灯接AT89C51的P0口,在P0口接一个上拉电阻,在P3口接一个串口控制流水灯闪烁,流水灯上面接一个PNP,控制电流。计算器按键接在P1口,用液晶模块LCD1602显示按键值,LCD1602P2口。利用74LS138译码器和74HC245连接数码管显示时钟,数码管的位选控制端接74LS138译码器的Y0-Y7,74LS138译码器的ABC引脚接P3口,负责接收输入的数据,传输给Y0-Y7,显示在数码管上。数码管的段选控制端接74HC245的B0-B7,74HC245的A0-A7接P0口,把接收到的信号传输到A0-A7,从而传输给数码管的段选控制端。
3.头文件

  1. #include<reg51.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. uchar code display1[]={0x1f,0x3f,0x5f,0x7f,0x9f,0xbf,0xdf,0xff};   //74LS138:Y0~Y7亮
  5. uchar code table1[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,0xee,0x3e,0x9c,0x7a,0x9e,0x8e};//共阴数码管编码表
  6. uchar code KEY_TABLE[]={ 0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb};//键盘表
  7. uchar code TABLE[]={'0','1','2','3','4','5','6','7','8','9'};  
  8. sbit lcdrs=P3^3;      
  9. sbit lcden=P3^2;
  10. sbit D1=P3^4;
  11. sbit A1=P3^5;
  12. sbit B1=P3^6;
  13. sbit C1=P3^7;
  14. long op1,op2,result;
  15. uchar i,tmp;
  16. uchar key;
  17. uchar opp_flag=0;
  18. char led_flag;
  19. 4.
  20. //------流水灯程序--------------------------------
  21. void delay0(uchar c)                                
  22. {
  23.    uchar a,b;
  24.    for(a=0;a<c;a++)
  25.           for(b=0;b<255;b++);
  26. }         
  27. void led_down_shift()                   //流水灯下移
  28. {           
  29.        D1=0;
  30.            tmp=0xfe;
  31.            for(i=0;i<8;i++)
  32.            {
  33.                      P0=tmp;
  34.                   delay0(500);
  35.                   tmp<<=1;
  36.            }
  37.             D1=1;
  38. }
  39. void led_up_shift()                       //流水灯上移
  40. {         
  41.        D1=0;                                           //低电平有电流通过,灯亮
  42.            tmp=0x7f;
  43.            for(i=0;i<8;i++)
  44.            {
  45.                      P0=tmp;
  46.                   delay0(500);
  47.                   tmp>>=1;
  48.            }
  49.            D1=1;
  50. }
  51. void led_mie_shift()           //8个向上灭后全亮{           
  52.        D1=0;
  53.            tmp=0xfe;
  54.            for(i=0;i<8;i++)                                 
  55.            {
  56.                      P0=~tmp;
  57.                   delay0(500);
  58.                   tmp>>=1;
  59.                   P0=0x00;                                 
  60.            }
  61.             delay0(500);
  62.                 D1=1;                                 
  63. }
  64. void comm(void) interrupt 4                   //流水灯中断
  65. {        
  66.       if(RI==1)
  67.     {
  68.            RI=0;
  69.            led_flag=SBUF;
  70.                    if(led_flag=='1')
  71.            {
  72.              led_down_shift();
  73.            }
  74.            if(led_flag=='2')
  75.            {
  76.                     led_up_shift();
  77.            }
  78.            if(led_flag=='3')
  79.            {
  80.            led_mie_shift();
  81.            }
  82.      }
  83.          else{
  84.             TI=0;
  85.         }
  86. }
  87. 5.
  88. //------------时钟程序-----------------------
  89. void delay1(uint t)                                   
  90. {
  91.         while(t--);
  92. }
  93. void display(uchar ,uchar ,uchar);
  94.        uint  count=0;
  95.        uchar h=12;
  96.        uchar m=30;
  97.        uchar s=46;
  98. void display(uchar hh,uchar mm,uchar ss)
  99. {
  100.            uchar h_s,h_g,m_s,m_g,s_s,s_g;
  101.            h_s=hh/10;
  102.            h_g=hh%10;
  103.            m_s=mm/10;
  104.               m_g=mm%10;
  105.            s_s=ss/10;
  106.            s_g=ss%10;
  107.            A1=1;                                                                 //给38译码器的引脚赋值,点亮数码管
  108.            B1=1;
  109.            C1=1;
  110.            P0=table1[h_s];
  111.            delay1(10);
  112.            A1=0;
  113.            B1=1;
  114.            C1=1;
  115.            P0=table1[h_g];
  116.            delay1(10);
  117.            A1=0;
  118.            B1=0;
  119.            C1=1;
  120.            P0=table1[m_s];
  121.            delay1(10);
  122.            A1=1;
  123.            B1=1;
  124.            C1=0;
  125.            P0=table1[m_g];
  126.            delay1(10);
  127.            A1=1;
  128.            B1=0;
  129.            C1=0;
  130.            P0=table1[s_s];
  131.            delay1(10);
  132.            A1=0;
  133.            B1=0;
  134.            C1=0;
  135.            P0=table1[s_g];
  136.            delay1(10);

  137. }
  138. void time0()interrupt 1                            //时钟中断
  139. {
  140.       TH0=(65536-50000)/256;
  141.       TL0=(65536-50000)%256;
  142.       count++;
  143.      if(count>=20)
  144.    {
  145.             count=0;
  146.      s++;
  147.      if(s>=60)
  148.     {
  149.      s=0;
  150.          m++;
  151.          if(m>=60)
  152.         {
  153.           m=0;
  154.            h++;
  155.           if(h>=24)
  156.           {
  157.            h=0;
  158.           }
  159.          }
  160.     }
  161.   }
  162. }
  163. 6.
  164. //----------计算器程序--------------------------
  165. void delay(uchar z)
  166. {
  167.    uchar y;
  168.    for(z;z>0;z--)
  169.    for(y=0;y<110;y++);
  170. }
  171. void write_com (uchar com)
  172. {   
  173.      lcdrs=0;
  174.          P2=com;
  175.          delay(5);                    
  176.          lcden=1;
  177.          delay(5);
  178.          lcden=0;                              
  179. }
  180. void write_data(uchar date)         
  181. {  
  182.          lcdrs=1;
  183.          P2=date;
  184.          delay(5);                    
  185.          lcden=1;
  186.          delay(5);
  187.          lcden=0;               
  188. }
  189. void init()
  190. {
  191.         delay(15);
  192.         lcden=0;
  193.         write_com(0x38);                //显示模式设置      
  194.         write_com(0x0e);                //显示模式设置:显示开,有光标,光标不闪烁        
  195.         write_com(0x06);               //显示模式设置:光标右移,字符不移
  196.         write_com(0x01);               //清屏幕指令
  197.         write_com(0x80+0x00);
  198.         }
  199. uchar keyscan()
  200. {
  201.            uchar temp1,temp2;
  202.         P1=0xf0;                                      //置行为0,列为1
  203.         if(P1!=0xf0)                              //有无按键被按下
  204.         {
  205.                 delay(10);
  206.                 if(P1!=0xf0)                         //语句为真 则有按键被按下
  207.                 {
  208.                   temp1=P1;                            //读入列值        
  209.                   P1=0x0f;                            //列 0, 行 1
  210.                   delay(3);
  211.                   temp2=P1;                                 //读入行值
  212.                   key=temp1|temp2;
  213.                   while(P1!=0x0f);
  214.                 return key;
  215.                 }
  216.         }
  217.         return 0xff;        
  218. }
  219. uchar key_dis()
  220. {
  221.      key=keyscan();
  222.      switch(key)
  223.          {
  224.          case  0xbb: write_data('+');return '+';
  225.          case  0x7b: write_data('-');return '-';
  226.          case  0xe7: write_data('*');return '*';
  227.          case  0xd7: write_data('/');return '/';
  228.          case  0xb7: write_com(0x80+0x40); write_data('=');return '=';
  229.          case  0x77: write_com(0x01);opp_flag = 0;op1 = 0;op2 = 0;result=0;;break;// 屏幕清零      
  230.          default:  break;
  231.          }
  232.          for(i=0;i<10;i++)
  233.          {
  234.            if(key==KEY_TABLE[ i])
  235. {
  236. write_data(TABLE[ i]);
  237.                         return i;
  238.            }
  239.          }
  240.          return 0xff;
  241.    }
  242. void sum()
  243. {
  244.    uchar k=0;
  245.    uchar arr[9];
  246.    uchar n;
  247.    key=key_dis();
  248.    if((key=='+')||(key=='-')||(key=='*')||(key=='/'))
  249.         {
  250.                 op2=op1;                                                                                               
  251.                 op1=0;
  252.                 opp_flag=key;
  253.         }
  254.    if((key >=0) && (key <= 9))
  255.    {
  256.       op1=op1*10+key;
  257.    }
  258.    if(key== '=')
  259.    {
  260.     write_com(0x80+0x41);
  261.         switch(opp_flag)
  262.         {
  263.             case '+':result=op2+op1; break;
  264.                 case '-':result=op2-op1; break;
  265.                 case '*':result=op2*op1;break;
  266.             case '/':result=op2/op1;break;
  267.                 default:result=0;break;
  268.         }
  269.           for(k=0;k<9;k++)
  270.           {        
  271.           arr[k]=result%10;                                         
  272.           result=result/10;
  273.           if(result==0)
  274.           break;
  275.           }
  276.           if(k==0)
  277.           {
  278.                    write_data(TABLE[arr[k]]);
  279.           }
  280.           else
  281.           {        k=k+1;
  282.            for(n=k;n>0;n--)
  283.            write_data(TABLE[arr[n-1]]);
  284.           }
  285.    }
  286. }
  287. 7.
  288. //------------main方法-------------------------
  289. void main()
  290. {
  291.       TMOD=0X21;                                        //设置定时器0为工作方式1
  292.       SM0=0;
  293.       SM1=1;
  294.       REN=1;
  295.       PCON=0;
  296.       TH1=0XFD;
  297.       TL1=0XFD;
  298.       TR1=1;                                                //打开定时/计数器
  299.       EA=1;                                                //打开总中断
  300.       ES=1;                                                 //串行口中断控制位,为1允许串行口中断
  301.       TH0=(65536-50000)/256;
  302.       TL0=(65536-50000)%256;
  303.       ET0=1;                        //定时/计数器T0中断控制位,等于1允许中断
  304.       TR0=1;                        //定时/计数器打开
  305.           init();
  306.           delay0(5);
  307.      while(1)
  308.    {
  309.              display(h,m,s);
  310.            sum();
  311.    }
  312. }  
复制代码


评分

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

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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