USB笔记三:PDIUSBD12基本指令程序
0赞经过特权的整理,以圈圈的程序代码为基础,结合周立功的《PDIUSBD12固件编程与驱动开发》一书,把D12的最底层的代码子程序做了较详细的注释和整理,PDIUSBD12的硬件提取层应该说才是真正意思上的最底层,其次是命令层,这应 该是USB编程入门的突破口,再有其它的操作无非都是基于这些基本的子程序 进行的。以下的代码应该结合这个文档进行理解:。(这个文档应该是周立功书上摘抄的)
#define USB_COMMAND_ADD 1
//USB_A0=USB_COMMAND_ADD:总线命令操作
#define USB_DATA_ADD 0
//USB_A0=USB_DATA_ADD:总线数据操作
/*********************PDIUSBD12硬件提取层********************/
///////////////////////////////////////////////
//函数:write_usb_command
//说明:写USB命 令
//入口:uchar usb_command:待写入的命令
//返回:无
///////////////////////////////////////////////
void write_usb_command(uchar usb_command)
{
USB_A0=USB_COMMAND_ADD; //命令操作
USB_DATA=usb_command;
USB_WR=0;
USB_WR=1;
USB_DATA=0xFF;
}
///////////////////////////////////////////////
//函数:write_a_usb_data
//说明:写一字节USB数 据
//入口:uchar usb_data:待写入的数据
//返回:无
///////////////////////////////////////////////
void write_a_usb_data(uchar usb_data)
{
USB_A0=USB_DATA_ADD; //数据操作
USB_DATA=usb_data;
USB_WR=0;
USB_WR=1;
USB_DATA=0XFF;
}
///////////////////////////////////////////////
//函数:read_a_usb_data
//说明:读一字节USB数 据
//入口:无
//返回:uchar temp:从D12读出的数据
///////////////////////////////////////////////
uchar read_a_usb_data(void)
{
uchar temp;
USB_A0=USB_DATA_ADD; //数据操作
USB_RD=0;
temp=USB_DATA;
USB_RD=1;
return temp;
}
/*********************PDIUSBD12硬件提取层********************/
/***********************PDIUSBD12命令层**********************/
///////////////////////////////////////////////
//函数:set_usb_addr
//说明:设置USB地 址/使能:指令为0xd0
//入口:uchar addr:设置的新地址
//返回:无
///////////////////////////////////////////////
void set_usb_addr(uchar addr)
{
write_usb_command(0xd0);
write_a_usb_data(0x80|addr); //把bit8置高表示使能
}
///////////////////////////////////////////////
//函数:set_endpoint_enable
//说明:设置端点使能:命令为0xd8
//入口:无
//返回:无
///////////////////////////////////////////////
void set_endpoint_enable(void)
{
write_usb_command(0xd8);
write_a_usb_data(0x01);
}
///////////////////////////////////////////////
//函数:set_mode
//说明:设置模式命令:指令为0xf3
//入口:uchar bconfig:配置字节信息
// uchar bclkdiv:时钟分频因数字节
//返回:无
///////////////////////////////////////////////
void set_mode(uchar bconfig,uchar bclkdiv)
{
write_usb_command(0xf3);
write_a_usb_data(bconfig);
write_a_usb_data(bclkdiv);
}
///////////////////////////////////////////////
//函数:set_dma
//说明:设置DMA命 令:指令为0xfb
//入口:uchar bmode:设置DMA字节
//返回:无
///////////////////////////////////////////////
void set_dma(uchar bmode)
{
write_usb_command(0xfb);
write_a_usb_data(bmode);
}
///////////////////////////////////////////////
//函数:read_interrupt_register
//说明:读USB中 断寄存器:指令为0xf4
//入口:无
//返回:uchar inter_reg:中断寄存器第一字节
///////////////////////////////////////////////
uchar read_interrupt_register(void)
{
uchar inter_reg;
uchar inter_reg2;
write_usb_command(0xf4);
inter_reg=read_a_usb_data(); //读第一字节
inter_reg2=read_a_usb_data(); //读第二字节
return inter_reg; //返回第一字节
}
///////////////////////////////////////////////
//函数:select_endpoint
//说明:选择端点:指令为0x00+endp
// 该命令将内部指针初 始化到选择的缓冲区
// 起始位置。
//入口:uchar endp:选择端点0-5
//返回:uchar state:bit0--1表示缓冲区满,0表示缓 冲区空
// bit1--1表示 端点处于停止状态
///////////////////////////////////////////////
uchar select_endpoint(uchar endp)
{
uchar state;
write_usb_command(0x00+endp);
state=read_a_usb_data();
return state;
}
///////////////////////////////////////////////
//函数:read_last_status
//说明:读取端点最后处理状态,命令为0x40+endp
// 该命令同时复位中断 寄存器中的相应位,
// 并将状态清零,表示已读取。
//入口:uchar endp:选择端点0-5
//返回:uchar read_a_usb_data():最后处理状态寄存器
///////////////////////////////////////////////
uchar read_last_status(uchar endp)
{
write_usb_command(0x40+endp);
return read_a_usb_data();
}
///////////////////////////////////////////////
//函数:set_endpoint_status
//说明:设置端点状态:命令为0x40+endp
//入口:uchar endp:选择端点0-5
// uchar status:设置状态值,bit1-bit7为保留位
// bit0=1--表 示端点处于停止状态
//返回:无
///////////////////////////////////////////////
void set_endpoint_status(uchar endp,uchar status)
{
write_usb_command(0x40+endp);
write_a_usb_data(status);
}
///////////////////////////////////////////////
//函数:send_resume
//说明:发送恢复命令:命令为0xf6
//入口:无
//返回:无
///////////////////////////////////////////////
void send_resume(void)
{
write_usb_command(0xf6);
}
///////////////////////////////////////////////
//函数:read_endpoint_status
//说明:读端点状态:命令为0x80+endp
//入口:uchar endp:选择端点0-5
//返回:uchar read_a_usb_data():当前端点状态信息
///////////////////////////////////////////////
uchar read_endpoint_status(uchar endp)
{
write_usb_command(0x80+endp);
return read_a_usb_data();
}
///////////////////////////////////////////////
//函数:clear_buffer
//说明:缓冲区清零:命令为0xf2
//入口:uchar endp:选择端点0-5
//返回:uchar read_a_usb_data():当前端点状态信息
///////////////////////////////////////////////
void clear_buffer(void)
{
write_usb_command(0xf2);
}
///////////////////////////////////////////////
//函数:validate_buffer
//说明:使缓冲区有效:命令为0xfa
//入口:无
//返回:无
///////////////////////////////////////////////
void validate_buffer(void)
{
write_usb_command(0xfa);
}
///////////////////////////////////////////////
//函数:
//说明:读缓冲区:命令为0xf0
//入口:uchar endp:选择端点
// uchar len:缓冲区数据长度
// uchar * buff:缓冲数据数组
//返回:uchar j:缓冲数据字节数
///////////////////////////////////////////////
uchar read_endpoint_buff(uchar endp,uchar len,uchar * buff)
{
uchar i,j;
read_last_status(endp); //读endp端点最后处理状态寄存器,同时复位中断寄存器的相应位
if(!(select_endpoint(endp)&0x01)) //端点endp缓冲区为空则返回
{
return 0;
}
if((read_endpoint_status(endp)&0x60)!=0x60) //两个缓冲区没有都满,才能清中断
{
read_last_status(endp); //清中断
}
write_usb_command(0xf0); //读缓冲区命令,读nB
read_a_usb_data(); //字节1,保留,可为任意值
j=read_a_usb_data(); //字节2,数据字节的长度
if(j>len) //数据字节长度最大130B
{
j=len;
}
for(i=0;i { USB_RD=0; *(buff+i)=USB_DATA; USB_RD=1; } clear_buffer(); //清缓冲区 return j; } /////////////////////////////////////////////// //函数: //说明:写缓冲区:命令为0xf0 //入口:uchar endp:选择端点 // uchar len:缓冲区数据长度 // uchar * buff:缓冲数据数组 //返回:uchar len:缓冲数据长度(最大130B) /////////////////////////////////////////////// uchar write_endpoint_buff(uchar endp,uchar len,uchar * buff) { uchar i; read_last_status(endp); //读endp端点最后处理状态寄存器,同时复位中断寄存器的相应位 select_endpoint(endp);//选择端点 write_usb_command(0xf0); //写缓冲区指令,写nB write_a_usb_data(0); //第1字节保留,总为0 write_a_usb_data(len); //第2字节,写入数据长度 for(i=0;i { USB_DATA=*(buff+i); USB_WR=0; USB_WR=1; } USB_DATA=0xFF; validate_buffer(); //使缓冲区有效 return len; } /***********************PDIUSBD12命令层**********************/