Provides a simple way to generate complex square wave signals on any available pin. In addition the SignalGenerator can generate a carrier wave which is useful when generating IR signals to control electronic devices like a TV etc. The signal generation can be carried out either synchronously or asynchronously. In the case of synchronous signal generation all interrupts can optionally be disabled to improve timing accuracy.
SignalGenerator.cpp@1:4a1bcc41c473, 2014-09-12 (annotated)
- Committer:
- taylorza
- Date:
- Fri Sep 12 04:13:43 2014 +0000
- Revision:
- 1:4a1bcc41c473
- Parent:
- 0:b7c65c0d82d3
- Child:
- 2:b2a449bd787f
Added author details in comments
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
taylorza | 1:4a1bcc41c473 | 1 | /////////////////////////////////////////////////////////////////////////////// |
taylorza | 1:4a1bcc41c473 | 2 | // Signal Generator |
taylorza | 1:4a1bcc41c473 | 3 | // Author: Chris Taylor (taylorza) |
taylorza | 0:b7c65c0d82d3 | 4 | #include "mbed.h" |
taylorza | 0:b7c65c0d82d3 | 5 | #include "SignalGenerator.h" |
taylorza | 0:b7c65c0d82d3 | 6 | |
taylorza | 0:b7c65c0d82d3 | 7 | SignalGenerator::SignalGenerator(PinName pin) : _pin(pin) |
taylorza | 0:b7c65c0d82d3 | 8 | { |
taylorza | 0:b7c65c0d82d3 | 9 | _pin = 0; |
taylorza | 0:b7c65c0d82d3 | 10 | } |
taylorza | 0:b7c65c0d82d3 | 11 | |
taylorza | 0:b7c65c0d82d3 | 12 | void SignalGenerator::set(bool pinState) |
taylorza | 0:b7c65c0d82d3 | 13 | { |
taylorza | 0:b7c65c0d82d3 | 14 | _pin = pinState ? 1 : 0; |
taylorza | 0:b7c65c0d82d3 | 15 | } |
taylorza | 0:b7c65c0d82d3 | 16 | |
taylorza | 1:4a1bcc41c473 | 17 | void SignalGenerator::set( |
taylorza | 1:4a1bcc41c473 | 18 | bool initialState, |
taylorza | 1:4a1bcc41c473 | 19 | uint32_t timingBuffer[], |
taylorza | 1:4a1bcc41c473 | 20 | uint16_t bufferCount, |
taylorza | 1:4a1bcc41c473 | 21 | uint32_t lastStateHoldTime, |
taylorza | 1:4a1bcc41c473 | 22 | int carrierFrequency) |
taylorza | 0:b7c65c0d82d3 | 23 | { |
taylorza | 0:b7c65c0d82d3 | 24 | uint32_t carrierHalfPeriod = 0; |
taylorza | 0:b7c65c0d82d3 | 25 | |
taylorza | 0:b7c65c0d82d3 | 26 | if (carrierFrequency > 0) |
taylorza | 0:b7c65c0d82d3 | 27 | { |
taylorza | 0:b7c65c0d82d3 | 28 | carrierHalfPeriod = (uint32_t)(500000 / carrierFrequency); |
taylorza | 0:b7c65c0d82d3 | 29 | |
taylorza | 0:b7c65c0d82d3 | 30 | bool state = initialState; |
taylorza | 0:b7c65c0d82d3 | 31 | for(uint16_t i = 0; i < bufferCount; i++) |
taylorza | 0:b7c65c0d82d3 | 32 | { |
taylorza | 0:b7c65c0d82d3 | 33 | int c = (int)((double)timingBuffer[i] / carrierHalfPeriod); |
taylorza | 0:b7c65c0d82d3 | 34 | if (!state) |
taylorza | 0:b7c65c0d82d3 | 35 | { |
taylorza | 0:b7c65c0d82d3 | 36 | wait_us(timingBuffer[i]); |
taylorza | 0:b7c65c0d82d3 | 37 | } |
taylorza | 0:b7c65c0d82d3 | 38 | else |
taylorza | 0:b7c65c0d82d3 | 39 | { |
taylorza | 0:b7c65c0d82d3 | 40 | for(int j = 0; j < c; j += 2) |
taylorza | 0:b7c65c0d82d3 | 41 | { |
taylorza | 0:b7c65c0d82d3 | 42 | _pin = 1; |
taylorza | 0:b7c65c0d82d3 | 43 | wait_us(carrierHalfPeriod); |
taylorza | 0:b7c65c0d82d3 | 44 | _pin = 0; |
taylorza | 0:b7c65c0d82d3 | 45 | wait_us(carrierHalfPeriod); |
taylorza | 0:b7c65c0d82d3 | 46 | } |
taylorza | 0:b7c65c0d82d3 | 47 | } |
taylorza | 0:b7c65c0d82d3 | 48 | state = !state; |
taylorza | 0:b7c65c0d82d3 | 49 | } |
taylorza | 0:b7c65c0d82d3 | 50 | |
taylorza | 0:b7c65c0d82d3 | 51 | if (lastStateHoldTime > 0) |
taylorza | 0:b7c65c0d82d3 | 52 | { |
taylorza | 0:b7c65c0d82d3 | 53 | int c = (int)((double)lastStateHoldTime / carrierHalfPeriod); |
taylorza | 0:b7c65c0d82d3 | 54 | if (!state) |
taylorza | 0:b7c65c0d82d3 | 55 | { |
taylorza | 0:b7c65c0d82d3 | 56 | wait_us(lastStateHoldTime); |
taylorza | 0:b7c65c0d82d3 | 57 | } |
taylorza | 0:b7c65c0d82d3 | 58 | else |
taylorza | 0:b7c65c0d82d3 | 59 | { |
taylorza | 0:b7c65c0d82d3 | 60 | for(int j = 0; j < c; j += 2) |
taylorza | 0:b7c65c0d82d3 | 61 | { |
taylorza | 0:b7c65c0d82d3 | 62 | _pin = 1; |
taylorza | 0:b7c65c0d82d3 | 63 | wait_us(carrierHalfPeriod); |
taylorza | 0:b7c65c0d82d3 | 64 | _pin = 0; |
taylorza | 0:b7c65c0d82d3 | 65 | wait_us(carrierHalfPeriod); |
taylorza | 0:b7c65c0d82d3 | 66 | } |
taylorza | 0:b7c65c0d82d3 | 67 | } |
taylorza | 0:b7c65c0d82d3 | 68 | } |
taylorza | 0:b7c65c0d82d3 | 69 | } |
taylorza | 0:b7c65c0d82d3 | 70 | else |
taylorza | 0:b7c65c0d82d3 | 71 | { |
taylorza | 0:b7c65c0d82d3 | 72 | set(initialState); |
taylorza | 0:b7c65c0d82d3 | 73 | for(uint16_t i = 0; i < bufferCount; ++i) |
taylorza | 0:b7c65c0d82d3 | 74 | { |
taylorza | 0:b7c65c0d82d3 | 75 | wait_us(timingBuffer[i]); |
taylorza | 0:b7c65c0d82d3 | 76 | _pin = !_pin; |
taylorza | 0:b7c65c0d82d3 | 77 | } |
taylorza | 0:b7c65c0d82d3 | 78 | |
taylorza | 0:b7c65c0d82d3 | 79 | if (lastStateHoldTime > 0) |
taylorza | 0:b7c65c0d82d3 | 80 | { |
taylorza | 0:b7c65c0d82d3 | 81 | wait_us(lastStateHoldTime); |
taylorza | 0:b7c65c0d82d3 | 82 | } |
taylorza | 0:b7c65c0d82d3 | 83 | } |
taylorza | 1:4a1bcc41c473 | 84 | } |