找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3117|回复: 2
收起左侧

用51单片机制作的电子秒表 含源码和proteus仿真 第一次发帖,不足之处望海涵

[复制链接]
ID:868449 发表于 2020-12-26 19:30 | 显示全部楼层 |阅读模式
设计一款能够任意启停的秒表,5LED数码显示,计时单位为1/100
基本任务:
1、设计出如图1所示的单片机电路。计时范围为000.00~999.99S
按键标号说明:
START
STOP
RST
RESTART
MOD-CHOOSE
NEXT
开始计时
暂停计时
复位清零
重新计时
计时模式切换
历史计时切换

Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)

图1

图1

1、单片机总电路
当刚上电时,数码管和LCD的显示值都为零。按下START键开始计时,按下STOP暂停计时,利用单片机的复位电路对示值清零,即按下RST键实现复位清零。
进阶任务:
1.设置重新启动功能。
重启功能即重新开始计时功能,可以用RESRTART按键实现。其中RESTART键和START键均可以使单片机进入外部中断0,两者之间通过二极管隔离,START按键按下时不会拉低RESRTART所连的P3.4端口的值。按下RESRTART键时不但可以拉低P3.4端口的值,同时可以进入外部中断零。
2.设置计时功能。可以同时计时三个时间,停止后可通过按键选择显示。
与进阶任务1中类似,使用相同的硬件电路。普通计时模式与次模式可以使用MOD-CHOOSE键进行切换,当这个键弹起时,为普通计时模式,按下时为同时计时三个时间。
当处于计时三个时间的模式时,STOP键需按下三次才会暂停,每一次按下时的时间都会存储起来,暂停以后可以通过NEXT键使时间从高到低循环显示。
3. 同时选用LCD液晶屏显示。
    如图1所示。

单片机源程序如下:
  1. #include <reg52.h>
  2. #include <stdio.h>
  3. #include <intrins.h>
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. sbit start=P3^2;
  7. sbit stop =P3^3;
  8. sbit clear=P3^4;
  9. sbit swch =P3^5;
  10. sbit next =P3^7;
  11. //sbit e1=P2^0;sbit e2=P2^1;sbit e3=P2^2;sbit e4=P2^3;sbit e5=P2^4;
  12. sbit rs=P3^0;
  13. sbit rw=P3^1;
  14. sbit en=P3^6;

  15. sbit dp=P1^7;

  16. char displaytemp[16];
  17. uchar table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
  18. uchar table2[5];//存储个位到万位
  19. uint k;   //每10ms加一
  20. uchar ktime=1;//停止按键按下次数
  21. uint table3[5];//存储多次计时的时间
  22. uchar ch2=0x01;
  23. uchar ch1=0;
  24. uchar q;
  25. uint flag=3;
  26. float klcd;

  27. void delay(uchar z)  //延时
  28. {
  29.   uchar x,y;
  30.   for(x=z;x>0;x--)
  31.   for(y=110;y>0;y--);
  32. }

  33. void led_disp(uchar ch0)  //led显示
  34. {
  35.   P2=~ch2;
  36.   P1=table[table2[ch0]];
  37.   if(ch2==0x04)
  38.     dp=1;
  39.   else
  40.     dp=0;
  41.   ch2=ch2<<1;
  42.   if(ch2==0x20)
  43.     ch2=0x01;
  44. }

  45. /*------------------------------------------------
  46.               判忙函数
  47. ------------------------------------------------*/
  48. bit lcd_busy(void)
  49. {
  50.   P0= 0xFF;
  51.   rs=0;
  52.   rw=1;
  53.   en=0;
  54.   _nop_();
  55.   en=1;
  56.   return (bit)(P0 & 0x80);
  57. }
  58. /*------------------------------------------------
  59.               写入命令函数
  60. ------------------------------------------------*/
  61. void LCD_Write_Com(unsigned char com)
  62. {  
  63.   //while(lcd_busy()); //忙则等待
  64.   delay(2);
  65.   rs=0;
  66.   rw=0;
  67.   en=1;
  68.   P0= com;
  69.   _nop_();
  70.   en=0;
  71. }
  72. /*------------------------------------------------
  73.               写入数据函数
  74. ------------------------------------------------*/
  75. void LCD_Write_Data(unsigned char Data)
  76. {
  77.   //while(lcd_busy()); //忙则等待
  78.   delay(2);
  79.   rs=1;
  80.   rw=0;
  81.   en=1;
  82.   P0= Data;
  83.   _nop_();
  84.   en=0;
  85. }

  86. void lcd_clear(void) //清屏
  87. {
  88.   LCD_Write_Com(0x01);
  89.   delay(3);
  90. }

  91. void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
  92. {     
  93.   if (y==0)
  94.   {     
  95.           LCD_Write_Com(0x80 + x);    //表示第一行
  96.   }
  97.   else
  98.   {      
  99.           LCD_Write_Com(0xC0 + x);    //表示第二行
  100.   }        
  101.   while (*s)
  102.   {     
  103.     LCD_Write_Data( *s);     
  104.     s++;     
  105.   }
  106. }

  107. void lcd_init(void)
  108. {
  109.   LCD_Write_Com(0x38);    /*显示模式设置*/
  110.   delay(2);
  111.   LCD_Write_Com(0x38);
  112.   delay(2);
  113.   LCD_Write_Com(0x38);
  114.   delay(2);
  115.   LCD_Write_Com(0x38);  
  116.   LCD_Write_Com(0x08);    /*显示关闭*/
  117.   LCD_Write_Com(0x01);    /*显示清屏*/
  118.   LCD_Write_Com(0x06);    /*显示光标移动设置*/
  119.   delay(2);
  120.   LCD_Write_Com(0x0C);    /*显示开及光标设置*/
  121. }

  122. void main(void)
  123. {
  124.    uchar m=0;
  125.    k=0;
  126.    lcd_init();
  127.    TMOD=0x11;
  128.    TH0=(65536-10000)/256;
  129.    TL0=(65536-10000)%256;
  130.    TH1=(65536-8000)/256;
  131.    TL1=(65536-8000)%256;
  132.    EA=1;
  133.    IT0=1;EX0=1;
  134.    IT1=1;EX1=1;
  135.    TR0=0;ET0=1;
  136.    TR1=1;ET1=1;
  137.    while(1)
  138.    {
  139.      klcd=(float)k/100;
  140.      sprintf(displaytemp,"% 3.2f",klcd);
  141.      LCD_Write_String(1,0,displaytemp);
  142.      if(table2[0]==table2[1]==table2[2]==table2[3]==table2[4]==9)
  143.      {
  144.        EA=0;
  145.        for(q=0;q++;q<5)
  146.          table2[q]=0;
  147.        EA=1;
  148.      }   
  149.    }
  150. }

  151. void int0(void) interrupt 0
  152. {
  153.   if(clear==0)
  154.   {
  155.     TR0=0;
  156.     k=0;
  157.     delay(2);
  158.     TR0=1;
  159.   }
  160.   else if(clear&next)
  161.     TR0=1;
  162.   else
  163. //       if(table3[3]!=0)
  164.        {
  165.          k=table3[flag];
  166.          flag--;
  167.          if(flag==0)
  168.            flag=3;
  169.        }      
  170. }

  171. void int1(void) interrupt 2
  172. {
  173.   if((swch==1))
  174.     TR0=0;
  175.   else
  176.   {
  177.     TR0=0;
  178.     table3[ktime]=k;
  179.     delay(1);
  180.     TR0=1;
  181.     ktime++;
  182.     if(ktime==4)
  183.     {
  184.       ktime=1;
  185.       TR0=0;
  186. ……………………

  187. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
电子秒表.7z (99.5 KB, 下载次数: 86)

评分

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

查看全部评分

回复

使用道具 举报

ID:906076 发表于 2021-4-15 10:38 | 显示全部楼层
感谢楼主,本人萌新,有不太懂的地方,楼主能否哦把仿真图各个模块讲解一下,感谢!!!
回复

使用道具 举报

ID:868449 发表于 2022-4-11 22:52 | 显示全部楼层
2018342326 发表于 2021-4-15 10:38
感谢楼主,本人萌新,有不太懂的地方,楼主能否哦把仿真图各个模块讲解一下,感谢!!!

抱歉,之前很久未登录,请问现在您应该疑惑已解了吧
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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