f362dc_featuresdemo.c

来自「8051试验程序 基础教材」· C语言 代码 · 共 754 行 · 第 1/2 页

C
754
字号
//-----------------------------------------------------------------------------
// F362DC_FeaturesDemo.c
//-----------------------------------------------------------------------------
// Copyright 2006 Silicon Laboratories, Inc.
// http://www.silabs.com
//
// Program Description:
//
// This program demonstrates the features available on the ToolStick
// F362 Daughter Card.
//
// Based on the setting of a level-sensitive interrupt pin, the firmware
// will either blink the green LED or PWM the LED.  The blinking speed
// or the PWM duty cycle is set based on the value of the potentiometer.
// Voltage across the potentiometer is measured using the on-chip 10-bit ADC.
//
// The program also outputs the status of the LED to the UART at a baud rate
// defined by <BAUDRATE>.
//
// Pressing the switch on the daughter card toggles the ADC enable bit.  If
// the ADC is disabled, turning the potentiometer will not have any effect
// on blink or PWM rate.
//
// How To Test:
// 1) Connect the ToolStickF362DC to the PC and download the code
// 2) Turn the potentiometer and see that the blink rate increases or decreases
// 3) Press the switch SW to turn off the ADC and check that turning the
//    potentiometer has no effect on the blink rate.
// 4) Press the switch SW again to re-enable the ADC and potentiometer.
// 5) Turn the potentiometer and see that the brightness of the LED changes.
// 6) Connect to the ToolStickF362DC using ToolStickTerminal and see that
//    the UART output changes as the potentiometer is turned
// 7) In ToolStickTerminal, toggle GPIO0/RTS to force the firmware to
//    switch modes.
// 8) Turn the potentiometer and see that the brightness of the LED changes
//    and check that the output of the UART also changes.
//
//
// FID:            36X000002
// Target:         ToolStickF362DC
// Tool chain:     Keil C51 7.50 / Keil EVAL C51
//                 Silicon Laboratories IDE version 2.6
//
// Release 1.0
//    -Initial Revision (TP)
//    -29 NOV 2006
//

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

#include <ioC8051F362.h>                 // SFR declarations
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

//-----------------------------------------------------------------------------
// 16-bit SFR Definitions
//-----------------------------------------------------------------------------
__sfr __no_init volatile unsigned short TMR3        @ 0x94;
__sfr __no_init volatile unsigned short TMR3RL      @ 0x92;
__sfr __no_init volatile unsigned short IDA0        @ 0x96;
__sfr __no_init volatile unsigned short ADC0        @ 0xBD;
__sfr __no_init volatile unsigned short TMR2RL      @ 0xCA;
__sfr __no_init volatile unsigned short TMR2        @ 0xCC;

//-----------------------------------------------------------------------------
// SFR and Bit Definitions
//-----------------------------------------------------------------------------

#define LED      P1_bit.P1_3           // LED='1' means ON
#define SW       P2_bit.P2_4           // Switch pressed='0'

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

#define SYSCLK          3062500L       // SYSCLK frequency in Hz

#define BAUDRATE        115200         // Baud rate of UART in bps
#define PRINT_RATE      20             // Times per second to update on UART

#define OVERFLOWS_NEEDED  (SYSCLK / 65536 / PRINT_RATE)

#define ADC_CLOCK       100000         // SAR clock
#define ADC_SAMPLE_RATE 100            // Timer 2 overflow rate in Hz
#define ADC_COUNTS      1024           // Number of ADC counts

#define MAX_BLINK_RATE  40             // Max blink rate in Hz for Timer mode
#define MIN_BLINK_RATE  1              // Min blink rate in Hz for Timer mode
#define BLINK_DIFF  (MAX_BLINK_RATE - MIN_BLINK_RATE) // For easy calculations

// Firmware states
#define TIMER_MODE      0              // Uses the Timer to blink the LED
#define PWM_MODE        1              // Use a PCA channel to PWM the LED

#define LEGACY_PAGE     0x00
#define CONFIG_PAGE		0x0F

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

void OSCILLATOR_Init (void);
void PORT_Init (void);
void TIMER0_Init (void);
void TIMER2_Init (int counts);
void TIMER3_Init (void);
void ADC0_Init (void);
void PCA0_Init (void);
void UART0_Init (void);
void INT0_Init (void);

void Print_String (char pstring[]);

// ISRs defined: INT0_ISR, TIMER0_ISR, TIMER1_ISR, TIMER3_ISR, ADC0_ISR.

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

bool Blink_State      = TIMER_MODE;     // Starts with blinking the LED

int PWM_Duty_Cycle   = 0;              // Percentage from 0 to 100
int Blink_Rate       = 0;              // From MIN_BLINK_RATE to MAX_BLINK_RATE
bool update           = 0;              // Forces a UART update

long Num_LED_Flashes = 0;              // Simply counts the number of times
                                       // the LED blinks

//-----------------------------------------------------------------------------
// 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;                    // WDTE = 0 (clear watchdog timer
                                       // enable)

   OSCILLATOR_Init ();                 // Initialize system clock to
                                       // 24.5/8 MHz

   PORT_Init ();                       // Initialize crossbar and GPIO

   TIMER0_Init ();                     // Initialize Timer0 for UART update

   TIMER2_Init (SYSCLK / 12 / ADC_SAMPLE_RATE);   // Init Timer2 for ADC

   TIMER3_Init ();                     // Init timer used to blink LED

   PCA0_Init ();                       // Init PCA Module 0 to blink LED

   ADC0_Init ();                       // Enable ADC0

   INT0_Init ();                       // Enable /INT0

   UART0_Init ();                      // Enable UART using global settings

   IE_bit.EA= 1;                             // Enable global interrupts

   SFRPAGE = LEGACY_PAGE;

   while (1)
   {
      // Toggle the ADC enable bit when the switch is pressed

      while (SW != 0);                 // Wait until SW is pressed

	  ADC0CN_bit.AD0EN = ~ADC0CN_bit.AD0EN;                  // Toggle the bit

      while (SW == 0);                 // Wait until SW is released
   }
}

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

//-----------------------------------------------------------------------------
// OSCILLATOR_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// This function initializes the system clock to use the internal 24.5/8 MHz
// oscillator as its clock source.  Also enables missing clock detector reset.
//
//-----------------------------------------------------------------------------
void OSCILLATOR_Init (void)
{
   unsigned char SFRPAGE_save = SFRPAGE; // Save the current SFRPAGE

   SFRPAGE = CONFIG_PAGE;              // Switch to the necessary SFRPAGE

   OSCICN = 0x80;                      // Configure internal oscillator for
                                       // its lowest frequency
   RSTSRC = 0x04;                      // Enable missing clock detector

   SFRPAGE = SFRPAGE_save;             // Restore the SFRPAGE
}

//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// This function configures the crossbar and GPIO ports.
//
// Pinout:
//
// P0.0                           Skipped
// P0.1                           Skipped
// P0.2                           Skipped
// P0.3                           Skipped
// P0.4   digital   push-pull     UART TX
// P0.5   digital   open-drain    UART RX
// P0.6   digital   open-drain    /INT0
// P0.7                           Skipped

// P1.0                           Skipped
// P1.1                           Skipped
// P1.2                           Skipped
// P1.3   digital   push-pull     LED (and CEX0 depending on Blink_State)
// P1.6   analog                  Potentiometer (ADC input) (Skipped)
//
// P2.4   digital   open-drain    Switch SW
//
//-----------------------------------------------------------------------------
void PORT_Init (void)
{
   unsigned char SFRPAGE_save = SFRPAGE; // Save the current SFRPAGE

   SFRPAGE = CONFIG_PAGE;              // Switch to the necessary SFRPAGE

   P1MDIN    = 0xBF;                   // P1.6 is analog, rest of P1 digital
   P0MDOUT   = 0x10;                   // P0.4 is push-pull
   P1MDOUT   = 0x08;                   // P1.3 is push-pull

   P0SKIP    = 0xCF;                   // Skip all of P0 except for UART0 pins
   P1SKIP    = 0x47;                   // Skip P1.6 and push CEX0 to P1.3

   P0       |= 0x44;                   // Set port latch for pins RX and /INT0
                                       // to configure as inputs

   XBR0      = 0x01;                   // Enable UART

   XBR1      = 0x40;                   // Enable Crossbar; pull-ups enabled

   SFRPAGE = SFRPAGE_save;             // Restore the SFRPAGE
}

//-----------------------------------------------------------------------------
// TIMER0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Initializes the Timer in 16-bit reload mode using SYSCLK as the time base.
//
//-----------------------------------------------------------------------------
void TIMER0_Init (void)
{
   unsigned char SFRPAGE_save = SFRPAGE; // Save the current SFRPAGE

   SFRPAGE = CONFIG_PAGE;              // Switch to the necessary SFRPAGE

   // Initialize Timer0; set global variable for number overflows to reach
   // interrupt rate set by <PRINT_RATE>

   TMOD   |= 0x01;                     // Mode 1 - 16-bit counter
   CKCON  |= 0x04;                     // Use SYSCLK as timebase

   TL0     = 0;                        // Clear Timer0 low byte
   TH0     = 0;                        // Clear Timer0 high byte

   IE     |= 0x02;                     // Enable Timer0 Interrupts

   TCON_bit.TR0   = 1;                         // Enable Timer 0

   SFRPAGE = SFRPAGE_save;             // Restore the SFRPAGE
}

//-----------------------------------------------------------------------------
// 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 16-bit auto-reload and generate an interrupt at
// interval specified by <counts> using SYSCLK/12 as its time base.
//
//-----------------------------------------------------------------------------
void TIMER2_Init (int counts)
{
   unsigned char SFRPAGE_save = SFRPAGE; // Save the current SFRPAGE

   SFRPAGE = CONFIG_PAGE;              // Switch to the necessary SFRPAGE

   TMR2CN  = 0x00;                     // Stop Timer2; Clear TF2;
                                       // use SYSCLK/12 as timebase
   CKCON  &= ~0x30;                    // Timer2 clocked based on T2XCLK;

   TMR2RL  = -counts;                  // Init reload values
   TMR2    = 0xffff;                   // Set to reload immediately
   IE_bit.ET2     = 0;                        // Disable Timer2 interrupts
   TMR2CN_bit.TR2     = 1;                        // Start Timer2

   SFRPAGE = SFRPAGE_save;             // Restore the SFRPAGE
}

//-----------------------------------------------------------------------------
// TIMER3_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Configure Timer3 to 16-bit auto-reload and generate an interrupt at
// interval specified by <counts> using SYSCLK/12 as its time base.
//
// Initially sets Timer3 to overflow at the maximum blink rate.  The Timer3 ISR
// is used to toggle the LED.
//
//-----------------------------------------------------------------------------
void TIMER3_Init (void)
{
   unsigned char SFRPAGE_save = SFRPAGE; // Save the current SFRPAGE

   SFRPAGE = CONFIG_PAGE;              // Switch to the necessary SFRPAGE

   TMR3CN  = 0x00;                     // Stop Timer3; Clear flags;
                                       // use SYSCLK/12 as timebase

   CKCON  &= ~0xC0;                    // Timer3 clocked based on T3XCLK;

   TMR3RL  = 0xFFFF&((0xFFFF-(SYSCLK / 12 / MIN_BLINK_RATE))+1);  // Init reload values

   TMR3    = 0xffff;                   // Set to reload immediately
   EIE1    |= 0x80;                    // Enable Timer3 interrupts

   TMR3CN  |= 0x04;                    // Start Timer3

   SFRPAGE = SFRPAGE_save;             // Restore the SFRPAGE
}

//-----------------------------------------------------------------------------
// ADC0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// This function initializes the ADC to measure potetiometer connected
// to P1.6 in single-ended mode.  Also enables the internal voltage reference.

⌨️ 快捷键说明

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