定时器可调时钟,proteus进行仿真

项目要求使用数码管进行时钟展示,按键可以调节时,分,秒的数值。

proteus仿真图如下:

源码如下:

头文件head.h:

#include<stdio.h>
#include<STC89C5xRC.H>
#include<intrins.h>

//定时器t0的初始值,10000是定时的时间,10000 = 10ms
#define T1MS 65536-11059200/12/10000

typedef unsigned int u16;  //无符号十六位
typedef unsigned char u8;     //无符号八位

extern u8 hour,minute,second,number;

void delayMs(unsigned int z);

void displaySingle_digitalTube(u8 dig,u8 num);

void displayTime(u8 hour,u8 minute,u8 second);

void timer_isr();

void initTimer();

void isButton();

主函数main.c:

#include"head.h"

u8 hour = 0; //时
u8 minute = 0;//分
u8 second = 1;//秒

u8 number = 0;//定时器的次数

void main()
{
    initTimer();
    //主程序,反复显示数码管上的数字
    while(1)
    {
        displayTime(hour,minute,second);
        isButton();
    }
}

子程序 定时器可调时钟.c:

#include"head.h"

void delayMs(unsigned int z)
{
  unsigned int x,y;
  for(x = z;x > 0;x--)
     for(y = 114;y > 0;y--);
}

//第dig个数码管显示num值
void displaySingle_digitalTube(u8 dig,u8 num)
{
    //共阳极数码管的段码表,不带小数点
//    unsigned char table[16] = {0xC0, 0xF9, 0xA4, 0xB0,
//                                                         0x99, 0x92, 0x82, 0xF8,
//                                                          0x80, 0x90, 0x88, 0x83,
//                                                         0xC6, 0xA1, 0x86, 0x8E};
    //带小数点
//    unsigned char table[16]    = {0x40, 0x79, 0x24, 0x30,
//                                                         0x19, 0x12, 0x02, 0x78,
//                                                         0x00, 0x10, 0x08, 0x03,
//                                                         0x46, 0x21, 0x06, 0x0E};            

    //共阴极
    unsigned char table[17] = {0x3f, 0x06, 0x5b, 0x4f,
                                                         0x66, 0x6d, 0x7d, 0x07,
                                                         0x7f, 0x6f, 0x77, 0x7c,
                                                         0x39, 0x5e, 0x79, 0x71,0x40};                                    
                                                        
    //片选
 u8 Dig[8] = {254,253,251,247,239,223,191,127};
        
    //片选
    P2 = Dig[dig - 1];
    //展示数字
    P3 = table[num];
}


void displayTime(u8 hour,u8 minute,u8 second)
{
    u8 hour1 = hour/10;
    u8 hour2 = hour%10;
    
    u8 minute1 = minute/10;
    u8 minute2 = minute%10;
    
    u8 second1 = second/10;
    u8 second2 = second%10;
    
    //显示小时
    displaySingle_digitalTube(1,hour1);
    displaySingle_digitalTube(2,hour2);
    displaySingle_digitalTube(3,16);
    //显示分钟
    displaySingle_digitalTube(4,minute1);
    displaySingle_digitalTube(5,minute2);
    displaySingle_digitalTube(6,16);
    //显示秒
    displaySingle_digitalTube(7,second1);
    displaySingle_digitalTube(8,second2);
}

// 中断服务程序
void timer_isr() interrupt 1 using 1 {
    
    //每隔10ms,number加一,numer等于十的时候就相当于定时了一秒
    number++;
    if(number == 100)
    {

        second++;
        if(second == 60)
        {
            minute++;
            second = 0;
            if(minute == 60)
            {
                hour++;
                minute = 0;
                if(hour == 24)
                {
                    hour = 0;
                }
            }
        }
    // 重新加载定时器

    TL0 = T1MS;
    TH0 = T1MS >> 8;
    //重新计数
    number = 0;
    }
}

//定时器0的初始化
void initTimer()
{
    // 初始化定时器0,用于产生10ms的中断    
    TL0 = T1MS;
    TH0 = T1MS >> 8;
    
    TMOD = 0x01; // 设置定时器0工作模式1,8位自动重载
    ET0 = 1; // 开启定时器0中断
    EA = 1; // 开启整个中断系统
    TR0 = 1; // 启动定时器0
}

//判断是否有按键按下
void isButton()
{
    //按键,时加一
    if(P00 == 0)
    {
        delayMs(150);
        if(P00 == 0){
            hour++;
            if(hour == 24)
            {
                hour = 0;
            }
        }
    }
    //按键,分加一
    if(P01 == 0)
    {
        delayMs(150);
        if(P01 == 0)
        {
            minute++;
            if(minute == 60)
            {
                hour ++;
                minute = 0;
                if(hour == 24)
                {hour = 0;}
            }
        }
    }
    //按键,秒加一
    if(P02 == 0)
    {
        delayMs(200); //按键消抖
        if(P02 == 0)
        {
            second++;
            if(second == 60)
            {
                second = 0;
                minute++;
                if(minute == 60)
                {
                    minute = 0;
                    hour ++;
                    if(hour == 24)
                    {
                    hour = 0;
                    }
                }
            }
        }
    }
}

        我做的这个感觉有点奇怪,感觉秒针加一的速度不太对劲,应该是定时器初始值计算不对,定时器计时和标红的代码有关。如果有大佬知道怎么修改,望指正。

  • 21
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现简易秒表的定时器,可以使用计数器和定时器中断。 具体步骤如下: 1. 将计数器初值设为 0。 2. 设置定时器时钟源和计数频率。 3. 启动定时器,并设置定时器中断。 4. 在定时器中断服务程序中,每次定时器计数到指定值时,将计数器加 1,并清除定时器计数器。 5. 在需要显示秒表时间的时候,读取计数器的值并转换成秒表格式。 下面是一个简单的示例代码: ```c #include <reg52.h> #define COUNT_PER_SECOND 100 // 定时器每秒计数次数 #define TIMER_TH0_INIT_VALUE (65536 - COUNT_PER_SECOND) unsigned char count = 0; // 计数器 void timer0_isr() interrupt 1 { TH0 = TIMER_TH0_INIT_VALUE / 256; TL0 = TIMER_TH0_INIT_VALUE % 256; count++; // 计数器加 1 } void main() { TMOD = 0x01; // 定时器 0 工作在模式 1 TH0 = TIMER_TH0_INIT_VALUE / 256; TL0 = TIMER_TH0_INIT_VALUE % 256; ET0 = 1; // 允许定时器 0 中断 EA = 1; // 允许中断 TR0 = 1; // 启动定时器 0 while (1) { // 在需要显示秒表时间的时候,读取计数器的值并转换成秒表格式 // 省略转换代码 } } ``` 在 Proteus仿真时,需要添加一个 8051 微控制器和定时器模块,并将二者连接起来。具体步骤如下: 1. 打开 Proteus,选择“New design”。 2. 在左侧的元件库中选择“Microcontroller”并拖动到画布上。 3. 双击微控制器,弹出“Edit Component”对话框,选择“AT89C52”型号并确定。 4. 在左侧元件库中选择“Timer”并拖动到画布上。 5. 双击定时器模块,弹出“Edit Component”对话框,选择“NE555”型号并确定。 6. 将微控制器的 P3.4 引脚与定时器的 GATE 引脚连接。 7. 将微控制器的 P3.5 引脚与定时器的 OUT 引脚连接。 8. 完成连接后,保存并运行仿真。 完成上述步骤后,就可以通过仿真来测试板子的秒表功能了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值