|
上一章讲了电机开发套件的硬件电路板,这一章就将软件,我是这方面的新手,软件部分可能进展的比较慢,而且是从最简单的有霍尔传感器的无刷电机入手,找到了一个电机
额定电压14.5V,自带霍尔传感器,功率40W.
在开发软件前先列出驱动一路电机的所有端口
序号 | 名称 | MAPS | 作用 | 1 | ADC端口 | GPIOA5/ANA5 | [url=]A相电流[/url] | 2 | GPIOB5/ANB5 | B相电流 | 3 | GPIOB4/ANB4 | C相电流 | 4 | GPIOA6/ANA6 | 电压 | 5 | GPIOA4/ANA4 | 母线电流 | | | | | 6 | PWM驱动信号 | GPIOE1/PWM0A | 进行电路上桥和下桥的驱动 | 7 | GPIOE0/PWM0B | 8 | GPIOE3/PWM1A | 9 | GPIOE2/PWM1B | 10 | GPIOE5/PWM2A | 11 | GPIOE4/PWM2B | | | | | 12 | 霍尔传感器 | GPIOC3(JP8_3-CN1_19) | [url=]霍尔A[/url](U) | 13 | [url=]GPIOC4[/url](JP7_3-CN1_20) | [url=]霍尔[/url]B(V) | 14 | GPIOC6 | 霍尔C(W) | | | | | 15 | 串口 | GPIOF4 (pin 62), TXD1 GPIOF5 (pin 63), RXD1 | 9600bps,进行监控用 | | | | | 16 | SPI | GPIOC10 (pin 54), MOSI0 | 对MC33937进行读写操作 | 17 | GPIOC8 (pin 52), MISO0 | 18 | GPIOC9 (pin 53), SCLK0 | 19 | GPIOC7 (pin 50), SS0_B | | | | | 20 | 按钮 | GPIOD5 | 进行转速加减操作 | 21 | GPIOD6 | | | | | [url=]22[/url] | 指示灯 | GPIOB3 | 故障显示 | | | | | 23 | 故障检测 | GPIOF0- XB_IN6 | 检测故障 | | | | | 24 | MC39337中断 | GPIOF3 | | | | | | 25 | MC39337使能 | [url=]GPIOF2[/url] | 使能MC33937,进行电机的驱动 | | | |
| 从上表可以知道,这个驱动电路共用了25个IO口。
程序的流程,程序还是比较简单,功能也简单,主要是实现电机的运转和调速。
现在对上述端口进行初始化
static void PeripheralCoreInit(void)
{
setReg16(INTC_VBA, 0x0000); /电源复位用的
setReg16(COP_CTRL, 0x00);//Computer Operating Properly(COP)
/* Initialize peripherals clock, system interrupt*/
PE_low_level_init();//初始化端口
OCCS_Init();//初始化时钟
Timer_Init();//初始化定时器,也就是3个霍尔传感器的检测,采用端口上升沿触发
PWM_A_Init(&udtPWMAreg);//6路PWM初始化,驱动的关键
ADC12_Init();//12位ADC初始化,主要用来进行模拟量(电压的采样)
SPI_Init();//MC33937的SPI初始化
/* SCI1 Init for FreeMATER communication */
SCI1_Init(9600);//实时监控FreeMATER的串口初始化
SIM_PCE0 |= SIM_PCE0_GPIOD; //两个按钮
SIM_PCE0 |= SIM_PCE0_GPIOB; // 故障指示灯
GPIOB_DDR |= GPIOB_DDR_DD_3; //电路板上的 User LED指示灯,用来故障显示
}
其他部分的初始化函数都比较简短,现在仅列出PWM初始化的代码
void PWM_A_Init(PWMA_REG_UPDATE *ptr)
{
SIM_PCE0 |= SIM_PCE0_GPIOE; // Enable GPIOE clock
GPIOE_PER |= (GPIOE_PER_PE_0 | GPIOE_PER_PE_1 | GPIOE_PER_PE_2 | GPIOE_PER_PE_3 | GPIOE_PER_PE_4 | GPIOE_PER_PE_5); // Enabled PWM peripheral on GPIO_E
/* enable PWMA 的 SM0, SM1, SM2模块 */
SIM_PCE3 |= (SIM_PCE3_PWMACH0 | SIM_PCE3_PWMACH1 | SIM_PCE3_PWMACH2); // Enable PWM Module Clock
/***************************************************************************************/
/* SM0模块 */
PWMA_SM0CTRL = PWMA_SM0CTRL_FULL; // full reload cycle
PWMA_SM0CTRL2 = PWMA_SM0CTRL2_FORCE_SEL_1; // Local Reload signal from this submodule
/* set 16kHz PWM period --> 62.5us = 10ns * (6249 + 1) */
PWMA_SM0INIT = 0;
PWMA_SM0VAL0 = 0;
PWMA_SM0VAL1 = 6249;
PWMA_SM0VAL2 = 0; //0% duty cycle
PWMA_SM0VAL3 = 0; //0% duty cycle
PWMA_SM0VAL4 = 0; //0% duty cycle
PWMA_SM0VAL5 = 0; //0% duty cycle
/* dead time = 1us */
PWMA_SM0DTCNT0 = 100;
PWMA_SM0DTCNT1 = 100;
/* PWM A output set to low polarity due to MC33937 MOSFET driver inputs */
PWMA_SM0OCTRL |= PWMA_SM0OCTRL_POLA | PWMA_SM0OCTRL_PWMAFS_0;
/* disable all faults */
PWMA_SM0DISMAP0 = 0xF011; // enable FAULT0
PWMA_SM0DISMAP1 = 0;
/* trigger signal 0 used to synchronize ADC via XBAR */
PWMA_SM0TCTRL |= PWMA_SM0TCTRL_OUT_TRIG_EN_0;
/***************************************************************************************/
/* SM1 模块 */
PWMA_SM1CTRL = PWMA_SM1CTRL_FULL; // full reload cycle
PWMA_SM1CTRL2 = PWMA_SM1CTRL2_FORCE_SEL_1 | PWMA_SM1CTRL2_CLK_SEL_1 | PWMA_SM1CTRL2_RELOAD_SEL | PWMA_SM1CTRL2_INIT_SEL_1;
/* 设置 16kHz PWM 周期 --> 62.5us = 10ns * (6249 + 1) */
PWMA_SM1INIT = 0;
PWMA_SM1VAL0 = 0;
PWMA_SM1VAL1 = 6249;
PWMA_SM1VAL2 = 0; //0% duty cycle
PWMA_SM1VAL3 = 0; //0% duty cycle
PWMA_SM1VAL4 = 0; //0% duty cycle
PWMA_SM1VAL5 = 0; //0% duty cycle
/* 死区时间 = 1us */
PWMA_SM1DTCNT0 = 100;
PWMA_SM1DTCNT1 = 100;
PWMA_SM1OCTRL |= PWMA_SM1OCTRL_POLA | PWMA_SM1OCTRL_PWMAFS_0;
PWMA_SM1DISMAP0 = 0xF011; // enable FAULT0
PWMA_SM1DISMAP1 = 0;
/***************************************************************************************/
/* SM2模块 */
PWMA_SM2CTRL = PWMA_SM2CTRL_FULL; // full reload cycle
PWMA_SM2CTRL2 = PWMA_SM2CTRL2_FORCE_SEL_1 | PWMA_SM2CTRL2_CLK_SEL_1 | PWMA_SM2CTRL2_RELOAD_SEL | PWMA_SM2CTRL2_INIT_SEL_1;
/* 设置 16kHz PWM 频率 --> 62.5us = 10ns * (6249 + 1) */
PWMA_SM2INIT = 0;
PWMA_SM2VAL0 = 0;
PWMA_SM2VAL1 = 6249;
PWMA_SM2VAL2 = 0; //0% duty cycle
PWMA_SM2VAL3 = 0; //0% duty cycle
PWMA_SM2VAL4 = 0; //0% duty cycle
PWMA_SM2VAL5 = 0; //0% duty cycle
PWMA_SM2DTCNT0 = 100;
PWMA_SM2DTCNT1 = 100;
PWMA_SM2OCTRL |= PWMA_SM1OCTRL_POLA | PWMA_SM2OCTRL_PWMAFS_0;
PWMA_SM2DISMAP0 = 0xF011; // enable FAULT0
PWMA_SM2DISMAP1 = 0;
/***************************************************************************************/
PWMA_MCTRL |= PWMA_MCTRL_CLDOK; // Clear LDOK bit
PWMA_MCTRL |= PWMA_MCTRL_LDOK; // LDOK
PWMA_MCTRL |= PWMA_MCTRL_RUN; // Enable clock
/***************************************************************************************/
/* PWM 失效监控打开,采用交叉开关的技术,把XB_IN6连接到XBAR_OUT29端口上*/
SIM_PCE0 |= SIM_PCE0_GPIOF;
SIM_GPSCL |= SIM_GPSFL_F0_0;
GPIOF_PER |= GPIOF_PER_PE_0;
XBARA_SEL14 = 0x0600U; // 输入XB_IN6连接到XBAR_OUT29
SIM_IPS0 |= SIM_IPS0_PWMAF0; // 选择 XBAR_OUT29 到 PWMA_FAULT0端口
PWMA_FCTRL0 = PWMA_FCTRL0_FLVL_0 | PWMA_FCTRL0_FAUTO_0; //1
PWMA_FFILT0 = PWMA_FFILT0_FILT_PER_5; // 滤波
PWMA_FSTS0 = 0x10; //使能循环输出
}
位置的判断和换向在3个定时器中实现,速度的控制在另一个定时器中实现,也就是定时器TA3
#pragma interrupt saveall
void IsrQTA3Compare(void)
{
CheckManualInterface(&udtInterfaceStatus);//检查按钮
if(f16DirectionOfRotation)//方向
f16SpeedActual = div_s(PERIOD_TO_SPEED,(Word16)uw16HSperiod);//当前速度计算
else
f16SpeedActual = negate(div_s(PERIOD_TO_SPEED,(Word16)uw16HSperiod));//方向的速度计算
if(!uw16HSperiod)//速度为0
f16SpeedActual = FRAC16(0.0);
f16SpeedRamp = GFLIB_Ramp16(f16SpeedRequired, f16SpeedRamp, &gfRampSpeed);//调用电机运行库计算
f16SpeedError= sub(abs_s(f16SpeedRamp),abs_s(f16SpeedActual));//速度偏差
f16DutyCycle= GFLIB_ControllerPIp(f16SpeedError, &gfPICtrlParamsSpeed, &i16PiSatFlagSpeed);//PI速度调节
//if(f16SpeedRequired<400)f16DutyCycle=f16SpeedRequired*2;//速度低于400,强制降低PWM占空比
MC33927_GetSR0(&mudtStatusRegister0);//读MC33937状态
MC33927_GetSR1(&mudtStatusRegister1);
MC33927_GetSR2(&mudtStatusRegister2);
mudtStatusRegister3= MC33927_GetSR3();
f16DcbVoltage = ADC12_RSLT0;//读电压值
clrReg16Bits(TMRA_3_SCTRL,0x8000);//清除中断标志
}
#pragma interrupt off
今天就到此为止了,下一次写程序运行情况 |
|