新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 基于STM32的PCL6045B開發體會

        基于STM32的PCL6045B開發體會

        作者: 時間:2016-12-01 來源:網絡 收藏
        上兩個月做了個關于尿殘渣的新項目,用到了電機驅動芯片PCL6045BL。這個系統方案有一個20余年工作經驗的老工程師提出來,主要采用的是STM32操作PCL6045,進而控制多軸電機運動。

        于是公司從每個不同項目組抽選人員組成了一個團隊。本人負責軟件部分,負責編寫驅動程序和調試電路板。
        全新項目,有一定挑戰性。經過分析,決定采用STM32總線方式(FSMC)驅動PCL6045B。對比FSMC的四種總線操作時序和PCL6045B操作時序。認為應該選用STM32的PCCARD模式操作。從數據庫中查找了一些文獻資料,就開干起來了。
        兩名硬件工程師按我的需求設計好硬件電路板。

        本文引用地址:http://www.104case.com/article/201612/324398.htm

        接下來分成以下幾個步驟進行:
        首先就是建立通訊。讓ARM能跟PCL6045B建立起來通訊。
        這一步主要就是配置STM32的FSMC為PCCARD模式,配置的過程就是按官方手冊上配置的。先系統初始化配置好STM32的時鐘(不贅述)。然后就是初始化端口,這里需要注意的是,要將跟FSMC相關的端口都設置為特殊功能口AF。如下:
        void PCCARD_IO_Init(void)
        {
        GPIO_InitTypeDef GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD RCC_APB2Periph_GPIOE RCC_APB2Periph_GPIOF RCC_APB2Periph_GPIOG,ENABLE);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 GPIO_Pin_2 GPIO_Pin_3 GPIO_Pin_4 GPIO_Pin_12 GPIO_Pin_5;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_Init(GPIOF, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 GPIO_Pin_8 GPIO_Pin_9 GPIO_Pin_10 GPIO_Pin_11 GPIO_Pin_12 GPIO_Pin_13 GPIO_Pin_14 GPIO_Pin_15;
        GPIO_Init(GPIOE, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 GPIO_Pin_15 GPIO_Pin_10 GPIO_Pin_9 GPIO_Pin_8 GPIO_Pin_1 GPIO_Pin_0;
        GPIO_Init(GPIOD, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 GPIO_Pin_5;//NOE,NWE引腳
        GPIO_Init(GPIOD, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//cs
        GPIO_Init(GPIOG, &GPIO_InitStructure);
        }
        接下來就是配置FSMC PC卡模式時序。如下:
        void PCCARD_Init(void)
        {
        FSMC_PCCARDInitTypeDef FSMC_PCCARDInitStructure;
        FSMC_NAND_PCCARDTimingInitTypeDef p;
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);////
        p.FSMC_SetupTime = 0x02;
        p.FSMC_WaitSetupTime = 0x04;
        p.FSMC_HoldSetupTime = 0x02;
        p.FSMC_HiZSetupTime = 0x03;
        FSMC_PCCARDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Enable ; //使能等待
        FSMC_PCCARDInitStructure.FSMC_TCLRSetupTime = 0x10;
        FSMC_PCCARDInitStructure.FSMC_TARSetupTime = 0x10;
        FSMC_PCCARDInitStructure.FSMC_CommonSpaceTimingStruct = &p;
        FSMC_PCCARDInitStructure.FSMC_AttributeSpaceTimingStruct = &p;
        FSMC_PCCARDInitStructure.FSMC_IOSpaceTimingStruct = &p;
        FSMC_PCCARDInit(&FSMC_PCCARDInitStructure);
        FSMC_PCCARDCmd(ENABLE);
        }
        到這里,就算配置完成。主函數調用。
        然后主函數通過控制PCL6045的其中一個口實驗成功,于是就算建立起了通信。
        接下來就可以試驗控制PCL6045參數指定數目的脈沖了。
        于是,我根據手冊又編寫了如下小測試程序:
        p645_wreg(AXS_AU, WPRMD, 0x00000041); //定長運動模式
        p645_wreg(AXS_AU, WRMV, 4012000000);
        p645_wreg(AXS_AU, WRFL, 500L);
        p645_wreg(AXS_AU, WRFH, 20000L);
        p645_wreg(AXS_AU, WRUR, 200L);
        p645_wreg(AXS_AU, WRDR, 400L);
        p645_wreg(AXS_AU, WRMG, 29L);
        p645_wcom(AXS_AU,STAUD);
        運行,成功產生脈沖!
        正常過程很簡單,但是,實際操作中,特別是第一次摸索的時候,遇到很多棘手的問題。
        比如PCL6045 硬件部分IF0 IF1 要接成8086方式。
        一開始,我們的硬件電路按如下圖鏈接:
        好像也沒什么問題,于是就接著往下調,發現了一個很郁悶的問題,當時把問題描述如下:
        #define AXS_AX ((volatile unsigned int ) 0x90000000)
        #define AXS_AY ((volatile unsigned int ) 0x90000004)
        #define AXS_AZ ((volatile unsigned int ) 0x9000008)
        #define AXS_AU ((volatile unsigned int ) 0x900000c)
        其中 AXS_AX、AXS_AY、AXS_AZ、AXS_AU 分別表示 X、Y、Z、U 軸寄存器的起始地址
        幾個地址均已經能夠操作,能控制各個軸電機運動。
        STM32通過FSMC與DSP通訊,通過16位傳送數據。
        #define outpw( address,data) (*(unsigned short *)(address)=(data));
        unsigned int inpw(unsigned int address) //讀寫某一段內存
        {
        unsigned short data;
        data=*(unsigned short*)address;
        return data;
        }
        寫寄存器函數如下:
        void p645_wreg(unsigned int base_addr,unsigned int rwcom,unsigned int data) //向某個軸的某個寄存器寫入數據
        {
        union udata{
        unsigned int ldata;
        unsigned short idata[2];
        }udt;
        udt.ldata = data;
        outpw (base_addr 2, udt. idata[0]);
        // Delay_Us(1); //就算加了延時也無效
        outpw (base_addr 3, udt. idata[1]);
        // Delay_Us(1); //就算加了延時也無效
        outpw (base_addr, rwcom);
        }
        //讀寄存器函數如下:
        unsigned long p645_rreg (unsigned int base_addr,unsigned int rrcom) //讀寄存器
        {
        unionudata{
        unsigned int ldata;
        unsigned short idata[2];
        }udt;
        outpw(base_addr, rrcom);
        // Delay_Us(1);
        udt.idata[0] = inpw (base_addr 2);
        // Delay_Us(1);
        udt.idata[1] = inpw (base_addr 3);
        return(udt. ldata);
        }
        在設置解碼倍頻時,發現,無論我寫入的是哪個數(00,01,10),都不能改變編碼器讀出的數據,即始終是默認的1倍解碼,即相關寄存器兩個bit是00的情況.


        上一頁 1 2 下一頁

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 绥滨县| 寿宁县| 汉阴县| 山东省| 郑州市| 张家口市| 达孜县| 界首市| 江永县| 南郑县| 大兴区| 万盛区| 萨迦县| 大厂| 乌审旗| 竹北市| 松桃| 阿克陶县| 郯城县| 西丰县| 特克斯县| 庆城县| 察哈| 辰溪县| 正镶白旗| 临西县| 荃湾区| 涟源市| 三江| 湖北省| 陵川县| 邵东县| 晋州市| 菏泽市| 彝良县| 大兴区| 达拉特旗| 南充市| 平塘县| 岳普湖县| 江源县|