You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
/*
Example uses counter modules to measure a duty cycle on P3.
For more info on counter modules, download the Propeller Manual from
https://www.parallax.com/downloads/propeller-manual
... and see pages 95 - 98
Also,
https://www.parallax.com/propeller/qna/Content/QnaTopics/QnaCounters.htm
https://www.parallax.com/sites/default/files/downloads/AN001-P8X32ACounters-v2.0.pdf
Use Run with Terminal to see this output
duty cycle generated = 0
duty cycle measured = 0
duty cycle generated = 100
duty cycle measured = 100
duty cycle generated = 1
duty cycle measured = 1
duty cycle generated = 25
duty cycle measured = 25
duty cycle generated = 50
duty cycle measured = 50
duty cycle generated = 75
duty cycle measured = 75
duty cycle generated = 99
duty cycle measured = 99
*/
#include "simpletools.h"
int dutyCycle(int pin, int timeout, int scale);
int dcTest;
int main()
{
low(3);
pause(85);
dcTest = dutyCycle(3, 85, 100);
print("duty cycle generated = 0\r");
print("duty cycle measured = %d\r\r", dcTest);
high(3);
pause(85);
dcTest = dutyCycle(3, 85, 100);
print("duty cycle generated = 100\r");
print("duty cycle measured = %d\r\r", dcTest);
// Start pwm signal tcycle = 40 ms.
pwm_start(40000);
pwm_set(3, 0, 400);
pause(85);
dcTest = dutyCycle(3, 85, 100);
print("duty cycle generated = 1\r");
print("duty cycle measured = %d\r\r", dcTest);
pwm_set(3, 0, 10000);
pause(85);
dcTest = dutyCycle(3, 85, 100);
print("duty cycle generated = 25\r");
print("duty cycle measured = %d\r\r", dcTest);
pwm_set(3, 0, 20000);
pause(85);
dcTest = dutyCycle(3, 85, 100);
print("duty cycle generated = 50\r");
print("duty cycle measured = %d\r\r", dcTest);
pwm_set(3, 0, 30000);
pause(85);
dcTest = dutyCycle(3, 85, 100);
print("duty cycle generated = 75\r");
print("duty cycle measured = %d\r\r", dcTest);
pwm_set(3, 0, 39600);
pause(85);
dcTest = dutyCycle(3, 85, 100);
print("duty cycle generated = 99\r");
print("duty cycle measured = %d\r\r", dcTest);
}
/**
@brief measure ratio of tHigh / (tHigh + tLow) in terms of some integer scale value.
@param pin I/O pin measuring the signal.
@param timeout ms to wait. Use at least two full signal cycles, three to be safe.
If the frequency varies, make sure to use enough ms for two cycles at the lowest
frequency.
@param scale number to multiply by factional value duty cycle. For percent duty
cycle, use 100.
WARNING: This function starts to roll over when scale * phsa > 2^31. Since phsa
is in 12.5 ns units, an example to cause this would be if you choose a scale of
10,000 and allow your measurement's high time to exceed 2684 us.
Example: 2685 us * 80 ticks/us * 10,000 = 2,148,000,000 > 2,147,483,648
@returns scale * tHigh / (tHigh + tLow) or -1 if timeout occurred mid-measurement.
*/
int dutyCycle(int pin, int timeout, int scale)
{
// Check state in case of timeout
int state = input(pin);
// Define timeout in terms of clock ticks
int dt = timeout * (CLKFREQ/1000);
// Mark free running clock counter time
int t = CNT;
// Assuming other functions in the application have been using counter modules,
// configure CTRA/B, FRQA/B, and PHSA/B.
// Set up free running counter module A to masure high time clock ticks
CTRA = (1000 << 26) | pin;
FRQA = 1;
// Set up free running counter module B to masure low time clock ticks
CTRB = (1100 << 26) | pin;
FRQB = 1;
// Set up pin mask
int mask = 1 << pin;
int phsa, phsb;
// Wait for high to low transition
while(INA & mask) if(CNT - t > dt) break;
// Start free-running high measurement while signal is low
PHSA = 0;
// Wait for low to high transition
while(!(INA & mask)) if(CNT - t > dt) break;
// Start free running low measurement while signal is high
PHSB = 0;
// Wait for high to low transition
while(INA & mask) if(CNT - t > dt) break;
// Complete high time measurement
phsa = PHSA;
// Wait for low to high transition
while(!(INA & mask)) if(CNT - t > dt) break;
// complete low time measurement
phsb = PHSB;
// print("phsa = %d, phsb = %d\r", phsa, phsb);
// Turn off counter modules for other functions to use them.
CTRA = 0;
CTRB = 0;
// If timeout, return 100, 0, or -1 for
if(CNT - t > dt)
{
// Signal was high the whole time
if(state == 1 && phsb == 0) return scale;
//Signal was low the whole time
else if(state == 0 && phsa == 0) return 0;
// Timeout occurred mid-measurement.
else return -1;
}
else
{
// If no timeout, return the duty cycle measurement.
int dc = (phsa * scale) / (phsa + phsb);
return dc;
}
}
The text was updated successfully, but these errors were encountered:
The text was updated successfully, but these errors were encountered: