Created
November 16, 2023 23:43
-
-
Save ajarmst/f542bdcbe2a29c9c95abee5757bda89f to your computer and use it in GitHub Desktop.
Simple demo of the HC9S12 Pulse Accumulator used as a frequency counter.
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: Pulse Accumulator Demo | |
// Processor: MC9S12XDP512 | |
// Bus Speed: 20 MHz (Requires Active PLL) | |
// Author: AJ Armstrong | |
// Details: Very rudimentary demo of a frequency counter | |
// using Pulse Accumulator A | |
// Date: Nov 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) | |
///////////////////////////////////////////////////////////////////////////// | |
// Local Prototypes | |
///////////////////////////////////////////////////////////////////////////// | |
void GetCount(void); //RTI event to read (duration below sets length of read) | |
void ShowCount(void); // RTI event to calculate events since last event and | |
// calculate the frequency of the input. | |
///////////////////////////////////////////////////////////////////////////// | |
// Global Variables | |
///////////////////////////////////////////////////////////////////////////// | |
int const sampleDuration = 25; //How long to measure in mSec. | |
int const updateDuration = 500; //How frequently to update display in mSec. | |
volatile unsigned int count = 0; //PACA count in most recent window | |
volatile unsigned int freq = 0; //Frequency (KHz) of count | |
///////////////////////////////////////////////////////////////////////////// | |
// Constants | |
///////////////////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////////////////// | |
// Main Entry | |
///////////////////////////////////////////////////////////////////////////// | |
void main(void) | |
{ | |
// Variables | |
_DISABLE_COP(); // No watchdog | |
///////////////////////////////////////////////////////////////////////////// | |
// 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 initializaton for 7-seg displays | |
RTI_Init(); // Initialize RTI timer | |
// I'm going to measure in 25 msec intervals. I could use the PIT or the ECT, but | |
// my RTI is already set up. | |
// So, I'm just going to use the 16-bit Pulse Accumulator A (PACA) (same pin as PT7) | |
// It has two modes: Gated Time Accumulation---which simply counts clock cycles | |
// as long as PT7 is high (not counting when it is low) and | |
// Event-Count---which simply counts events (transitions) on TC7. Counting | |
// can be started and stopped. The counter can be reset by just setting it to 0. | |
// We're going to use PACA in Event-Count mode to implement a simple frequency | |
// counter. In this configuration, it will be good from 1 KHz to about 2.6 MHz. | |
//Configuring PACA (Enabled, Event-Count mode, Rising Edge) | |
//I also have the option of setting interrupts on edge detection or on overflow | |
//I don't need those for this application. | |
PACTL |= PACTL_PAEN_MASK | PACTL_PEDGE_MASK; | |
//Now that I'm set up, start measuring. I'm going to use my RTI to determine the intervals | |
RTI_RegisterEvent(0,GetCount,sampleDuration); //How long to count edges | |
RTI_RegisterEvent(1,ShowCount,updateDuration); //How frequently to update the segs | |
// NB: If I wanted to get fancy, I could automatically adjust the sample duration | |
// for longer when the frequency is low and shorter when the frequency is high | |
// to keep my counter as accurate as possible over a greater range. (A 16-bit | |
// pulse accumulator can only count to 65,535. But even then, I could use my PACA | |
// overflow interrupt to keep track of longer values. This is left as an exercise--- | |
// or future assignment---for the reader.) | |
///////////////////////////////////////////////////////////////////////////// | |
// Main Program Loop | |
///////////////////////////////////////////////////////////////////////////// | |
EnableInterrupts; // Ensure our board will respond to interrupt signals. | |
for (;;) | |
{ | |
//Nothing to do. | |
asm WAI; | |
} | |
} | |
///////////////////////////////////////////////////////////////////////////// | |
// Functions | |
///////////////////////////////////////////////////////////////////////////// | |
//Used by RTI to get events since last read, calculate frequency, display. | |
void GetCount(void) | |
{ | |
//Update count from last measure | |
count = PACN32; //Read current value of PACA | |
PACN32 = 0; //Reset my count to 0 (why do I do this at the top?) | |
freq = count / sampleDuration; // Because 1 ms RTI, this is KHz. | |
} | |
void ShowCount(void) | |
{ | |
SEG_16D(count,0); // Show the raw count | |
SEG_16D(freq ,1); // Display frequency in KHz. | |
} | |
///////////////////////////////////////////////////////////////////////////// | |
// Interrupt Service Routines | |
///////////////////////////////////////////////////////////////////////////// |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment