#include <C8051F040.h> // SFR declarations
#include <stdio.h>
//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F04x
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Global Constants
//-----------------------------------------------------------------------------
#define BAUDRATE 115200 // Baud rate of UART in bps
// SYSCLK = System clock frequency in Hz
#define SYSCLK 22118400L
#define T0_CLOCKS 245 // Use 245 clocks per T0 Overflow
// (245 = 10 us)
#define T2_RELOAD_CLOCKS 6125
#define uint unsigned int
#define uchar unsigned char
sfr16 PCA0CP0 = 0xFB; // PCA0 Compare Register Definition
sfr16 RCAP2 = 0xCA; // Timer2 Reload Register
sfr16 TMR2 = 0xCC; // Timer2 counter
//-----------------------------------------------------------------------------
// Function Prototypes
//-----------------------------------------------------------------------------
sbit LED1 = P3^3;
bit busy;
void OSCILLATOR_Init (void);
void PORT_Init_UART0 (void);
void UART0_Init (void);
void tx() ;
void PORT_Init (void);
void PCA0_Init (void);
void TestTimerInit (void);
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
uint Uart; // Global variable -- when '0', UART0
// is used for stdio; when '1', UART1
uint k0,k1,k2,k3,k4,k5; // is used for stdio
void TxSend(char dat)
{ char SFRPAGE_SAVE;
SFRPAGE_SAVE = SFRPAGE;
SFRPAGE = UART0_PAGE;
while (busy); //等待上个数据发送完成
busy = 1;
SBUF0 = dat; //发送数据
SFRPAGE = SFRPAGE_SAVE;
}
void tx()
{
TxSend('P');
TxSend('C');
TxSend('A');
// TxSend(id + '0');
TxSend('=');
TxSend(Uart/10000 + '0');
TxSend(Uart%10000/1000 + '0');
TxSend(Uart%1000/100 + '0');
TxSend(Uart%100/10 + '0');
TxSend(Uart%10 + '0');
TxSend(0x0d);
TxSend(0x0a);
}
void SendString(char *s)
{
while (*s) //判断字符串结束标志
{
TxSend(*s++); //发送字符
}
}
void main (void)
{
SFRPAGE = CONFIG_PAGE;
WDTCN = 0xDE; // Disable watchdog timer
WDTCN = 0xAD;
OSCILLATOR_Init (); // Initialize oscillator
PORT_Init_UART0 (); // Initialize crossbar and GPIO
UART0_Init ();
// Initialize UART0
PCA0_Init (); // Initialize PCA0
TestTimerInit (); // Configure Timer2 for test signal
EA = 1;
while (1)
{
// print something to UART0
//PORT_Init_UART0 (); // Configure Crossbar to pinout
Uart=k0;
tx() ; // UART0 TX and RX to P0.0 and P0.1
Uart=k1;
tx() ; // UART0 TX and RX to P0.0 and P0.1
Uart=k2;
tx() ;
Uart=k3;
tx() ;
Uart=k4;
tx() ;
Uart=k5;
tx() ;
}
}
void OSCILLATOR_Init (void)
{
int i; // Software timer
char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page
SFRPAGE = CONFIG_PAGE; // Set SFR page
OSCICN = 0x80; // Set internal oscillator to run
// at its slowest frequency
CLKSEL = 0x00; // Select the internal osc. as
// the SYSCLK source
// Initialize external crystal oscillator to use 22.1184 MHz crystal
OSCXCN = 0x67; // Enable external crystal osc.
for (i=0; i < 256; i++); // Wait at least 1ms
while (!(OSCXCN & 0x80)); // Wait for crystal osc to settle
CLKSEL = 0x01; // Select external crystal as SYSCLK
// source
SFRPAGE = SFRPAGE_SAVE; // Restore SFRPAGE
}
void PORT_Init_UART0 (void)
{
char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page
SFRPAGE = CONFIG_PAGE; // Set SFR page
XBR0 = 0x34; // Enable UART0
XBR1 = 0x00;
XBR2 = 0x40; // Enable crossbar and weak pull-up
XBR3 = 0x00;
P0MDOUT |= 0x01; // Set TX pin to push-pull
P1MDOUT |= 0x40; // Set P1.6(LED) to push-pull
P3MDOUT |= 0x08;
LED1=0;
SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
}
void UART0_Init (void)
{
char SFRPAGE_SAVE;
SFRPAGE_SAVE = SFRPAGE; // Preserve SFRPAGE
SFRPAGE = TMR2_PAGE;
TMR2CN = 0x00; // Timer in 16-bit auto-reload up timer
// mode
TMR2CF = 0x08; // SYSCLK is time base; no output;
// up count only
RCAP2 = - ((long) SYSCLK/BAUDRATE/16);
TMR2 = RCAP2;
TR2= 1; // Start Timer2
SFRPAGE = UART0_PAGE;
SCON0 = 0x50; // 8-bit variable baud rate;
// 9th bit ignored; RX enabled
// clear all flags
SSTA0 = 0x15; // Clear all flags; enable baud rate
// doubler (not relevant for these
// timers);
// Use Timer2 as RX and TX baud rate
// source;
TI0 = 1; // Indicate TX0 ready
ES0 = 1;
IP |= 0x10;
SFRPAGE = SFRPAGE_SAVE; // Restore SFRPAGE
}
void UART0_Interrupt (void) interrupt 4
{
SFRPAGE = UART0_PAGE;
if (RI0 == 1)
{
RI0 = 0; // Clear interrupt flag
//Byte = SBUF0; // Read a character from UART
}
if (TI0 == 1) // Check if transmit flag is set
{
TI0 = 0; // Clear interrupt flag
// SBUF0 = 0x01;
busy = 0;
}
}
void PCA0_Init (void)
{
char SFRPAGE_save = SFRPAGE; // Save current SFR Page
SFRPAGE = PCA0_PAGE;
// Configure PCA time base; overflow interrupt disabled
PCA0CN = 0x00; // Stop counter; clear all flags
PCA0MD = 0x02; // 使用 系统时钟/4
PCA0CPM0 = 0x21; // Module 0 = Rising Edge Capture Mode
// enable CCF flag.
// Start PCA counter
CR = 1; //=PCA0CN=0x40
SFRPAGE = CONFIG_PAGE;
EIE1 |= 0x08; // Enable PCA interrupts
SFRPAGE = SFRPAGE_save;
}
void TestTimerInit (void)
{
char SFRPAGE_save = SFRPAGE; // Save current SFR Page
SFRPAGE = TMR3_PAGE;
RCAP3L = -(int)T2_RELOAD_CLOCKS; // Set up Timer 2 reload rate
TMR3L = -(int)T2_RELOAD_CLOCKS; // Preload timer
TMR3CN = 0x04; // Timer 2 run in 16b auto-reload
SFRPAGE = CONFIG_PAGE;
EIE2=0X01;
SFRPAGE = SFRPAGE_save;
}
void PCA0_ISR (void) interrupt 9
{
static unsigned int current_capture_value0,current_capture_value1,current_capture_value2,current_capture_value3,
current_capture_value4,current_capture_value5, previous_capture_value;
static unsigned int capture_period;
if (CCF0) // If Module 0 caused the interrupt
{
CCF0 = 0; // Clear module 0 interrupt flag.
capture_period = PCA0CPH0;
capture_period = (capture_period << 8) + PCA0CPL0;
previous_capture_value =capture_period- current_capture_value0;
current_capture_value0 = capture_period;
k0= 0xff;
}
if (CCF1) // If Module 0 caused the interrupt
{
CCF1 = 0; // Clear module 0 interrupt flag.
capture_period = PCA0CPH1;
capture_period = (capture_period << 8) + PCA0CPL1;
previous_capture_value =capture_period- current_capture_value1;
current_capture_value1 = capture_period;
k1= 0xff;
}
if (CCF2) // If Module 0 caused the interrupt
{
CCF2 = 0; // Clear module 0 interrupt flag.
capture_period = PCA0CPH2;
capture_period = (capture_period << 8) + PCA0CPL2;
previous_capture_value =capture_period- current_capture_value2;
current_capture_value2 = capture_period;
k2= 0xff;
}
if (CCF3) // If Module 0 caused the interrupt
{
CCF3 = 0; // Clear module 0 interrupt flag.
capture_period = PCA0CPH3;
capture_period = (capture_period << 8) + PCA0CPL3;
previous_capture_value =capture_period- current_capture_value3;
current_capture_value3 = capture_period;
k3= 0xff;
}
if (CCF4) // If Module 0 caused the interrupt
{
CCF4 = 0; // Clear module 0 interrupt flag.
capture_period = PCA0CPH4;
capture_period = (capture_period << 8) + PCA0CPL4;
previous_capture_value =capture_period- current_capture_value4;
current_capture_value4 = capture_period;
k4=0xff;
}
if (CCF5) // If Module 0 caused the interrupt
{
CCF5 = 0; // Clear module 0 interrupt flag.
capture_period = PCA0CPH5;
capture_period = (capture_period << 8) + PCA0CPL5;
previous_capture_value =capture_period- current_capture_value5;
current_capture_value5 = capture_period;
k5= 0xff;
}
if(CF == 1) //PCA溢出中断
{
CF = 0; //清PCA溢出中断标志
}
}
void Timer2_ISR (void) interrupt 14
{
if (TF3)
{ LED1 =~LED1;
TF3 = 0; // Clear T2 overflow
}
}
|