Skip to content

Instantly share code, notes, and snippets.

@ajarmst
Last active October 13, 2023 14:49
Show Gist options
  • Save ajarmst/6e12c1aa7693bab002e065f53b683d73 to your computer and use it in GitHub Desktop.
Save ajarmst/6e12c1aa7693bab002e065f53b683d73 to your computer and use it in GitHub Desktop.
/////////////////////////////////////////////////////////////////////////////
// HC12 Program: Demo 3 - Serial Interrupts
// Processor: MC9S12XDP512
// Bus Speed: 20 MHz (Requires Active PLL)
// Author: AJ Armstrong
// Details: Demonstrates basic SCI operation using the DB-9 connector
// using interrupts.
// Date: Oct 2023
// Revision History :
/////////////////////////////////////////////////////////////////////////////
#include <hidef.h> /* common defines and macros */
#include "derivative.h" /* derivative-specific definitions */
// other system includes or your includes go here
#include "pll.h"
#include "swled.h"
#include "segs.h"
#include "timer.h"
#include "lcd.h"
/////////////////////////////////////////////////////////////////////////////
// Local Prototypes
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Global Variables
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Constants
/////////////////////////////////////////////////////////////////////////////
const char kszMessage[] =
"\n_______________________________\n"
"Four score and seven years ago our fathers brought forth \n"
"upon this continent, a new nation, conceived in Liberty, \n"
"and dedicated to the proposition that all men are created equal. \n"
"Now we are engaged in a great civil war, testing whether that nation, \n"
"or any nation so conceived and so dedicated, can long endure. We are \n"
"met on a great battle-field of that war. W have come to dedicate a \n"
"portion of that field, as a final resting place for those who here \n"
"gave their lives that that nation might live. It is altogether \n"
"fitting and proper that we should do this.\n"
"\n"
"But, in a larger sense, we can not dedicate--we can not consecrate--we \n"
"can not hallow--this ground. The brave men, living and dead, \n"
"who struggled here, have consecrated it, far above our poor power to add "
"\n"
"or detract. The world will little note, nor long remember what we say "
"here, \n"
"but it can never forget what they did here. It is for us the living, "
"rather, \n"
"to be dedicated here to the unfinished work which they who fought here "
"have \n"
"thus far so nobly advanced. It is rather for us to be here dedicated to \n"
"the great task remaining before us--that from these honored dead we take "
"\n"
"increased devotion to that cause for which they gave the last full "
"measure \n"
"of devotion--that we here highly resolve that these dead shall not have \n"
"died in vain--that this nation, under God, shall have a new birth of \n"
"freedom--and that government of the people, by the people, for the "
"people, \n"
"shall not perish from the earth.\n";
/////////////////////////////////////////////////////////////////////////////
// Main Entry
/////////////////////////////////////////////////////////////////////////////
int main(void)
{
_DISABLE_COP();
EnableInterrupts; // Ensure our board will respond to interrupt signals.
/////////////////////////////////////////////////////////////////////////////
// One-Time Initializations
/////////////////////////////////////////////////////////////////////////////
PLL_To20MHz(); // Configure the main clock to 20 MHz (implications for
// timers)
SWL_Init(); // Standard initialization for switches and LEDs
SEG_Init(); // Standard initialization for 7-segment displays
LCD_Init(); // Standard initialization for LCD
LCD_DispControl(42, 13); // Blinkencursor
/////////////////////////////////////////////////////////////////////////////
// Periodic Interrupt on PIT0 (500 ms)
/////////////////////////////////////////////////////////////////////////////
//Enable interrupt on PIT Channel 0 (only)
PITINTE = 0b00000001;
//Turn on channel0 (only)
PITCE = 0b00000001;
//Configure 8-bit micro timer 0 base to 200 (remember it auto adds 1)
//Note that we are not tied to the timer prescaler on these, just
//the bus clock. 8-bit max is 255
PITMTLD0 = 199; //Base tick = (199 + 1) * 1/(20 * 10^6 Hz) = 10 micros
//Configure 16-bit PIT 0 for 500ms (50,000 of the ticks spec. above)
//16-bit max is 65,535 (plus 1)
PITLD0 = 49999;
//Enable periodic interrupts, count even in WAI, no count in freeze
PITCFLMT = 0b10100000;
/////////////////////////////////////////////////////////////////////////////
// Configure SCI UART 0
/////////////////////////////////////////////////////////////////////////////
SCI0BD = 130; // 9600 Baud is 20 M / (9600 * 16) = 130.2
SCI0CR1 = 0b00000000; // Use 8N1 Framing (the default)
SCI0CR2 = 0b00001100; // Enable Tx/Rx on SCI0 (my dB9 port), no interrupts
SCI0CR2_RIE = 1; // Enable receive buffer full interrupts
/////////////////////////////////////////////////////////////////////////////
// Main Program Loop
/////////////////////////////////////////////////////////////////////////////
for (;;) {
asm wai; //Just wait for interrupts
}
}
/////////////////////////////////////////////////////////////////////////////
// Functions
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Interrupt Service Routines
/////////////////////////////////////////////////////////////////////////////
//SCI O Event Handler
interrupt VectorNumber_Vsci0 ISR_SCI0 (void)
{
//Local static to keep track of LCD cursor.
static unsigned char a = 0;
//Get current state of SCI0 flags
//storage in a variable captures initial state
//so we don't need to be concerned about it
//changing during processing.
unsigned char status = SCI0SR1; //Status register 1 for SCI0
if (status & SCI0SR1_RDRF_MASK)
{
if (SCI0DRL == 0x08) { // Backspace
if (a) a--; // Move back unless home
LCD_Addr(a % 40);
LCD_Data(' '); // Use space to erase
} else { //Ordinary char, just display
SEG_8H(2, SCI0DRL);
LCD_Addr((a++) % 40);
LCD_Data(SCI0DRL);
}
}
}
//Periodic Timer Event Handler
interrupt VectorNumber_Vpit0 void IOC0 (void)
{
//Local static to keep track of which character we
//are on in our message
static char* pMess = kszMessage;
TFLG1 = TFLG1_C0F_MASK; //Ack interrupt
TC0 = TC0 + 49999; //Rearm for next event
// if the transmitter buffer is empty, load a new byte to send (TX)
if (*pMess) //Am I still in the message?
{
if (SCI0SR1_TDRE) // Can I send?
SCI0DRL = *(pMess++); //Send current char, move to next
//Uses my own routine which shows numbers 0-7 on LEDs
// pmess - kszMessage is index of current character.
SWL_SetLEDs((pMess - kszMessage) % 8); //Count up on LEDs as we send
}
else
{
//Go back to beginning
pMess = kszMessage;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment