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

📄 c8051uart0.c

📁 很好用的串口通信程序
💻 C
字号:
//-----------------------------------------------------------------------------
// 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
//-----------------------------------------------------------------------------
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
}

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 + -