單片機(jī)與單片機(jī)通過(guò)CH375實(shí)現(xiàn)USB之間連接
頭文件1//是CH375的專(zhuān)屬相關(guān)命令
#ifndef CH375_H
#define CMD_GET_STATUS 0x22 // 獲取中斷狀態(tài)并取消中斷請(qǐng)求 ,通過(guò)它可以得到中斷信息,即什么中斷;
#define CMD_SET_USB_MODE 0x15 // 設(shè)置USB工作模式 ,設(shè)置usb是那種工作模式,是主機(jī)的那種,還是從機(jī)的那種;
#define CMD_RET_SUCCESS 0x51
#define CMD_SET_ENDP6 0x1C
#define CMD_SET_ENDP7 0x1D
#define CMD_RD_USB_DATA 0x28
#define CMD_WR_USB_DATA7 0x2B
#define CMD_ISSUE_TOKEN 0x4F
#define CMD_CLR_STALL 0x41
#define USB_INT_SUCCESS 0x14
#define USB_INT_CONNECT 0x15
#define DEMO_CXP_CMD 0x56//命令字
#define CMD_CHECK_EXIST 0x06
#define CMD_RESET_ALL 0x05
#define USB_INT_EP2_IN 0x0A
#define CMD_UNLOCK_USB 0x23
#endif
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#endif
#ifndef BIANLIAN_H
sbit CH375_INT_WIRE = P3^2;//INT0
unsigned char volatile xdata CH375_CMD_PORT _at_ 0xFDff;
unsigned char volatile xdata CH375_DAT_PORT _at_ 0xFCff;
unsigned char endp6_mode,endp7_mode;//兩種模式變量,用來(lái)奇偶替換;來(lái)對(duì)應(yīng)奇偶次傳送數(shù)據(jù)時(shí),改變對(duì)應(yīng)的配置奇偶模式
unsigned char key;//為主程序記錄那個(gè)鍵按下
sbit KEYPIN1 = P2^2;
sbit KEYPIN2 = P2^3;
sbit KEYPIN3 = P2^4;
sbit KEYPIN4 = P2^5;
sbit KEYPIN5 = P2^6;
sbit KEYPIN6 = P2^7;
sbit CH375_INT_WIRE = P3^2;//INT0
unsigned char volatile xdata CH375_CMD_PORT _at_ 0xFDff;
unsigned char volatile xdata CH375_DAT_PORT _at_ 0xFCff;
unsigned char endp6_mode,endp7_mode;//兩種模式變量,用來(lái)奇偶替換;來(lái)對(duì)應(yīng)奇偶次傳送數(shù)據(jù)時(shí),改變對(duì)應(yīng)的配置奇偶模式
unsigned
typedef struct _COMMAND_PACKET
{
unsigned char mCommandCode;
unsigned char mCommandCodeNot;
union
{
unsigned char mParameter[5];
struct
{
unsigned char mBufferID;
unsigned int mBufferAddr;
unsigned int mLength;
} buf;
} u;
} mCOMMAND_PACKET, *mpCOMMAND_PACKET;
mCOMMAND_PACKET cmd_cui;
sbit CH375RS = P3^4;
bit FLAG_INT_WAIT;
#endif
{
}
#endif
#ifndef CUI_H
//兩微妙的延時(shí);為了給指令的書(shū)寫(xiě)一個(gè)緩沖過(guò)度時(shí)間;誰(shuí)叫咋東西破了
void Delay2us( )
{
unsigned char i;
#define DELAY_START_VALUE 1
for ( i=DELAY_START_VALUE; i!=0; i-- );
}
void Delay_ms(unsigned char ms) //延時(shí)ms
{
unsigned char i;
unsigned char us;
for(i=0; i {
us=100;
while(us--);
}
}
//查當(dāng)前中斷狀態(tài),由他來(lái)查看當(dāng)前是什么中斷,到底有沒(méi)有中斷
unsigned char wait_complete()
{
while(CH375_INT_WIRE);//這里采用的中斷零,故接P3^2;
CH375_CMD_PORT = CMD_GET_STATUS;//中斷狀態(tài)控制字;
Delay2us( );
return CH375_DAT_PORT;
}
//設(shè)置usb的工作模式;奇次|偶次
void set_usb_mode(unsigned char mode)
{
CH375_CMD_PORT = CMD_SET_USB_MODE;//命令字模式設(shè)置;
Delay2us( );
CH375_DAT_PORT = mode;//什么模式?如果做主機(jī),就是5|6模式兩種均可(前提兩邊都有CH375),如果是從機(jī),模式為2(根據(jù)主機(jī)要
{
#define DELAY_START_VALUE
}
void Delay_ms(unsigned char ms)
{
}
//查當(dāng)前中斷狀態(tài),由他來(lái)查看當(dāng)前是什么中斷,到底有沒(méi)有中斷
unsigned char wait_complete()
{
}
//設(shè)置usb的工作模式;奇次|偶次
void set_usb_mode(unsigned char mode)
{
//求)
endp6_mode = endp7_mode = 0x80;//初始沒(méi)有發(fā)送數(shù)據(jù)的時(shí)候,這個(gè)奇偶標(biāo)志的玩意的狀態(tài)為奇狀態(tài),放在這里相當(dāng)于延時(shí)
while(CH375_DAT_PORT != CMD_RET_SUCCESS);//確認(rèn)模式設(shè)置成功
}
}
/設(shè)置DAT0的奇偶模式,由于CH375在數(shù)據(jù)發(fā)送時(shí),分奇偶的,所以要配對(duì)奇偶對(duì)應(yīng)的模式,這里是配置的是通道DAT0/
void set_endp6()
{
CH375_CMD_PORT = CMD_SET_ENDP6;//選通道DAT0
Delay2us( );
CH375_DAT_PORT = endp6_mode;//初始狀態(tài)為奇0x80;偶為0xC0
endp6_mode ^=0x40;//^=是異或的意思,恰好0x80異或0x40是0xC0,而0xC0以后0x40是0x80;這樣每次發(fā)送后,這個(gè)是變到對(duì)應(yīng)的模式的
Delay2us( );
}
void set_endp6()
{
}
//同上,只是配置的DAT1
void set_endp7()
{
CH375_CMD_PORT = CMD_SET_ENDP7;
Delay2us( );
CH375_DAT_PORT = endp7_mode;
endp7_mode ^=0x40;//;
Delay2us( );
}
void set_endp7()
{
}
//這里是讀 usb緩存的數(shù)據(jù)
unsigned char rd_usb_data(unsigned char *buf)
{
unsigned char i,len;
CH375_CMD_PORT = CMD_RD_USB_DATA;//讀當(dāng)前中斷狀態(tài)下對(duì)應(yīng)的端點(diǎn),ch375有3種端點(diǎn),而CMD_RD_USB_DATA,是那個(gè)端點(diǎn)的
{
//收數(shù)據(jù)緩存來(lái)了數(shù)據(jù),響應(yīng)了對(duì)應(yīng)的中斷,就讀誰(shuí)。。。即讀產(chǎn)生響應(yīng)的誰(shuí)誰(shuí)誰(shuí)
Delay2us( );
len = CH375_DAT_PORT;//一般第一個(gè)數(shù)據(jù)是長(zhǎng)短,即后面發(fā)的數(shù)據(jù)有多大(幾個(gè)字節(jié),一次最大只能64個(gè))
Delay2us( );
for (i=0;i!=len;i++)
*buf++ = CH375_DAT_PORT;//讀啊讀,讀len個(gè)8位數(shù)據(jù)
return(len);
}
}
//上面讀,下面就是寫(xiě)了
void wr_usb_data(unsigned char len,unsigned char*buf )
{
CH375_CMD_PORT = CMD_WR_USB_DATA7;//寫(xiě)命令
Delay2us( );
CH375_DAT_PORT = len;//自我約定第一個(gè)數(shù)是要發(fā)送數(shù)據(jù)的大小,當(dāng)然也可以賤點(diǎn),設(shè)置自己的描述后面數(shù)據(jù)符號(hào)
while(len--)CH375_DAT_PORT = *buf++;
}
void wr_usb_data(unsigned char len,unsigned char*buf )
{
}
unsigned char issue_token(unsigned char endp_and_pid)
{
CH375_CMD_PORT = CMD_ISSUE_TOKEN;//這個(gè)了就是發(fā)送的令牌的指令了,令牌了,其實(shí)也是一種配置,配置你選用什么端口(一般
{
//為2),是輸入還是輸出,當(dāng)然,這是對(duì)主機(jī)而言的,他有資格發(fā)送令牌,
Delay2us( );
CH375_DAT_PORT = endp_and_pid;//這里配置的是端口和輸入或輸出的方式,高四位是端點(diǎn)號(hào),低四位了,就是輸入還是輸出
return (wait_complete());//等待配置成功
}
}
//這里是當(dāng)發(fā)送錯(cuò)誤的時(shí)候,要將對(duì)應(yīng)的端口經(jīng)行清洗下;去掉原來(lái)的錯(cuò)誤數(shù)據(jù),為下次接受提供條件
unsigned char ERROR(unsigned char err)
{
CH375_CMD_PORT = CMD_CLR_STALL ;要清楚那個(gè)端點(diǎn)的命令;
Delay2us( );
CH375_DAT_PORT = err;//那個(gè)端點(diǎn)
return(wait_complete());
unsigned char ERROR(unsigned char err)
{
}
//左主機(jī)時(shí)候發(fā)送
void host_send(unsigned char len,unsigned char *buf)
{
wr_usb_data(len,buf);//先向?qū)?yīng)的端點(diǎn)的緩存中寫(xiě)數(shù)據(jù),這里采用的是端點(diǎn)2
set_endp7();//對(duì)端點(diǎn)DAT1奇偶配置一下,也為下次左準(zhǔn)備
if(issue_token(0x21) !=USB_INT_SUCCESS)ERROR(0x02);//這里的令牌是端點(diǎn)2,低位的1是輸出模式
else if(buf == NULL) printf("0k");
}
void host_send(unsigned char len,unsigned char *buf)
{
}
//這個(gè)是主機(jī)接受了
unsigned char host_recv(unsigned char *buf)
{
set_endp6();//端點(diǎn)2的DAT0奇偶配置一下,為下次作準(zhǔn)備
if(issue_token(0x29) != USB_INT_SUCCESS)ERROR(0x82);//這里令牌是端點(diǎn)2,低位9為輸入模式
return (rd_usb_data(buf));//讀啊,讀
}
unsigned char GetKeyCode(void)//這個(gè)是按鍵,對(duì)應(yīng)命令
{
if(KEYPIN1==0) return 1;//對(duì)應(yīng)從機(jī)的燈打開(kāi);
if(KEYPIN2==0) return 2;//對(duì)應(yīng)的從機(jī)燈全關(guān)
if(KEYPIN3==0) return 3;
if(KEYPIN4==0) return 4;
if(KEYPIN5==0) return 5;
if(KEYPIN6==0) return 6;
return 0;
}
unsigned char host_recv(unsigned char *buf)
{
}
unsigned char
{
}
#endif
{
}
void init_rst() //rst//初始時(shí),復(fù)位下
{
CH375RS = 1;
Delay_ms(100);
CH375RS = 0;
Delay_ms(200);
}
{
}
void CH375_Init( )//初始化,首先檢測(cè)單片機(jī)與CH375的硬件并口是否連通
{
unsigned char i;
CH375_CMD_PORT = CMD_CHECK_EXIST;
Delay2us( );
CH375_DAT_PORT = 0x55;
Delay2us( );
i = ~ 0x55;
if ( CH375_DAT_PORT != i )
{
for ( i=80; i!=0; i-- )
{
CH375_CMD_PORT = CMD_RESET_ALL;
Delay2us( );
}
CH375_CMD_PORT = 0;
Delay_ms(50);
{
}
評(píng)論