凌阳61单片机使用7段数码管显示数字时钟的程序

原创 2006年06月18日 18:31:00

#include <SPCE061v004.h>

#include <unspmacro.h>

//中断函数定义

void IRQ1(void) __attribute__((ISR));

void IRQ5(void) __attribute__((ISR));

void IRQ6(void) __attribute__((ISR));

enum { RUN, CHGSECOND, CHGMINUTE, CHGHOUR } clock_status;   //时钟的状态

unsigned int hour,minute,second;

unsigned int show_hour, show_minute, show_second;

enum { NOKEY, PRESSING, PRESSED } key_status;           //键盘按下与否的状态

unsigned key_code;

// 7LED数码管的字形码,采用高八位输出,决定显示的字形,如: '0''1'

const unsigned int zhixingma[] = {  0x3f00, 0x0600, 0x5b00, 0x4f00,

                                    0x6600, 0x6d00, 0x7c00, 0x0700,

                                    0x7f00,0x6f00 };

// 数码管选择的"位段码",决定哪一位数码管显示

const unsigned int weiduanma[] = {0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040};

//数码管的两个DD引脚, 为时,中间的冒号亮

const unsigned int wei_DD = 0x0081;

 

void display(unsigned int wei, unsigned int number)

{

    *P_IOA_Data = zhixingma[number];

    //设置位段码时,不能改变冒号的状态  

    *P_IOB_Data = weiduanma[wei] | (*P_IOB_Buffer & wei_DD);

}

//取反数码管中间的冒号

void opposite_dots()

{  

*P_IOB_Data = wei_DD ^ (*P_IOB_Buffer);

}

void delay(unsigned int howlong)

{

    while(howlong--){

        unsigned int temp = 0x00ff;

        *P_Watchdog_Clear = 1;

        while(temp--);

    }

}

void init()

{  

INT_OFF();

    *P_IOA_Dir = 0xff00;

    *P_IOA_Attrib = 0xff00;

    *P_IOB_Dir = 0x00ff;

    *P_IOB_Attrib = 0x00ff;

    *P_TimerA_Data = 0xffff - 256;

    *P_TimerA_Ctrl = C_SourceA_1 | C_SourceB_256Hz;

    *P_INT_Ctrl = C_IRQ1_TMA | C_IRQ6_TMB2 | C_IRQ5_2Hz;

    INT_IRQ();

}

void change_clock()

{  

unsigned int key_code = get_key();

    static unsigned int max;

    switch(key_code){   // key_code == 0 will do nothing

        case 1:

            switch( clock_status ){

            case CHGSECOND:

                if(++second == 60) second = 0;

                break;

            case CHGMINUTE:

                if(++minute == 60) minute = 0;

                break;

            case CHGHOUR:

                if(++hour == 24) hour =0;

                break;

            default:

                break;

            }

            break;

        case 2:

            switch( clock_status ){

            case CHGSECOND:

                if(--second == 0) second = 59;

                break;

            case CHGMINUTE:

                if(--minute == 0) minute = 59;

                break;

            case CHGHOUR:

                if(--hour == 0) hour = 23;

                break;

            default:

                break;

            }

            break;

        case 3:    

            switch( clock_status ){

            case RUN:

                clock_status = CHGSECOND;

                break;

            case CHGSECOND:

                clock_status = CHGMINUTE;

                break;

            case CHGMINUTE:

                clock_status = CHGHOUR;

                break;

            case CHGHOUR:

                clock_status = RUN;

                break;

            }

            break;

        default:

            break;

    }

}

 

int main()

{  

init();

    while(1){

        change_clock();    

        if(show_second){

            display(5, second % 10);

            delay(1);  

            display(4, second / 10);

            delay(1);

        }

        if(show_minute){

            display(3, minute % 10);

            delay(1);

            display(2, minute / 10);

            delay(1);

        }

        if(show_hour){

            display(1, hour % 10);

            delay(1);

            display(0, hour / 10);

            delay(1);

        }

    }

}

 

void IRQ1()

{

    //时钟计数中断

    if( (C_IRQ1_TMA & *P_INT_Ctrl) != 0 )

    {   if( clock_status == RUN )

        {   second++;

            if(second >= 60 ) second=0, minute++;

            if(minute >= 60 ) minute=0, hour++;

            if(hour >= 24 ) hour=0;

        }

        *P_INT_Clear = C_IRQ1_TMA;

    }

}

 

void IRQ5()

{// 数码管闪烁

    if( (C_IRQ5_2Hz & *P_INT_Ctrl) != 0)

    {

switch(clock_status){

        case RUN:

            opposite_dots();

            show_hour = show_minute = show_second = 0xffff;

            break;

        case CHGSECOND:

            show_second ^= 0xffff;

            show_minute = show_hour = 0xffff;

            break;

        case CHGMINUTE:

            show_minute ^= 0xffff;

            show_second = show_hour = 0xffff;

            break;

        case CHGHOUR:

            show_hour ^= 0xffff;

            show_second = show_minute = 0xffff;

            break;

        }

        *P_INT_Clear = C_IRQ5_2Hz;

    }

}

 

 

 

 

void IRQ6()

{   // 10ms扫描一次键盘

    static unsigned int old_key = 0;       

    static unsigned int key_count = 0;

    unsigned int current_key;

   

    if( (C_IRQ6_TMB2 & *P_INT_Ctrl) != 0)

    {   current_key = *P_IOA_Data & 0x0007;

        if( current_key != 0)

        {           //有按键

            if( key_status == NOKEY )  

            {   old_key = current_key;

                key_count++;

                key_status = PRESSING;

            }else{

                if( current_key == old_key) //不相等,抖动

                {

                    if( ++key_count >= 5)  

//>5次扫描的值相等,说明不是抖动,判断按键值

                    {   if(current_key == 0x0001) key_code = 1;

                        if(current_key == 0x0002) key_code = 2;

                        if(current_key == 0x0004) key_code = 3;

                    }

                }else{

                    // 抖动

                    old_key = 0;

                    key_count = 0;

                    key_status = NOKEY;

                }

            }

        }else{          //无按键

            old_key = 0;

            key_count = 0;

            if( key_status == PRESSING ) key_status = PRESSED;  //按键释放了

        }

        *P_INT_Clear = C_IRQ6_TMB2;

    }

}

   

汇编语言编程实例---串行控制七段数码管

串行控制七段数码管 ORG 00H START: MOV 30H,#1 ; 低位七段数码管DS0显示数据 MOV 31H,#5 ; 高位七段数...
  • yang889999888
  • yang889999888
  • 2017年06月03日 10:52
  • 414

利用单片机的数码管模拟时钟的显示时间

在八段数码管上显示时间的驱动程序
  • baidu_35534327
  • baidu_35534327
  • 2016年09月16日 20:49
  • 1122

单片机编程:让led数码管显示数字0到9

led数码管在单片机系统中应用非常普遍,是由发光二极管构成的。数码管由7个发光二极管组成的一个“日”字形,如果需要显示小数点,那么就再加上一个点,就是8段数码管。     数码管显示亮度高,相应...
  • zhang5476499
  • zhang5476499
  • 2015年05月11日 17:07
  • 11200

51单片机入门之四:静态数码管

本文旨在介绍单片机入门的基础知识,为初接触或即将接触单片的新手提供一个入门指导。本文章会陆续推出,隔几天一个章节。所使用单片机为ATMEL公司的AT89C52,软件为PROTEUS和KEIL;只提供原...
  • zhenxing2000
  • zhenxing2000
  • 2016年02月20日 20:37
  • 1245

7段数码管显示驱动电路参数推导

以三极管驱动的7段数码管驱动电流计算及电阻参数选择
  • electrocrazy
  • electrocrazy
  • 2017年03月04日 14:19
  • 1974

1~99秒倒计时数码管显示C程序+Proteus仿真

1~99秒倒计时数码管显示C程序+Proteus仿真文件。 优化了程序,使用51单片机内部定时器,可以实现1-99秒内倒计时。 仿真效果为:   源程序为: /* 调试环境:Proteus 7...
  • tcjy1000
  • tcjy1000
  • 2014年02月17日 12:44
  • 3698

xilinx FPGA实现数字钟——数码管显示

这两天学习xilinx的板子,做了一个数码管显示的数字时钟,本设计实现了数字时钟的数码管显示,没有实现调时间功能,现将实现过程记录下来。供有类似需要的童鞋做个参考。  设计主要分为三个模块:时钟分频模...
  • baijingdong
  • baijingdong
  • 2014年03月01日 17:11
  • 3619

51单片机 数码管的静态显示和动态显示

51单片机 数码管的静态显示和动态显示 附有代码示例
  • yunfeiyang62
  • yunfeiyang62
  • 2015年09月05日 16:26
  • 6323

7段数码管 数值编码

共阳极芯片 如:7SEG-MPX4-CA  其中 CA: Common Anode 单片机LED共阳极段码表【0-F】 DB 0c0H,0f9H,0a4H,0b0H,99H,9...
  • Flower195
  • Flower195
  • 2013年10月30日 09:24
  • 1606

51单片机入门之五:数码管显示(动态)

本文旨在介绍单片机入门的基础知识,为初接触或即将接触单片的新手提供一个入门指导。本文章会陆续推出,隔几天一个章节。所使用单片机为ATMEL公司的AT89C52,软件为PROTEUS和KEIL;只提供原...
  • zhenxing2000
  • zhenxing2000
  • 2016年02月23日 21:18
  • 2395
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:凌阳61单片机使用7段数码管显示数字时钟的程序
举报原因:
原因补充:

(最多只允许输入30个字)