找回密码
 立即注册

QQ登录

只需一步,快速开始

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

STC单片机做的个性时钟 附程序 制作出来的实物图

[复制链接]
ID:41347 发表于 2022-9-27 10:40 | 显示全部楼层 |阅读模式
共阳数码管 LED指示灯共阳
W1-位1-P2.4
W2-位2-P2.7
W3-位3-P2.6
W4-位4-P2.5
数码管段:P0口
LED指示灯阴极;P1口+P2.0--P2.3口
K1 P3.2
K2 P3.3
共阳是码管顺序:由上至下顺时针 W1 a f W2 W3 b---W4 g c dp d e

制作出来的实物图如下:
psu.jpg psu (2).jpg psu (1).jpg
单片机源程序如下:
/***************************************************************************
数码管的显示 LED 个性时钟
单片机:STC12C5A60S2或STC89C52RC
调时间时按键有连发功能
******************************************************************************/
//头文件:
#include "reg52.h"
#define yes  1
#define no   0
#define keyon  0    //按键开
#define keyoff  1   //按键关
#define uchar unsigned char
#define uint unsigned int
//变量定义:
unsigned char qian,bai,shi,ge;
unsigned char hour,minute,secont;
unsigned int count;
unsigned char miaocount;
code unsigned char table[]=
   {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳数码管
code unsigned char table1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
     //表:共阳带点数码管 0-9
code unsigned char led[]={0xff,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0xf7,
                              0xfb,0xfd,0xfe};//LED显示数组
#define hidden 0xff;
//引脚定义:  
sbit SMG_q=P2^4; //定义数码管阳级控制脚(千位)
sbit SMG_b=P2^7; //定义数码管阳级控制脚(百位)
sbit SMG_s=P2^6; //定义数码管阳级控制脚(十位)
sbit SMG_g=P2^5; //定义数码管阳级控制脚(个位)
//KEY 调整
sbit key1=P3^2;
sbit key2=P3^3;
bit IS5ms; //5ms 标志位
bit IS10ms;//10ms标志位
uchar w;//定义数码管位变量
uchar preset=100;//预设置用来调整时间的精度
/***********************************************/
void init()
     {
    hour=0;  
    minute=0;   //初始时间设置
    TMOD=0x11;//16位定时器0和定时器1的工作方式
    TH0=(65536-10027)/256;
    TL0=(65566-10027)%256;  //10ms 细调
    EA=1;  //总中断允许
    ET0=1; //允许TMR0中断
    TR0=1;  //启动定时器
    TH1=(65536-5000)/256;
    TL1=(65566-5000)%256;  //5ms
    ET1=1;//允许TMR1中断
    TR1=1;//启动TMR1
  }
/***************************************************/
  //显示函数,参数为显示内容
void display()
{  
        qian=hour/10;  //显示时间的千位
          bai=hour%10;   //显示时间的百位
          shi=minute/10;   //显示时间的十位
          ge=minute%10;     //显示时间的个位     
   if((w==1)&&(qian==0))
      {
    SMG_q=1;
       SMG_b=1;
       SMG_s=1;  
       SMG_g=1;
       P0=hidden; //千位是0的话进行消隐不显示
   }else
   {
    SMG_q=0;
       SMG_b=1;
       SMG_s=1;  
       SMG_g=1;
       P0=table[qian]; //输出显示内容
   }
   if(w==2)      //百位
      {
    SMG_q=1;
       SMG_b=0;
       SMG_s=1;  
       SMG_g=1;
       P0=table1[bai]; //输出显示内容
   }
   if(w==3)      //十位
      {
    SMG_q=1;
       SMG_b=1;
       SMG_s=0;  
       SMG_g=1;
       P0=table[shi]; //输出显示内容
   }
   if(w==4)      //个位
      {
    SMG_q=1;
       SMG_b=1;
       SMG_s=1;  
       SMG_g=0;
       P0=table[ge]; //输出显示内容
   }
w++;       //位循环显示
if(w>4)
   {
    w=1;
   }
}  
/*******************************/
/******************************/
void timer0() interrupt 1  //定时器0中断
           {
        static uchar timecount,num=0;
        TH0=(65536-10027)/256;
                TL0=(65566-10027)%256;  //10ms
       timecount++;    //10MS*100=1000ms时间计数
       if(timecount>=preset)  //预置值
          {
          timecount=0;   //清0时间计数
       ++num;      //LED位数+
       if(num<=8)     //P1口的8位显示
         { P2=0xff;
           P1=led[num];      
         }else if((num>=9)&&(num<=12))  //P2口的4位显示
                 {
            P1=0xff;
            P2=led[num];
         if(num==12)
           {  
          num=0;  
           }
            }
         
         
         if(++secont>59)    //如果59秒到
         {
          secont=0;
          minute++;     //分钟+
       if(minute>59)    //如果59分到
          {
           minute=0;
           hour++;     //时+
        if(hour>23)   //如果时间大于23点
           {
             hour=0; //重回到0
           }
          }
         }
       }
     }

/***********************/
void timer1(void) interrupt 3
       {
     static uchar count;
       TH1=(65536-5000)/256;
       TL1=(65566-5000)%256;  //5ms,用来进行数码管扫描
    IS5ms=yes;
    count++;
    if(count==2)    //  每到10MS进行一次键盘扫描
      {
    count=0;
    IS10ms=yes;   //10MS到的标志
   }
     
    }
/********************************/
uchar GetKey()   //按键扫描函数
{
uchar keyRetu=0;    //返回的按键值
static uchar s_keyState=0,keyTime=0; //按键状态,按键按下的时间计数器
switch (s_keyState)
{
   case 0:
    if(key1==keyon)   //检测到有按键按下,转到状态1,相当于是消抖过程
    {
     s_keyState=1;
    }
if(key2==keyon)
{
  s_keyState=4;
}
    break;
   case 1:
    if(key1==keyon)    //再次检测到有按键,转到状态2
    {
     s_keyState=2;
     keyTime=0;       //清零按键时间计数器
    }
    else
    {
     s_keyState=0; //没有检测到按键,说明状态0检测到是一个抖动,重新转到状态0
    }
    break;
   case 2:
    if(key1==keyoff)    //检测到按键松开
    {
     s_keyState=0; //状态转到状态0
     keyRetu=1;   //输出1
    }
    else
    {
     if(++keyTime>=25)    //按下时间>0.5s
     {
      s_keyState=3;   //转到状态3
      keyTime=0;   //清零按键时间计数器
      keyRetu=1;    // 输出1
     }
    }
    break;
   case 3:
    if(key1==keyoff)    //检测到按键松开
    {
     s_keyState=0; //状态转到状态0
    }
    else
    {
     if(++keyTime>=10)    //按下时间>0.2s
     {
      keyTime=0;   //清零按键时间计数器
      keyRetu=1;    // 输出1
     }
    }
    break;
  case 4:
    if(key2==keyon)    //再次检测到有按键,转到状态5
    {
     s_keyState=5;
     keyTime=0;   //清零按键时间计数器
    }
    else
    {
     s_keyState=0; //没有检测到按键,说明状态0检测到是一个抖动,重新转到状态0
    }
    break;
//
   case 5:
    if(key2==keyoff)    //检测到按键松开
    {
     s_keyState=0; //状态转到状态0
     keyRetu=2;   //输出2
    }
    else
    {
     if(++keyTime>=25)    //按下时间>0.5s
     {
      s_keyState=6;   //转到状态6
      keyTime=0;   //清零按键时间计数器
      keyRetu=2;    // 输出2
     }
    }
    break;
//
case 6:
    if(key2==keyoff)    //检测到按键松开
    {
     s_keyState=0; //状态转到状态0
    }
    else
    {
     if(++keyTime>=10)    //按下时间>0.2s
     {
      keyTime=0;   //清零按键时间计数器
      keyRetu=2;    // 输出2
     }
    }
    break;
}
return keyRetu;   //返回键值
}
/**********************************************/
//主函数,C语言的入口函数:  
void main()
{
init(); //端口及定时器初始化
while(1)
      //死循环
{
        if(IS5ms==yes)  //5MS到的标志
        {
       IS5ms=no;
      display();  //调用显示函数
     }
      if(IS10ms==yes)   //10MS到的标志
      {
        IS10ms=no;
      switch(GetKey()) //扫描按键得到键值
      {
      case 1:    //键值处理
       hour++;
    if(hour>23)
      {
       hour=0;
      }
      break;
      case 2:      //键值处理
       minute++;
    if(minute>59)
      {
       minute=0;
      }
      break;
      }
      
      }
   
              
        
      
}
}

评分

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

查看全部评分

回复

使用道具 举报

ID:16255 发表于 2022-9-27 18:56 | 显示全部楼层
确定挺有“个性”的。
回复

使用道具 举报

ID:74784 发表于 2022-9-27 21:49 | 显示全部楼层
我做的是60个模拟秒:


3代床头表.jpg

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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