上两个月做了个关于尿残渣的新项目,用到了电机驱动芯片PCL6045BL。这个体系计划有一个20余年工作经验的老工程师提出来,首要选用的是STM32操作PCL6045,从而操控多轴电机运动。
所以公司从每个不同项目组抽选人员组成了一个团队。自己担任软件部分,担任编写驱动程序和调试电路板。
全新项目,有必定挑战性。经过剖析,决议选用STM32总线方法(FSMC)驱动PCL6045B。比照FSMC的四种总线操作时序和PCL6045B操作时序。以为应该选用STM32的PCCARD形式操作。从数据库中查找了一些文献资料,就开干起来了。
两名硬件工程师按我的需求设计好硬件电路板。
接下来分红以下几个进程进行:
首要便是树立通讯。让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的状况.