基于STM32的PCL6045B開發(fā)體會
于是公司從每個不同項目組抽選人員組成了一個團隊。本人負責軟件部分,負責編寫驅(qū)動程序和調(diào)試電路板。
全新項目,有一定挑戰(zhàn)性。經(jīng)過分析,決定采用STM32總線方式(FSMC)驅(qū)動PCL6045B。對比FSMC的四種總線操作時序和PCL6045B操作時序。認為應(yīng)該選用STM32的PCCARD模式操作。從數(shù)據(jù)庫中查找了一些文獻資料,就開干起來了。
兩名硬件工程師按我的需求設(shè)計好硬件電路板。
接下來分成以下幾個步驟進行:
首先就是建立通訊。讓ARM能跟PCL6045B建立起來通訊。
這一步主要就是配置STM32的FSMC為PCCARD模式,配置的過程就是按官方手冊上配置的。先系統(tǒng)初始化配置好STM32的時鐘(不贅述)。然后就是初始化端口,這里需要注意的是,要將跟FSMC相關(guān)的端口都設(shè)置為特殊功能口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);
}
到這里,就算配置完成。主函數(shù)調(diào)用。
然后主函數(shù)通過控制PCL6045的其中一個口實驗成功,于是就算建立起了通信。
接下來就可以試驗控制PCL6045參數(shù)指定數(shù)目的脈沖了。
于是,我根據(jù)手冊又編寫了如下小測試程序:
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);
運行,成功產(chǎn)生脈沖!
正常過程很簡單,但是,實際操作中,特別是第一次摸索的時候,遇到很多棘手的問題。
比如PCL6045 硬件部分IF0 IF1 要接成8086方式。
一開始,我們的硬件電路按如下圖鏈接:
好像也沒什么問題,于是就接著往下調(diào),發(fā)現(xiàn)了一個很郁悶的問題,當時把問題描述如下:
#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 軸寄存器的起始地址
幾個地址均已經(jīng)能夠操作,能控制各個軸電機運動。
STM32通過FSMC與DSP通訊,通過16位傳送數(shù)據(jù)。
#define outpw( address,data) (*(unsigned short *)(address)=(data));
unsigned int inpw(unsigned int address) //讀寫某一段內(nèi)存
{
unsigned short data;
data=*(unsigned short*)address;
return data;
}
寫寄存器函數(shù)如下:
void p645_wreg(unsigned int base_addr,unsigned int rwcom,unsigned int data) //向某個軸的某個寄存器寫入數(shù)據(jù)
{
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);
}
//讀寄存器函數(shù)如下:
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);
}
在設(shè)置解碼倍頻時,發(fā)現(xiàn),無論我寫入的是哪個數(shù)(00,01,10),都不能改變編碼器讀出的數(shù)據(jù),即始終是默認的1倍解碼,即相關(guān)寄存器兩個bit是00的情況.
評論