Hi
I am working on a cnc project based on Tiva c series launchpad board (TM4C123GH6PM) and i want to control a stepper motor in closed loop using an optical incremental rotary encoder 600ppr feedback. I am facing an issue that while motor is running motor, error bit in QEISTAT goes high and motor also does not moves upto desired distance. I want to make it immune to missing steps. Encoder shaft is driven via a timing belt.
here is my code
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_gpio.h"
#include "inc/hw_types.h"
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h"
#include "driverlib/gpio.h"
#include "driverlib/qei.h"
#include "tm4c123gh6pm.h"
volatile int qeiPosition;
void forward(volatile int steps);
void reverse(volatile int steps);
void portfinit(void);
int main(void) {
// Set the clocking to run directly from the crystal.
SysCtlClockSet(SYSCTL_SYSDIV_4|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
// Enable QEI Peripherals
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
SysCtlPeripheralEnable(SYSCTL_PERIPH_QEI0);
HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
HWREG(GPIO_PORTD_BASE + GPIO_O_CR) |= 0x80;
HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = 0;
//Set Pins to be PHA0 and PHB0
GPIOPinConfigure(GPIO_PD6_PHA0);
GPIOPinConfigure(GPIO_PD7_PHB0);
//Set GPIO pins for QEI. PhA0 -> PD6, PhB0 ->PD7.
GPIOPinTypeQEI(GPIO_PORTD_BASE, GPIO_PIN_6 | GPIO_PIN_7);
//DISable peripheral and int before configuration
QEIDisable(QEI0_BASE);
QEIIntDisable(QEI0_BASE,QEI_INTERROR | QEI_INTDIR | QEI_INTTIMER | QEI_INTINDEX);
//QEIConfigure(QEI0_BASE, (QEI_CONFIG_CAPTURE_A | QEI_CONFIG_NO_RESET | QEI_CONFIG_QUADRATURE | QEI_CONFIG_NO_SWAP), 9000);
QEI0_MAXPOS_R = 0X0000195F;
QEIEnable(QEI0_BASE); // Enable the quadrature encoder.
QEIPositionSet(QEI0_BASE, 00);
portfinit();
while (1) //This is the main loop of the program
{
unsigned long in;
unsigned long out;
in=GPIO_PORTF_DATA_R & 0X01; // checking switch to start motor
if(in == 0x00)
{
forward (1000); // calling function to rotate motor in forward direction
SysCtlDelay (900000);
reverse (1000); // calling function to rotate motor in reverse direction
SysCtlDelay (60000);
}
}
void forward (volatile int steps)
{
QEIPositionSet(QEI0_BASE, steps);
//QEIDisable(QEI0_BASE);
QEI0_CTL_R |= 0X00000000;
QEI0_CTL_R &= 0Xfffffffd;
QEIEnable(QEI0_BASE);
while(QEI0_POS_R>50)
{
GPIO_PORTF_DATA_R = 0x02; // PF2 direction, PF1 step for stepper motor
SysCtlDelay (15000);
GPIO_PORTF_DATA_R = 0x00;
SysCtlDelay (15000);
}
}
void reverse (volatile int steps)
{
QEIPositionSet(QEI0_BASE, steps);
//QEIDisable(QEI0_BASE);
QEI0_CTL_R |=0X00000002;
QEIEnable(QEI0_BASE);
while(QEI0_POS_R>50)
{
GPIO_PORTF_DATA_R = 0x06; // PF2 directiion, PF1 step ,for stepper motor
SysCtlDelay (15000);
GPIO_PORTF_DATA_R = 0x04;
SysCtlDelay (15000);
}
}
void portfinit(void)
{ volatile unsigned long delay;
GPIO_PORTF_LOCK_R |= 0X4C4F434B;
GPIO_PORTF_CR_R = 0X1F;
GPIO_PORTF_AMSEL_R =0X00;
GPIO_PORTF_DIR_R = 0X0E;
GPIO_PORTF_PUR_R = 0X11;
GPIO_PORTF_DEN_R = 0X1F;
}