This makes Amplitude Modulated Pulse Train, which can be regarded as the discretized wave of the signal. Pulse Train can be defined by frequency and duty cycle, which can be temporarily changed, referring to PWM.

Dependents:   Interference_Simple

Revision:
1:19c3a52c80c3
Child:
4:7d5afb2e3b79
diff -r 6400e338266f -r 19c3a52c80c3 PulseTrain.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PulseTrain.cpp	Mon Jan 06 20:26:53 2020 +0000
@@ -0,0 +1,109 @@
+#include "PulseTrain.h"
+
+PulseTrain::PulseTrain(
+    uint32_t const arg_freq,
+    float const arg_duty,
+    uint32_t const arg_freq_max
+):
+    FREQ_MAX(arg_freq_max),
+    m_freq(velidateRange<uint32_t>(arg_freq, 1, FREQ_MAX)),
+    m_duty(velidateRange<float>(arg_duty, 0.0, 1.0))
+{
+    m_period_us = 1000000 / m_freq + (1000000 % m_freq > m_freq /2 ? 1 : 0);
+    init();
+    m_callback_asClock = doNothing;
+    m_callback_asPulseEdge = doNothing;
+
+}
+
+void PulseTrain::attachCallback_asClock(Callback<void(bool)> arg_callback)
+{
+    m_callback_asClock = arg_callback;
+}
+
+void PulseTrain::attachCallback_asPulseEdge(Callback<void(bool)> arg_callback)
+{
+    m_callback_asPulseEdge = arg_callback;
+}
+
+void PulseTrain::setFrequency(uint32_t const arg_freq)
+{
+    m_freq = velidateRange<uint32_t>(arg_freq, 1, FREQ_MAX);
+    m_period_us = 1000000 / m_freq + (1000000 % m_freq > m_freq /2 ? 1 : 0);
+    init();
+}
+
+void PulseTrain::setDutycycle(float const arg_duty)
+{
+    m_duty = velidateRange<float>(arg_duty, 0.0, 1.0);
+    init();
+}
+
+template <typename T>
+T PulseTrain::velidateRange(T const arg_val, T const arg_min, T const arg_max)
+{
+    if(arg_val < arg_min) return arg_min;
+    else if (arg_val <=  arg_max) return arg_val;
+    else return arg_max;
+}
+
+void PulseTrain::init()
+{
+    int a, b, r;
+    a = m_period_us;
+    b = a * m_duty;
+    r = a % b;
+    while ( r != 0 ) {
+        a = b;
+        b = r;
+        r = a % b;
+    }
+    m_clock_period_us = b;
+    
+     m_period_pcp = m_period_us / m_clock_period_us;
+     m_falling = m_period_pcp * m_duty;
+}
+
+void PulseTrain::incrementClock()
+{
+    static unsigned int l_itr = 0;
+
+    if (l_itr == m_raising) {
+        m_pulsestate = true;
+        m_callback_asPulseEdge(m_pulsestate);
+    } else if (l_itr == m_falling) {
+        m_pulsestate = false;
+        m_callback_asPulseEdge(m_pulsestate);
+    }
+
+    l_itr = (l_itr + 1) % m_period_pcp;
+
+    m_callback_asClock(m_pulsestate);
+}
+
+
+bool PulseTrain::getState()
+{
+    return m_pulsestate;
+}
+
+uint32_t PulseTrain::getFrequency()
+{
+    return m_freq;
+}
+
+float PulseTrain::getDutycycle()
+{
+    return m_duty;
+}
+
+uint32_t
+PulseTrain::getPeriod_us()
+{
+    return m_period_us;
+}
+
+uint32_t PulseTrain::getClockperiod_us()
+{
+    return m_clock_period_us;
+}
\ No newline at end of file