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

📄 main.c

📁 包含介绍C8051F320的USB控制器的固件编程对固件设计者很有帮助
💻 C
字号:
/*
   Copyright 2003 Cygnal Integrated Products, Inc.

   File:     main.c
   Author:   JS
   Created:  JAN 03
   Modified: JUL 03 -- BW (changed 'while(!(CLKMUL & 0x20));')


   Target Device: C8051F320

   Source file for USB firmware. Includes main routine and
   all hardware initialization routines.

   This is the main routine file for the USBProgramGuide.wsp project,
   which includes the following source files:

   main.c
   usb_desc.c
   usb_isr.c
   usb_stdreq.c
   usb_utils.c

   This firmware is intended to work with the Cygnal USB Test Application,
   implementing two Interrupt pipes with 8-byte transfers. The endpoints
   used are as follows:

   Endpoint1 IN - Interrupt IN
   Endpoint2 OUT - Interrupt OUT

   The transmit buffer (used with IN packets) is the 8-byte array
   <IN_PACKET>. This buffer is updated in the main loop. The receive
   buffer (used with OUT packets) is the 8-byte array <OUT_PACKET>. The
   information in received packets is used to update Port I/O in the
   main loop.
******************************************/

#include <c8051f320.h>                    // SFR declarations
#include "usb_regs.h"
#include "usb_structs.h"
#include "usb_main.h"
#include "usb_desc.h"

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

sbit LED1 = P2^2;                         // LED='1' means ON
sbit LED2 = P2^3;
sbit BTN1 = P2^0;                         // Target board button 1
sbit BTN2 = P2^1;                         // Target board button 2

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

void USB0_Init (void);
void USB0_Enable (void);
void PORT_Init (void);
void SYSCLK_Init (void);
void Timer2_Init (void);
void ADC_Init (void);

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

DEVICE_STATUS gDeviceStatus;
EP_STATUS gEp0Status;
EP_STATUS gEp1InStatus;
EP_STATUS gEp2OutStatus;
EP0_COMMAND gEp0Command;

BYTE OUT_PACKET[8]   = {0,0,0,0,0,0,0,0}; // Last packet received from host
BYTE IN_PACKET[8] = {0,0,0,0,0,0,0,0};    // Next packet to sent to host

//------------------------------------------------------------------------
// Main Routine
//------------------------------------------------------------------------

void main (void)
{
   BYTE LastBTN1, LastBTN2 = 0;

   PCA0MD &= ~0x40;                       // Disable Watchdog timer

   PORT_Init ();                          // Initialize Crossbar and GPIO
   SYSCLK_Init ();                        // Initialize oscillator
   Timer2_Init ();                        // Initialize timer2
   ADC_Init ();                           // Initialize ADC
   USB0_Init ();                          // Initialize USB0

   EA = 1;                                // Enable global interrupts

   USB0_Enable ();                        // Enable USB0

   // Main loop updates the IN_PACKET with Port I/O and analog
   // measurement status, and updates Port I/O with information
   // from the OUT_PACKET.
   while (1)
   {
      LED1 = OUT_PACKET[0];               // Update status of LED #1
      LED2 = OUT_PACKET[1];               // Update status of LED #2
      P1 = (OUT_PACKET[2] & 0x0F);        // Update Port1 outputs

      // If button 1 is pressed and its previous state was open,
      // toggle the button 1 flag.
      if ((BTN1 == 0) && (LastBTN1 == 1))
      {
         IN_PACKET[0] = ~IN_PACKET[0];
      }
      LastBTN1 = BTN1;                    // Store the current button state

      // If button 2 is pressed and its previous state was open,
      // toggle the button 2 flag.
      if ((BTN2 == 0) && (LastBTN2 == 1))
      {
         IN_PACKET[1] = ~IN_PACKET[1];
      }
      LastBTN2 = BTN2;                    // Store the current button state

      IN_PACKET[2] = (P0 & 0x0F);         // Update Port0 [0-3] indicators

      // ADC data updated in ADC0 ISR
   }
}

//------------------------------------------------------------------------
// Interrupt Service Routines (non-usb)
//------------------------------------------------------------------------

//---------------------------
// ADC0_ISR
//---------------------------
// - Record conversion data
// - Update MUX for next conversion
//
void ADC0_ISR (void) interrupt 10
{
   // Handle Temperature Sensor measurement
   if (AMX0P == AMX_TEMP_SENSE)
   {
      IN_PACKET[4] = ADC0H;               // Update IN packet
      AMX0P = AMX_P1_7;                   // Update AMUX
   }

   // Handle Potentiometer measurement
   else
   {
      IN_PACKET[3] = ADC0H;               // Update IN packet
      AMX0P = AMX_TEMP_SENSE;             // Update AMUX
   }

   AD0INT = 0;

}

//------------------------------------------------------------------------
// Initialization Routines
//------------------------------------------------------------------------

//---------------------------
// SYSCLK_Init
//---------------------------
// SYSLCK Initialization
// - Initialize the system clock and USB clock
//
void SYSCLK_Init (void)
{
   unsigned char delay = 100;

   OSCICN |= 0x03;                        // Configure internal oscillator for
                                          // its maximum frequency

   CLKMUL = 0x00;                         // Select internal oscillator as
                                          // input to clock multiplier

   CLKMUL |= 0x80;                        // Enable clock multiplier
   while (delay--);                       // Delay for >5us
   CLKMUL |= 0xC0;                        // Initialize the clock multiplier

   while(!(CLKMUL & 0x20));               // Wait for multiplier to lock

   CLKSEL |= USB_4X_CLOCK;                // Select USB clock
   CLKSEL |= SYS_INT_OSC;                 // Select system clock
}


//---------------------------
// USB0_Init
//---------------------------
// USB Initialization
// - Initialize USB0
// - Enable USB0 interrupts
// - Enable USB0 transceiver
// - USB0 left disabled
//
void USB0_Init (void)
{
   UWRITE_BYTE(POWER, 0x08);              // Asynch. reset

   UWRITE_BYTE(IN1IE, 0x0F);              // Enable Endpoint0 Interrupt
   UWRITE_BYTE(OUT1IE, 0x0F);
   UWRITE_BYTE(CMIE, 0x04);               // Enable Reset interrupt

   USB0XCN = 0xC0;                        // Enable transceiver
   USB0XCN |= FULL_SPEED;                 // Select device speed

   UWRITE_BYTE(CLKREC, 0x80);             // Enable clock recovery,
                                          // single-step mode disabled

   EIE1 |= 0x02;                          // Enable USB0 Interrupts
}

//---------------------------
// USB0_Enable
//---------------------------
// USB Enable
// - Enable USB0
//
void USB0_Enable (void)
{

   UWRITE_BYTE(POWER, 0x00);              // Enable USB0 by clearing the
                                          // USB Inhibit bit
                                          // Suspend mode disabled
}

//---------------------------
// ADC_Init
//---------------------------
// ADC initialization
// - Single-ended mode
// - Conversions on Timer2 overflows
// - Left-justified data
// - Low power tracking mode
// - Interrupts enabled
//
void ADC_Init (void)
{
   REF0CN = 0x0E;                         // Temperature sensor enabled,
                                          // internal bias enabled,
                                          // internal voltage reference
                                          // enabled

   AMX0P = AMX_TEMP_SENSE;                // Temp sensor as positive input
   AMX0N = AMX_GND;                       // GND as negative input
                                          // (single-ended)

   ADC0CF = (SYSCLK/2000000) << 3;        // SAR clock set to 2MHz
   ADC0CF |= 0x04;                        // Left-justified data

   ADC0CN = 0xC2;                         // ADC0 enabled, low power
                                          // tracking mode,
                                          // Timer2 conversions

   EIE1 |= 0x08;                          // Enable conversion complete
                                          // interrupt
}

//---------------------------
// Timer2_Init
//---------------------------
// Timer initialization
// - Timer2 configured to overflow at the frequency defined
// by <SAMPLERATE> for ADC conversions
//
void Timer2_Init ()
{
   TMR2CN  = 0x00;                        // Stop Timer2; Clear TF2;
   CKCON  |= 0x10;                        // SYSCLK as Timer2 clock source
   TMR2RL  = -(SYSCLK/SAMPLERATE);        // Timer2 overflows at <SAMPLERATE>
   TMR2    = 0xFFFF;                      // set to reload immediately

   TR2     = 1;                           // start Timer2
}

//---------------------------
// PORT_Init
//---------------------------
// Port Initialization
// - Configure the Crossbar and GPIO ports.
//
void PORT_Init (void)
{
   P1MDIN   = 0x7F;                       // P0.7: analog input
   P0MDOUT  = 0x0F;                       // P0.0-P0.3: push-pull
   P1MDOUT  = 0x0F;                       // P1.0-P1.3: push-pull
   P2MDOUT  = 0x0C;                       // P2.3-P2.2: push-pull
   P1SKIP   = 0x80;                       // P1.7 skipped by Crossbar
   XBR0     = 0x00;                       //
   XBR1     = 0x40;                       // Enable Crossbar
}

⌨️ 快捷键说明

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