This tutorial covers the details of Driving a motor on the on the Kinetis K40 using the TWR-K40x256-KIT evaluation board.
In this exercise students will utilize the sample project to turn a motor on and off using the TWR-K40x256-KIT evaluation board.
Students will:
To successfully complete this exercise students will need the following board and development environment.
There are several steps in this process:
If needed, obtain background information on motors, timer modules, PWM signals and counters by navigating to the driving a DC motor article.
1. You will need to connect the Tower K40 to the Motor Board via the TWR-PROTO or some other mechanism.
2. You will need to connect the Motor Board to the DC motors and Battery
This link shows a video of the motors spinning. They start from Off and slowly pick up speed
http://www.youtube.com/watch?v=kY2bRiICzwc&feature=relmfu
This board takes the low-voltage, low-power "control" signals from the MCU and through an H-Bridge takes ahigh-voltage, high-power power supply (the battery) to drive the motors.
Motor Board page.
1. Be careful with the wires connected to the motor. Constant flexing of the solder connection can result in joint failure. If this happens, just re-solder it.
2. The wires which protrude from the motors of The Freescale Cup Chassis are in the format of Insulated Crimp On Bullet Connectors. These can be found at Radio Shack if they are missing from the kit.
If you have more than one project in your project view, make sure the proper project is the focus. The most reliable way to do this is to right click the project and choose Build Project as shown below. You can also go to the Project menu and choose the same command.
The edge-aligned mode is selected when (QUADEN = 0), (DECAPEN = 0), (COMBINE
0), (CPWMS = 0), and (MSnB = 1).
The EPWM period is determined by (MOD − CNTIN + 0x0001) and the pulse width
(duty cycle) is determined by (CnV − CNTIN).
The CHnF bit is set and the channel (n) interrupt is generated (if CHnIE = 1) at the
channel (n) match (FTM counter = CnV), that is, at the end of the pulse width.
This type of PWM signal is called edge-aligned because the leading edges of all PWM
signals are aligned with the beginning of the period, which is the same for all channels
within an FTM.
void InitMotorPWM()
{
//Enable the Clock to the FTM1 Module
SIM_SCGC6 |= SIM_SCGC6_FTM1_MASK;
// PORTC_PCR4 = PORT_PCR_MUX(1) | PORT_PCR_DSE_MASK; //Enable GPIO on on the pin -
//route the output of that channel 0 to the pin... (pick a different multiplexer value for routing the timer)
//ch 11.4.1 of the k40 reference manual is the pin control register
//For port c pin 1.. bits 10-8 Pin Mux Control...
PORTA_PCR8 = PORT_PCR_MUX(3) | PORT_PCR_DSE_MASK;
PORTA_PCR9 = PORT_PCR_MUX(3) | PORT_PCR_DSE_MASK;
// Choose EDGE-Aligned PWM: selected when QUADEN=0, DECAPEN=0, COMBINE=0, CPWMS=0, and MSnB=1 (page 964)
// Properly set up Flex Timer Module
//FTM0_MODE[WPDIS] = 1; //Disable Write Protection - enables changes to QUADEN, DECAPEN, etc.
FTM1_MODE |= FTM_MODE_WPDIS_MASK;
//FTMEN is bit 0, need to set to zero so DECAPEN can be set to 0
FTM1_MODE &= ~1;
//Set Edge Aligned PWM
FTM1_QDCTRL &=~FTM_QDCTRL_QUADEN_MASK;
//QUADEN is Bit 1, Set Quadrature Decoder Mode (QUADEN) Enable to 0, (disabled)
//FTM0_SC = 0x16; //Center Aligned PWM Select = 0, sets FTM Counter to operate in up counting mode,
//it is field 5 of FTMx_SC (status control) - also setting the pre-scale bits here
// Also need to setup the FTM0C0SC channel control register - Page 897 section 37.3.6
FTM1_CNT = 0x0; //FTM Counter Value - (initialize the CNT before writing to MOD) (16 bit available - bits 0-15 are count)
FTM1_MOD = FTM1_MOD_VALUE; //Set the Modulo resister (16 bit available - bits 0-15), Mod is set to 24000
FTM1_CNTIN = 0; //Set the Counter Initial Value to 0 (pg 915)
//change MSnB = 1
FTM1_C0SC |= FTM_CnSC_ELSB_MASK;
FTM1_C0SC &= ~FTM_CnSC_ELSA_MASK;
FTM1_C0SC |= FTM_CnSC_MSB_MASK;
FTM1_C0V = FTM1_MOD_VALUE/2; //Set the Channel n Value to (16 bit available - bits 0-15)
//Set the complimentary pinout
FTM1_C1SC |= FTM_CnSC_ELSB_MASK;
FTM1_C1SC &= ~FTM_CnSC_ELSA_MASK;
FTM1_C1SC |= FTM_CnSC_MSB_MASK;
FTM1_C1V = FTM1_MOD_VALUE/2;
FTM1_SC = FTM_SC_PS(0) | FTM_SC_CLKS(1);
// Interrupts
FTM1_SC |= FTM_SC_TOIE_MASK; //enable the interrupt mask
enable_irq(63); // (79-16) Set NVIC location, but you still have to change/check NVIC file sysinit.c under Project Settings Folder
}
void SetMotorPWM(float DutyCycle)
{
//float compDuty = (float)100.0-DutyCycle;
FTM1_C0V =(int)((DutyCycle*.01)* (float)FTM1_MOD_VALUE);
FTM1_C1V =(int)((1.0-DutyCycle*.01)* (float)FTM1_MOD_VALUE);
}
void MotorTick()
{
if (MotorTickVar < 0xff)//if motor tick less than 255 count up...
MotorTickVar++;
//Clear the overflow mask if set
if(FTM1_SC & FTM_SC_TOF_MASK)
FTM1_SC &= ~FTM_SC_TOF_MASK;
//LED_E2_TOGGLE; // ends up being ___ Hz (correct)
}
The function SetMotorPWM(MotorPwm) turns the motor at the "MotorPwm" rate from 0-49 (backwards), 50 (stall) and 100 (forwards).