經過特權的整理,以圈圈的程序代碼為基礎,結合周立功的《PDIUSBD12固件編程與驅動開發》一書,把D12的最底層的代碼子程序做了較詳細的注釋和整理,PDIUSBD12的硬件提取層應該說才是真正意思上的最底層,其次是命令層,這應該是USB編程入門的突破口,再有其它的操作無非都是基于這些基本的子程序進行的。以下的代碼應該結合這個文檔進行理解,請參考附件http://share.eepw.com.cn/share/download/id/234488。(這個文檔應該是周立功書上摘抄的) #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命令層**********************/ |