单片机四位秒表程序_51单片机4位秒表程序 - CSDN
  • 要求:(1)4数码动态显示,最低按1/10秒计数,最高计数单位为9.59.9。(2)用开关K0控制秒表的启动、停止、清零功能,按一次启动计时,按一次停止,再按一次清零,在三个状态中循环。(3)要求K0使用外部中断,...

    要求:
    (1)4位数码动态显示,最低位按1/10秒计数,最高计数单位为9.59.9。
    (2)用开关K0控制秒表的启动、停止、清零功能,按一次启动计时,按一次停止,再按一次清零,在三个状态中循环。
    (3)要求K0使用外部中断,优先级高于T0的优先级。
    悬赏分:5 | 解决时间:2011-6-19 15:59
    ;====================================================
    最佳答案:

    所使用的电路可见:

    http://xiangce.baidu.com/picture/detail/e0e3dcca6a23826c17c97c512f075f13e02d51f6


    下列程序已经调试通过,


          ORG  0000H
          JMP  MAIN
          ORG  0003H
          JMP  X0_INT
          ORG  000BH
          JMP  T0_INT
    ;---------------------------------------
    X0_INT:
          INC  R0 
          CJNE R0, #1, STOP
          SETB TR0
          RETI
    ;---------------------
    STOP:
          CJNE R0, #2, R0_0
          CLR  TR0
          RETI
    ;---------------------
    R0_0:
          CLR  A
          MOV  R0, A
          MOV  R1, A
          MOV  R2, A
          MOV  R3, A
          MOV  R4, A
          MOV  R5, A
          MOV  R6, A
          RETI
    ;---------------------------------------
    T0_INT:
          MOV  TL0, #(55536 MOD 256)
          MOV  TH0, #(55536 / 256)
          INC  R2          ;百分之一秒.
          CJNE R2, #10, T0_E
          MOV  R2, #0
          INC  R3          ;十分之一秒.
          CJNE R3, #10, T0_E
          MOV  R3, #0
          INC  R4          ;秒个位.
          CJNE R4, #10, T0_E
          MOV  R4, #0
          INC  R5          ;秒十位.
          CJNE R5, #6, T0_E
          MOV  R5, #0
          INC  R6          ;分.
          CJNE R6, #10, T0_E
          MOV  R6, #0
    T0_E:
          RETI
    ;---------------------------------------
    MAIN:
          MOV  TMOD, #01H
          MOV  TH0, #(55536 / 256)   ;10ms@12MHz
          MOV  TL0, #(55536 MOD 256)
          SETB TR0
          SETB ET0
          SETB IT0
          SETB PX0
          SETB EX0
          SETB EA
          CLR  A
          MOV  R1, A
          MOV  R2, A
          MOV  R3, A
          MOV  R4, A
          MOV  R5, A
          MOV  R6, A
          MOV  R0, #1
    LP1:  LCALL XIANSHI
          JMP LP1
    ;---------------------------------------
    XIANSHI:
          MOV  DPTR, #D_TAB
          MOV  R1, #03H
          MOV  R7, #255 - 8
    LOOP:
          MOV  A,  @R1
          MOVC A, @A + DPTR
          MOV  P2, #255       ;消隐.
          MOV  P0, A          ;输出段码.
          MOV  P2, R7         ;输出位码.
          CALL DL
          MOV  A, R7
          RR   A
          MOV  R7, A
          INC  R1
          CJNE R1, #07H, LOOP
          RET
    D_TAB: 
          DB  0C0H, 0F9H, 0A4H, 0B0H, 99H,  92H, 82H, 0F8H
          DB   80H,  90H,  88H,  83H, 86H, 0A1H, 86H,  8EH
    ;---------------------------------------
    DL:
          DJNZ ACC, $
          DJNZ ACC, $
          RET
    ;---------------------------------------
    END
    ;====================================================
    回答时间:2011-6-18 17:00
    回答者: 做而论道 | 十五级 采纳率:43% 
    原题网址:http://zhidao.baidu.com/question/281050349.html
    ;====================================================

    展开全文
  • 基于51单片机(普中开发板)的四位数码管秒表设计

    千次阅读 多人点赞 2019-05-18 00:18:34
    今天学校布置的课后作业,利用51单片机做一个秒表,本来是做了个8位数码管的秒表,但后来想了下秒表计时一般都不会用到以小时为单位,就把小时的部分以及毫秒的部分去掉了,就留下了分钟跟秒。 每个开发板的电路...

    说明

    今天学校布置的课后作业,利用51单片机做一个秒表,本来是做了个8位数码管的秒表,但后来想了下秒表计时一般都不会用到以小时为单位,就把小时的部分以及毫秒的部分去掉了,就留下了分钟跟秒。

    每个开发板的电路连接不一定是一样的,我所使用这块开发板是普中科技的,连接数码管的位选是接了一个138译码器的,如果是购买的普中科技的开发板可以直接复制程序就能使用,如果开发板的数码管的位选是接了锁存器的,那么就要相应地更改。

    如果不理解138芯片使用方法的,我也要把138芯片的真值表附在下面了,顺便说下它的用法:
    74HC138译码器可接受3位二进制加权地址输入(A0, A1和A2),并当使能时,提供8个互斥的低有效输出(Y0至Y7)。74HC138特有3个使能输入端:两个低有效(E1和E2)和一个高有效(E3)。除非E1和E2置低且E3置高,否则74HC138将保持所有输出为高。74HC138正常工作的话,一次只能输出一个低电平,其他全为高电平

    要求:

    1. 按下按钮S1,秒表开始计时;
    2. 按下按钮S2,秒表暂停计时(停留在计时的数);
    3. 按下按钮S3,秒表清零;
    4. 计时精确到0.5s

    电路图

    **单片机****8个数码管****4个独立按键****138芯片**138芯片真值表

    程序

    程序已经过测试,可以正常使用,注释非常多,比较容易理解。

    /****************************************************************************************
    								秒表实验
    实验现象:按下按钮S1开始计时,最大为59.59。按下按钮S2定时器暂停,按下按钮S3清零
    
    *****************************************************************************************/
    #include <reg52.h>
    #define uint unsigned int						  //对数据类型进行声明定义
    #define uchar unsigned char
    
    sbit LS138_A = P2^2;							  //138芯片A2引脚
    sbit LS138_B = P2^3;							  //138芯片A1引脚
    sbit LS138_C = P2^4;							  //138芯片A0引脚
    
    uchar DT_s = 0;								  //秒计时
    uchar DT_min = 0;									  //分计时
    
    uchar code duan[] = {0x3F,0x06,0x5B,0x4F,		  //共阴数码管无小数点 显示0~9
    					 0x66,0x6D,0x7D,0x07,
    					 0x7F,0x6F	
    					};
    
    uchar code duanpoint[] = {0xbf,0x86,0xdb,0xcf,	   //共阴数码管有小数点 显示0~9
    						  0xe6,0xed,0xfd,0x87,
    						  0xff,0xef,0xf7,0xfc,
    						  0xb9,0xde,0xf9,0xf1
    						 };
    
    /************************************************
    函数名				:delay1ms
    函数功能            :t=1,大约延时1ms
    ************************************************/
    void delay1ms(uint t)
    {
    	uint i,j;
    	for(i=0;i<t;i++)
    	{
    		for(j=0;j<120;j++);	
    	}
    }
    
    /************************************************
    函数名				:Timer0Init
    函数功能			:定时/计数器0中断初始化
    *************************************************/
    void Timer0Init()
    {
    	TMOD = 0x01; 		//选择T0定时/计数器,工作在方式1,16位计数器		
    	TH0 = 0xFC;			//计数初始值,计数从64536开始,计1000个数,完成一次计数,时间为1ms
    	TL0 = 0x18;		
    	ET0 = 1;			//定时/计数器0中断允许位
    	EA = 1;				//总中断
    }
    
    /************************************************
    函数名				:S3
    函数功能			:按下按钮S3时,秒表归零
    *************************************************/
    void S3()
    {
    	DT_s = 0;			//秒归零
    	DT_min = 0;			//分归零
    	TR0 = 0;			//运行控制位清0,关闭定时器
    }
    
    /**********************************************************
    函数名				:ScanKey
    函数功能			:按键扫描函数,循环扫描哪个键被按下
    **********************************************************/
    void ScanKey()
    {
    	uchar Key;		   //临时变量
    	Key = P3&0x07;	   //只需要三个按键,分别接的P3^1,P3^2,P3^3,故把P3高五位被屏蔽
    	if(Key!=0x07)	   //判断哪个键被按下
    	{
    		delay1ms(10);	 //消抖10ms
    		Key = P3&0x07;	 //再次赋值,避免此时按键状态改变
    		if(Key!=0x07)	 //确认按键被按下
    		{
    			switch(Key)
    			{
    				case 0x05:				  //S1(P3^2)被按下
    							TR0 = 1;	  //定时器0运行控制位为1,启动定时器0
    							break;
    				case 0x06:				  //S2(P3^1)被按下
    							TR0 = 0;	  //定时器0运行控制位为0,关闭定时器0
    							break;
    				case 0x03:				  //S3(P3^3)被按下
    							S3();
    							break;
    			}
    		}
    		while(Key!=0x07)		//松手检测
    		{
    			Key = P3&0x07;
    		}
    	}
    }
    
    /*******************************************************************
    函数名				:DigDisplay
    函数功能			:数码管动态扫描函数,循环扫描8个数码管显示
    ********************************************************************/
    void DigDisplay(uchar s,uchar min)
    {
    	LS138_A = 0;			  //秒个位位选
    	LS138_B = 0;
    	LS138_C = 0;
    	P0 = duan[s%10];		  //发送段码,显示秒个位
    	delay1ms(5);			  //间隔一段时间扫描
    	LS138_A = 1;			  //秒十位位选
    	LS138_B = 0;
    	LS138_C = 0;
    	P0 = duan[s/10];		  //发送段码显示秒十位
    	delay1ms(5);			  //间隔一段时间扫描
    
    	LS138_A = 0;			  //分的个位位选
    	LS138_B = 1;
    	LS138_C = 0;
    	P0 = duanpoint[min%10];		  //发送段码,显示分的个位
    	delay1ms(5);			  //间隔一段时间扫描
    	LS138_A = 1;			  //分的十位位选
    	LS138_B = 1;			  //间隔一段时间扫描
    	LS138_C = 0;
    	P0 = duan[min/10];		  //发送段码,显示分的十位
    	delay1ms(5);			  //间隔一段时间扫描
    	P0 = 0x00;				  //消隐
    }
    
    /**********************************************************
    函数名				:主函数
    函数功能			:无
    **********************************************************/
    void main(void)
    {
    	P0 = 0x00;		  //读端口前写1
    	P3 = 0xFF;		  //读端口前写1
    	Timer0Init();	  //定时器中断初始化函数
    	while(1)
    	{
    		DigDisplay(DT_s,DT_min);	   //数码管显示函数
    		ScanKey();							   //按键扫描函数
    	}
    }
    
    /**********************************************************
    函数名				:Timer0
    函数功能			:定时器计数
    **********************************************************/
    void Timer0() interrupt 1
    {
    	static uint count_s;	
    	static uint count_min;		
    	TH0 = 0xFC;				//计数值初始化,从64536开始计数,计满时为65536,溢出时即为 1ms
    	TL0 = 0x18;
    	count_s++;				 //秒计数
    	count_min++;				 //分计数
    	if(count_s==1000)			 //计数到1s时,秒计数器开始工作
    	{
    		count_s = 0;		 //秒计数清零
    		DT_s++;			 //显示秒计数值自增
    		if(DT_s>59)		 //秒数最大为59
    		{
    			DT_s = 0;
    		}
    	}
    	if(count_min==60000)		  //计数到60000ms时,秒计数器开始工作
    	{
    		count_min = 0;		  //分计数清零
    		DT_min++;				  //显示分计数值自增
    		if(DT_min>59)			  //分数最大为59
    		{
    			DT_min = 0;
    		}
    	}
    }
    
    展开全文
  • 本人是一个新手 对于下边的c程序每一个子函数能看懂,但是像这么多子函数放到一起 就晕了,想请亲们帮我把这个程序的流程梳理梳理中断是何时工作,各个子函数怎么在这个整体里运行 越详细越好,本人十分感谢! ``` ...
  • 51单片机数码管秒表显示,程序很简单,初学单片机者适用
  • 基于51单片机的电子秒表设计

    万次阅读 2018-01-11 09:19:38
    由于并没有使用24c02,导致程序去数据较大,仿真可能不行。实际验证通过 程序界面如图: 仿真界面如图:       如果编译出错,将keil按如图参数设置: 以下为程序...

    设计要求:

    最多可记录十组数据

    可删除其中多组数据

    可上下查阅所记录的数据

    数据通过lcd1602显示

    计时精度到0.01s

    由于并没有使用24c02,导致程序去数据较大,仿真可能不行。实际验证通过

    程序界面如图:


    仿真界面如图:


       
      如果编译出错,将keil按如图参数设置:



    以下为程序代码:

    包括两个文件,主程序里面是:

    #include<1602.h>
    #include<reg52.h>




    #ifndef uchar
    #define uchar unsigned char
    #endif


    #ifndef uint 
    #define uint unsigned int
    #endif


    /*按键定义*/
    /*开始键,计数键,停止计数键或者清零键,上下查阅键,删除数据键*/


    sbit key_start=P1^0;
    sbit key_count=P1^1;
    sbit key_stop=P1^2;
    sbit key_up=P1^3;
    sbit key_down=P1^4;




    /*变量定义*/
    int count=0;//计数器


    uint i,j,state,k=0,countnum,m,delete;


    /*设置标志位*/


    char flag;
    char maxflag;
    char clearflag;
    char turnflag; //
    char upflag;  //为1时可以继续上翻
    char minflag=0; //为0时可以继续下翻
    char downflag; 


    /*定义数组 */
     unsigned char str[] = "time:";
     unsigned char str2[]= "num:";
     unsigned char str3[]="...press start..";
     unsigned char str4[]="....counting....";
     unsigned char str5[]=".. press count..";
     unsigned char str6[]="press up or down";
     unsigned char str7[]="..overcounting..";




     int number[10]=0;
     int num2[5]=0;


    void keyscan();
    void init();




    void main()
    {
       
        InitLcd1602();
        init();
    /*以下为调试程序段*/
       LcdShowStr(0,0,str3);
      //  LcdShowStr(0,1,str2);
    //  LcdWriteCom(0x91);
    //  LcdWriteData('0'+1);
    //  LcdWriteCom(0x90);
    //   LcdWriteData('0'+1);
    /*以上为调试程序段*/




        while(1)
    { //LcdShowStr(0,1,str4); //测试
        keyscan();
    Lcd1602_Delay1ms(50);
    }


    }
    void init()
    {
    IT0=0;
    EX0=0;
    TMOD=0x01;
    TH0=(65536-10000)/256; 
    TL0=(65536-10000)%256;
    EA=0; //开总中断


    // key_count=0;
    // key_stop=0;
    // key_up=0;
    // key_down=0;
    // key_delete=0;


    flag=0; //标志位为0时代表未计时状态,为1时代表为计时状态
    i=0;
    maxflag=0;//定时标志位,为1时代表定时已满
    clearflag=0;//清除标志位
    turnflag=0;//为1时可以上下翻页显示
    downflag=0;
    upflag=1;
    }
    void keyscan()
    {
    if((key_start==0)&&(flag==0)) //防抖处理
    {
    Lcd1602_Delay1ms(10); //防抖处理
    if((key_start==0)&&(flag==0))//防抖处理
    {
    while((!(key_start==0)&&(flag==0)));//防抖处理
    InitLcd1602();
    EA=1;//检测到开始按键按下后,启动定时器
    ET0=1; //计时器0开启
     TR0=1; //计时器打开
    flag=1;//设置标志位为计时状态
    LcdShowStr(0,0,str4);
    LcdShowStr(0,1,str5);
    }
    }
    if((key_count==0)&&(flag==1)&&(maxflag==0))
    {
           Lcd1602_Delay1ms(50);
    if((key_count==0)&&(flag==1)&&(maxflag==0))
    {

    while(!((key_count==0)&&(flag==1)&&(maxflag==0)));

        InitLcd1602();
    LcdShowStr(0,0,str);
        LcdShowStr(0,1,str2);
    number[i]=count;
    LcdWriteCom(0xC7);
            LcdWriteData('0'+i+1); 
    LcdWriteCom(0xC6);
            LcdWriteData('0');
    if(i==9)
    {
    LcdWriteCom(0xC7);
    LcdWriteData('0'); 
    LcdWriteCom(0xC6);
    LcdWriteData('0'+1);
    }




    num2[0]=number[i]/10000;
    num2[1]=number[i]/1000%10;
    num2[2]=number[i]/100%10;
    num2[3]=number[i]/10%10;
    num2[4]=number[i]%10;

    LcdWriteCom(0x86);
        LcdWriteData('0'+num2[0]);


    LcdWriteCom(0x87);
        LcdWriteData('0'+num2[1]);


    LcdWriteCom(0x88);
        LcdWriteData('0'+num2[2]);


    LcdWriteCom(0x89);
        LcdWriteData('.');


     LcdWriteCom(0x8A);
        LcdWriteData('0'+num2[3]);


    LcdWriteCom(0x8B);
        LcdWriteData('0'+num2[4]);


    LcdWriteCom(0x8D);
        LcdWriteData('S');


    i++;
    state=i;


    if(i==10)
    {
    maxflag=1;

    }
    }
    }


    if(key_stop==0)
    {
    Lcd1602_Delay1ms(50);

     if(key_stop==0)
    {
    while(!(key_stop==0));
    if(clearflag==0)
    {
    TR0=0;  //关定时器,查阅时定时就停止
    EX0=1;  //开外部中断,保证只有在上下翻阅时才能触发外部中断
    count=0;//计数清零
    clearflag=1;//清除标志位打开,也就是说再按一下这个按键所有制清零
    turnflag=1;
    minflag=0;

    }
    else if(clearflag==1)//此块执行清除任务
    {

    InitLcd1602();
    number[10]=0;
    clearflag=0;
    LcdShowStr(0,0,str3);
    turnflag=0;
    maxflag=0;
    flag=0;
    i=0;//将数组计数给清零
    }
    }
    }





    if(key_up==0)
    {
    Lcd1602_Delay1ms(50);
         if(key_up==0)
    {
    while(!(key_up==0));
    if(upflag==0)
    {
    InitLcd1602();
    LcdShowStr(0,0,str);
    LcdShowStr(0,1,str2);
     minflag=0;//只要上翻过后都可以下翻
     state++;
    if(state==10)
    {
    LcdWriteCom(0xC7);
    LcdWriteData('0'); 
    LcdWriteCom(0xC6);
    LcdWriteData('0'+1);
    }
    else
    {
    LcdWriteCom(0xC7);
    LcdWriteData('0'+state); 
    LcdWriteCom(0xC6);
    LcdWriteData('0');
    }
    m=state-1;
    delete=m;
     
     /*显示时间*/
    num2[0]=number[m]/10000;
    num2[1]=number[m]/1000%10;
    num2[2]=number[m]/100%10;
    num2[3]=number[m]/10%10;
    num2[4]=number[m]%10;

    LcdWriteCom(0x86);
    LcdWriteData('0'+num2[0]);

    LcdWriteCom(0x87);
    LcdWriteData('0'+num2[1]);

    LcdWriteCom(0x88);
    LcdWriteData('0'+num2[2]);

    LcdWriteCom(0x89);
    LcdWriteData('.');

    LcdWriteCom(0x8A);
    LcdWriteData('0'+num2[3]);

    LcdWriteCom(0x8B);
    LcdWriteData('0'+num2[4]);

    LcdWriteCom(0x8D);
    LcdWriteData('S');
    if(state==10)
    {
    upflag=1;
    }
    }
     
     
    }

    }


    if(key_down==0)
    {
     Lcd1602_Delay1ms(50);
     if(key_down==0)
    {
    while(!(key_down==0));
    if((turnflag==1)&&(minflag==0))
    {
    InitLcd1602();
    LcdShowStr(0,0,str);
    LcdShowStr(0,1,str2);
    /*显示组号*/
    state--;
    LcdWriteCom(0xC7);
    LcdWriteData('0'+state); 
    LcdWriteCom(0xC6);
    LcdWriteData('0');
    k=state-1;
    delete=k;


    /*显示时间*/
    num2[0]=number[k]/10000;
    num2[1]=number[k]/1000%10;
    num2[2]=number[k]/100%10;
    num2[3]=number[k]/10%10;
    num2[4]=number[k]%10;

    LcdWriteCom(0x86);
    LcdWriteData('0'+num2[0]);

    LcdWriteCom(0x87);
    LcdWriteData('0'+num2[1]);

    LcdWriteCom(0x88);
    LcdWriteData('0'+num2[2]);

    LcdWriteCom(0x89);
    LcdWriteData('.');

    LcdWriteCom(0x8A);
    LcdWriteData('0'+num2[3]);

    LcdWriteCom(0x8B);
    LcdWriteData('0'+num2[4]);

    LcdWriteCom(0x8D);
    LcdWriteData('S');

    if(state==1)
    {
    minflag=1;

    }
    upflag=0;

    }
    }
     }




    }


    void timer0() interrupt 1
    {
    TH0=(65536-10000)/256; 
    TL0=(65536-10000)%256;
    count++;
    if(count==6000)
    {
    count=0; 
    ET0=0; //计时器0关闭
    TR0=0; //计时器关闭
    turnflag=1;
    EX0=1;
    InitLcd1602();
    LcdShowStr(0,0,str6);
    LcdShowStr(0,1,str7);
    }
    }


    void  counter0(void) interrupt 0  using 1
    {
      number[delete]=0;
    LcdWriteCom(0x86);
    LcdWriteData('0');

    LcdWriteCom(0x87);
    LcdWriteData('0');

    LcdWriteCom(0x88);
    LcdWriteData('0');


    LcdWriteCom(0x89);
    LcdWriteData('.');


    LcdWriteCom(0x8A);
    LcdWriteData('0');


    LcdWriteCom(0x8B);
    LcdWriteData('0');


    LcdWriteCom(0x8D);
    LcdWriteData('S');

    }


    然后是lcd的驱动程序:



    #include<1602.h>








    void Read_Busy()           //忙检测函数,判断bit7是0,允许执行;1禁止
    {
        unsigned char sta;      //
        LCD1602_DB = 0xff;
        LCD1602_RS = 0;
        LCD1602_RW = 1;
        do
        {
            LCD1602_EN = 1;
            sta = LCD1602_DB;
            LCD1602_EN = 0;    //使能,用完就拉低,释放总线
        }while(sta & 0x80);
    }


    void Lcd1602_Write_Cmd(unsigned char cmd)     //写命令
    {
        Read_Busy();
        LCD1602_RS = 0;
        LCD1602_RW = 0;
        LCD1602_DB = cmd;
        LCD1602_EN = 1;
        LCD1602_EN = 0;    
    }


    void Lcd1602_Write_Data(unsigned char dat)   //写数据
    {
          Read_Busy();
          LCD1602_RS = 1;
          LCD1602_RW = 0;
          LCD1602_DB = dat;
          LCD1602_EN = 1;
          LCD1602_EN = 0;
    }


    void LcdSetCursor(unsigned char x,unsigned char y)  //坐标显示
    {
        unsigned char addr;
        if(y == 0)
            addr = 0x00 + x;
        else
            addr = 0x40 + x;
        
        Lcd1602_Write_Cmd(addr|0x80);
    }




    void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str)     //显示字符串
    {
        LcdSetCursor(x,y);      //当前字符的坐标
        while(*str != '\0')
        {
            Lcd1602_Write_Data(*str++);
        }
    }


    void InitLcd1602()              //1602初始化
    {
        Lcd1602_Write_Cmd(0x38);    //打开,5*8,8位数据
        Lcd1602_Write_Cmd(0x0c);
        Lcd1602_Write_Cmd(0x06);
        Lcd1602_Write_Cmd(0x01);    //清屏   
    }


      
     void Lcd1602_Delay1ms(uint c)   //误差 0us
    {
        uchar a,b;
    for (; c>0; c--)
    {
    for (b=199;b>0;b--)
    {
      for(a=1;a>0;a--);
    }      
    }
       
    }
    /*******************************************************************************
    * 函 数 名         : LcdWriteCom
    * 函数功能   : 向LCD写入一个字节的命令
    * 输    入         : com
    * 输    出         : 无
    *******************************************************************************/
    #ifndef LCD1602_4PINS //当没有定义这个LCD1602_4PINS时
    void LcdWriteCom(uchar com)  //写入命令
    {
    LCD1602_EN = 0;     //使能
    LCD1602_RS = 0;   //选择发送命令
    LCD1602_RW = 0;   //选择写入

    LCD1602_DB = com;     //放入命令
    Lcd1602_Delay1ms(1); //等待数据稳定


    LCD1602_EN = 1;          //写入时序
    Lcd1602_Delay1ms(5);  //保持时间
    LCD1602_EN = 0;
    }
    #else 
    void LcdWriteCom(uchar com)  //写入命令
    {
    LCD1602_EN = 0; //使能清零
    LCD1602_RS = 0; //选择写入命令
    LCD1602_RW = 0; //选择写入


    LCD1602_DB = com; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
    Lcd1602_Delay1ms(1);


    LCD1602_EN = 1; //写入时序
    Lcd1602_Delay1ms(5);
    LCD1602_EN = 0;


    // Lcd1602_Delay1ms(1);
    LCD1602_DB = com << 4; //发送低四位
    Lcd1602_Delay1ms(1);


    LCD1602_EN = 1; //写入时序
    Lcd1602_Delay1ms(5);
    LCD1602_EN = 0;
    }
    #endif


    /*******************************************************************************
    * 函 数 名         : LcdWriteData
    * 函数功能   : 向LCD写入一个字节的数据
    * 输    入         : dat
    * 输    出         : 无
    *******************************************************************************/   
    #ifndef LCD1602_4PINS   
    void LcdWriteData(uchar dat) //写入数据
    {
    LCD1602_EN = 0; //使能清零
    LCD1602_RS = 1; //选择输入数据
    LCD1602_RW = 0; //选择写入


    LCD1602_DB = dat; //写入数据
    Lcd1602_Delay1ms(1);


    LCD1602_EN = 1;   //写入时序
    Lcd1602_Delay1ms(5);   //保持时间
    LCD1602_EN = 0;
    }
    #else
    void LcdWriteData(uchar dat) //写入数据
    {
    LCD1602_EN = 0;  //使能清零
    LCD1602_RS = 1;  //选择写入数据
    LCD1602_RW = 0;  //选择写入


    LCD1602_DB = dat; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
    Lcd1602_Delay1ms(1);


    LCD1602_EN = 1;  //写入时序
    Lcd1602_Delay1ms(5);
    LCD1602_EN = 0;


    LCD1602_DB = dat << 4; //写入低四位
    Lcd1602_Delay1ms(1);


    LCD1602_EN = 1;  //写入时序
    Lcd1602_Delay1ms(5);
    LCD1602_EN = 0;
    }
    #endif

    还有一个1602.h文件:

    #include<reg52.h>


    #ifndef uchar
    #define uchar unsigned char
    #endif


    #ifndef uint 
    #define uint unsigned int
    #endif


    #define LCD1602_DB  P0    




    sbit LCD1602_RS = P2^6;
    sbit LCD1602_RW = P2^5;
    sbit LCD1602_EN = P2^7;




    void InitLcd1602(); //初始化lcd1602


    void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str);//写入一个字符串


    void LcdWriteData(uchar dat1);//写入一个单个字
    void LcdWriteCom(uchar com);//写入地址
    void Lcd1602_Delay1ms(uint c);
    void InitLcd1602();



    实际效果如图:

    展开全文
  • 郭天祥TX-1C开发板实现秒表程序 附开发板图片和原理图 代码 #include <reg52.h> sbit key1=P3^4; //按键S2 sbit key2=P3^5; //按键S3 sbit U1=P2^6; //LED选 sbit U2=P2^7; //LED片选 unsigned char ...

    郭天祥TX-1C开发板实现秒表程序

    更新,加入按键启停和重置功能
    附开发板图片和原理图
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    代码

    /*
        定时器中断工作方式1实现一个精度为0.01s的秒表,并使用数码管显示
        要求:数码管前两位显示计时的整数部分,范围为0~59s;数码管的第三位和第四位显示计时的小数部分,0~0.99s。计时到达59.99s后归零
    
    */
    #include <reg52.h>
    sbit U1 = P2^6;     //数码管段选
    sbit U2 = P2^7;     //数码管位选
    unsigned char code ledchar[]={
        0x3F,0x06,0x5B,0x4F,0x66,0x6D,
        0x7D,0x07,0x7F,0x6F,0x77,0x7C,
        0x39,0x5E,0x79,0x71};
    unsigned char ledbuff[4];
    unsigned char DecimalPart = 0;      //秒表小数部分
    unsigned char IntegerPart = 0;      //秒表整数部分
    void stopwatchdisplay();
    void delayms(unsigned int);
    void main()
    {
        EA = 1;
        TMOD = 0x01;
        TH0 = 0xDC;     //定时10ms
        TL0 = 0x00;
        ET0 = 1;
        TR0 = 1;
        while(1)
        {
            stopwatchdisplay();
        }
    }
    void stopwatchdisplay()
    {   
        
        ledbuff[0]=ledchar[DecimalPart%10];
        ledbuff[1]=ledchar[DecimalPart/10];
        ledbuff[2]=ledchar[IntegerPart%10];
        ledbuff[3]=ledchar[IntegerPart/10];
        ledbuff[2] |= 0x80;
        
        P0=ledbuff[0];
        U1=1;
        U1=0;
        P0=0xFF;
        U2=1;
        P0=0xF7;
        U2=0;
        delayms(1);
        
        P0=ledbuff[1];
        U1=1;
        U1=0;
        P0=0xFF;
        U2=1;
        P0=0xFB;
        U2=0;
        delayms(1);
        
        P0=ledbuff[2];
        U1=1;
        U1=0;
        P0=0xFF;
        U2=1;
        P0=0xFD;
        U2=0;
        delayms(1);
        
        P0=ledbuff[3];
        U1=1;
        U1=0;
        P0=0xFF;
        U2=1;
        P0=0xFE;
        U2=0;
        delayms(1);
    }
    void stopwatchcount()
    {
        DecimalPart++;
        if(DecimalPart>=100)
        {   
            DecimalPart = 0;
            IntegerPart++;
            if(IntegerPart>=60)
                IntegerPart=0;
        }
    }
    void InterruptTimer0() interrupt 1
    {
        TH0 = 0xDC;
        TL0 = 0x00;
        stopwatchcount();
    }
    void delayms(unsigned int ms)
    {
        int x,y;
        for(x=ms;x>0;x--)
            for(y=110;y>0;y--);
    }
    

    按键s6控制启停,s7控制重置

    #include <reg52.h>
    sbit U1 = P2^6;     //数码管段选
    sbit U2 = P2^7;     //数码管位选
    unsigned char code ledchar[]={      //数码管显示数组
        0x3F,0x06,0x5B,0x4F,0x66,0x6D,
        0x7D,0x07,0x7F,0x6F,0x77,0x7C,
        0x39,0x5E,0x79,0x71};
    unsigned char ledbuff[4];         //数码管显示缓冲数组
    unsigned char DecimalPart = 0;      //秒表小数部分
    unsigned char IntegerPart = 0;      //秒表整数部分
    bit stopwatchrunstop = 0;           //启停标志位
    void stopwatchdisplay();            //秒表显示函数
    void delayms(unsigned int);         //延时函数
    void main()
    {
        EA = 1;
        TMOD = 0x10;
        TH1 = 0xDC;     //定时10ms
        TL1 = 0x00;
        ET1 = 1;
        TR1 = 1;
        while(1)
        {   
            stopwatchdisplay();
        }
    }
    void stopwatchdisplay()
    {   
        unsigned char buff;
        ledbuff[0]=ledchar[DecimalPart%10];
        ledbuff[1]=ledchar[DecimalPart/10];
        ledbuff[2]=ledchar[IntegerPart%10];
        buff=IntegerPart/10;
        if(buff==0)
            ledbuff[3]=0x00;
        else
            ledbuff[3]=ledchar[IntegerPart/10];
        ledbuff[2] |= 0x80;
         
        P0=ledbuff[0];
        U1=1;
        U1=0;
        P0=0xFF;
        U2=1;
        P0=0xF7;
        U2=0;
        delayms(1);
        
        P0=ledbuff[1];
        U1=1;
        U1=0;
        P0=0xFF;
        U2=1;
        P0=0xFB;
        U2=0;
        delayms(1);
        
        P0=ledbuff[2];
        U1=1;
        U1=0;
        P0=0xFF;
        U2=1;
        P0=0xFD;
        U2=0;
        delayms(1);
        
        P0=ledbuff[3];
        U1=1;
        U1=0;
        P0=0xFF;
        U2=1;
        P0=0xFE;
        U2=0;
        delayms(1);
    }
    void stopwatchcount()
    {
        if(stopwatchrunstop)
        {   
            DecimalPart++;
            if(DecimalPart>=100)
            {   
                DecimalPart = 0;
                IntegerPart++;
                if(IntegerPart>=60)
                {   IntegerPart=0;
                    stopwatchrunstop = 0;
                }
            }
            
        }
    }
    void runstop()
    {
        if(stopwatchrunstop)
            stopwatchrunstop = 0;
        else
            stopwatchrunstop = 1;
        
    }
    void refresh()
    {
        DecimalPart = 0;
        IntegerPart = 0;
        stopwatchrunstop = 0;
    }
    void keyscan()
    {   
        unsigned char tmp;
        P3 = 0xFE;     
        tmp = P3;      
        tmp &= 0xF0;   
        if(tmp!=0xF0)  
        {
            delayms(10);   
            tmp = P3;      
            tmp &= 0xF0;   
            if(tmp!=0xF0)   
            {
                tmp=P3;
                switch(tmp)
                {
                    case 0xEE:runstop();break;
                    case 0xDE:refresh();break;
                    default :break;
                }
                while(tmp!=0xF0)  
                {
                    tmp = P3;
                    tmp &= 0xF0;
                }
            }
        }
    }
    void InterruptTimer0() interrupt 3
    {
        TH1 = 0xDC;
        TL1 = 0x00;
        stopwatchcount();
        keyscan();
    }
    void delayms(unsigned int ms)
    {
        int x,y;
        for(x=ms;x>0;x--)
            for(y=110;y>0;y--);
    }
    
    展开全文
  • 该系统采用STC89C52单片机为中心器件,利用其定时器/计数器定时和记数的原理,结合显示电路、LED数码管以及外部中断电路来设计计时器,使得系统能够实现四位LED显示,显示时间为00.00~99.99秒,计时精度为0.01秒,...
  • //仅改变后四位(置零) TMOD |= 0X01; TH0 = T0RH; TL0 = T0RL; ET0 = 1; TR0 = 1; } void StopwatchDisplay()//显示函数(数字分割显示) { signed char i; u8 buf[4]; // LedBuff[0] = ...
  • 单片机实现秒表倒数计数器

    热门讨论 2020-02-29 10:17:43
    单片机实现秒表计数器 最近博主在学习单片机的课程,这快到期末考试了,老师让做个简单的课设,我看了看老师给的课题,感觉这个比较容易实现,今天下午花了两个小时左右的时间,把仿真程序电路图画好了,现在分享...
  • 由STC89C51单片机+数码管显示模块+按键模块+报警提示及指示模块等构成 具体功能: 1、秒表精度为0.01s 2、按键可以实现启动、暂停及清零; 3、可以通过按键打开或关闭提醒功能,每一秒提醒一次。
  • 基于51单片机—多功能秒表

    千次阅读 2018-07-10 13:10:20
    1.两片573驱动三个数码管显示 2.显示范围:00.0~99.9 3.一次计时中可储4个数据在EEPROM中 4.两个按键控制,暂停,启动,存数,翻页
  • 秒表计数器(两数) 一.
  • 二、编写程序 /******************************************************************************************************************** ---- @Project: LED-74HC595 ---- @File: main.c ---- @Edit: ZHQ ---- ...
  • 四位数码管显示程序

    2020-07-26 23:30:31
    基于51单片机,用C语言编程,四位数码管显示秒表,使用P1和P0口
  • c595四位数码管在STM32上计时显示,在阅读了51的程序后大概了解了主要代码思路,花了一点时间把程序移植到了STM32上,写了一个计时的功能。和大家分享下。我手上的单片机是**STM32f103C8T6.**
  • 单片机MSP430G2553四位扫描数码管动态显示程序,验证结果:程序运行时,数码管显示“0000”十六进制数值,当按键按下,该16进制数值不断增加。其他程序比如按键中断、定时器中断、PWM等单片机MSP430G2553系列代码我...
  • STC89C52RC数码管秒表程序编写

    千次阅读 2014-06-30 12:10:08
    数码管显示秒表 具体要求,采用动态扫描的方式让,6个数码管前三个显示秒数,后两个显示毫秒。第个不用。秒数精确到1%。
  • c595四位数码管在STM32上计时显示

    千次阅读 2019-01-17 10:21:07
    在某宝上买了这个四位数码管(3642BS)打算用来做项目,没想到给的例程只有51和arduino的,并没有给出STM32的驱动程序。在阅读了51的程序后大概了解了主要代码思路,花了一点时间把程序移植到了STM32上,写了一个...
  • 51单片机按键控制数码管加减和秒表

    千次阅读 2018-12-23 21:24:19
    #include&amp;lt;reg52.h&amp;gt; #define uchar unsigned char #define uint unsigned int sbit k1=P3^4; sbit k2=P3^5; sbit k3=P3^6; sbit k4=P3^7; sbit du=P2^6;...uchar code table...
  • 4.16 1602液晶工作于四位模式实时显示当前时间 4.17 2×20串行字符液晶演示 4.18 LGM12864液晶显示程序 4.19 PG160128A液晶图文演示 4.21 TG126410液晶串行模式演示 4.21 用带SPI接口的MCP23S17扩展16位通用IO...
1 2 3 4 5 ... 9
收藏数 166
精华内容 66
关键字:

单片机四位秒表程序