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

📄 usb.c

📁 一个通过D12与计算机进行USB通信的单片机程序,开发者可以参考
💻 C
📖 第 1 页 / 共 2 页
字号:
			/* clear TX stall for IN on EPn. */
			D12_SetEndpointStatus(endp*2 + 1, 0);
		else
			/* clear RX stall for OUT on EPn. */
			D12_SetEndpointStatus(endp*2, 0);
		single_transmit(0, 0);
	}
	else
		stall_ep0();
}

//特性设置
void set_feature(void)
{
	unsigned char endp;
	unsigned char bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;

	if (bRecipient == USB_RECIPIENT_DEVICE && ControlData.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP)
	{											//设置远程唤醒功能
		DISABLE;
		bEPPflags.bits.remote_wakeup = 1;
		ENABLE;
		single_transmit(0, 0);
	}
	else if (bRecipient == USB_RECIPIENT_ENDPOINT && ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL)
	{											//设置端点stall
		endp = (unsigned char)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
		if (ControlData.DeviceRequest.wIndex & (unsigned char)USB_ENDPOINT_DIRECTION_MASK)
			/* clear TX stall for IN on EPn. */
			D12_SetEndpointStatus(endp*2 + 1, 1);
		else
			/* clear RX stall for OUT on EPn. */
			D12_SetEndpointStatus(endp*2, 1);
		single_transmit(0, 0);
	}
	else
		stall_ep0();
}

//设置地址
void set_address(void)
{
	D12_SetAddressEnable((unsigned char)(ControlData.DeviceRequest.wValue &	DEVICE_ADDRESS_MASK), 1);
	single_transmit(0, 0);
}

//获取描述符
void get_descriptor(void)
{
	unsigned char bDescriptor = MSB(ControlData.DeviceRequest.wValue);
	if (bDescriptor == USB_DEVICE_DESCRIPTOR_TYPE)
	{											//获取设备描述符
		code_transmit((unsigned char code *)&DeviceDescr, sizeof(USB_DEVICE_DESCRIPTOR));
	}
	else if (bDescriptor == USB_CONFIGURATION_DESCRIPTOR_TYPE)
	{											//获取配置描述符
		code_transmit((unsigned char code *)&ConfigDescr, CONFIG_DESCRIPTOR_LENGTH);
	}
	else
		stall_ep0();
}
//获取配置状态
void get_configuration(void)
{
	unsigned char c = bEPPflags.bits.configuration;
	single_transmit(&c, 1);
}

//设置配置状态
void set_configuration(void)
{
	if (ControlData.DeviceRequest.wValue == 0)
	{
		//设备进入未配置状态
		single_transmit(0, 0);
		DISABLE;
		bEPPflags.bits.configuration = 0;
		ENABLE;
		init_unconfig();
	}
	else if (ControlData.DeviceRequest.wValue == 1)
	{
		//配置设备
		single_transmit(0, 0);
		
		init_unconfig();
		init_config();
		DISABLE;
		bEPPflags.bits.configuration = 1;
		ENABLE;
	}
	else
		stall_ep0();
}

//获取接口状态
void get_interface(void)
{
	unsigned char txdat = 0;        /* Only/Current interface = 0 */
	single_transmit(&txdat, 1);
}

//设置接口状态
void set_interface(void)
{
	if (ControlData.DeviceRequest.wValue == 0 && ControlData.DeviceRequest.wIndex == 0)	single_transmit(0, 0);
	else
		stall_ep0();
}

//设置地址使能
void D12_SetAddressEnable(unsigned char bAddress, unsigned char bEnable)
{
	if(bEPPflags.bits.in_isr == 0)	DISABLE;
	outportb(D12_COMMAND, 0xD0);			//输出指令
	if(bEnable)	bAddress |= 0x80;
	outportb(D12_DATA, bAddress);			//设置地址
	if(bEPPflags.bits.in_isr == 0)	ENABLE;
}

//设置端点使能
void D12_SetEndpointEnable(unsigned char bEnable)
{
	if(bEPPflags.bits.in_isr == 0)
		DISABLE;

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

	if(bEPPflags.bits.in_isr == 0)
		ENABLE;
}

//模式设置
void D12_SetMode(unsigned char bConfig, unsigned char bClkDiv)
{
	if(bEPPflags.bits.in_isr == 0)
		DISABLE;
	outportb(D12_COMMAND, 0xF3);//设置模式
	outportb(D12_DATA, bConfig);
	outportb(D12_DATA, bClkDiv);
	if(bEPPflags.bits.in_isr == 0)
		ENABLE;
}

//DMA工作方式设置
void D12_SetDMA(unsigned char bMode)
{
	if(bEPPflags.bits.in_isr == 0)
		DISABLE;
	outportb(D12_COMMAND, 0xFB);//设置DMA工作方式
	outportb(D12_DATA, bMode);
	if(bEPPflags.bits.in_isr == 0)
		ENABLE;
}

//读取中断寄存器
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;
}

//端点选择
unsigned char D12_SelectEndpoint(unsigned char bEndp)
{
	unsigned char c;
	if(bEPPflags.bits.in_isr == 0)
		DISABLE;
	outportb(D12_COMMAND, bEndp);	//端点选择
	c = inportb(D12_DATA);
	if(bEPPflags.bits.in_isr == 0)
		ENABLE;
	return c;
}

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

//读取端点状态
unsigned char D12_ReadEndpointStatus(unsigned char bEndp)
{
	unsigned char c;
	if(bEPPflags.bits.in_isr == 0)
		DISABLE;
	outportb(D12_COMMAND, 0x80 + bEndp);//读取端点状态
	c = inportb(D12_DATA);
	if(bEPPflags.bits.in_isr == 0)
		ENABLE;
	return c;
}

//设置端点状态
void D12_SetEndpointStatus(unsigned char bEndp, unsigned char bStalled)
{
	if(bEPPflags.bits.in_isr == 0)
		DISABLE;

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

	if(bEPPflags.bits.in_isr == 0)
		ENABLE;
}

//传输恢复
void D12_SendResume(void)
{
	outportb(D12_COMMAND, 0xF6);//设置发送恢复
}

//读取当前帧号
unsigned short D12_ReadCurrentFrameNumber(void)
{
	unsigned short i,j;

	if(bEPPflags.bits.in_isr == 0)
		DISABLE;

	outportb(D12_COMMAND, 0xF5);//读取当前帧数目
	i= inportb(D12_DATA);
	j = inportb(D12_DATA);
	i += (j<<8);

	if(bEPPflags.bits.in_isr == 0)
		ENABLE;

	return i;
}

unsigned short D12_ReadChipID(void)
{
	unsigned short i,j;

	if(bEPPflags.bits.in_isr == 0)
		DISABLE;

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

	if(bEPPflags.bits.in_isr == 0)
		ENABLE;

	return i;
}

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

	if(bEPPflags.bits.in_isr == 0)
		DISABLE;

	outportb(D12_COMMAND, endp);
	if((inportb(D12_DATA) & D12_FULLEMPTY) == 0)
	{
		if(bEPPflags.bits.in_isr == 0)
			ENABLE;
		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);

	if(bEPPflags.bits.in_isr == 0)
		ENABLE;

	return j;
}

//写端点
unsigned char D12_WriteEndpoint(unsigned char endp, unsigned char len, unsigned char * buf)
{
	unsigned char i;

	if(bEPPflags.bits.in_isr == 0)
		DISABLE;

	outportb(D12_COMMAND, endp);
	i = inportb(D12_DATA);

	outportb(D12_COMMAND, 0xF0);
	outportb(D12_DATA, 0);
	outportb(D12_DATA, len);

	for(i=0; i<len; i++)
		outportb(D12_DATA, *(buf+i));

	outportb(D12_COMMAND, 0xFA);

	if(bEPPflags.bits.in_isr == 0)
		ENABLE;

	return len;
}

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

//输出数据
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 get_firmware_version()
{
	unsigned char i;

	i = 0x31; // firmware version number
	single_transmit((unsigned char *)&i, 1);
}

//获取端点2缓存区大小
void get_buffer_size()
{
	unsigned char i[4];
	if(bNoRAM == TRUE)
	{
		i[0] = EP2_PACKET_SIZE;
		i[1] = 0;
		i[2] = 0;
		i[3] = 0;
	}
	else
	{
		i[0] = 0;
		i[1] = 1;
		i[2] = 0;
		i[3] = 0;
	}
	single_transmit((unsigned char *)&i, 4);
}

//厂商请求处理
void read_write_register(void)
{
	unsigned char i,len,epstatus;

	if(ControlData.DeviceRequest.bmRequestType & (unsigned char)USB_ENDPOINT_DIRECTION_MASK)
	{
		if(bEPPflags.bits.verbose)
			printf("Read Registers: Offset = 0x%x, Length = 0x%x, Index = 0x%x.\n",
				ControlData.DeviceRequest.wValue,
				ControlData.DeviceRequest.wLength,
				ControlData.DeviceRequest.wIndex);

		if(ControlData.DeviceRequest.wIndex == GET_FIRMWARE_VERSION &&
			ControlData.DeviceRequest.wValue == 0 &&
			ControlData.DeviceRequest.wLength == 1)
			get_firmware_version();//获取固件版本号
		else
			if(ControlData.DeviceRequest.wIndex == GET_BUFFER_SIZE &&
			ControlData.DeviceRequest.wValue == 0 &&
			ControlData.DeviceRequest.wLength == 4)
			get_buffer_size();//获取缓冲区大小
		else
			stall_ep0();

	}	// if read register
	else
	{
		if(bEPPflags.bits.verbose)
		{

			printf("Write Registers: Offset = 0x%x, Length = 0x%x, Index = 0x%x.\n",
				ControlData.DeviceRequest.wValue,
				ControlData.DeviceRequest.wLength,
				ControlData.DeviceRequest.wIndex);

			printf("Data: ");
			for(i = 0; i < ControlData.DeviceRequest.wLength; i ++)
				printf("0x%bx, ", *((ControlData.dataBuffer)+i));
			printf("\n");
		}

		if(ControlData.DeviceRequest.wIndex == SETUP_DMA_REQUEST &&
			ControlData.DeviceRequest.wValue == 0 &&
			ControlData.DeviceRequest.wLength == 6)
		{
			if(ControlData.dataBuffer[5]==0x81)
			{
				D12_WriteEndpoint(5, ControlData.dataBuffer[3], EpBuf);//发送数据
			}
			if(ControlData.dataBuffer[5]==0x80)
			{
				epstatus=D12_ReadEndpointStatus(4);
				epstatus &= 0x60;
				if (epstatus == 0x60)
					len = D12_ReadEndpoint(4, 64, EpBuf);//读取双缓冲区数据
			}
			single_transmit(0, 0);
			//setup_dma_request();//DMA设置处理,因为未使用DMA所以屏蔽掉
		}
		else
			stall_ep0();
	}	// if write register
}

//定时器0初始化程序
//定时器用来定时检测按键状态
void init_timer0(void)
{
	TMOD &= 0XF0;                    /* clear Timer 0   */
	TMOD  |= 0X1;
	TL0 = 0X0;                   /* value set by user    */
	TH0 = 0X0;                  /* value set by user  */
	ET0 = 1;        /* IE.1*/
	TR0 = 1;                /* TCON.4 start timer  */
	PT0 = 1;

	EA = 1;
}
//中断设置
void init_special_interrupts(void)
{
	IT0 = 0;
	EX0 = 1;
	PX0 = 0;
}

//I/O口初始化程序
void init_port()
{
	P0 = 0xFF;
	P1 = 0xFF;
	P2 = 0xFF;
	P3 = 0xFF;
	MCU_D12CS = 0x0;
	D12SUSPD = 0;
}

//串行口设置
void init_serial(void)
{
	SCON = 0X52;
	PCON = 0X80 | PCON;
	TMOD = 0X20;
	TCON = 0x69;    // TCON
	TH1 = 0xFA;
}

⌨️ 快捷键说明

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