完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
经过特权的整理,以圈圈的程序代码为基础,把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_u***_command //说明:写USB命令 //入口:uchar u***_command:待写入的命令 //返回:无 /////////////////////////////////////////////// void write_u***_command(uchar u***_command) { USB_A0=USB_COMMAND_ADD; //命令操作 USB_DATA=u***_command; USB_WR=0; USB_WR=1; USB_DATA=0xFF; } /////////////////////////////////////////////// //函数:write_a_u***_data //说明:写一字节USB数据 //入口:uchar u***_data:待写入的数据 //返回:无 /////////////////////////////////////////////// void write_a_u***_data(uchar u***_data) { USB_A0=USB_DATA_ADD; //数据操作 USB_DATA=u***_data; USB_WR=0; USB_WR=1; USB_DATA=0XFF; } /////////////////////////////////////////////// //函数:read_a_u***_data //说明:读一字节USB数据 //入口:无 //返回:uchar temp:从D12读出的数据 /////////////////////////////////////////////// uchar read_a_u***_data(void) { uchar temp; USB_A0=USB_DATA_ADD; //数据操作 USB_RD=0; temp=USB_DATA; USB_RD=1; return temp; } /*********************PDIUSBD12硬件提取层********************/ /***********************PDIUSBD12命令层**********************/ /////////////////////////////////////////////// //函数:set_u***_addr //说明:设置USB地址/使能:指令为0xd0 //入口:uchar addr:设置的新地址 //返回:无 /////////////////////////////////////////////// void set_u***_addr(uchar addr) { write_u***_command(0xd0); write_a_u***_data(0x80|addr); //把bit8置高表示使能 } /////////////////////////////////////////////// //函数:set_endpoint_enable //说明:设置端点使能:命令为0xd8 //入口:无 //返回:无 /////////////////////////////////////////////// void set_endpoint_enable(void) { write_u***_command(0xd8); write_a_u***_data(0x01); } /////////////////////////////////////////////// //函数:set_mode //说明:设置模式命令:指令为0xf3 //入口:uchar bconfig:配置字节信息 // uchar bclkdiv:时钟分频因数字节 //返回:无 /////////////////////////////////////////////// void set_mode(uchar bconfig,uchar bclkdiv) { write_u***_command(0xf3); write_a_u***_data(bconfig); write_a_u***_data(bclkdiv); } /////////////////////////////////////////////// //函数:set_dma //说明:设置DMA命令:指令为0xfb //入口:uchar bmode:设置DMA字节 //返回:无 /////////////////////////////////////////////// void set_dma(uchar bmode) { write_u***_command(0xfb); write_a_u***_data(bmode); } /////////////////////////////////////////////// //函数:read_interrupt_register //说明:读USB中断寄存器:指令为0xf4 //入口:无 //返回:uchar inter_reg:中断寄存器第一字节 /////////////////////////////////////////////// uchar read_interrupt_register(void) { uchar inter_reg; uchar inter_reg2; write_u***_command(0xf4); inter_reg=read_a_u***_data(); //读第一字节 inter_reg2=read_a_u***_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_u***_command(0x00+endp); state=read_a_u***_data(); return state; } /////////////////////////////////////////////// //函数:read_last_status //说明:读取端点最后处理状态,命令为0x40+endp // 该命令同时复位中断寄存器中的相应位, // 并将状态清零,表示已读取。 //入口:uchar endp:选择端点0-5 //返回:uchar read_a_u***_data():最后处理状态寄存器 /////////////////////////////////////////////// uchar read_last_status(uchar endp) { write_u***_command(0x40+endp); return read_a_u***_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_u***_command(0x40+endp); write_a_u***_data(status); } /////////////////////////////////////////////// //函数:send_resume //说明:发送恢复命令:命令为0xf6 //入口:无 //返回:无 /////////////////////////////////////////////// void send_resume(void) { write_u***_command(0xf6); } /////////////////////////////////////////////// //函数:read_endpoint_status //说明:读端点状态:命令为0x80+endp //入口:uchar endp:选择端点0-5 //返回:uchar read_a_u***_data():当前端点状态信息 /////////////////////////////////////////////// uchar read_endpoint_status(uchar endp) { write_u***_command(0x80+endp); return read_a_u***_data(); } /////////////////////////////////////////////// //函数:clear_buffer //说明:缓冲区清零:命令为0xf2 //入口:uchar endp:选择端点0-5 //返回:uchar read_a_u***_data():当前端点状态信息 /////////////////////////////////////////////// void clear_buffer(void) { write_u***_command(0xf2); } /////////////////////////////////////////////// //函数:validate_buffer //说明:使缓冲区有效:命令为0xfa //入口:无 //返回:无 /////////////////////////////////////////////// void validate_buffer(void) { write_u***_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_u***_command(0xf0); //读缓冲区命令,读nB read_a_u***_data(); //字节1,保留,可为任意值 j=read_a_u***_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_u***_command(0xf0); //写缓冲区指令,写nB write_a_u***_data(0); //第1字节保留,总为0 write_a_u***_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命令层**********************/。 |
|
|
|
只有小组成员才能发言,加入小组>>
如何使用STM32+nrf24l01架构把有线USB设备无线化?
2419 浏览 7 评论
请问能利用51单片机和nRF24L01模块实现实时语音无线传输吗?
2199 浏览 5 评论
2940 浏览 3 评论
2646 浏览 8 评论
为什么ucosii上移植lwip后系统进入了HardFault_Handler?
2617 浏览 4 评论
请教各位大咖:有没有接收频率32M左右的芯片推荐的?先感谢啦!
395浏览 1评论
653浏览 0评论
715浏览 0评论
443浏览 0评论
247浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-8-9 03:10 , Processed in 0.917578 second(s), Total 79, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号