📄 复件 30日精简容易识别usbkeyboard.c
字号:
uint8 control_in_port :1;
uint8 port_out_1 :1;
uint8 port_in_1 :1;
uint8 main_out_port :1;
uint8 main_in_port :1;
uint8 bus_reset :1;
uint8 suspend_change :1;
uint8 DMA_EOT :1;
uint8 not_use :7;
}Interrupt;
}Interrupt_Register;
bank1 union //端点最后处理状态
{
uint8 Register;
struct
{
uint8 successful :1;
uint8 error_code :4;
uint8 setup_packet :1;
uint8 data_1 :1;
uint8 prestatus_not_read :1;
}Status;
}Last_Status;
//***************** 延时x毫秒函数 ***********
void delay(uint16 x)
{
char i;
for(i=0;i<x;i++);
for(i=0;i<10;i++);
}
//********************************************
//*******************************写USB命令******************************************
void write_usb_command(uint8 usb_command)
{
RDIO=0X00;//端口D全部为输出
USB_RD=1; //不读
USB_A0=1; //A0为1表示命令
PORTD=usb_command;//命令放到D12数据端口
delay(1);
USB_WR=0;//写使能
// TXREG=usb_command;while(TXIF==0);while(TRMT==0);
USB_WR=1;//写完毕
USB_A0=0;//A0恢复数据格式
//USB_DATA=0xFF;
//RDIO=0X00;
}
//******************************************************************************
//*********************写一字节USB数据*******************************************
void write_a_usb_data(uint8 usb_data)
{
RDIO=0X00;
USB_RD=1;
USB_A0=0; //数据
//delay(1);
USB_DATA=usb_data; //数据放到D12数据端口
delay(1);
USB_WR=0; //写使能
//TXREG=usb_data;while(TXIF==0);while(TRMT==0);
USB_WR=1; //写完毕
//USB_DATA=0XFF;
//RDIO=0X00;
}
//******************************************************************************
//****************************读一字节USB数据************************************
uint8 read_a_usb_data(void)
{
uint8 temp;
RDIO=0XFF;//端口D为输出
USB_A0=USB_DATA_ADD; //A0为0是数据
//delay(1);
USB_RD=0; //读使能
//delay(1);
temp=PORTD; //从数据端口读数据
USB_RD=1; //读完毕
//RDIO=0X00;
//TXREG=temp;while(TXIF==0);while(TRMT==0);
return temp; //返回所读的数据
}
//******************************************************************************
//************************读USB中断寄存器**************************************
void read_interrupt_register(void)
{
write_usb_command(Read_Interrupt_Register); //写0xf4命令,返回2个字节
Interrupt_Register.Register[0]=read_a_usb_data();//status byte1, 7:SUSPEND CHANGE,6:BUS RESET
Interrupt_Register.Register[1]=read_a_usb_data(); //status byte2
//TXREG=Interrupt_Register.Register[0];while(TXIF==0);while(TRMT==0);
}
//******************************************************************************
//************************设置USB地址*******************************************
void set_usb_addr(uint8 addr)
{
write_usb_command(Set_Address);//0x05,Endpoint 2 IN,读一个字节
write_a_usb_data(0x80|addr);//缺省地址为0x80
delay(1);
}
//******************************************************************************
//*************************端点使能******************************************
void set_endpoint_enable(void)
{
write_usb_command(Set_Endpoint_Enable);//写命令0xd8
write_a_usb_data(0x01);//generic/isochronous endpoints are enabled.
}
//******************************************************************************
//****************************选择终端点*************************************
uint8 select_endpoint(uint8 endp)
{
write_usb_command(Select_EndPoint+endp); //0x00+endp为终端点
delay(1);
return read_a_usb_data(); //返回此终端点的状态,stall 和full/empty
}
//******************************************************************************
//****************************读端点最后状态**********************************
uint8 read_last_status(uint8 endp)
{
write_usb_command(Read_Last_Status+endp); //0x40+endp为要读的终端点
delay(1);
return read_a_usb_data();//返回此终端点的最后事务状态,会清除相对应的中断寄存器中断位
}
//******************************************************************************
//****************************设置端点状态**************************************
void set_endpoint_status(uint8 endp,uint8 status)
{
write_usb_command(0x40+endp); //0x40+endp为要设置的终端点
write_a_usb_data(!status); //写入端点状态
}
//******************************************************************************
//*****************************读端点状态**************************************
uint8 read_endpoint_status(uint8 endp)
{
write_usb_command(0x80+endp); //0x80+endp为要读的端点
return read_a_usb_data();//返回此端点状态
}
//******************************************************************************
//************************清缓冲,在读取缓冲数据后调用**************************
void clear_buffer(void)
{
write_usb_command(Clear_Buffer);//0xf2为清除缓冲区命令,不做任何事务
}
//******************************************************************************
//***********************缓冲区数据有效,在写缓冲后调用**************************
void validate_buffer(void)
{
write_usb_command(Validate_Buffer);//0xfa,不做任何事务,数据写到IN 缓冲区后使缓冲区满标志位置位
}
//******************************************************************************
//***************************应答建立包************************************
void ack_setup(uint8 endp)
{
select_endpoint(endp); //要建立包的端点
write_usb_command(Ack_Setup); //0xf1,保证最后的安装包能保存在缓冲区内
}
//******************************************************************************
//***********************出错处理******************************************
void error(uint8 number)
{
// Prints("有错误发生!!!",1);
delay(1);
number=0;
}
//******************************************************************************
//*************************读终端点缓冲****************************************
//读端点endp数据,长度为len,数据存储在buff中
uint8 read_endpoint_buff(uint8 endp,uint8 len,uint8 * buff)
{
uint8 i,j;
read_last_status(endp);//要读的终端点
if(!(select_endpoint(endp))&0x01){error(0); return 0;}
read_endpoint_status(endp);
write_usb_command(Read_Buffer); //读缓冲区命令0xf0 ,可以读多个字节
read_a_usb_data();//读第一字节,忽略
j=read_a_usb_data(); //读第二个字节,数据长度
if(j>len)//如果所读的长度大于要求的长度,则取要求的长度
j=len;
//
RDIO=0XFF;//端口D为输入
for(i=0;i<j;i++)
{ //一次只能读一个字节
USB_RD=0; //读使能
//delay(1);
*(buff+i)=USB_DATA; //从第三个字节开始读,读j个字节放到缓冲区内
//delay(1);
USB_RD=1; //读完毕
}
//
RDIO=0X00; //端口D为输出
clear_buffer(); //读完缓冲区后清除缓冲区
return j; //返回数据长度
}
//******************************************************************************
//*************************写终端点缓冲*****************************************
//写端点endp,数据长度为len,从缓冲区buff中写入
uint8 write_endpoint_buff(uint8 endp,uint8 len,uint8 * buff)
{
uint8 i;
read_last_status(endp); //读终端点的状态,忽略此状态
select_endpoint(endp); //选中要写入数据的端点
write_usb_command(Write_Buffer);//写缓冲区命令0xf0,可以写入多个字节
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -