Created
December 7, 2023 21:47
-
-
Save ajarmst/44c5d899c5f66e0a1d307b127dda7b81 to your computer and use it in GitHub Desktop.
Stepper Motor Control Demo (9S12 Board)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
///////////////////////////////////////////////////////////////////////////// | |
// HC12 Program: Stepper (Port A4-A7) Demo | |
// Processor: MC9S12XDP512 | |
// Bus Speed: 20 MHz (Requires Active PLL) | |
// Author: AJ Armstrong | |
// Details: Simple Demo of Full-Wave Reversible Stepper Control | |
// (using a ) | |
// Date: Dec 2023 | |
// Revision History : | |
///////////////////////////////////////////////////////////////////////////// | |
#include <stdio.h> // For sprintf, etc | |
#include <ctype.h> // For character utilities | |
#include <string.h> // Various string utilities | |
#include <hidef.h> // Common defines and macros | |
#include "derivative.h" // Derivative-specific definitions | |
#include "pll.h" // Phase-locked loop clock control | |
#include "swled.h" // GPIO switches and LEDs | |
#include "segs.h" // 7-Segment Displays | |
#include "timer.h" // Enhanced capture timer | |
#include "portj.h" // Interrupt buttons | |
#include "pit.h" // Periodic Interrupt timer | |
#include "rti.h" // Realtime interrupts | |
#include "lcd.h" // LCD Display | |
#include "sci.h" // Serial communications interface (EIA/TIA-232) | |
#include "i2c.h" // Carlos Estay's I2C Driver Libraries | |
///////////////////////////////////////////////////////////////////////////// | |
// Local Prototypes | |
///////////////////////////////////////////////////////////////////////////// | |
void ProcessStep(void); // RTI Function to advance through waveforms | |
void SwitchDirection(void); //RTI Function to switch direction through wave | |
///////////////////////////////////////////////////////////////////////////// | |
// Global Variables | |
///////////////////////////////////////////////////////////////////////////// | |
int direction = 0; // True or false for direction | |
///////////////////////////////////////////////////////////////////////////// | |
// Constants | |
///////////////////////////////////////////////////////////////////////////// | |
//Waveforms for bipolar full stepping | |
const unsigned char waveLength = 8; //Number of entries in waveform map below | |
const unsigned char gkA1[] = {1,1,0,0,1,1,0,0}; | |
const unsigned char gkA2[] = {0,0,1,1,0,0,1,1}; | |
const unsigned char gkB1[] = {0,1,1,0,0,1,1,0}; | |
const unsigned char gkB2[] = {1,0,0,1,1,0,0,1}; | |
///////////////////////////////////////////////////////////////////////////// | |
// Main Entry | |
///////////////////////////////////////////////////////////////////////////// | |
void main(void) | |
{ | |
///////////////////////////////////////////////////////////////////////////// | |
// One-Time Initializations | |
///////////////////////////////////////////////////////////////////////////// | |
_DISABLE_COP(); // No watchdog | |
PLL_To20MHz(); // Configure the main clock to 20 MHz (implications for timers) | |
SWL_Init(); // Standard initialization for switches and LEDs | |
SEG_Init(); // Standard initializaton for 7-seg displays | |
RTI_Init(); // Initialize RTI timer | |
///////////////////////////////////////////////////////////////////////////// | |
// Main Program Loop | |
///////////////////////////////////////////////////////////////////////////// | |
EnableInterrupts; // Ensure our board will respond to interrupt signals. | |
LCD_Init(); // My current LCD drivers need RTI and interrupts. //FIXME | |
LCD_StringRCentered(0,"Stepper Demo"); //Top line, centered | |
LCD_StringRCentered(1,"------------"); //Second line, centered | |
//I'm just going to bit-bang using Port A, which is pretty available. | |
// Connections: | |
// PA7 -> Coil 1 (A) | |
// PA6 -> Coil 2 (A') | |
// PA7 -> Coil 3 (B) | |
// PA9 -> Coil 4 (B') | |
//Set up Port A, bits 4-7, as outputs | |
DDRA |= 0b11110000; | |
//Use RTI interrupts to set step period (msec) | |
RTI_RegisterEvent(0,ProcessStep,10); | |
//Use RTI to flip the direction | |
RTI_RegisterEvent(1,SwitchDirection,5000); //Switch direction every 5 sec | |
for (;;) | |
{ | |
asm WAI; //Wait for something interesting to happen | |
} | |
} | |
///////////////////////////////////////////////////////////////////////////// | |
// Functions | |
///////////////////////////////////////////////////////////////////////////// | |
// RTI Interupt handler, which sets the next part of the pulses on Port A | |
void ProcessStep(void) | |
{ | |
static unsigned char currStep = 0; // Keep track of which part of wave we're on | |
// Now, set my four bits in the upper nibble by the current waveform state | |
unsigned char temp = PORTA & 0x0F; // Grab lower bits on port | |
SWL_ClearLEDs(eAllLEDs); | |
if (direction) { | |
SWL_SetLEDs(eGreen); | |
temp |= (gkA1[currStep] << 7) // Bit 7 is A1 | |
| (gkA2[currStep] << 6) // Bit 6 is A2 | |
| (gkB1[currStep] << 5) // Bit 5 is B2 | |
| (gkB2[currStep] << 4); // Bit 4 is B1 | |
} else { //Flip Current direction in A to get opposite direction | |
SWL_SetLEDs(eRed); | |
temp |= (gkA2[currStep] << 7) // Bit 7 is A2 (note flip from above) | |
| (gkA1[currStep] << 6) // Bit 6 is A1 (note flip from above) | |
| (gkB1[currStep] << 5) // Bit 5 is B1 | |
| (gkB2[currStep] << 4); // Bit 4 is B2 | |
} | |
//Write current state of waveform. | |
PORTA = temp; | |
// Advance step to the next step, cycling 7->0 | |
currStep = (currStep + 1) % waveLength; | |
} | |
void SwitchDirection(void) | |
{ | |
//Flip the bit on direction. | |
direction = direction?0:1; //Boolean toggle 0->1, 1->0 | |
} | |
///////////////////////////////////////////////////////////////////////////// | |
// Interrupt Service Routines | |
///////////////////////////////////////////////////////////////////////////// |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment