新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 利用DM6437的McBSP配置SPI與ARM_S2440通信

        利用DM6437的McBSP配置SPI與ARM_S2440通信

        作者: 時間:2016-11-21 來源:網絡 收藏
        McBSP是多通道緩沖串行口,DM6437提供了McBSP0&McBSP1兩個串行口,每個串行口有7個管腳,可以支持多通道串行數據通信。
        MCBSP的內部框圖


        這兩個端口也支持時鐘停止模式,內部FSR與FSX、CLKX與CLKR連接在一起,這時候DX為MOSI,,DR為MISO,CLKX為SCK和FSX為nSS。
        配置SPI口要注意的地方:通信模式選擇要一致;SPI提供了四種通信模式:SPI0、SPI1、SPI2、SPI3。
        McBSP通過配置CLKSTP與CLKXP來設置這四種模式:

        一般而言SPI0模式采用的多一些。
        SPI初始化步驟:

        在這之前還有兩個操作必須完成,DM6437的管腳復用設置為McBSP模式、McBSP的IO上電。(可以直接寫相關寄存器、或者調用CSL函數),管腳復用只是設置DSP芯片管腳的引出方式,McBSP會有一個特殊情況,需要檢測第一個幀同步信號;這個時候就可以復用FSX腳為GPIO腳,用GPIO來檢測信號的變化,因此我們有理由相信無論用戶采用配置出來是什么形態,內部這些腳其實是連在一起的。另外還申明一個誤區:管腳復用和接口寄存器配置并沒有關系,用戶可以隨時配置McBSP接口的相關寄存器,而不需要指定這些腳已經映射為McBSP管腳;當然還是得滿足IO上拉的條件。

        DM6437 SPI Master Config

        DM6437 SPI Slaver Config

        編寫程序可以根據CSL庫提供的函數,可能看到TI針對DM6437不再提供CSL驅動了,而是提供PSP驅動;但是這話不絕對,TI還是有DM6437可用的CSL庫函數可以用,但是對我而言采用的是CSL提供的定義,自己編寫函數;因為我找到了CSL支持的寄存器數據結構,但是沒有找到相應的CSL函數說明,沒有看到函數原型。
        配置SPI口其實是很簡單的,雖然我花費了太多的時間,這個最后我會說明,自己配置寄存器,可以很簡單的直接給寄存器賦值,只要計算好該寄存器最后的值是什么直接賦值就可以了,但是需要注意復位腳設置什么的。。。該延時的要延時。這種寄存器配置一般而言沒有什么先后順序,沒有什么要求;有要求的文檔會有標注。如果不是一次性設定寄存器的值,那么在設置寄存器的時候一定要很小心取與取或的時候不要覆蓋了前面的設置;這個因為我第一次是一位一位設置的,沒有注意;到得到的和自己想要的完成是兩回事。推薦一次性設置,當然可讀性不就會這么好,可讀性可以在程序跑通了再追求。

        PSP_103什么版本的,如果自己電腦上面正好有這個驅動,那么直接調用,那就可以很簡單了,和填空差不多了。LLC提供了底層驅動的,這個部分和自己配置寄存器一樣的道理,DDC為驅動核心層,提供了OS與底層的交互,也就是我們常說的PSP驅動了;BIOS是上層系統層調用了。如果對PSP熟悉,那么可以自己決定程序寫在哪一層,這個就是DM6437與DM642最大的不同。一般而言,我喜歡直接操作底層,從DM642養成的習慣。

        另外說一下SPI數據通信的能力:
        如果主設備采用內部時鐘,則SPI內部時鐘為CPU時鐘/6,因為主設備和從設備要保持同步,卻又采用各自的時鐘,所以必須保證從設備擁有同步能力,從設備的時鐘必須大于主設備時鐘8倍,從設備通常默認設置到最大時鐘能力、即CLKDVG=1。
        另外數據的傳輸方式也會對數據通信能力有很大引向,McBSP提供了三種方式:CPU查詢模式、CPU中斷模式、EDMA3模式。采用EDMA3模式可以獲得最大的數據通信能力,當然驅動編寫就復雜一些,如果采用PSP倒也罷了。

        最后說一下在調試中遇到的問題:
        1) 配置寄存器,一位一位配置,得到很意外的結果,最后一步一步跟蹤才找到原因。
        2) 根據文檔配置SPI口,但是就是不能正常通信。后來查找SPI協議,了解了SPI口相關知識,才知道CLKXP并不能隨意配置
        3) 配置好SPI口,左看右看程序沒有問題,但是就是不能正常通信,逐個檢測管腳狀態,發現DR腳,沒有連接時,都有波形輸出,倒是數據采樣不對,換另一個端口,終于正常通信了。

        void SPI_Slave_Init ( unsigned long Bits )
        {
        unsigned long i;

        CSL_FINST(mcbsp0Regs->SPCR,MCBSP_SPCR_FRST,RESET); //frame sync reset
        CSL_FINST(mcbsp0Regs->SPCR,MCBSP_SPCR_XRST,DISABLE); //transmitter reset
        CSL_FINST(mcbsp0Regs->SPCR,MCBSP_SPCR_RRST,DISABLE); //receiver reset
        CSL_FINST(mcbsp0Regs->SPCR,MCBSP_SPCR_GRST,CLKG); //SRGR reset

        //serial port control register SPCR
        mcbsp0Regs->SPCR = CSL_FMKT(MCBSP_SPCR_CLKSTP,DELAY); //In SPI mode, data sampled on rising edge with delay

        //pin control register
        mcbsp0Regs->PCR = CSL_FMKT(MCBSP_PCR_FSXM,EXTERNAL) //external frame sync
        | CSL_FMKT(MCBSP_PCR_CLKXM,INPUT) //trans clock mode
        | CSL_FMKT(MCBSP_PCR_FSXP,ACTIVELOW); //active low

        //sample rate generator SRGR
        mcbsp0Regs->SRGR = CSL_FMKT(MCBSP_SRGR_CLKSM,INTERNAL) //internal clock
        | CSL_FMK(MCBSP_SRGR_CLKGDV,1); //clock divider value

        switch ( Bits )
        {
        case SPI_8BIT:
        // receive control register
        mcbsp0Regs->RCR = CSL_FMKT(MCBSP_RCR_RWDLEN1,8BIT); //receive word 8bit
        //transmit control register
        mcbsp0Regs->XCR = CSL_FMKT(MCBSP_XCR_XWDLEN1,8BIT); //trans word 8bit
        break;
        case SPI_12BIT:
        // receive control register
        mcbsp0Regs->RCR = CSL_FMKT(MCBSP_RCR_RWDLEN1,12BIT); //receive word 12bit
        //transmit control register
        mcbsp0Regs->XCR = CSL_FMKT(MCBSP_XCR_XWDLEN1,12BIT); //trans word 12bit
        break;
        case SPI_16BIT:
        // receive control register
        mcbsp0Regs->RCR = CSL_FMKT(MCBSP_RCR_RWDLEN1,16BIT); //receive word 16bit
        //transmit control register
        mcbsp0Regs->XCR = CSL_FMKT(MCBSP_XCR_XWDLEN1,16BIT); //trans word 16bit
        break;
        case SPI_20BIT:
        // receive control register
        mcbsp0Regs->RCR = CSL_FMKT(MCBSP_RCR_RWDLEN1,20BIT); //receive word 20bit
        //transmit control register
        mcbsp0Regs->XCR = CSL_FMKT(MCBSP_XCR_XWDLEN1,20BIT); //trans word 20bit
        break;
        case SPI_24BIT:
        // receive control register
        mcbsp0Regs->RCR = CSL_FMKT(MCBSP_RCR_RWDLEN1,24BIT); //receive word 24bit
        //transmit control register
        mcbsp0Regs->XCR = CSL_FMKT(MCBSP_XCR_XWDLEN1,24BIT); //trans word 24bit
        break;
        case SPI_32BIT:
        // receive control register
        mcbsp0Regs->RCR = CSL_FMKT(MCBSP_RCR_RWDLEN1,32BIT); //receive word 32bit
        //transmit control register
        mcbsp0Regs->XCR = CSL_FMKT(MCBSP_XCR_XWDLEN1,32BIT); //trans word 32bit
        break;
        default:;
        }

        //start the mcbsp running
        CSL_FINST(mcbsp0Regs->SPCR,MCBSP_SPCR_GRST,CLKG); //SRGR out of reset
        for ( i = 0; i < 200; i++ ) { i++; }
        CSL_FINST(mcbsp0Regs->SPCR,MCBSP_SPCR_RRST,ENABLE); //receiver enable
        CSL_FINST(mcbsp0Regs->SPCR,MCBSP_SPCR_XRST,ENABLE); //transmitter enable
        for ( i = 0; i < 200; i++ ) { i++; }
        CSL_FINST(mcbsp0Regs->SPCR,MCBSP_SPCR_FRST,FSG); //enable frame sync
        }


        評論


        技術專區

        關閉
        主站蜘蛛池模板: 永嘉县| 南雄市| 尤溪县| 泽库县| 辉南县| 九寨沟县| 封丘县| 曲松县| 合作市| 苏尼特右旗| 平远县| 广州市| 登封市| 永定县| 莲花县| 衡水市| 本溪| 五华县| 潢川县| 屯留县| 正定县| 揭阳市| 蒙山县| 山东| 双牌县| 广灵县| 仪陇县| 沧源| 江门市| 体育| 界首市| 廉江市| 牟定县| 汽车| 达拉特旗| 安多县| 云安县| 剑阁县| 东安县| 邵阳县| 镇赉县|