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

📄 main.c

📁 单片机和D12通讯的C程序.实现了单片机通过USB口和电脑通讯.
💻 C
字号:


#include "InsUsb.h"
#include <intrins.h>

#define _Debug_
//global structure variable
SYS_INFORMATION data sSysInformation;
//global array variable
unsigned char xdata mEp0OutBuffer[EP0_OUT_BUFFER_SIZE];
unsigned char data  mEp0InBuffer[EP0_IN_BUFFER_SIZE];
unsigned char data  mEp1OutBuffer[EP1_OUT_BUFFER_SIZE];			//store led status
unsigned char data  mEp1InBuffer[EP1_IN_BUFFER_SIZE];			//store switch status
unsigned char xdata mRamBuffer[RAM_BUFFER_SIZE];
unsigned char xdata  mSerialNumber[4];


void UsbBusReset(void);
extern void D12SetMode(unsigned char bConfiguration, unsigned char bClockkDivision);
extern void D12SetAddressEnable(unsigned char bAddress, unsigned char bEnable);
extern void D12SetEndpointStatus(unsigned char bEndpointIndex, unsigned char bStalled);
extern void D12WriteBuffer(unsigned char bEndpointIndex,unsigned char bLength, unsigned char * pBuffer);
extern void D12SetEndpointEnable(unsigned char bEndpointEnable);
extern void D12SetDMA(unsigned char bValue);
extern void D12SendResume(void);
extern void UsbIsr(void);
extern void UsbSetUpDeal(void);
extern void ControlOutDealWith(void);

//
//*************************************************************************
//	Paremeter:
//		In : None
//		Out: None
//	Function:
//		On PDIUSBD12 Develop Board,the interrupt pin of PDIUSBD12 is connected
//		to INT0 of P89C51RD2.When interrupt has happened,this function
//		will call UsbIsr(),which will deal with USB interrupt

void UsbInterrupt(void) interrupt 0
{
	#ifdef _INT_MODE_
	UsbIsr();	//USB interrupt service routine
	#endif
}

//
//*************************************************************************
//	Paremeter:
//		In : None
//		Out: None
//	Function:
//		This interrupt is use to refresh LED and switch status
void Timer0Interrupt(void) interrupt 1
{
	static unsigned char data bTimer0Tiems = 0x00;

	if ((++bTimer0Tiems) >= 5) 	//5*65535*6*(1/18.432)=107ms
	{
		sSysInformation.bTimer0 = TRUE;
		bTimer0Tiems = 0x00;
	}

	TH0 = 0x00;
	TL0 = 0x00;
	
}

//
//*************************************************************************
//	Paremeter:
//		In : None
//		Out: None
//	Function:
//		After system power on reset finished,this function will initialize
//		system,include reset PDIUSBD12,initialize all variable,test innteral
//		RAM of P89C51RD2,and set UART,set LED,Switch
void SysInitialize(void)
{

	unsigned int data i;
	unsigned char xdata * data pInnerRam = &MCU_INNER_RAM;

	D12_RESET = 0;							//reset PDIUSBD12
	LED_ADDRESS	= 0xFF;						//all led will turn off

	sSysInformation.bRamError = FALSE;	//no error
	sSysInformation.bTimer0	=FALSE;			//bTimer0
	sSysInformation.bBusReset = FALSE;
	sSysInformation.bSuspendChange = FALSE;
	sSysInformation.bInSuspend = FALSE;	
	sSysInformation.bRemoteWakeUpEnable = FALSE;
	sSysInformation.bD12ConfigurationValue = 0x00;	
	sSysInformation.bSetup = FALSE;
	sSysInformation.bUsbStatus = IDLE;

	sSysInformation.sUsbSetUpDealwith.wRemaindLength = 0;
	sSysInformation.sUsbSetUpDealwith.bControlOutDataComplete = TRUE; 
	sSysInformation.sUsbSetUpDealwith.bControOutCommandIsPending = FALSE;

	sSysInformation.sRamControl.bRamCommand = RAM_COMMAND_LOOPBACK;
	sSysInformation.sRamControl.bRamRwStatus = IDLE;
	sSysInformation.sRamControl.iRamStartAddress = &mRamBuffer;
	sSysInformation.sRamControl.iRamRwLength = 0;
	sSysInformation.sRamControl.iRamRemaindLength = 0;

	//check internal ram of P89C51RD2,it has a internal ram which size is 768 byte.
	//first write 0x5a to all ram unit ,then read and compare,if error happened,
	//set bRamError flag
	for (i=0;i<768;i++) 
	{
		*pInnerRam = 0x5A;					//all inner ram is written to 0x5a
		pInnerRam++;
	}
	pInnerRam = &MCU_INNER_RAM;
	for (i=0;i<768;i++) 
	{
		if (*pInnerRam != 0x5A) 			//read back from high address of inner ram
		{
			sSysInformation.bRamError = TRUE;		//if not equal to 0x5a,error happened
			break;									//and exit from this cycle
		}
		pInnerRam++;

	}
	//second write 0xa5 to all ram unit ,then read and compare,if error happened,
	//set bRamError flag
	pInnerRam = &MCU_INNER_RAM;
	if (sSysInformation.bRamError==FALSE)//test inner ram the second time,write 0xa5
	{
		for (i=0;i<768;i++) 
		{
			*pInnerRam = 0xA5;
			pInnerRam++;
		}
		pInnerRam = &MCU_INNER_RAM;
		for (i=1;i<768;i++) 
		{
			if (*pInnerRam != 0xA5) 
			{
				sSysInformation.bRamError = TRUE;
				break;
			}
			pInnerRam++;
		}
	}	
	//if no ram error found,initialize all ram unit to 0xFF
	pInnerRam = &MCU_INNER_RAM;
	for (i=0;i<768;i++) 
	{
		*pInnerRam = 0xFF;	
		pInnerRam++;
	}


	//Timer1 set,used as UART baud rate generator

	TMOD = 0x20;						
	SCON = 0x50;
	PCON = 0x80;
	TH1	 = 0xFB; 			//OSC is 18.432MHz,MCU is 6 clock mode,then BaudRate will be 38400
	TL1	 = 0xFB;
	TI=1;
	TR1=1;

	//INT0 set,interrupt source is PDIUSBD12
	#ifdef _INT_MODE_
	IT0 = 0;				//low level trigle
	EX0 = 1;
	PX0 = 0;
	#endif

	//Timer0 set, used as switch and led refresh timing
	TMOD &=	0XF0;		
	TMOD  |= 0X1;
	TL0 = 0X0;		    
	TH0 = 0X0;		    
	ET0 = 1;			
	TR0 = 1;			
	PT0 = 1;

	D12_RESET = 1;	//release PDIUSBD12 reset
}

//
//*************************************************************************
//	Paremeter:
//		In : None
//		Out: None
//	Function:
//		This is main function of firmware.It is an infinate cycle and check 
//		sSysInformation,if any flag is set, call corresponding function to 
//		deal with it.
void main(void)
{
	unsigned char data i;
	unsigned int data j;


	EA = 0;	//MCU global interrupt is enabled

	SysInitialize();

	#ifdef _Debug_
	j = FIRMWARE_VERSION;
	printf("Interface Studio PDIUSBD12 USB1.1 Develop Board FirmWare V%x.\n,",j);
	#endif

	if (sSysInformation.bRamError == FALSE)
	{
		#ifdef _Debug_
		printf("On Chip XRAM tested,and no error.\n");
		#endif
	}
	else
	{
		#ifdef _Debug_
		printf("On Chip XRAM error.\n");
		#endif
		while(1);	//if on chip XRAM error,data transfer of bulk transfer will 
					//be error,so here is a dead cycle;
	}

	D12_SUSPEND = 0;					//pull down D12_SUSPEND pin for access it
	D12SetAddressEnable(USB_DEFAULT_DEVICE_ADDRESS,TRUE);		//after reset D12,use default address,namely endpoint0,address 0

	D12SetMode(0x00, 0x4B);
	D12SetDMA(0xC0);
	#ifdef _Debug_
		printf("Connecting to USB...");
	#else
		//we found that if here has no delay,PDIUSBD12 can not setup USB connection correctly!!
		for (j=0;j<1000;j++)	_nop_ ();
	#endif

	D12SetMode(0x10,0x4B);				//enable soft connect
	#ifdef _Debug_
	printf("Connection finished!\n");
	#endif

	for (j=0;j<10000;j++)	_nop_ ();


	mEp1InBuffer[0] = SWITCH_ADDRESS;

	EA = 1;	//MCU global interrupt is enabled

	//Main	program	loop
	while(1)
	{

		#ifndef _INT_MODE_
		if (U_INT!=1)
		{
			UsbIsr();	//USB interrupt service routine
		}
		#endif

		if (sSysInformation.bTimer0)
		{
			//if Host driver has successfully configed our device
			if (sSysInformation.bD12ConfigurationValue != 0x00)
			{
				i = SWITCH_ADDRESS;
				if (mEp1InBuffer[0] != i)
				{
					//Here we will write switch status to endpoint1-in buffer if switch status changed.
					//When interrupt IN token is received,this switch status will be transmit to Host 
					//automatically  by PDIUSBD12.Host software should transmit IN token periodly according
					//to the interval describled by endpoint descriptor.If no switch status change,
				 	//endpoint1-in buffer has no valid data and when Host transmit IN token,PDIUSBD12
					//will return NAK automatically.
					mEp1InBuffer[0] = i;
					D12WriteBuffer(D12_SELECT_ENDPOINT_ENDPOINT1_IN,0x01,&mEp1InBuffer[0]);
				
				}
				//refresh led status,always be executed periodly

				LED_ADDRESS = mEp1OutBuffer[0];
				sSysInformation.bTimer0 = FALSE;
			}
		}		


		if (sSysInformation.bSuspendChange) 
		{
			//According to USB specification,when Host request device enter suspend state,
			//device should draw no more than 500uA current.This requirement is very strict.
			//Interface studio USB1.1 develop board is self powered,so we can ignore this
			//requirement.We just set bInSuspend flag,but run our firmware as usual.

			#ifdef _Debug_
			printf("Suspend change.\n");
			#endif

			D12_SUSPEND = 1;			//release SUSPEND pin,if D12 enter SUSPEND state,
										//this pin will be drive high by D12;
										//else if D12 exit SUSPEND,this pin will be drive low by D12
			for (i=0;i<10;i++);			//delay for suspend pin is stable  driven by PDIUSBD12
			if(D12_SUSPEND == 1) 
			{
				D12_SUSPEND = 0;		//pull low to access D12
				LED_ADDRESS = 0xFF;		//close all led for save power
				sSysInformation.bSuspendChange = FALSE;	//clear suspend flag
				sSysInformation.bInSuspend = TRUE;	//set suspend flag,used for MCU is exit powrdown mode
				D12_SUSPEND = 1;
				#ifdef _Debug_
				printf("Enter suspend.\n");
				#endif

			}
			else
			{
				sSysInformation.bInSuspend = FALSE;	//set suspend flag,used for MCU is exit powrdown mode				
				sSysInformation.bSuspendChange = FALSE;	//clear suspend flag
				#ifdef _Debug_
				printf("Exit suspend.\n");
				#endif
			}
			
		} 

		if (sSysInformation.bBusReset) 
		{
			UsbBusReset();
			#ifdef _Debug_
			printf("Bus reset.\n");
			#endif
		}

		//if received a setup packet
		if (sSysInformation.bSetup)
		{
			EA = 0;
			#ifdef _Debug_
				printf("--------------------------------------------\n");
				printf("SetUp: bRequest code is :");
				printf("%x,%x,%x,%x,%x,\n",	(unsigned int)(sSysInformation.sUsbDeviceRequest.bmRequestType),
											(unsigned int)(sSysInformation.sUsbDeviceRequest.bRequest),
														  (sSysInformation.sUsbDeviceRequest.wValue),
														  (sSysInformation.sUsbDeviceRequest.wIndex),
														  (sSysInformation.sUsbDeviceRequest.wLength));
			#endif
			UsbSetUpDeal();
			sSysInformation.bSetup = FALSE;
			EA = 1;
		}
		//if there is a uncompleted control-out transfer
		if (sSysInformation.sUsbSetUpDealwith.bControOutCommandIsPending)
		{
			ControlOutDealWith();
		}

	} // Main Loop end

}


void UsbBusReset(void)
{
	//When first connect to Host, Host will always issue a bus reset command.
	//And if USB communication has error,host may issue bus reset command also.

	//When no USB cable connect between Host and PDIUSBD12,D+ and D- wire will be 
	//high impedance,and no USB event should be produced by PDIUSBD12;but unfortunately,
	//unsure state of D+/D- will make PDIUSBD12 produce error USB bus event to MCU.
	//To avoid this case,we can attach a 1Mohm pullup resistor to D-,and a 1Mohm 
	//pulldown resistor to D+,thus when there has no USB connection,PDIUSBD12 will
	//report a bus reset state to MCU.but this has no trouble to our application.

	
	//If Host transmit bus reset signal
	sSysInformation.bBusReset = FALSE;
	sSysInformation.bRemoteWakeUpEnable = FALSE;
	sSysInformation.bD12ConfigurationValue = 0x00;	
	sSysInformation.bSetup = FALSE;
	sSysInformation.bUsbStatus = IDLE;

	sSysInformation.sUsbSetUpDealwith.wRemaindLength = 0;
	sSysInformation.sUsbSetUpDealwith.bControlOutDataComplete = TRUE; 
	sSysInformation.sUsbSetUpDealwith.bControOutCommandIsPending = FALSE;

	sSysInformation.sRamControl.bRamCommand = RAM_COMMAND_LOOPBACK;
	sSysInformation.sRamControl.bRamRwStatus = IDLE;
	sSysInformation.sRamControl.iRamStartAddress = &mRamBuffer;
	sSysInformation.sRamControl.iRamRwLength = 0;
	sSysInformation.sRamControl.iRamRemaindLength = 0;

	D12SetAddressEnable(USB_DEFAULT_DEVICE_ADDRESS,TRUE);	//after reset D12,use default address,namely endpoint0,address 0
	D12SetEndpointEnable(0x00);								//disable generic/isochronous endpoint


}

//
//*************************************************************************


⌨️ 快捷键说明

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