找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机1602显示秒的程序

[复制链接]
ID:453720 发表于 2018-12-24 18:26 | 显示全部楼层 |阅读模式
51单片机开发板1602显示秒
  1. /*********************************************************************************
  2. * 【作    者】: 清翔电子:03
  3. * 【外部晶振】: 11.0592mhz       
  4. * 【主控芯片】: STC89C52
  5. * 【编译环境】: Keil μVisio3       
  6. * 【程序功能】:                                                                                            
  7. * 【使用说明】: 液晶1脚接1602黑色排母的1脚  如果是无背光的液晶只有14个脚 排母右边空2个位   
  8.                  请把液晶对比度电位器顺时针调制10点钟方向,请勿多调超出极限位置会损坏电位器!
  9. *  说明:免费开源,不提供源代码分析.
  10. **********************************************************************************/

  11. /*******************************************************************


  12. *                                                                         *
  13. * 描述:                                                                  *
  14. *                                                                         *
  15. *   上电后液晶屏先显示信息,接着按下S2,定时开始,再次按下              *
  16. *                                                                         *
  17. *   S2暂停,第3次按下显示累积计时,第4次按下暂停计时,任何时候按下S3*
  18. *                                                                         *
  19. *   计数清零。                                                                 *
  20. *                                                                                                        *
  21. *                                                                         *
  22. ************************************************************************/

  23. #include <reg51.h>
  24. #include <intrins.h>

  25. #define uchar unsigned char
  26. #define uint  unsigned int

  27. uchar KeyCount=0;

  28. sbit  S2 = P3^0;
  29. sbit  S3 = P3^1;

  30. sbit BEEP = P2^3;          //蜂鸣器

  31. uchar code  cdis1[ ] = {"  STOPWATCH  0  "};
  32. uchar code  cdis2[ ] = {"    QX-MCS51    "};
  33. uchar code  cdis3[ ] = {"TIME            "};

  34. uchar code  cdis4[ ] = {" BEGIN COUNT  1 "};
  35. uchar code  cdis5[ ] = {" PAUSE COUNT  2 "};
  36. uchar code  cdis6[ ] = {" BEGIN COUNT  3 "};
  37. uchar code  cdis7[ ] = {" PAUSE COUNT  4 "};
  38. uchar code  cdis8[ ] = {"                "};

  39. sbit LCD_RS = P3^5;            
  40. sbit LCD_RW = P3^6;
  41. sbit LCD_EN = P3^4;
  42. sbit dula=P2^6;
  43. sbit wela=P2^7;

  44. #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};

  45. uchar display[] =  {0x00,0x00,0x00,0x00,0x00,0x00,0x00};
  46. uchar display2[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

  47. /*********************************************************
  48. 延时函数
  49. *********************************************************/

  50. void Delay(uint num)//延时函数
  51. {
  52.   while( --num );
  53. }

  54. /*********************************************************
  55. 蜂鸣器响一声                                          
  56. **********************************************************/
  57. void beep()
  58. {
  59.     unsigned char y;
  60.     for (y=0;y<180;y++)
  61.     {
  62.       BEEP=!BEEP;                //BEEP取反
  63.           Delay(70);
  64.     }
  65.     BEEP=1;                      //关闭蜂鸣器
  66. }

  67. /*********************************************************
  68. 延时函数1
  69. *********************************************************/
  70. void delay1(int ms)
  71. {
  72.    unsigned char n;
  73.    while(ms--)
  74.    {
  75.      for(n = 0; n<250; n++)
  76.     {
  77.       _nop_();
  78.       _nop_();
  79.       _nop_();
  80.       _nop_();
  81.     }
  82.    }
  83. }

  84. /**********************************************************
  85. *                                                         *
  86. *写指令数据到LCD                                          *
  87. *RS=L,RW=L,E=高脉冲,D0-D7=指令码。                     *
  88. *                                                         *
  89. **********************************************************/
  90. void lcd_wcmd(uchar cmd)
  91. {                          
  92. //   while(lcd_busy());
  93.     LCD_RS = 0;
  94. //    LCD_RW = 0;
  95.     LCD_EN = 0;
  96.     _nop_();
  97.     _nop_();
  98.     P0 = cmd;
  99.     delayNOP();
  100.     LCD_EN = 1;
  101.     delayNOP();
  102.     LCD_EN = 0;
  103.     Delay(10);
  104. }

  105. /**********************************************************
  106. *                                                         *
  107. *写显示数据到LCD                                          *
  108. *RS=H,RW=L,E=高脉冲,D0-D7=数据。                       *
  109. *                                                         *
  110. **********************************************************/
  111. void lcd_wdat(uchar dat)
  112. {                          
  113. //   while(lcd_busy());
  114.     LCD_RS = 1;
  115. //    LCD_RW = 0;
  116.     LCD_EN = 0;
  117.     P0 = dat;
  118.     delayNOP();
  119.     LCD_EN = 1;
  120.     delayNOP();
  121.     LCD_EN = 0;
  122.     Delay(10);
  123. }

  124. /**********************************************************
  125. *                                                         *
  126. *  LCD初始化设定                                          *
  127. *                                                         *
  128. **********************************************************/
  129. void lcd_init()
  130. {   
  131.    
  132.     LCD_RW = 0;
  133.         dula=0;
  134.      wela=0;
  135.     delay1(15);   
  136.     lcd_wcmd(0x01);      //清除LCD的显示内容            
  137.     lcd_wcmd(0x38);      //16*2显示,5*7点阵,8位数据
  138.     delay1(5);
  139.     lcd_wcmd(0x38);         
  140.     delay1(5);
  141.     lcd_wcmd(0x38);         
  142.     delay1(5);

  143.     lcd_wcmd(0x0c);      //开显示,不显示光标  
  144.     delay1(5);

  145.     lcd_wcmd(0x01);      //清除LCD的显示内容
  146.     delay1(5);
  147. }

  148. /**********************************************************
  149. *                                                         *
  150. *  设定显示位置                                           *
  151. *                                                         *
  152. **********************************************************/

  153. void lcd_pos(uchar pos)
  154. {                          
  155.   lcd_wcmd(pos | 0x80);  //数据指针=80+地址变量
  156. }

  157. /********************************************************
  158. 显示函数
  159. *********************************************************/
  160. void play()
  161. {
  162.    uchar  i;
  163.    for(i=0;i<6;i++)
  164.    {
  165.     display2[i]=display[i]+0x30;  
  166.    }

  167.    display2[7]=display[6]/10+0x30;   //时单位数据处理
  168.    display2[6]=display[6]%10+0x30;
  169.    
  170.    lcd_pos(0x45);
  171.    lcd_wdat(display2[7]);   //显示时
  172.    lcd_wdat(display2[6]);
  173.    lcd_wdat(0x3a);          //显示':'
  174.   
  175.    lcd_wdat(display2[5]);   //显示分
  176.    lcd_wdat(display2[4]);
  177.    lcd_wdat(0x3a);          //显示':'

  178.    lcd_wdat(display2[3]);   //显示秒
  179.    lcd_wdat(display2[2]);
  180.    lcd_wdat(0x3a);          //显示':'

  181.    lcd_wdat(display2[1]);   //显示毫秒
  182.    lcd_wdat(display2[0]);  
  183. }

  184. /********************************************************
  185. 主函数
  186. *********************************************************/
  187. main()
  188. {
  189.    uchar m;
  190.   
  191.    TMOD=0x01;
  192.    TH0=0xdc; TL0=0x00;      //50ms定时   
  193.    EA=1; ET0=1;

  194.    lcd_init();
  195.    
  196.    lcd_pos(0x00);             //设置显示位置为第一行
  197.    for(m=0;m<16;m++)
  198.    lcd_wdat(cdis1[m]);        //显示字符

  199.    lcd_pos(0x40);             //设置显示位置为第二行
  200.    for(m=0;m<16;m++)
  201.    {
  202.     lcd_wdat(cdis2[m]);        //显示字符
  203.     delay1(60);
  204.    }

  205.    delay1(100);

  206.    lcd_pos(0x40);             //设置显示位置为第二行
  207.    for(m=0;m<16;m++)
  208.    lcd_wdat(cdis3[m]);

  209.    while(1)
  210.    {   
  211.      if(S2==0)
  212.      {
  213.            KeyCount++;          //计数
  214.        beep();
  215.            delay1(100);   
  216.      
  217.        switch (KeyCount)
  218.        {
  219.         case 1:
  220.         TR0=1;              //启动中断
  221.         lcd_pos(0x00);
  222.             for(m=0;m<16;m++)
  223.         lcd_wdat(cdis4[m]);     
  224.         break;
  225.   
  226.         case 2:
  227.         TR0=0;              //停止中断
  228.         lcd_pos(0x00);
  229.             for(m=0;m<16;m++)
  230.         lcd_wdat(cdis5[m]);     
  231.         break;
  232.       
  233.                 case 3:
  234.         TR0=1;              //启动中断
  235.         lcd_pos(0x00);
  236.             for(m=0;m<16;m++)
  237.         lcd_wdat(cdis6[m]);     
  238.         break;

  239.         case 4:
  240.         TR0=0;              //停止中断
  241.         lcd_pos(0x00);
  242.             for(m=0;m<16;m++)
  243.         lcd_wdat(cdis7[m]);     
  244.         break;
  245.      
  246.         default:  
  247.         TR0=0;                   //停止中断
  248.         break;
  249.        }
  250.      }
  251.      if(S3==0)
  252.      {
  253.            TR0=0;                     //停止中断
  254.        KeyCount=0;
  255.            for(m=0;m<8;m++)
  256.        display[m]=0x00;           //计时单元清零
  257.        lcd_pos(0x00);             //设置显示位置为第一行
  258.        for(m=0;m<16;m++)
  259.        lcd_wdat(cdis1[m]);
  260.        beep();
  261.        delay1(100);              
  262.      }

  263.      play();
  264.    }
  265. }

  266. /*********************************************************
  267. *                                                        *
  268. * Time0中断函数                                          *
  269. *                                                        *
  270. **********************************************************/
  271. void Time0(void) interrupt 1 using 0
  272. {
  273.    TH0=0xdc;               //10ms定时
  274.    TL0=0x00;

  275.    display[0]++;         //0.01S  

  276.    if(display[0]==10)
  277.    {
  278.     display[0]=0;
  279.         display[1]++;         //0.1S
  280.    }
  281.    if(display[1]==10)
  282.    {
  283.     display[1]=0;
  284.     display[2]++;         //秒个位
  285.    }
  286.    if(display[2]==10)
  287.    {
  288.     display[2]=0;
  289.     display[3]++;         //秒十位
  290.    }
  291.    if(display[3]==6)
  292.    {
  293.     display[3]=0;
  294.     display[4]++;         //分个位
  295.    }
  296.    if(display[4]==10)
  297.    {
  298.     display[4]=0;
  299.     display[5]++;         //分十位
  300.    }
  301.    if(display[5]==6)
  302.    {
  303.     display[5]=0;
  304.     display[6]++;        //时
  305.    }
  306.    if(display[6]==24)
  307.    {
  308.      display[6]=0;
  309.    }
  310. }

  311. /*********************************************************/
复制代码


1602显示秒表.rar

21.24 KB, 下载次数: 4, 下载积分: 黑币 -5

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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