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

📄 usb_main.c

📁 REVISIONS: 11/22/02 - DM: Added support for switches and sample USB
💻 C
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
// USB_MAIN.c
//-----------------------------------------------------------------------------
// Copyright 2003 ZZLXKJ, Inc.
//
// AUTH: WHL
// DATE: 22 FEB 02
//
//
// Target: C8051F32x
// Tool chain: KEIL C51 6.03 / KEIL EVAL C51
//
// REVISIONS:  11/22/02 - DM:  Added support for switches and sample USB
// interrupt application.
//
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------

#include <c8051f320.h>               
#include "USB_REGISTER.h"
#include "USB_MAIN.h"
#include "USB_DESCRIPTOR.h"
#include "math.h"

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

sfr16 TMR2RL   = 0xca;		// Timer2 reload value
sfr16 TMR2     = 0xcc;		// Timer2 counter   
sfr16 TMR3RL   = 0x92;		// Timer2 reload registers
sfr16 TMR3     = 0x94;		// Timer3 counter registers
  
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
//
//25AA040 instruction set
//
#define READ_25AA	0x03	//Read data from memory array beginning at selected address
#define WRITE_25AA	0x02	//Write data to memory array beginning at selected address
#define WRDI_25AA	0x04	//Reset the write enable latch(disable write operation)
#define WREN_25AA	0x06	//set the write enagle latch(enable write operations)
#define RDSR_25AA	0x05	//Read status register
#define WRSR_25AA	0x01	//Write status registet
sbit	CS_25AA	=P2^3;

// This example demonstrates how the C8051F32x SMBus interface can communicate
// with a 128 byte I2C Serial EEPROM (Microchip 24LC01B) .
// - Interrupt-driven SMBus implementation
// - Only master states defined (no slave or arbitration)
// - Timer1 used as SMBus clock source
// - Timer2 used by SMBus for SCL low timeout detection
// - SCL frequency defined by <SMB_FREQUENCY> constant
// - Pinout:
//    P1.0 -> SDA (SMBus)
//    P1.1 -> SCL (SMBus)

/*

//24CXX instruction set
#define READ_24LC	0x01	// SMBus READ command
#define WRITE_24LC	0x00	// SMBus WRITE command

// Device addresses (7 bits, lsb is a don't care)
#define EEPROM_ADDR	0xA0		// Device address for slave target Note: This address is specified
									// in the Microchip 24LC01B datasheet.
// SMBus Buffer Size
#define SMB_BUFF_SIZE	0x08		// Defines the maximum number of bytes
									// that can be sent or received in a single transfer
// Status vector - top 4 bits only
#define SMB_MTSTA	0xE0	// (MT) start transmitted
#define SMB_MTDB	0xC0	// (MT) data byte transmitted
#define SMB_MRDB	0x80	// (MR) data byte received

//unsigned char whl;
unsigned char* pSMB_DATA_IN;		// Global pointer for SMBus data All receive data is written here
unsigned char SMB_SINGLEBYTE_OUT;	// Global holder for single byte writes.
unsigned char* pSMB_DATA_OUT;		// Global pointer for SMBus data. All transmit data is read from here
unsigned char SMB_DATA_LEN;			// Global holder for number of bytes
									// to send or receive in the current SMBus transfer.
unsigned char WORD_ADDR;			// Global holder for the EEPROM word address that will be accessed in
									// the next transfer
unsigned char TARGET;				// Target SMBus slave address

bit SMB_BUSY = 0;		// Software flag to indicate when the
						// EEPROM_ByteRead() or EEPROM_ByteWrite() functions have claimed the SMBus
bit SMB_RW;				// Software flag to indicate the direction of the current transfer
bit SMB_SENDWORDADDR;	// When set, this flag causes the ISR to send the 8-bit <WORD_ADDR> after sending the slave address.
bit SMB_RANDOMREAD;		// When set, this flag causes the ISR to send a START signal after sending the word address.
bit SMB_ACKPOLL;		// When set, this flag causes the ISR to send a has acknowledged its slave address

*/


#define SYSCLK_EXT		24000000    // SYSCLK  External frequency in Hz
#define	BAUDRATE		460800		// 961200 // Baud rate of UART in bps
#define	TIMER2_RATE		20000    // Timer 2 overflow rate in Hz
#define  SMB_FREQUENCY  100000 	// Target SCL clock rate

sbit Led1 = P2^0;                         // LED='1' means ON
sbit Led2 = P2^1;

#define Sw1 0x01                          // These are the port2 bits for Sw1
#define Sw2 0x02                          // and Sw2 on the development board
// BYTE Switch1State = 0;                    // Indicate status of switch 
// BYTE Switch2State = 0;                    // starting at 0 == off

// BYTE Toggle1 = 0;                         // Variable to make sure each button
// BYTE Toggle2 = 0;                         // press and release toggles switch

// BYTE Potentiometer = 0x00;                // Last read potentiometer value
// BYTE Temperature = 0x00;                  // Last read temperature sensor value

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

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

//-----------------------------------------------------------------------------
// Main Routine
//-----------------------------------------------------------------------------
void main(void) 
{
	int y;
	char in_buff[8] = {0};                    // incoming data buffer
	char out_buff[8] = "abcdefg";             // outgoing data buffer
	unsigned char temp_char;                  // temporary variable

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

	Sysclk_Init();							// Initialize oscillator
	Port_Init();							// Initialize crossbar and GPIO
	Usb0_Init();							// Initialize USB0
	Timer2_Init(SYSCLK_EXT/TIMER2_RATE);    // Init Timer 2
	Adc_Init();								// Initialize ADC
	UART0_Init();		// Initialize UART
//	SPI0_Init();		// Initialize SPI
//	Timer0_Init ();		// Configure Timer0 for use as SMBus clock source
	Timer1_Init ();		// Configure Timer1 for use as UART0 clock source
//	Timer3_Init ();		// Configure Timer3 for use with SMBus low timeout detect
//	SMBus_Init();		// Initialize IIC

//	EIE1 |= 0x80;	// Timer3 interrupt enable
	IE |= 0x20;		// Timer2 interrupt enable
	EA = 1;			// Global interrupt enable

/*	EEPROM_ByteWrite(0x25, 0xAA);	// Write the value 0xBB to location 0x25 in the EEPROM
	temp_char = EEPROM_ByteRead(0x25);	// Read the value at location 0x25 in the EEPROM
	EEPROM_ByteWrite(0x25, 0xBB);		// Write the value 0xBB to location 0x25 in the EEPROM
	EEPROM_ByteWrite(0x38, 0xCC);	// Write the value 0xCC to location 0x38 in the EEPROM
	temp_char = EEPROM_ByteRead(0x25);	// Read the value at location 0x25 in the EEPROM
	temp_char = EEPROM_ByteRead(0x38);	// Read the value at location 0x38 in the EEPROM
	EEPROM_WriteArray(0x50, (unsigned char) out_buff, sizeof(out_buff));	// Store the outgoing data buffer at EEPROM address 0x50
	EEPROM_ReadArray((unsigned char) in_buff, 0x50, sizeof(in_buff));	// Fill the incoming data buffer with data starting at EEPROM address 0x50
*/


   while (1)
{
	// It is possible that the contents of the following packets can change
	// while being updated.  This doesn't cause a problem in the sample 
	// application because the bytes are all independent.  If data is NOT 
	// independent, packet update routines should be moved to an interrupt
	// service routine, or interrupts should be disabled during data updates.

	if (Out_Packet[0] == 1)
	{	Led1 = 1;   // Update status of LED #1
//		Led2 = 0;
		Out_Packet[0] = 0;
		for(y=0;y<100;y++)
		Delay();
//		Delay();
	}
	else
	{	Led1 = 0;
		Out_Packet[0] = 1;
//		Led2 = 1;
		for(y=0;y<200;y++)
//	  	Delay();
		Delay();
	}
	
	
//      if (Out_Packet[0] == 1) Led1 = 1;   // Update status of LED #1
//     else Led1 = 0;
//      if (Out_Packet[1] == 1) Led2 = 1;   // Update status of LED #2
//      else Led2 = 0;
      P1 = (Out_Packet[2] & 0x0F);        // Set Port 1 pins 

/*	In_Packet[0] = Read_25aa_status();
	Write_25aa_enable();
	Write_25aa_data(00,0x21);
	In_Packet[1] = Read_25aa_data(00);
*/
/*	In_Packet[0] = Switch1State;        // Send status of switch 1
	In_Packet[1] = Switch2State;        // and switch 2 to host
	In_Packet[2] = (P0 & 0x0F);         // Port 0 [0-3] (make sure j9 & j10 jumpered)
	In_Packet[3] = Potentiometer;       // Potentiometer value
	In_Packet[4] = Temperature;         // Temperature sensor value
*/
 
 }
}

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

//-------------------------
// Sysclk_Init
//-------------------------
// SYSLCK Initialization
// - Initialize the system clock and USB clock
//
void Sysclk_Init(void)
{
#ifdef _USB_LOW_SPEED_

	OSCICN |= 0x03;				// Configure internal oscillator for
								// its maximum frequency and enable
								// missing clock detector

	CLKSEL  = SYS_INT_OSC;			// Select System clock
	CLKSEL |= USB_INT_OSC_DIV_2;	// Select USB clock
#else
#ifdef _INT_OSC_
	OSCICN |= 0x03;			// Configure internal oscillator for
							// its maximum frequency and enable
							// missing clock detector
	CLKMUL  = 0x00;			// Select internal oscillator as 
							// input to clock multiplier
	CLKMUL |= 0x80;			// Enable clock multiplier
	CLKMUL |= 0xC0;			// Initialize the clock multiplier
	Delay();				// Delay for clock multiplier to begin
	while(!(CLKMUL & 0x20));	// Wait for multiplier to lock
	CLKSEL  = SYS_INT_OSC;		// Select System clock
	CLKSEL |= USB_4X_CLOCK;		// Select USB clock 
#else
	P0MDIN &=0xF3;			// p0.2,p0.3 XTAL1 XTAL2
	P0SKIP |=0x0C;			// p0.2,p0.3 skipped by crossbar
	XBR0 |=0x08;			                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
//	XBR1 |=0x40;			//Enable Crossbar

	OSCXCN |=0x67;
	Delay();					// Delay for clock multiplier to begin
	while(!(OSCXCN & 0x80));	// Wait for multiplier to lock
	CLKSEL  = SYS_EXT_OSC;		// Select system clock  External oscillator
	OSCICN = 0x00;				// internal oscillator OFF

	CLKMUL  = 0x02;			// Select External oscillator/2 as input to clock multiplier
	CLKMUL |= 0x80;			// Enable clock multiplier
	CLKMUL |= 0xC0;			// Initialize the clock multiplier
	Delay();				// Delay for clock multiplier to begin
	while(!(CLKMUL & 0x20));	// Wait for multiplier to lock
	CLKSEL |= USB_4X_CLOCK;		// Select USB clock 
#endif
#endif  /* _USB_LOW_SPEED_ */ 
}

//-------------------------
// Port_Init
//-------------------------
// Port Initialization
// - Configure the Crossbar and GPIO ports.
//
void Port_Init(void)
{  
	P0MDIN	|= 0x30;	// P0.4,P0.5 set as UTAR0 TX0,RX0
	P0MDOUT |= 0x10;	// enable UTX as push-pull output

	P0MDIN	|= 0xC3;	// P0.0,P0.1 P0.6,P0.7 set as SPI0 SCK,MISO MOSI NSS
	P0MDOUT |= 0x41;	// enable SPI_MOSI,SCK as push-pull output

	P1MDIN	|= 0x03;	// P0.0,P0.1 set as SMBus SDA,SCL
	P1MDOUT	|= 0x03;	// enable SMBus_SDA,SCL as push-pull output

	P1MDIN	&= 0x3F;	// Port 1 pin 7,6 set as analog input

	P2MDOUT |= 0x0F;	// Port 2 pins 0,1 set high impedence
	
	
	P0SKIP	|= 0x80;
	P1SKIP   = 0xC0;	// Port 1 pin 7,6 skipped by crossbar

	XBR0	|= 0x07;	// Enable UART0,SPI0,SMBus 
	XBR1     = 0x40;	// Enable Crossbar

	CS_25AA	=1;
}

//-------------------------
// Usb0_Init
//-------------------------
// USB Initialization
// - Initialize USB0
// - Enable USB0 interrupts
// - Enable USB0 transceiver
// - Enable USB0 with suspend detection
//
void Usb0_Init(void)
{
   POLL_WRITE_BYTE(POWER,  0x08);          // Force Asynchronous USB Reset
   POLL_WRITE_BYTE(IN1IE,  0x07);          // Enable Endpoint 0-2 in interrupts
   POLL_WRITE_BYTE(OUT1IE, 0x07);          // Enable Endpoint 0-2 out interrupts
   POLL_WRITE_BYTE(CMIE,   0x07);          // Enable Reset, Resume, and Suspend interrupts
#ifdef _USB_LOW_SPEED_
   USB0XCN = 0xC0;                         // Enable transceiver; select low speed
   POLL_WRITE_BYTE(CLKREC, 0xA0);          // Enable clock recovery; single-step mode
                                           // disabled; low speed mode enabled
#else                                      
   USB0XCN = 0xE0;                         // Enable transceiver; select full speed
   POLL_WRITE_BYTE(CLKREC, 0x80);          // Enable clock recovery, single-step mode
                                           // disabled
#endif /* _USB_LOW_SPEED_ */

   EIE1 |= 0x02;                           // Enable USB0 Interrupts
   EA = 1;                                 // Global Interrupt enable
                                           // Enable USB0 by clearing the USB Inhibit bit
   POLL_WRITE_BYTE(POWER,  0x01);          // and enable suspend detection
}

//-------------------------
// Timer_Init
//-------------------------
// Timer initialization
// - Timer 2 reload, used to check if switch pressed on overflow and
// used for ADC continuous conversion
//
void Timer2_Init (int counts)
{
   TMR2CN = 0x00;                      // STOP Timer2; Clear TF2H and TF2L;                                       // disable low-byte interrupt; disable                                       // split mode; select internal timebase   CKCON |= 0x10;                      // Timer2 uses SYSCLK as its timebase   TMR2RL  = -counts;                  // Init reload values   TMR2    = TMR2RL;                   // Init Timer2 with reload value   ET2 = 0;                            // disable Timer2 interrupts   TR2 = 1;                            // start Timer2
}	

//-------------------------
// Adc_Init
//-------------------------
// ADC initialization
// - Configures ADC for single ended continuous conversion or Timer2
//
void Adc_Init(void)
{                 
	REF0CN  = 0x0E;			// Enable voltage reference VREF
//	REF0CN  = 0x03;			//Enable voltage reference VREF  from p0.7
//	AMX0P = 0x07;			// Positive input starts as temp sensor  
	AMX0P = 0x06;			// Positive input starts as temp sensor  
	AMX0N = 0x1F;			// Single ended mode(negative input = gnd)
//	AMX0P	= 0x07;
//	AMX0N	= 0x06;
	ADC0CF = (SYSCLK/3000000) << 3;     // ADC conversion clock <= 3MHz
	ADC0CF |= 0x04;                    // Make ADC0 right-justified
	ADC0CN	= 0xC2;			// Continuous converion on timer 2 overflow
							// with low power tracking mode on
	EIE1	|= 0x08;		// Enable conversion complete interrupt
}

//-----------------------------------------------------------------------------// UART0_Init//-----------------------------------------------------------------------------//// Configure the UART0 using Timer1, for <BAUDRATE> and 8-N-1.// void UART0_Init (void){	SCON0 = 0x10;		// SCON0: 8-bit variable bit rate level of STOP bit is ignored						// RX enabled ninth bits are zeros clear RI0 and TI0 bits	if (SYSCLK_EXT/BAUDRATE/2/256 < 1)
	{		TH1 = -(SYSCLK_EXT/BAUDRATE/2);		CKCON &= ~0x0B;                  // T1M = 1; SCA1:0 = xx

⌨️ 快捷键说明

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