#include "LPC17xx.h"
#include "lpc/lpc17xx_nvic.h"
#include "lpc/lpc17xx_gpio.h"
#include "lpc/lpc17xx_pinsel.h"
#include "lpc/lpc17xx_libcfg.h"
#include "lpc/lpc17xx_timer.h"
#include "lpc/lpc17xx_clkpwr.h"
#include "lpc/lpc17xx_pinsel.h"
#include "lpc/lpc17xx_mcpwm.h"
#include "BLDC.h"
#include <cr_section_macros.h>
#include <NXP/crp.h>
__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;
/* Pin configuration data */
/** Motor Control Channel 0 Output A */
const PINSEL_CFG_Type mcpwm_mco0a_pin[1] = {{1, 19, 1, 0, 0}};
/** Motor Control Channel 0 Output B */
const PINSEL_CFG_Type mcpwm_mco0b_pin[1] = {{1, 22, 1, 0, 0}};
/** Motor Control Channel 1 Output A */
const PINSEL_CFG_Type mcpwm_mco1a_pin[1] = {{1, 25, 1, 0, 0}};
/** Motor Control Channel 1 Output B */
const PINSEL_CFG_Type mcpwm_mco1b_pin[1] = {{1, 26, 1, 0, 0}};
/** Motor Control Channel 2 Output A */
const PINSEL_CFG_Type mcpwm_mco2a_pin[1] = {{1, 28, 1, 0, 0}};
/** Motor Control Channel 2 Output B */
const PINSEL_CFG_Type mcpwm_mco2b_pin[1] = {{1, 29, 1, 0, 0}};
/** Motor Control Feed Back Channel 0 - MCI0 */
const PINSEL_CFG_Type mcpwm_mcfb0_pin[1] = {{1, 20, 1, 0, 0}};
/** Motor Control Feed Back Channel 1 - MCI1 */
const PINSEL_CFG_Type mcpwm_mcfb1_pin[1] = {{1, 23, 1, 0, 0}};
/** Motor Control Feed Back Channel 2 - MCI2 */
const PINSEL_CFG_Type mcpwm_mcfb2_pin[1] = {{1, 24, 1, 0, 0}};
/** Motor Control Low-active abort feed back */
const PINSEL_CFG_Type mcpwm_mcabort_pin[1] = {{ 1, 21, 0, 0, 0}};
/** @brief MCPWM Channel configuration data */
MCPWM_CHANNEL_CFG_Type channelsetup[3];
/** @brief Capture configuration data */
MCPWM_CAPTURE_CFG_Type captureCfg;
/** Motor controlling structure */
volatile PIDstr PID_Motor
= {
/* PID_Motor.p */ 4,
/* PID_Motor.i */ 10,
/* PID_Motor.d */ 0,
/* PID_Motor.sp */ 1500,
/* PID_Motor.pv */ 0,
/* PID_Motor.err[3] */ {0,0,0},
/* PID_Motor.mv */ 0,
/* PID_Motor.HALstate */ 0,
/* PID_Motor.CMT_CNT */ 0,
/* PID_Motor.CMT_step */ 0,
/* PID_Motor.RPM */ 0,
/* PID_Motor.Enable */ DISABLE,
/* PID_Motor.Direction */ CW,
/* PID_Motor.Brake */ ENABLE,
/* PID_Motor.Period */ 900,
/* PID_Motor.Poles */ 1,
/* PID_Motor.Tick_cur */ 0,
/* PID_Motor.Tick_old */ 0,
/* PID_Motor.Tick_new */ 0
};
/** Commutation table, connected to hall sensor */
volatile uint8_t CMT_tbl[2][8] = {{0xF, 2, 0, 1, 4, 3, 5, 0xF},
{0xF, 5, 3, 4, 1, 0, 2, 0xF} };
volatile unsigned char activationPattern[8] = { MCPWM_PATENT_A0 | MCPWM_PATENT_B1,
MCPWM_PATENT_A2 | MCPWM_PATENT_B1,
MCPWM_PATENT_A2 | MCPWM_PATENT_B0,
MCPWM_PATENT_A1 | MCPWM_PATENT_B0,
MCPWM_PATENT_A1 | MCPWM_PATENT_B2,
MCPWM_PATENT_A0 | MCPWM_PATENT_B2,MCPWM_PATENT_B0 | MCPWM_PATENT_B1 | MCPWM_PATENT_B2,
0
};
/**
* @briefInitialize the system to control the Brushless DC motor
*/
void BLDC_Init (void)
{
int i = 0;
/* MCPWM INITIALIZATION *******************************************/
/* Initializes pin corresponding to MCPWM function */
PINSEL_ConfigPin((PINSEL_CFG_Type *)&mcpwm_mco0a_pin[0]);
PINSEL_ConfigPin((PINSEL_CFG_Type *)&mcpwm_mco0b_pin[0]);
PINSEL_ConfigPin((PINSEL_CFG_Type *)&mcpwm_mco1a_pin[0]);
PINSEL_ConfigPin((PINSEL_CFG_Type *)&mcpwm_mco1b_pin[0]);
PINSEL_ConfigPin((PINSEL_CFG_Type *)&mcpwm_mco2a_pin[0]);
PINSEL_ConfigPin((PINSEL_CFG_Type *)&mcpwm_mco2b_pin[0]);
PINSEL_ConfigPin((PINSEL_CFG_Type *)&mcpwm_mcabort_pin[0]);
/* Configure the MCPWM Feedback pins to be CAP inputs */
PINSEL_ConfigPin((PINSEL_CFG_Type *)&mcpwm_mcfb0_pin[0]);
PINSEL_ConfigPin((PINSEL_CFG_Type *)&mcpwm_mcfb1_pin[0]);
PINSEL_ConfigPin((PINSEL_CFG_Type *)&mcpwm_mcfb2_pin[0]);
/* Disable interrupt for MCPWM */
NVIC_SetPriority(MCPWM_IRQn, ((0x01<<3)|0x01));
NVIC_DisableIRQ(MCPWM_IRQn);
/* Init MCPWM peripheral */
MCPWM_Init(LPC_MCPWM);
for(i = 0; i < 3; i++)
{
/* MCPWM Channel i setup */
channelsetup.channelType = MCPWM_CHANNEL_EDGE_MODE;
channelsetup.channelPolarity = MCPWM_CHANNEL_PASSIVE_LO;
channelsetup.channelDeadtimeEnable = DISABLE;
channelsetup.channelDeadtimeValue = 0;
channelsetup.channelUpdateEnable = ENABLE;
channelsetup.channelTimercounterValue = 0;
channelsetup.channelPeriodValue = PID_Motor.Period;
channelsetup.channelPulsewidthValue = 200;
/* Apply the setup to the channels */
MCPWM_ConfigChannel(LPC_MCPWM, i, &channelsetup);
captureCfg.captureChannel = i;
captureCfg.captureFalling = ENABLE;
captureCfg.captureRising = ENABLE;
captureCfg.hnfEnable = DISABLE;
captureCfg.timerReset = DISABLE;
MCPWM_ConfigCapture(LPC_MCPWM, i, &captureCfg);
}
}
/**
*@brief
* This function enables the BLDC motor control by setting the MCPWM in the
*right mode, enable the capturing and starting the MCPWM
*/
void BLDC_Enable (void)
{
/* Enable the MCPWM DC mode and all output pins */
MCPWM_DCMode(LPC_MCPWM, ENABLE, DISABLE, ( 0 ));
/* Set the PWM output value */
channelsetup[0].channelPulsewidthValue = 100;
/* Write to the shadow register */
MCPWM_WriteToShadow(LPC_MCPWM, 0, &channelsetup[0]);
/* Disable LIM0 and MAT0 interrupt flag */
MCPWM_IntConfig(LPC_MCPWM, MCPWM_INTFLAG_LIM0, DISABLE);
MCPWM_IntConfig(LPC_MCPWM, MCPWM_INTFLAG_MAT0, DISABLE);
/* Disable LIM1 and MAT1 interrupt flag */
MCPWM_IntConfig(LPC_MCPWM, MCPWM_INTFLAG_LIM1, DISABLE);
MCPWM_IntConfig(LPC_MCPWM, MCPWM_INTFLAG_MAT1, DISABLE);
/* Disable LIM2 and MAT2 interrupt flag */
MCPWM_IntConfig(LPC_MCPWM, MCPWM_INTFLAG_LIM2, DISABLE);
MCPWM_IntConfig(LPC_MCPWM, MCPWM_INTFLAG_MAT2, DISABLE);
/* Enable interrupt for capture event on MCI0 (MCFB0) */
MCPWM_IntConfig(LPC_MCPWM, MCPWM_INTFLAG_CAP0, ENABLE);
/* Enable interrupt for capture event on MCI0 (MCFB1) */
MCPWM_IntConfig(LPC_MCPWM, MCPWM_INTFLAG_CAP1, ENABLE);
/* Enable interrupt for capture event on MCI0 (MCFB2) */
MCPWM_IntConfig(LPC_MCPWM, MCPWM_INTFLAG_CAP2, ENABLE);
/* Enable interrupt for MCPWM */
NVIC_EnableIRQ(MCPWM_IRQn);
/* Start up the MCPWM */
MCPWM_Start(LPC_MCPWM, ENABLE, ENABLE, ENABLE);
/* Disable the brake */
PID_Motor.Brake = DISABLE;
/* Enable the motor */
PID_Motor.Enable = ENABLE;
// Enable Motor Control Board Output
GPIO_SetDir(1, 0x200000, GPIO_DIR_OUT);
GPIO_ClearValue(1, 0x200000);
}
void BLDC_setDuty (unsigned int duty)
{
/* Set the PWM output value */
channelsetup[0].channelPulsewidthValue = duty;
/* Write to the shadow register */
MCPWM_WriteToShadow(LPC_MCPWM, 0, &channelsetup[0]);
}
/**
* @brief This function handles the MCPWM feedback interrupts.
* The HALL sensor is connected to the MCPWM feedback inputs
* and will cause a pattern which determines the next commutation pattern.
*/
void MCPWM_IRQHandler (void)
{
/* Clear pending interrupt */
MCPWM_IntClear(LPC_MCPWM, MCPWM_INTFLAG_CAP0);
MCPWM_IntClear(LPC_MCPWM, MCPWM_INTFLAG_CAP1);
MCPWM_IntClear(LPC_MCPWM, MCPWM_INTFLAG_CAP2);
/* Read the current HALL sensor input */
unsigned char pinstat = 0;
pinstat = (GPIO_ReadValue(1) & 1<<20) >> 20;
pinstat |= (GPIO_ReadValue(1) & 3<<23) >> 22;
PID_Motor.CMT_step = pinstat;
// Commutate the motor
LPC_MCPWM->MCCCP = activationPattern[CMT_tbl[0][pinstat]];
return;
}
int main(void)
{
SystemInit();
SystemCoreClockUpdate();
BLDC_Init();
BLDC_Enable();
BLDC_setDuty(PID_Motor.Period/4); // Set the motor power to 75%
MCPWM_IRQHandler(); // Startup the motor
while (1);
return 1;
}
|