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

📄 复件 30日精简容易识别usbkeyboard.c

📁 此程序能实现PIC16F877A与D12实现USB通讯
💻 C
📖 第 1 页 / 共 2 页
字号:
   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 + -