首页 | 基础知识 | 汇编/C语言

Hardware RTC Demo Board

这次做的Mini ITX Model在S5下会断掉Chipset的Standby Power, 这样普通的RTC就没法再跑了,但板子毕竟不能不测RTC就出货,所以我就想着用MCU做一个自动开机的Demo Board.

MCU还是采用最简单的51, 在功能要求不多的情况下我更喜欢用2051, 不仅因为她的体积比较小,而且还比较便宜.

由于MotherBoard会在S5下对Chipset断电,而板子上的Standby Power还在, 所以整体思路是让MCU控制Power Button, 做到模仿人工的自动开机,关机过程仍旧是开机后自运行RTC,这样不但可以记录圈数, 就算宕掉了,之前的记录还是会保存在U盘下面的Log文件里. 当RTC程序运行后自动Shutdown, MCU侦测Main Power Loss, 会等待12s,之后自动拉PWRBTN#,这样就自动开机了. 硬件原理图很简单:

Hardware RTC Diagram

剩下的就是程序的编写了,好久不写程序了,只好在以前写的C程序上修修补补了:

/********************************************************************************************

* Hardware RTC V0.01

* MCU:  AT89C2051

* Frequency: Crystal Frequency 12Mhz*

* Description:  Port 3.7 Output High to set PWRBTNIN# Low

* Author:  Flevi Liu

* Website:  http://Fleviliu.com

* Contact:  Flevi@Fleviliu.com

********************************************************************************************/

#include <reg51.h>

#include <intrins.h>

#include <stdio.h>

#define uchar unsigned char

void delay15us(uchar n);   //A delay program that will be delay n*15us

void pwrbtnin(void);        // PowerBTN# Low active program

sbit STARTUP = P3^7;    //STARTUP

sbit TESTLED = P1^6;    //Debug LED

sbit STALED = P1^7;      //Status indicator

uchar DELAYCOUNT = 0;

uchar COUNT = 0;

void main(void)

{

pwrbtnin();

// Waiting 3s to set Power Button as low active

for(COUNT = 0; COUNT < 5; ++COUNT)

  {

  for(DELAYCOUNT = 0; DELAYCOUNT < 200; ++DELAYCOUNT) //Delay 0.6s

    {

    delay15us(200); //Delay 3ms

    }

   }

IP = 0x01;       // EX0 has high priority

TCON = 0x01;    //External interrupt is pulse detect.

IE = 0x81;       // EX0 interrupt is enabled.

TESTLED = 0;    // TEST LED On

/*****************************************

* Nothing to do

*****************************************/

   while(1)

      {

      }

((void (code *)(void))0x0000)(); //Software Reset [1]

}

/********************************************************

* External Interrupt 0

* If the power loss (Shutdown), it will wait 12s;

********************************************************/

void PWRLOSS(void) interrupt 0 using 0

{

STALED = 0; // After OS Shutdown OS , Status LED will be turn on, and Test LED be turn off.

TESTLED = 1;

// Wait 12s to Power ON

for(COUNT = 0; COUNT < 20; ++COUNT)

{

for(DELAYCOUNT = 0; DELAYCOUNT < 200; ++DELAYCOUNT) //Delay 0.6s

{

delay15us(200); //Delay 3ms

}

}

//Power ON

pwrbtnin(); //Power On

TESTLED = 0;

}

/*******************************************************************************************

* PWRBTNIN# Low active program

********************************************************************************************/

void pwrbtnin(void)

{

  STARTUP = 1; //PWTBTN# active

  STALED = 0;

  for(DELAYCOUNT = 0; DELAYCOUNT < 10; ++DELAYCOUNT) //Delay 30ms

     {

      delay15us(200); //Delay 3ms

     }

   STARTUP = 0; //PWTBTN# Inactive

   STALED = 1; // After Start OS the LED will always on

}

/*******************************************************************************************

* Delay 15us

* One do()...while and 13 NOPs will be equal to 15 NOPS.

* If the frequency is 12MHz, 1 NOP command will be 1us.

********************************************************************************************/

void delay15us(uchar n)

{

  do

   {

   _nop_();_nop_();_nop_();

   _nop_();_nop_();_nop_();

   _nop_();_nop_();_nop_();

   _nop_();_nop_();_nop_();

   _nop_();

   --n;

  }while(n);

  return;

}

 

上一页 | 下一页