netsplan 发表于 2023-1-23 01:34:44

秒表源码分享

#include <reg52.h>
#include <intrins.h>

typedef unsigned char u8;
typedef unsigned int u16;

#define SMG_A_DP_PORT        P0        //使用宏定义数码管段码口

//定义数码管位选信号控制脚
#define SMG_POS_PORT         P2

sbit KEY3=P3^2;// K3
sbit KEY4=P3^3;// K4

//共阴极数码管显示0~F的段码数据                                                                                                                                                  -    .
u8 gsmg_code={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0,0x40,0x80};

// 显示样式:00.00.00.00
u8 hour=0;      // 时           1位
u8 minute=0;      // 分           2位
u8 second=0;      // 秒数2位
u8 dot=0;// 小数部分1位      
u8 vbuf={0};   // 8各数码管,编码索引,缓存
u16 speed=10;   // 计数频率

/**
* @brief延时 10us, 1s=10^6s
*
* @param ten_us
*/
void delay_10us(u16 ten_us)
{
        while(ten_us--);
}

/**
* @brief 延时 ms
*
* @param ms 毫秒数
*/
void delay_ms(u16 ms)
{
        u16 i,j;
        for(i=ms;i>0;i--)
                for(j=110;j>0;j--);
}

/**
* @brief 外部中断0 1 初始化
*
*/
void extint_init()
{
        EA=1; //打开总终端开关
        EX0=1; // 打开外部中断0
        IT0=1; // 设置外部中断的出发方式

        EX1=1; // 打开外部中断0
        IT1=1; // 设置外部中断的出发方式
}

/**
* @brief 定时器0 初始化
*
*/
void timer_init()
{
   TMOD=0X01;   // 定时器0 工作方式位1
   TH0=0xd8;// 定时器赋初值,定时10ms
   TL0=0xf0;

   EA=1;        //打开总终端开关
   //TR0=1;    // 定时器0 打开 开始计时
   ET0=1;    // 打开定时器0 中断允许
}
/**
* @brief 单个数码管 显示
*
* @param pos   数码管位置
* @param value 数码管值的索引
*/
void smg_display(u8 pos,u8 value)
{
        SMG_POS_PORT= ~(pos<<2);   //P2的2 3 4 点
        SMG_A_DP_PORT= gsmg_code;//传送段选数据
        delay_10us(100);//延时一段时间,等待显示稳定
        SMG_A_DP_PORT=0x00;//消影
}

/**
* @brief 数码管显示
*
*/
void smg_show()
{
u8 i;
for(i=0;i<8;i++)
{
        smg_display(i,vbuf);
}
delay_ms(10);//延时一段时间,等待显示稳定
}

/**
* @brief 数码管值更新
* 显示样式:00.00.00.00
*/
void smg_update()
{
vbuf=hour/10;
vbuf=(hour % 10) + 19;
vbuf=minute/10;
vbuf=(minute % 10) + 19;       
vbuf=second/10;
vbuf=(second % 10) + 19;               
vbuf=dot/10;
vbuf=dot % 10;       
}

/**
* @brief 数码管编码初始化
* 0-9 补个点 ,填充到数码管编码数组钟
*
*/
void seg_code_init()
{
          u8 i;
          for(i=0;i<10;i++)
          {
                  gsmg_code=gsmg_code | gsmg_code;
          }
}
void main()
{
        seg_code_init();
        extint_init();
        speed=1;
        timer_init();
        smg_update();

       
        while(1)
        {
           smg_show();
        }
}

/**
* @brief 外部中断0
* 按钮3,功能:控制定时器0 0启动/1暂停 切换,初始状态暂停
*
*/
void exti0() interrupt 0
{
   delay_ms(10);
   if(KEY3 == 0)
   {       
       TR0= !TR0 ; //定时器00启动/1暂停 切换
   }
}
/**
* @brief 外部中断1
* 按钮4,功能,复位: 定时器关闭,数据置0
*/
void exti1() interrupt 2
{
   delay_ms(10);
   if(KEY4 == 0)
   {
                TR0=0; // 定时器停止
                hour=0;      // 时           1位
                minute=0;      // 分           2位
                second=0;      // 秒数2位
                dot=0;// 小数部分1?
                smg_update();
   }
}
/**
* @brief 定时器0 中断
*
*/
void timer() interrupt 1
{
        static u16 i=0;
   TH0=0xd8;// 定时器赋初值,定时10ms
   TL0=0xf0;

        i++;
        if(i >= speed)// 10ms 的倍数
        {
           dot++ ;   
               
           if(dot >= 100)//秒
           {
              dot=0;
                  second++;
                  if( second>= 60)// 分
                  {
                  second=0;
                        minute++;
                        if( minute>= 60)//时
                        {
                          minute=0;
                          hour++;
                          if(hour == 100 )
                          {
                                  hour=0;
                          }
                        }
                  }
           }
           smg_update();// 数码管缓存更新
           i=0;
        }
}


tao4091 发表于 2023-1-23 18:28:48

亲爱的楼主,您发的帖子真是太棒了。
页: [1]
查看完整版本: 秒表源码分享