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