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 + -
显示快捷键?