f530dc_softwaretimer.c

来自「8051试验程序 基础教材」· C语言 代码 · 共 340 行

C
340
字号
//-----------------------------------------------------------------------------
// F530DC_SoftwareTimer.c
//-----------------------------------------------------------------------------
// Copyright 2006 Silicon Laboratories, Inc.
// http://www.silabs.com
//
// Program Description:
//
// This program keep track of the amount of time since the microcontroller
// has been reset.  This time is output to the UART at 9600 baud.  The program
// also monitors P1.1 and stops incrementing the clock if the pin is logic low.
//
// How To Test:
// 1) Connect the ToolStick LIN DC to the PC and compile and download the code
// 2) Connect to the ToolStick LIN DC using ToolStickTerminal at 9600 baud
//    and see that Terminal displays the time since the last reset
// 3) In the ToolStickTerminal Settings menu, change GPIO0/RTS to push-pull
//    and then toggle the GPIO low.
// 5) See that ToolStick Terminal displays that the timer is halted.
//
//
// FID:            52X000009
// Target:         C8051F530 (Toolstick LIN DC)
// Tool chain:     Keil C51 7.50 / Keil EVAL C51
// Command Line:   None
//
// Release 1.0
//    -Initial Revision (GP)
//    -17 OCT 2006
//

//-----------------------------------------------------------------------------
// Global Defines
//-----------------------------------------------------------------------------

// The UART signals TX and RX are assigned to port pins through the device's
// crossbar.  The behavior of the crossbar with respect to the UART pins is
// different between C8051F52x-53x Revision A devices and C8051F52x-53x
// Revision B and later devices.  Revision A devices assign TX to P0.3 and
// RX to P0.4.  Revision B and later devices assign TX to P0.4 and RX to P0.5.
// See the C8051F52x-F53x datasheet for more details.

// Change the revision below to match the revision of the device.

#define REVISION 'A'                   // Revision of the 'F53x Device (A or B)

//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------

#include <ioC8051F530.h>                 // SFR declarations
#include <stdio.h>

//-----------------------------------------------------------------------------
// 16-bit SFR Definitions
//-----------------------------------------------------------------------------
__sfr __no_init volatile unsigned short TMR2RL        @ 0xCA;
__sfr __no_init volatile unsigned short TMR2          @ 0xCC;


//-----------------------------------------------------------------------------
// Global Constants
//-----------------------------------------------------------------------------

#define SYSCLK        765625           // SYSCLK frequency in Hz (24.5 Mhz/32)
#define BAUDRATE        9600           // Baud rate of UART in bps
#define TIMER2_RATE        1           // Timer2 overflow rate in Hz

//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------

unsigned char Seconds;                 // Time since the program has started
unsigned char Minutes;                 // running
unsigned char Hours;

//-----------------------------------------------------------------------------
// Sbit Definitions
//-----------------------------------------------------------------------------

#define STOP_CLOCK  P1_bit.BIT1                // Timer2 is  halted if pin is low

//-----------------------------------------------------------------------------
// Function Prototypes
//-----------------------------------------------------------------------------

void OSCILLATOR_Init (void);
void UART0_Init (void);
void PORT_Init (void);
void TIMER2_Init (int);

void Print_String (char pstring[]);


//-----------------------------------------------------------------------------
// PUTCHAR Routine
//-----------------------------------------------------------------------------
int putchar(int ch)
{
  if (ch == '\n')  {
    while (!SCON0_bit.TI0);
    SCON0_bit.TI0 = 0;
    SBUF0 = 0x0d;                         // output CR
  }

  while (!SCON0_bit.TI0);
  SCON0_bit.TI0 = 0;
  return	 (SBUF0 = ch);
}

//-----------------------------------------------------------------------------
// main Routine
//-----------------------------------------------------------------------------
void main (void)
{
   PCA0MD &= ~0x40;                     // Disable the watchdog timer

   PORT_Init ();                        // Initialize Port I/O
   OSCILLATOR_Init ();                  // Initialize Oscillator
   TIMER2_Init (SYSCLK/TIMER2_RATE/12); // Init Timer 2
   UART0_Init ();                       // Initialize UART0

   Seconds = 0;
   Minutes = 0;
   Hours = 0;

   IE_bit.EA = 1;

   while (1) {}
}

//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Initializes the port pins
//
// P0.3    digital    push-pull     UART TX (Rev A)
// P0.4    digital    open-drain    UART RX (Rev A)
//
// P0.4    digital    push-pull     UART TX (Rev B)
// P0.5    digital    open-drain    UART RX (Rev B)
//
// P1.1    digital    open-drain    (STOP_CLOCK) GPIO trigger from TS Terminal
//
//-----------------------------------------------------------------------------
void PORT_Init (void)
{
#if REVISION == 'A'
   P0MDOUT |= 0x08;                    // Enable UTX as push-pull output
#else
   P0MDOUT |= 0x10;                    // Enable UTX as push-pull output
#endif

   P1MDOUT &= ~0x02;                   // Set P1.1 to open-drain
   P1      |= 0x02;                    // Set P1.1 latch to '1'

   XBR0    = 0x01;                     // Enable UART
   XBR1    = 0x40;                     // Enable crossbar and weak pull-ups
}

//-----------------------------------------------------------------------------
// OSCILLATOR_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// This routine initializes the system clock to use the internal 24.5MHz/32
// oscillator as its clock source.  Also enables missing clock detector reset
// and VREGOUT monitor.
//
//-----------------------------------------------------------------------------
void OSCILLATOR_Init (void)
{
   OSCICN |= 0x02;                     // Configure internal oscillator for
                                       // 24.5 Mhz / 32
   RSTSRC = 0x06;                      // Enable missing clock detector
                                       // Enable VREGOUT monitor
}

//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Configure the UART0 using Timer1, for <BAUDRATE> and 8-N-1.
//
//-----------------------------------------------------------------------------
void UART0_Init (void)
{
   SCON0 = 0x10;                       // SCON0: 8-bit variable bit rate
                                       //        level of STOP bit is ignored
                                       //        RX enabled
                                       //        ninth bits are zeros
                                       //        clear RI0 and TI0 bits
   if (SYSCLK/BAUDRATE/2/256 < 1) {
      TH1 = (0xFF-(SYSCLK/BAUDRATE/2))+1;
      CKCON &= ~0x0B;                  // T1M = 1; SCA1:0 = xx
      CKCON |=  0x08;
   } else if (SYSCLK/BAUDRATE/2/256 < 4) {
      TH1 = (0xFF-(SYSCLK/BAUDRATE/2/4))+1;
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 01
      CKCON |=  0x09;
   } else if (SYSCLK/BAUDRATE/2/256 < 12) {
      TH1 = (0xFF-(SYSCLK/BAUDRATE/2/12))+1;
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 00
   } else {
      TH1 = 0xFF&(0xFFFF-(SYSCLK/BAUDRATE/2/48))+1;
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 10
      CKCON |=  0x02;
   }

   TL1 = TH1;                          // Init Timer1
   TMOD &= ~0xf0;                      // TMOD: timer 1 in 8-bit autoreload
   TMOD |=  0x20;
   TCON_bit.TR1 = 1;                            // START Timer1
   SCON0_bit.TI0 = 1;                            // Indicate TX0 ready
}

//-----------------------------------------------------------------------------
// TIMER2_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   :
//   1)  int counts - number of milliseconds of delay
//                    range is postive range of integer: 0 to 32767
//
// Configure Timer2 to auto-reload at interval specified by <counts> (no
// interrupt generated) using SYSCLK/12 as its time base.
//
//-----------------------------------------------------------------------------
void TIMER2_Init (int counts)
{
   TMR2CN = 0x00;                      // STOP Timer2; Clear TF2H and TF2L;
                                       // disable low-byte interrupt; disable
                                       // split mode; select internal timebase
   CKCON = 0x00;                       // Timer2 uses clock defined by T2XCLK

   TMR2RL  = -counts;                  // Init reload values
   TMR2    = 0xFFFF;                   // Init Timer2 to interrupt immediately
   IE_bit.ET2 = 1;                            // Enable Timer2 interrupts
   TMR2CN_bit.TR2 = 1;                            // Start Timer2
}

//-----------------------------------------------------------------------------
// Interrupt Service Routines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// TIMER2_ISR
//-----------------------------------------------------------------------------
//
// Timer2 is configured to interrupt once a second.  The firmware first
// prints the time since the program has started and then updates the clock
// if P1.1 (STOP_CLOCK) is not logic low.
//
// Manual calls to putchar() to save the code space cost of printf().
//
//-----------------------------------------------------------------------------
#pragma vector = TF2H_int
__interrupt void TIMER2_ISR (void)
{
   TMR2CN &= ~0xC0;                    // Clear Timer2 Flags

   putchar ('\f');                     // Clear Screen

   // Print the time the firmware has been running
   Print_String ("Time Running: ");
   putchar (Hours/10 + 0x30);
   putchar (Hours%10 + 0x30);
   putchar (':');
   putchar (Minutes/10 + 0x30);
   putchar (Minutes%10 + 0x30);
   putchar (':');
   putchar (Seconds/10 + 0x30);
   putchar (Seconds%10 + 0x30);

   if(STOP_CLOCK == 0)                // Level-sensitive trigger
   {
      Print_String (" (halted)");
   }
   else
   {
      // Update the time
      Seconds++;                       // Set breakpoint here
      if (Seconds == 60)
      {
         Seconds = 0;
         Minutes++;
	     if (Minutes == 60)
         {
            Minutes = 0;
            Hours++;
         }
      }
   }
}

//-----------------------------------------------------------------------------
// Support Subroutines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Print_String
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   :
//         1) char pstring[] - null terminated character string
//
// Prints the strings stored in pstring to the UART.
// This function is used instead of printf() because printf() consumes
// a considerable amount of code space.
//
//-----------------------------------------------------------------------------

void Print_String (char pstring[])
{
   unsigned char i = 0;
   while (pstring[i])
   {
      putchar(pstring[i++]);
   }
}

//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?