基于STM32的PCL6045B开发体会Word格式文档下载.docx
《基于STM32的PCL6045B开发体会Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《基于STM32的PCL6045B开发体会Word格式文档下载.docx(9页珍藏版)》请在冰点文库上搜索。
![基于STM32的PCL6045B开发体会Word格式文档下载.docx](https://file1.bingdoc.com/fileroot1/2023-5/4/df8c3791-e9a6-43f4-8124-8c88cf0a4f06/df8c3791-e9a6-43f4-8124-8c88cf0a4f061.gif)
{
GPIO_InitTypeDefGPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIODRCC_APB2Periph_GPIOERCC_APB2Periph_GPIOFRCC_APB2Periph_GPIOG,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1GPIO_Pin_2GPIO_Pin_3GPIO_Pin_4GPIO_Pin_12GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_Init(GPIOF,&
amp;
GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7GPIO_Pin_8GPIO_Pin_9GPIO_Pin_10GPIO_Pin_11GPIO_Pin_12GPIO_Pin_13GPIO_Pin_14GPIO_Pin_15;
GPIO_Init(GPIOE,&
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_14GPIO_Pin_15GPIO_Pin_10GPIO_Pin_9GPIO_Pin_8GPIO_Pin_1GPIO_Pin_0;
GPIO_Init(GPIOD,&
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4GPIO_Pin_5;
//NOE,NWE引脚
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
//cs
GPIO_Init(GPIOG,&
}
接下来就是配置FSMCPC卡模式时序。
voidPCCARD_Init(void)
FSMC_PCCARDInitTypeDefFSMC_PCCARDInitStructure;
FSMC_NAND_PCCARDTimingInitTypeDefp;
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=&
FSMC_PCCARDInitStructure.FSMC_IOSpaceTimingStruct=&
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硬件部分IF0IF1要接成8086方式。
一开始,我们的硬件电路按如下图链接:
好像也没什么问题,于是就接着往下调,发现了一个很郁闷的问题,当时把问题描述如下:
#defineAXS_AX((volatileunsignedint)0x90000000)
#defineAXS_AY((volatileunsignedint)0x90000004)
#defineAXS_AZ((volatileunsignedint)0x9000008)
#defineAXS_AU((volatileunsignedint)0x900000c)
其中AXS_AX、AXS_AY、AXS_AZ、AXS_AU分别表示X、Y、Z、U轴寄存器的起始地址
几个地址均已经能够操作,能控制各个轴电机运动。
STM32通过FSMC与DSP通讯,通过16位传送数据。
#defineoutpw(address,data)(*(unsignedshort*)(address)=(data));
unsignedintinpw(unsignedintaddress)//读写某一段内存
unsignedshortdata;
data=*(unsignedshort*)address;
returndata;
写寄存器函数如下:
voidp645_wreg(unsignedintbase_addr,unsignedintrwcom,unsignedintdata)//向某个轴的某个寄存器写入数据
unionudata{
unsignedintldata;
unsignedshortidata[2];
}udt;
udt.ldata=data;
outpw(base_addr2,udt.idata[0]);
//Delay_Us
(1);
//就算加了延时也无效
outpw(base_addr3,udt.idata[1]);
outpw(base_addr,rwcom);
//读寄存器函数如下:
unsignedlongp645_rreg(unsignedintbase_addr,unsignedintrrcom)//读寄存器
outpw(base_addr,rrcom);
udt.idata[0]=inpw(base_addr2);
udt.idata[1]=inpw(base_addr3);
return(udt.ldata);
在设置解码倍频时,发现,无论我写入的是哪个数(00,01,10),都不能改变编码器读出的数据,即始终是默认的1倍解码,即相关寄存器两个bit是00的情况.
于是我猜想是不是我写入的数据不能改变高16位,只能改变低16位.
所以我就做了以下测试工作:
现在发现向DSP各轴缓冲区写入数据时,总是不能写进去高16位,而低十六位能写进去。
比如,我写p645_wreg(AXS_AX,WRENV1,0x00000001);
//控制脉冲类型。
p645_wreg(AXS_AX,WRENV1,0x00000002);
p645_wreg(AXS_AX,WRENV1,0x00000003);
分别能看到输出不同类型的脉冲。
证明低位操作有效!
但是当我写做定长测试时,代码如下
p645_wreg(AXS_AZ,WPRMD,0x00000041);
p645_wreg(AXS_AZ,WRMV,65536L);
//这里写入65535以下的数均能准确控制电机走的步数,超过65535,则会出现电机持续运动而不受控制的异常状况!
p645_wreg(AXS_AZ,WRFL,500L);
p645_wreg(AXS_AZ,WRFH,2000L);
p645_wreg(AXS_AZ,WRUR,200L);
p645_wreg(AXS_AZ,WRDR,400L);
p645_wreg(AXS_AZ,WRMG,5L);
p645_wcom(AXS_AZ,STAUD);
另外,超过65535时我读取出COUNT1中数据也是没有规律的。
而不超过65535时,则完全正常!
1.当写入65535时,电机运转过程读出数据如下:
Counter1Counter2
指令编码器(这里是默认的1倍,跟我们的编码器对应上是对的)
00000196620000000958
00000397900000001937
00000599180000002917
00000655350000003191
2.当写入65536及以上时,电机运转过程读出数据如下:
00000599170000002917
00000145090000003898
00000346370000004878
00000547640000005857
00000093560000006837
00000294840000007818
00000496110000008797
00000042030000009776
00000444580000011737
00000645860000012718
00000191770000013697
00000393050000014676
00000594330000015657
00000341520000017617
00000542790000018596
00000088710000019577
00000289990000020557
00000491260000021536
00000037180000022516
00000238460000023497
00000439730000024476
00000186920000026436
00000589480000028397
00000135390000029375
00000336670000030355
00000537940000031335
以上数据均不超过65535
基于上述现象,我做了个程序来测试读写,发现,我写入的数据到缓冲去时超过0x00ffffff时,读出来的数据是不对的,只有低24位能读出来,高8位读出来的均是0.
写寄存器函数修改如下:
voidp645_wreg(unsignedintbase_addr,unsignedintrwcom,unsignedintdata)
//outpw(base_addr,rwcom);
测试代码如下:
p645_wreg(AXS_AZ,WRENV2,0xffffffff);
data3=inpw(AXS_AZ2);
data4=inpw(AXS_AZ3);
读出的数据只能是data3=65535;
data4=255,即最高8位丢失!
当p645_wreg(,,);
写入的数据是低0x00ffffff以下的数据时,data3;
data4读出来的数据是对的。
即写什么读出什么。
这就是对我现在遇到的问题的详细叙述。
后来经过一番折腾,经过大量的测量观察发现。
是高16位中的高低字节顺序被对调了。
郁闷了。
于是我与日本方便的工程师交流,他们让将STM32的A1~A4与PCL6045的A1~A4相连,(原来是STM32的A0~A3与PCL6045的A1~A4)
于是地址也更改为
#defineAXS_AX0x90000000
#defineAXS_AY0x90000008
#defineAXS_AZ0x90000010
#defineAXS_AU0x90000018
我感觉很奇怪。
地址线的不同应该只是地址的不一样而已,怎么会导致高两个字节的高低8位对调呢。
日本方面说是他们的芯片内部设计是那样的,而我在日脉手册上没有看到任何说明。
之后进一步研究,我的PCL6045控制自如,全部功能顺利验证了一遍。
以上就是我开发PCL6045B过程中的开发体会。
转载请注明出处,有问题欢迎交流。