新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 單片機與單片機通過CH375實現USB之間連接

        單片機與單片機通過CH375實現USB之間連接

        作者: 時間:2016-11-24 來源:網絡 收藏
        USB的對象,有主從之分,這樣才能在開始時,兩個設備之間的握手可以由主設備打破;但是對于CH375,它的主從的配置是完全不同的。通道可以由主機在設置令牌時去做。一般主機配置端口2,它在設置為主機模式時候,有專有的主機通道,即它有兩種通道;如果沒有配置,默認發送的端口是端點0。而主機發送信息時候,在發送次數為第"奇"次與第“偶”次發送的配置是不同的,這需要在發送的時候不停的修改。
        發送信息的過程:首先設置為發送的模式,可以是5也可以是6(兩種都是配置主機模式),一般為6。接著將發送的信息配置完后,寫到對應的端點,這里為端點2;接著對對應的端點的通道寫發送的模式(奇?偶);剩下的發送令牌,根據令牌CH375將數據左對應的操作;
        頭文件1//是CH375的專屬相關命令
        #ifndef CH375_H
        #defineCMD_GET_STATUS0x22// 獲取中斷狀態并取消中斷請求 ,通過它可以得到中斷信息,即什么中斷;
        #defineCMD_SET_USB_MODE0x15// 設置USB工作模式 ,設置usb是那種工作模式,是主機的那種,還是從機的那種;
        #defineCMD_RET_SUCCESS0x51
        #defineCMD_SET_ENDP60x1C
        #defineCMD_SET_ENDP70x1D
        #defineCMD_RD_USB_DATA0x28
        #defineCMD_WR_USB_DATA70x2B
        #defineCMD_ISSUE_TOKEN0x4F
        #defineCMD_CLR_STALL0x41
        #defineUSB_INT_SUCCESS0x14
        #defineUSB_INT_CONNECT0x15
        #defineDEMO_CXP_CMD0x56//命令字
        #defineCMD_CHECK_EXIST0x06
        #defineCMD_RESET_ALL0x05
        #defineUSB_INT_EP2_IN0x0A
        #defineCMD_UNLOCK_USB0x23
        #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;//兩種模式變量,用來奇偶替換;來對應奇偶次傳送數據時,改變對應的配置奇偶模式
        unsigned char key;//為主程序記錄那個鍵按下
        sbit KEYPIN1 = P2^2;
        sbit KEYPIN2 = P2^3;
        sbit KEYPIN3 = P2^4;
        sbit KEYPIN4 = P2^5;
        sbit KEYPIN5 = P2^6;
        sbit KEYPIN6 = P2^7;
        typedefstruct_COMMAND_PACKET
        {
        unsigned charmCommandCode;
        unsigned charmCommandCodeNot;
        union
        {
        unsigned charmParameter[5];
        struct
        {
        unsigned charmBufferID;
        unsigned intmBufferAddr;
        unsigned intmLength;
        } buf;
        } u;
        }mCOMMAND_PACKET,*mpCOMMAND_PACKET;
        mCOMMAND_PACKET cmd_cui;
        sbit CH375RS = P3^4;
        bitFLAG_INT_WAIT;
        #endif

        #ifndef CUI_H
        //兩微妙的延時;為了給指令的書寫一個緩沖過度時間;誰叫咋東西破了
        voidDelay2us( )
        {
        unsigned char i;
        #define DELAY_START_VALUE1
        for ( i=DELAY_START_VALUE; i!=0; i-- );
        }
        void Delay_ms(unsigned char ms) //延時ms
        {
        unsigned char i;
        unsigned char us;
        for(i=0; i {
        us=100;
        while(us--);
        }
        }
        //查當前中斷狀態,由他來查看當前是什么中斷,到底有沒有中斷
        unsigned char wait_complete()
        {
        while(CH375_INT_WIRE);//這里采用的中斷零,故接P3^2;
        CH375_CMD_PORT = CMD_GET_STATUS;//中斷狀態控制字;
        Delay2us( );
        return CH375_DAT_PORT;
        }
        //設置usb的工作模式;奇次|偶次
        void set_usb_mode(unsigned char mode)
        {
        CH375_CMD_PORT = CMD_SET_USB_MODE;//命令字模式設置;
        Delay2us( );
        CH375_DAT_PORT = mode;//什么模式?如果做主機,就是5|6模式兩種均可(前提兩邊都有CH375),如果是從機,模式為2(根據主機要
        //求)
        endp6_mode = endp7_mode = 0x80;//初始沒有發送數據的時候,這個奇偶標志的玩意的狀態為奇狀態,放在這里相當于延時
        while(CH375_DAT_PORT != CMD_RET_SUCCESS);//確認模式設置成功
        }
        /設置DAT0的奇偶模式,由于CH375在數據發送時,分奇偶的,所以要配對奇偶對應的模式,這里是配置的是通道DAT0/
        void set_endp6()
        {
        CH375_CMD_PORT = CMD_SET_ENDP6;//選通道DAT0
        Delay2us( );
        CH375_DAT_PORT = endp6_mode;//初始狀態為奇0x80;偶為0xC0
        endp6_mode ^=0x40;//^=是異或的意思,恰好0x80異或0x40是0xC0,而0xC0以后0x40是0x80;這樣每次發送后,這個是變到對應的模式的
        Delay2us( );
        }
        //同上,只是配置的DAT1
        void set_endp7()
        {
        CH375_CMD_PORT = CMD_SET_ENDP7;
        Delay2us( );
        CH375_DAT_PORT = endp7_mode;
        endp7_mode ^=0x40;//;
        Delay2us( );
        }
        //這里是讀 usb緩存的數據
        unsigned char rd_usb_data(unsigned char *buf)
        {
        unsigned char i,len;
        CH375_CMD_PORT = CMD_RD_USB_DATA;//讀當前中斷狀態下對應的端點,ch375有3種端點,而CMD_RD_USB_DATA,是那個端點的
        //收數據緩存來了數據,響應了對應的中斷,就讀誰。。。即讀產生響應的誰誰誰
        Delay2us( );
        len = CH375_DAT_PORT;//一般第一個數據是長短,即后面發的數據有多大(幾個字節,一次最大只能64個)
        Delay2us( );
        for (i=0;i!=len;i++)
        *buf++ = CH375_DAT_PORT;//讀啊讀,讀len個8位數據
        return(len);
        }
        //上面讀,下面就是寫了
        void wr_usb_data(unsigned char len,unsigned char*buf )
        {
        CH375_CMD_PORT = CMD_WR_USB_DATA7;//寫命令
        Delay2us( );
        CH375_DAT_PORT = len;//自我約定第一個數是要發送數據的大小,當然也可以賤點,設置自己的描述后面數據符號
        while(len--)CH375_DAT_PORT = *buf++;
        }
        unsigned char issue_token(unsigned char endp_and_pid)
        {
        CH375_CMD_PORT = CMD_ISSUE_TOKEN;//這個了就是發送的令牌的指令了,令牌了,其實也是一種配置,配置你選用什么端口(一般
        //為2),是輸入還是輸出,當然,這是對主機而言的,他有資格發送令牌,
        Delay2us( );
        CH375_DAT_PORT = endp_and_pid;//這里配置的是端口和輸入或輸出的方式,高四位是端點號,低四位了,就是輸入還是輸出
        return (wait_complete());//等待配置成功
        }
        //這里是當發送錯誤的時候,要將對應的端口經行清洗下;去掉原來的錯誤數據,為下次接受提供條件
        unsigned char ERROR(unsigned char err)
        {
        CH375_CMD_PORT = CMD_CLR_STALL ;要清楚那個端點的命令;
        Delay2us( );
        CH375_DAT_PORT = err;//那個端點
        return(wait_complete());
        }
        //左主機時候發送
        void host_send(unsigned char len,unsigned char *buf)
        {
        wr_usb_data(len,buf);//先向對應的端點的緩存中寫數據,這里采用的是端點2
        set_endp7();//對端點DAT1奇偶配置一下,也為下次左準備
        if(issue_token(0x21) !=USB_INT_SUCCESS)ERROR(0x02);//這里的令牌是端點2,低位的1是輸出模式
        else if(buf == NULL) printf("0k");
        }
        //這個是主機接受了
        unsigned char host_recv(unsigned char *buf)
        {
        set_endp6();//端點2的DAT0奇偶配置一下,為下次作準備
        if(issue_token(0x29) != USB_INT_SUCCESS)ERROR(0x82);//這里令牌是端點2,低位9為輸入模式
        return (rd_usb_data(buf));//讀啊,讀
        }
        unsigned char GetKeyCode(void)//這個是按鍵,對應命令
        {
        if(KEYPIN1==0) return 1;//對應從機的燈打開;
        if(KEYPIN2==0) return 2;//對應的從機燈全關
        if(KEYPIN3==0) return 3;
        if(KEYPIN4==0) return 4;
        if(KEYPIN5==0) return 5;
        if(KEYPIN6==0) return 6;
        return 0;
        }
        #endif

        #include
        #include
        #include "ch375.h"
        #include"bianlian.h"
        #include "cui.h"
        void init_uart()//uart init串口的配置,為了下載和終端上面檢測用的
        {
        SCON = 0x50;
        PCON = 0x80;
        TMOD = 0x20;
        TH1 = 0xfd;
        TR1 = 1;
        TI = 1;
        }
        void init_rst() //rst//初始時,復位下
        {
        CH375RS = 1;
        Delay_ms(100);
        CH375RS = 0;
        Delay_ms(200);
        }
        void CH375_Init( )//初始化,首先檢測單片機與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);
        }
        set_usb_mode(6);
        //開中斷,低電平有效
        IT0 = 0;
        IE0 = 0;
        EX0 = 1;
        }
        int main()
        {
        unsigned char *buf;
        init_uart();
        init_rst();
        CH375_Init( );
        while(wait_complete() != USB_INT_CONNECT);//查看usb有插入設備
        printf("lianjie");
        while(1){

        key = GetKeyCode();//獲取按鍵
        switch(key){
        case 1://0x9我整的是從機燈亮
        cmd_cui.mCommandCode = DEMO_CXP_CMD;//配置一個命令字給從機,來完成想要的控制
        cmd_cui.mCommandCodeNot = ~(DEMO_CXP_CMD);//跟上面數據相反,用來校驗
        cmd_cui.u.mParameter[1] = 0x8;//控制的模式
        cmd_cui.u.mParameter[2] = 0x9;//控制模式,這兩個數據根據自己需要,當然整個變量野可以自己修改,東西是死的,人是活的;
        //printf("1lallais %c",cmd_cui.u.mParameter[1]) ;
        buf = (unsigned char *)(&cmd_cui);//將上面數據以字節8位的形式發送出去,先取它的首地址,然后一個個字節發送
        printf("cmd_cui is %c",buf[3]);//由于從機要用到此發送的命令信息,在這里可以在終端上面顯示,是否數據正確
        host_send(7,buf);
        //host_send(0,NULL);
        break;
        case 2://0x8整的是從機燈滅
        cmd_cui.mCommandCode = DEMO_CXP_CMD;
        cmd_cui.mCommandCodeNot = ~(DEMO_CXP_CMD);
        cmd_cui.u.mParameter[1] = 0x9;
        cmd_cui.u.mParameter[2] = 0x8;
        //printf("1lallais %c",cmd_cui.u.mParameter[1]) ;
        buf = (unsigned char *)(&cmd_cui);
        printf("cmd_cui is %c",buf[3]);
        host_send(7,buf);
        break;
        default:
        //printf("err");
        break;

        }
        key = 0;
        // printf("ririri");
        }

        }


        關鍵詞: 單片機CH375US

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 翁牛特旗| 宜宾县| 长顺县| 仲巴县| 怀仁县| 桃源县| 常宁市| 鄢陵县| 房产| 荃湾区| 昆明市| 同德县| 河曲县| 陆川县| 定安县| 治县。| 塘沽区| 军事| 化州市| 东宁县| 汾西县| 闻喜县| 辛集市| 毕节市| 武汉市| 桐城市| 马边| 福鼎市| 外汇| 柘城县| 银川市| 朝阳县| 会同县| 台中县| 柳江县| 罗甸县| 温泉县| 柳林县| 苏尼特右旗| 本溪市| 锡林浩特市|