⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart0_autobaud1.c

📁 c8051f020开发板的所有参考程序
💻 C
字号:
//-----------------------------------------------------------------------------
// UART0_Autobaud1.c
//-----------------------------------------------------------------------------
// Copyright 2002 Cygnal Integrated Products, Inc.
//
// AUTH: BW
// DATE: 30 APR 02
//
// This program shows an example of how the PCA can be used to enable accurate
// UART auto-baud detection when running from the on-chip internal oscillator.
// This algorithm assumes a 0x55 character ( ASCII "U") is sent from the 
// remote transmitter.  Baud rates between 4800 to 19.2kbps can be reliably
// synchronized.
//
// UART0 is then configured to operate in polled mode, suitable for use
// with the <stdio> functions printf() and scanf().
// 
// Target: C8051F02x
// Tool chain: KEIL C51 6.03 / KEIL EVAL C51
//

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

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

//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F02x
//-----------------------------------------------------------------------------

sfr16 DP       = 0x82;                 // data pointer
sfr16 TMR3RL   = 0x92;                 // Timer3 reload value
sfr16 TMR3     = 0x94;                 // Timer3 counter
sfr16 ADC0     = 0xbe;                 // ADC0 data
sfr16 ADC0GT   = 0xc4;                 // ADC0 greater than window
sfr16 ADC0LT   = 0xc6;                 // ADC0 less than window
sfr16 RCAP2    = 0xca;                 // Timer2 capture/reload
sfr16 T2       = 0xcc;                 // Timer2
sfr16 RCAP4    = 0xe4;                 // Timer4 capture/reload
sfr16 T4       = 0xf4;                 // Timer4
sfr16 DAC0     = 0xd2;                 // DAC0 data
sfr16 DAC1     = 0xd5;                 // DAC1 data

//-----------------------------------------------------------------------------
// Structures, Unions, Enumerations, and Type definitions
//-----------------------------------------------------------------------------

typedef union UInt {
   unsigned int Int;
   unsigned char UChar[2];
} UInt;

//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------

sbit LED = P1^6;                       // LED = 1 means ON

//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------

void SYSCLK_Init (void);
void PORT_Init (void);
void UART0_Init (void);

//-----------------------------------------------------------------------------
// Global VARIABLES
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------

void main (void) {

   WDTCN = 0xde;                       // disable watchdog timer
   WDTCN = 0xad;

   SYSCLK_Init ();                     // initialize oscillator
   PORT_Init ();                       // initialize crossbar and GPIO
   UART0_Init ();                      // initialize UART0

   // transmit example

   printf ("Howdy!\n");

   while (1);

}

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

//-----------------------------------------------------------------------------
// SYSCLK_Init
//-----------------------------------------------------------------------------
//
// This routine initializes the system clock to use the internal oscillator 
// operating at its maximum frequency.
//
void SYSCLK_Init (void)
{
   OSCICN = 0x07;                      // internal osc max frequency
}

//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Configure the Crossbar and GPIO ports
//
void PORT_Init (void)
{
   XBR0    |= 0x04;                    // Enable UART0
   XBR2    |= 0x40;                    // Enable crossbar and weak pull-ups
   P0MDOUT |= 0x01;                    // enable TX0 as a push-pull output
   P1MDOUT |= 0x40;                    // enable LED as push-pull output
}

//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
//
// Configure the UART0 using Timer1, for auto-baud detect and 8-N-1.
//
// In this example, the CEX1 is directed to appear on P0.1 (which is where the
// UART0 RX pin will appear on 'F02x devices) and CEX0 is directed to appear
// on P0.0 (which is where the UART RX pin would appear).  CEX0 is not used.
//
// The detection algorithm assumes that the host transmitter will send a 0x55
// character, which is an ASCII captial "U".
//
//  ----+     +-----+     +-----+     +-----+     +-----+     +---------
//      |  S  | LSB |  1  |  2  |  3  |  4  |  5  |  6  | MSB |  P  
//      +-----+     +-----+     +-----+     +-----+     +-----+
//
// The PCA time base is configured to count SYSCLKs.  SYSCLK is assumed to
// be operating from the internal oscillator at its max frequency, though this
// should not affect the operation of the algorithm (though a lower frequency
// will decrease the maximum UART baud rate that can be matched).
//
// A bit period at 9600bps is ~104us, or about 63ns.  Therefore there are about
// 1670 SYSCLKs in 1 bit period.
//
// The algorithm operates as follows:
//  1. The time at which the falling edge is recorded in <last_time>.
//  2. The times between successive rising and falling edges are recorded
//     in edge_array.
//  3. The average bit time is calculated from the information in edge_array.
//  4. Timer1 is configured in 8-bit auto-reload mode to reload 16 times faster
//     than the average bit time.
//  5. The PCA modules are disabled in the Crossbar and UART0 is enabled.
//
void UART0_Init (void)
{
   unsigned int edge_array[9];         // holds bit times of received
                                       // training character
   unsigned int last_time;             // PCA0 value when last edge occurred
   UInt temp;                          // byte-addressable unsigned int

   unsigned char i;                    // edge counter

   // Route CEX0 and CEX1 to P0.0 and P0.1 on Crossbar   
   XBR2 = 0x00;                        // Disable Crossbar
   XBR0 = 0x10;                        // Enable CEX0 and CEX1 (P0.0, P0.1)
   XBR2 = 0x40;                        // Enable Crossbar and weak pull-ups

   // Configure PCA for edge-capture operation
   PCA0MD = 0x08;                      // Configure PCA time base to use SYSCLK
   PCA0CPM0 = 0x00;                    // Module 0 is not used
   PCA0CPM1 = 0x30;                    // Module 1 configured for edge capture
                                       // (no interrupt generated)
   PCA0CN = 0x40;                      // Start PCA counter; clear all flags

   while (!CCF1);                      // wait for edge
   CCF1 = 0;                           // clear edge flag

   temp.UChar[0] = PCA0CPH1;           // read edge time
   temp.UChar[1] = PCA0CPL1;
   last_time = temp.Int;

   for (i = 0; i < 8; i++) {
      
      while (!CCF1);                   // wait for edge
      CCF1 = 0;                        // clear edge flag
      // read the edge
      temp.UChar[0] = PCA0CPH1;        // read edge time
      temp.UChar[1] = PCA0CPL1;

      // store the edge
      edge_array[i] = temp.Int - last_time;
      last_time = temp.Int;            // update last edge timer
   }

   // add 8 bit times in prep for averaging
   last_time = 0x0000;                 // initialize holding variable
   for (i = 0; i < 8; i++) {
      last_time += edge_array[i];
   }

   last_time = last_time >> (3 + 4);   // divide by 8 for averaging
                                       // and by 16 for Timer reload rate

   // Disable CEX0 and CEX1 through Crossbar and enable UART0
   XBR2 = 0x00;                        // Disable Crossbar
   XBR0 = 0x04;                        // Enable UART0 in Crossbar
   XBR2 = 0x40;                        // Enable Crossbar and weak pull-ups

   // Configure UART0 and Timer1
   SCON0  = 0x50;                      // SCON0: mode 1, 8-bit UART, enable RX
   TMOD   = 0x20;                      // TMOD: timer 1, mode 2, 8-bit reload
   TH1    = -last_time;                // set Timer1 reload value for baudrate
   TR1    = 1;                         // start Timer1
   CKCON |= 0x10;                      // Timer1 uses SYSCLK as time base
   PCON  |= 0x80;                      // SMOD00 = 1
   TI0    = 1;                         // Indicate TX0 ready

   printf ("\nAuto-baud detection statistics:\n");
   printf ("Edge Array:\n");
   for (i = 0; i < 8; i++) {
      printf (" bit width %d: %u SYSCLKs\n", (int) i, edge_array[i]);
   }
   printf ("Timer 1 reload value: 0x%02x\n", (unsigned) (TH1 & 0xFF));
}

⌨️ 快捷键说明

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