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

📄 success6.c

📁 在单片机系统下实现基本的固件枚举,对应用开发者大有裨益
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <reg52.h>
#include <absacc.h>
#include <intrins.h>
#include <D12.h>

unsigned char xdata GenEpBuf[EP1_PACKET_SIZE];
unsigned char  EpBufL[8]={11,22,33,44,55,66,77,88};
// 能设置地址了

void outportb(unsigned int Addr, unsigned char Data)  // 输出数据
{
	*((unsigned char xdata *) Addr) = Data;
}

unsigned char inportb(unsigned int Addr)              // 输入数据
{
	return *((unsigned char xdata *) Addr);
}

void delay(unsigned int cnt)                  // 延时函数,11.0592的晶振,产生13*cnt+20us 的延时
{
	unsigned int i;
	for(i=0;i<cnt;i++);	  	
}

void serial_output(unsigned char temp)  // 串口输出程序
{
  	   SBUF=temp;
  	   while(TI==0);
  	   TI=0;
 }

void D12_SetMode(unsigned char bConfig, unsigned char bClkDiv)  //模式设置
{

	outportb(D12_COMMAND, 0xF3);         // 设置模式,后面跟2字节数据
	outportb(D12_DATA, bConfig);         // 第一个字节包含配置字节信息
	outportb(D12_DATA, bClkDiv);         // 第二个字节包含时钟分频因子信息
}

void D12_SetEndpointStatus(unsigned char bEndp, unsigned char bStalled)
{


	outportb(D12_COMMAND, 0x40 + bEndp);//设置端点状态
	outportb(D12_DATA, bStalled);


}

void D12_AcknowledgeEndpoint(unsigned char endp)  // 设置端点应答
{
	outportb(D12_COMMAND, endp);    // 选择端点
	outportb(D12_COMMAND, 0xF1);    // 设置应答
	if(endp == 0)
		outportb(D12_COMMAND, 0xF2);
}

unsigned short D12_ReadInterruptRegister(void) // 读取中断寄存器
{
	unsigned char b1;
	unsigned int j;

	outportb(D12_COMMAND, 0xF4);    // 读取中断寄存器命令
	b1 = inportb(D12_DATA);
	j = inportb(D12_DATA);

	j <<= 8;
	j += b1;

	return j;
}

void D12_SetAddressEnable(unsigned char bAddress, unsigned char bEnable) // 设置地址/使能
{                            // 地址                            使能该功能

	outportb(D12_COMMAND, 0xD0);  // 输出指令
	if(bEnable)
		bAddress |= 0x80;
	outportb(D12_DATA, bAddress); // 设置地址

}

void D12_SetEndpointEnable(unsigned char bEnable)  // 设置端点使能
{

	outportb(D12_COMMAND, 0xD8);    // 输出指令
	if(bEnable)
		outportb(D12_DATA, 1);      // 设置端点允许
	else
		outportb(D12_DATA, 0);      // 设置端点禁止

}

unsigned short D12_ReadChipID(void)    // 读芯片ID
{
	unsigned short i,j;

	outportb(D12_COMMAND, 0xFD);
	i=inportb(D12_DATA);
	j=inportb(D12_DATA);
	i += (j<<8);
	
	return i;
}

unsigned char D12_ReadLastTransactionStatus(unsigned char bEndp) // 读取最后处理状态
{
	outportb(D12_COMMAND, 0x40 + bEndp);//返回最后传输状态
	return inportb(D12_DATA);
}

unsigned char D12_ReadEndpoint(unsigned char endp, unsigned char len, unsigned char * buf) // 读取端点数据
{                                                                                          // 返回数据的长度
	unsigned char i, j; 

	outportb(D12_COMMAND, endp);                   // 选择管道
	if((inportb(D12_DATA) & D12_FULLEMPTY) == 0)   // 缓冲区空
	{
		return 0;
	}
    // 缓冲区有内容
	outportb(D12_COMMAND, 0xF0);    // 读缓冲区
	j = inportb(D12_DATA);          // 第一字节无意义
	j = inportb(D12_DATA);          // 第二字节是数据字节的长度

	if(j > len)
		j = len;

	for(i=0; i<j; i++)
		*(buf+i) = inportb(D12_DATA);

	outportb(D12_COMMAND, 0xF2);     // 缓冲区清零

	return j;
}

unsigned char D12_WriteEndpoint(unsigned char endp, unsigned char len, unsigned char * buf) // 写端点
{                                                                                      // 返回数据的长度
	unsigned char i;

	outportb(D12_COMMAND, endp);    // 选管道
	i = inportb(D12_DATA);

	outportb(D12_COMMAND, 0xF0);    // 写缓冲区
	outportb(D12_DATA, 0);          // 第一字节保留,为0
	outportb(D12_DATA, len);        // 第二字节为数据字节长度

	for(i=0; i<len; i++)
		outportb(D12_DATA, *(buf+i)); // 写入数据

	outportb(D12_COMMAND, 0xFA);      // 使缓冲区有效


	return len;
}

/*unsigned char D12_ReadEndpointStatus(unsigned char bEndp) // 读取端点状态
{
	unsigned char xdata c;


	outportb(D12_COMMAND, 0x80 + bEndp);   // 读取端点状态
	c = inportb(D12_DATA);

	return c;
}*/

void stall_ep0(void)
{
	D12_SetEndpointStatus(0, 1);
	D12_SetEndpointStatus(1, 1);
}
/*******************************************************************************************************/

void disconnect_USB(void)     // 断开USB总线
{
	// Initialize D12 configuration
	D12_SetMode(D12_NOLAZYCLOCK,D12_CLOCK_12M);
}

void connect_USB(void)        // 连接USB总线
{
	// Initialize D12 configuration
	D12_SetMode(D12_NOLAZYCLOCK|D12_SOFTCONNECT, D12_CLOCK_12M);
}

void reconnect_USB(void)          //重新连接到USB总线
{	
//    SUSPEND = 0;        
	disconnect_USB();
	delay(191);                  // 2.5ms
	delay(191);                  // 2.5ms
	delay(191);                  // 2.5ms
	delay(191);                  // 2.5ms
	D12_SetAddressEnable(0,1);   // 设置地址0使能
	D12_SetEndpointEnable(1);    // 设置端点使能
	connect_USB();

}

void init_MCS51(void)      // I/O口初始化程序
{
    
	P1 = 0xFF;
	P3 = 0xFF;
	D12SUSPD = 0;          // 挂起为低电平

	SCON = 0x40;           // 串口工作方式1,8位UART
	PCON = 0x00;           // 波特率不加倍
	TMOD = 0x20;           // T1工作方式2,8位可自动重载
	TH1  = 0xfd;           // 11.0592M晶振下波特率9600
	TL1  = 0xfd; 
	
	IT1 = 0;               // 外部中断1为电平触发方式,低电平有效
	EX1 = 1;               // 允许外部中断1 	
}

void init_unconfig(void)        // 恢复到未配置状态
{
	D12_SetEndpointEnable(0);	/* Disable all endpoints but EPP0. */
}

void init_config(void)         // 设置配置状态
{
	D12_SetEndpointEnable(1);	/* Enable  generic/iso endpoints. */
}

void single_transmit(unsigned char * buf, unsigned char len) // 从端点号1发送数据
{
	
	if( len <= EP0_PACKET_SIZE) 
	{		
		D12_WriteEndpoint(1, len, buf);
	}

}

void code_transmit(unsigned char code * pRomData, unsigned short len) // 发送端点号1建立代码
{
	ControlData.wCount = 0;
	if(ControlData.wLength > len)
		ControlData.wLength = len;
    
	ControlData.pData = pRomData;
	if( ControlData.wLength >= EP0_PACKET_SIZE) 
	{
		D12_WriteEndpoint(1, EP0_PACKET_SIZE, ControlData.pData);  // 发送16字节数据
		ControlData.wCount += EP0_PACKET_SIZE;
//		DISABLE;
		bEPPflags.bits.control_state = USB_TRANSMIT;
//		ENABLE;
	}
	else 
	{
		D12_WriteEndpoint(1, ControlData.wLength, pRomData);      // 发送16字节内数据
		ControlData.wCount += ControlData.wLength;
//		DISABLE;
		bEPPflags.bits.control_state = USB_IDLE;
//		ENABLE;
	}

}

void set_address(void)   // 为设备设置一个唯一的地址
{
	D12_SetAddressEnable((unsigned char)(ControlData.DeviceRequest.wValue & 0x7F), 1);
	single_transmit(0, 0);
}

void get_descriptor(void) // 获得设备的某种描述符
{
	unsigned char bDescriptor = MSB(ControlData.DeviceRequest.wValue); // 取wValue的高8位

    switch(bDescriptor)
    {
    	case DEVICE_DESCRIPTOR_TYPE : // 获取设备描述符
		code_transmit((unsigned char code *)&DeviceDescr, DEVICE_DESCRIPTOR_SIZE);
		break;
	 
		case CONFIGURATION_DESCRIPTOR_TYPE :  // 获取配置描述符
		code_transmit((unsigned char code *)&ConfigDescr, TOTAL_CONFIG_SIZE);break;
	 
	    default :stall_ep0();
		
    }

}

void get_configuration(void) // 获得指定设备的当前配置的值
{
	unsigned char xdata c = bEPPflags.bits.configuration;
	single_transmit(&c, 1);
}

void set_configuration(void)   // 激活设备的某个配置
{

	if (ControlData.DeviceRequest.wValue == 0) 
	{
		//设备进入未配置状态
		single_transmit(0, 0);

		bEPPflags.bits.configuration = 0;

		init_unconfig();
	} 
	else if (ControlData.DeviceRequest.wValue == 1) 
	{
		//配置设备
		single_transmit(0, 0);  
		init_unconfig();
		init_config();
        
		bEPPflags.bits.configuration = 1;

⌨️ 快捷键说明

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