用MCU定时器/中断计数秒和分钟? [英] Count seconds and minutes with MCU timer/interrupt?

查看:209
本文介绍了用MCU定时器/中断计数秒和分钟?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找出如何为C8051F020 MCU创建一个计时器。以下代码使用以下公式传递给 init_Timer2()的值:



65535-(0.1 /( 12/2000000)= 48868。



我设置了每次执行的计时器,每10次计数一次,这是基于上述公式48868传递到 init_Timer2 将产生0.1秒的延迟,每秒钟需要10个,但是当我测试定时器的时候有点快,10点秒钟定时器报告11秒,在20秒钟定时器报告22秒,我想要尽可能接近完美的第二个可以。



这是我的代码:

  #include< compiler_defs.h> 
#include< C8051F020_defs.h>

void init_Clock(void);
void init_Watchdog(void);
void init_Ports(void);
void init_Timer2(unsigned int counting);
void start_Timer2(void) ;
void timer2_ISR(void);

unsigned int timer2_Count;
unsigned int秒;
unsigned int minutes;

int main(void)
{
init_Clock();
init_Watchdog();
init_Ports();
start_Timer2();

P5& = 0xFF;

while(1);
}

// ================================ ========================
//函数
// =========== ==================================================
void init_Clock(void)
{
OSCICN = 0x04; // 2Mhz
// OSCICN = 0x07; // 16Mhz
}

void init_Watchdog(void)
{
//禁用看门狗定时器
WDTCN = 0xDE;
WDTCN = 0xAD;
}

void init_Ports(void)
{
XBR0 = 0x00;
XBR1 = 0x00;
XBR2 = 0x40;

P0 = 0x00;
P0MDOUT = 0x00;
P5 = 0x00; //将P5设为1111
P74OUT = 0x08; //设置P5 4 - 7(LED)推拉(输出)
}

void init_Timer2(unsigned int counting)
{
CKCON = 0x00; //将所有定时器设置为系统时钟除以12

T2CON = 0x00; //将定时器2设置为定时器模式

RCAP2 =计数;

T2 = 0xFFFF; // 655535

IE | = 0x20; //启用定时器2

T2CON | = 0x04; //启动计时器2
}

void start_Timer2(void)
{
EA = 0;

init_Timer2(48868);

EA = 1;
}

void timer2_ISR(void)interrupt 5
{
T2CON& =〜(0x80);

P5 ^ = 0xF0;

timer2_Count ++;

if(timer2_Count%10 == 0)
{
秒++;
}

if(seconds%60 == 0&& seconds!= 0)
{
minutes ++;
}
}


解决方案

在回答这个问题时不能完全信用。每个人都贡献最后我用22.1184Mhz的外部时钟。以下代码片段是原始邮政编码部分,已更改为使其正常工作:

  void init_Clock(void) 
{
OSCXCN = 0x67; // External 22.1184Mhz

while(!(OSCXCN& 0x80));

OSCICN = 0x88;
}

  void start_Timer2(void)
{
EA = 0;

//外部时钟
init_Timer2(47103);

EA = 1;
}

从我的测试中,这是非常准确的。


I am trying to figure out how to create a timer for my C8051F020 MCU. The following code uses the value passed to init_Timer2() with the following formula:

65535-(0.1 / (12/2000000)=48868.

I set up the timer to count every time it executes and for every 10 counts, count one second. This is based on the above formula. 48868 when passed to init_Timer2 will produce a 0.1 second delay. It would take ten of them per second. However, when I test the timer it is a little fast. At ten seconds the timer reports 11 seconds, at 20 seconds the timer reports 22 seconds. I would like to get as close to a perfect second as I can.

Here is my code:

#include <compiler_defs.h>
#include <C8051F020_defs.h>

void init_Clock(void);
void init_Watchdog(void);
void init_Ports(void);
void init_Timer2(unsigned int counts);
void start_Timer2(void);
void timer2_ISR(void);

unsigned int timer2_Count;
unsigned int seconds;
unsigned int minutes;

int main(void)
{
    init_Clock();
    init_Watchdog();
    init_Ports();
    start_Timer2();

    P5 &= 0xFF;

    while (1);
}

//=============================================================
//Functions
//=============================================================
void init_Clock(void)
{
    OSCICN = 0x04;  //2Mhz
    //OSCICN = 0x07;    //16Mhz
}

void init_Watchdog(void)
{
    //Disable watchdog timer
    WDTCN = 0xDE;
    WDTCN = 0xAD;
}

void init_Ports(void)
{
    XBR0    = 0x00;
    XBR1    = 0x00;
    XBR2    = 0x40;

    P0      = 0x00;
    P0MDOUT = 0x00;
    P5      = 0x00; //Set P5 to 1111
    P74OUT  = 0x08; //Set P5 4 - 7 (LEDs) to push pull (Output)
}

void init_Timer2(unsigned int counts)
{
    CKCON = 0x00;   //Set all timers to system clock divided by 12

    T2CON = 0x00;   //Set timer 2 to timer mode

    RCAP2 = counts; 

    T2 = 0xFFFF;    //655535

    IE |= 0x20;     //Enable timer 2

    T2CON |= 0x04;  //Start timer 2
}

void start_Timer2(void)
{
    EA = 0;

    init_Timer2(48868);

    EA = 1;
}

void timer2_ISR(void) interrupt 5
{    
    T2CON &= ~(0x80);

        P5 ^= 0xF0;

        timer2_Count++;

        if(timer2_Count % 10 == 0)
        {
            seconds++;
        }

        if(seconds % 60 == 0  && seconds != 0)
        {
            minutes++;
        }
}

解决方案

I cannot take full credit for answering this question. Everyone contributed. I ended up using the external clock at 22.1184Mhz. The following snippets of code are the sections of the original post code that has changed to make it work:

void init_Clock(void)
{
    OSCXCN = 0x67;  //External 22.1184Mhz

    while ( !(OSCXCN & 0x80) );

    OSCICN = 0x88;
}

and

void start_Timer2(void)
{
    EA = 0;

    //External clock
    init_Timer2(47103);

    EA = 1;
}

From my tests this is very accurate.

这篇关于用MCU定时器/中断计数秒和分钟?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆