Stephen Price
/
SigGen
Signal Generator - Square, Sine. Arbitrary with mods
SigGen.cpp@0:e4b2af8e875a, 2010-07-22 (annotated)
- Committer:
- smpedi
- Date:
- Thu Jul 22 14:24:52 2010 +0000
- Revision:
- 0:e4b2af8e875a
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
smpedi | 0:e4b2af8e875a | 1 | #include "mbed.h" |
smpedi | 0:e4b2af8e875a | 2 | |
smpedi | 0:e4b2af8e875a | 3 | #define MAXWAVEPTS 20 |
smpedi | 0:e4b2af8e875a | 4 | #define SQUARE 0 |
smpedi | 0:e4b2af8e875a | 5 | #define SINE 1 |
smpedi | 0:e4b2af8e875a | 6 | #define UP 65 |
smpedi | 0:e4b2af8e875a | 7 | #define DOWN 66 |
smpedi | 0:e4b2af8e875a | 8 | #define RIGHT 67 |
smpedi | 0:e4b2af8e875a | 9 | #define LEFT 68 |
smpedi | 0:e4b2af8e875a | 10 | |
smpedi | 0:e4b2af8e875a | 11 | AnalogOut wave(p18); |
smpedi | 0:e4b2af8e875a | 12 | Ticker timer; |
smpedi | 0:e4b2af8e875a | 13 | float wValue; |
smpedi | 0:e4b2af8e875a | 14 | float waveVals[MAXWAVEPTS]; |
smpedi | 0:e4b2af8e875a | 15 | float *fpW, *fpEnd; |
smpedi | 0:e4b2af8e875a | 16 | float fAmp, fModAmp; |
smpedi | 0:e4b2af8e875a | 17 | short itype; |
smpedi | 0:e4b2af8e875a | 18 | |
smpedi | 0:e4b2af8e875a | 19 | void init_wave(int, int); |
smpedi | 0:e4b2af8e875a | 20 | void write_wavePt(); |
smpedi | 0:e4b2af8e875a | 21 | int DoTermIO(char); |
smpedi | 0:e4b2af8e875a | 22 | void ChangeRate(float); |
smpedi | 0:e4b2af8e875a | 23 | extern float input_control(); |
smpedi | 0:e4b2af8e875a | 24 | extern void ledOut(int); |
smpedi | 0:e4b2af8e875a | 25 | |
smpedi | 0:e4b2af8e875a | 26 | DigitalOut oled(p8); |
smpedi | 0:e4b2af8e875a | 27 | Serial pc(USBTX, USBRX); // tx, rx |
smpedi | 0:e4b2af8e875a | 28 | |
smpedi | 0:e4b2af8e875a | 29 | int main() { |
smpedi | 0:e4b2af8e875a | 30 | float rate, delay; |
smpedi | 0:e4b2af8e875a | 31 | unsigned int idelay; |
smpedi | 0:e4b2af8e875a | 32 | char c; |
smpedi | 0:e4b2af8e875a | 33 | |
smpedi | 0:e4b2af8e875a | 34 | fAmp = 0.606f; |
smpedi | 0:e4b2af8e875a | 35 | fModAmp = 0.5f; |
smpedi | 0:e4b2af8e875a | 36 | pc.printf("\fFrequency (Hz)? "); |
smpedi | 0:e4b2af8e875a | 37 | pc.scanf("%f",&rate); |
smpedi | 0:e4b2af8e875a | 38 | if (rate > 2000.0f) rate = 2000.0f; |
smpedi | 0:e4b2af8e875a | 39 | pc.printf("\n%f Hz, Got it\nSine (1) or Square? (0)",rate); |
smpedi | 0:e4b2af8e875a | 40 | pc.scanf("%c",&c); |
smpedi | 0:e4b2af8e875a | 41 | itype = c - 48; |
smpedi | 0:e4b2af8e875a | 42 | pc.printf("\nType is %s \n",(itype ? "Sine" : "Square")); |
smpedi | 0:e4b2af8e875a | 43 | |
smpedi | 0:e4b2af8e875a | 44 | delay = 1000000 / rate; // delay for one cycle |
smpedi | 0:e4b2af8e875a | 45 | delay = delay / (float)(MAXWAVEPTS - 1); // delay per point |
smpedi | 0:e4b2af8e875a | 46 | idelay = (int)(delay); // delay in int format |
smpedi | 0:e4b2af8e875a | 47 | init_wave((int)MAXWAVEPTS, itype); |
smpedi | 0:e4b2af8e875a | 48 | |
smpedi | 0:e4b2af8e875a | 49 | pc.printf("\nrate = %f\n",rate); |
smpedi | 0:e4b2af8e875a | 50 | pc.printf("delay = %f\n",delay); |
smpedi | 0:e4b2af8e875a | 51 | pc.printf("idelay = %u micro-seconds\n",idelay); |
smpedi | 0:e4b2af8e875a | 52 | |
smpedi | 0:e4b2af8e875a | 53 | timer.attach_us(&write_wavePt,idelay); |
smpedi | 0:e4b2af8e875a | 54 | oled = 0; |
smpedi | 0:e4b2af8e875a | 55 | while (1) { |
smpedi | 0:e4b2af8e875a | 56 | switch (DoTermIO(pc.getc())) { |
smpedi | 0:e4b2af8e875a | 57 | case 'i': |
smpedi | 0:e4b2af8e875a | 58 | fModAmp *= 1.01; |
smpedi | 0:e4b2af8e875a | 59 | if (fModAmp > 1.0) |
smpedi | 0:e4b2af8e875a | 60 | fModAmp = 1.0; |
smpedi | 0:e4b2af8e875a | 61 | init_wave((int)MAXWAVEPTS, itype); |
smpedi | 0:e4b2af8e875a | 62 | break; |
smpedi | 0:e4b2af8e875a | 63 | case 'd': |
smpedi | 0:e4b2af8e875a | 64 | fModAmp *= 0.99; |
smpedi | 0:e4b2af8e875a | 65 | if (fModAmp < 0.05) |
smpedi | 0:e4b2af8e875a | 66 | fModAmp = 0.05; |
smpedi | 0:e4b2af8e875a | 67 | init_wave((int)MAXWAVEPTS, itype); |
smpedi | 0:e4b2af8e875a | 68 | break; |
smpedi | 0:e4b2af8e875a | 69 | |
smpedi | 0:e4b2af8e875a | 70 | case UP: |
smpedi | 0:e4b2af8e875a | 71 | rate += 1.0f; |
smpedi | 0:e4b2af8e875a | 72 | ChangeRate(rate); |
smpedi | 0:e4b2af8e875a | 73 | break; |
smpedi | 0:e4b2af8e875a | 74 | case DOWN: |
smpedi | 0:e4b2af8e875a | 75 | rate -= 1.0f; |
smpedi | 0:e4b2af8e875a | 76 | ChangeRate(rate); |
smpedi | 0:e4b2af8e875a | 77 | break; |
smpedi | 0:e4b2af8e875a | 78 | case RIGHT: |
smpedi | 0:e4b2af8e875a | 79 | rate += 25.0f; |
smpedi | 0:e4b2af8e875a | 80 | ChangeRate(rate); |
smpedi | 0:e4b2af8e875a | 81 | break; |
smpedi | 0:e4b2af8e875a | 82 | case LEFT: |
smpedi | 0:e4b2af8e875a | 83 | rate -= 25.0f; |
smpedi | 0:e4b2af8e875a | 84 | ChangeRate(rate); |
smpedi | 0:e4b2af8e875a | 85 | break; |
smpedi | 0:e4b2af8e875a | 86 | case -1: |
smpedi | 0:e4b2af8e875a | 87 | pc.printf("%c",12); |
smpedi | 0:e4b2af8e875a | 88 | break; |
smpedi | 0:e4b2af8e875a | 89 | } |
smpedi | 0:e4b2af8e875a | 90 | } |
smpedi | 0:e4b2af8e875a | 91 | } |
smpedi | 0:e4b2af8e875a | 92 | |
smpedi | 0:e4b2af8e875a | 93 | int DoTermIO(char c) { |
smpedi | 0:e4b2af8e875a | 94 | char e; |
smpedi | 0:e4b2af8e875a | 95 | |
smpedi | 0:e4b2af8e875a | 96 | if (c==17) |
smpedi | 0:e4b2af8e875a | 97 | return(-1); |
smpedi | 0:e4b2af8e875a | 98 | |
smpedi | 0:e4b2af8e875a | 99 | if (c == 27) { // escape sequence? |
smpedi | 0:e4b2af8e875a | 100 | e = pc.getc(); |
smpedi | 0:e4b2af8e875a | 101 | if (e != 91) { |
smpedi | 0:e4b2af8e875a | 102 | return((int)(-1)); |
smpedi | 0:e4b2af8e875a | 103 | } |
smpedi | 0:e4b2af8e875a | 104 | pc.printf("%c",c); |
smpedi | 0:e4b2af8e875a | 105 | return((int)(pc.getc())); |
smpedi | 0:e4b2af8e875a | 106 | } |
smpedi | 0:e4b2af8e875a | 107 | pc.putc(c); |
smpedi | 0:e4b2af8e875a | 108 | return((int)c); |
smpedi | 0:e4b2af8e875a | 109 | } |
smpedi | 0:e4b2af8e875a | 110 | |
smpedi | 0:e4b2af8e875a | 111 | |
smpedi | 0:e4b2af8e875a | 112 | void ChangeRate(float val) { |
smpedi | 0:e4b2af8e875a | 113 | int idelay; |
smpedi | 0:e4b2af8e875a | 114 | float delay; |
smpedi | 0:e4b2af8e875a | 115 | |
smpedi | 0:e4b2af8e875a | 116 | pc.printf("\f"); |
smpedi | 0:e4b2af8e875a | 117 | pc.printf(" FFreq = %8.0f",val); |
smpedi | 0:e4b2af8e875a | 118 | |
smpedi | 0:e4b2af8e875a | 119 | delay = 1000000 / val; // delay for one cycle |
smpedi | 0:e4b2af8e875a | 120 | delay = delay / (float)(MAXWAVEPTS - 1); // delay per point |
smpedi | 0:e4b2af8e875a | 121 | idelay = (int)(delay); // delay in int format |
smpedi | 0:e4b2af8e875a | 122 | |
smpedi | 0:e4b2af8e875a | 123 | pc.printf("\nrate = %f\n",val); |
smpedi | 0:e4b2af8e875a | 124 | pc.printf("delay = %f\n",delay); |
smpedi | 0:e4b2af8e875a | 125 | pc.printf("idelay = %u micro-seconds\n",idelay); |
smpedi | 0:e4b2af8e875a | 126 | timer.detach(); |
smpedi | 0:e4b2af8e875a | 127 | timer = Ticker(); |
smpedi | 0:e4b2af8e875a | 128 | timer.attach_us(&write_wavePt,idelay); |
smpedi | 0:e4b2af8e875a | 129 | } |
smpedi | 0:e4b2af8e875a | 130 | |
smpedi | 0:e4b2af8e875a | 131 | |
smpedi | 0:e4b2af8e875a | 132 | void write_wavePt |
smpedi | 0:e4b2af8e875a | 133 | |
smpedi | 0:e4b2af8e875a | 134 | if (fpW >= fpEnd) { |
smpedi | 0:e4b2af8e875a | 135 | fpW = waveVals; |
smpedi | 0:e4b2af8e875a | 136 | } |
smpedi | 0:e4b2af8e875a | 137 | wave.write(*fpW); |
smpedi | 0:e4b2af8e875a | 138 | } |
smpedi | 0:e4b2af8e875a | 139 | |
smpedi | 0:e4b2af8e875a | 140 | /* load wave array with values. Currently supports square and sine, but any |
smpedi | 0:e4b2af8e875a | 141 | arbitrary wave shape can be defined, as long as it is MAXWAVEPTS long |
smpedi | 0:e4b2af8e875a | 142 | */ |
smpedi | 0:e4b2af8e875a | 143 | |
smpedi | 0:e4b2af8e875a | 144 | void init_wave(int iNumPts, int itype) { |
smpedi | 0:e4b2af8e875a | 145 | int i, iMid; |
smpedi | 0:e4b2af8e875a | 146 | float fddeg, fdeg, pi; |
smpedi | 0:e4b2af8e875a | 147 | float *fp; |
smpedi | 0:e4b2af8e875a | 148 | float amp; |
smpedi | 0:e4b2af8e875a | 149 | |
smpedi | 0:e4b2af8e875a | 150 | amp = fAmp * fModAmp; |
smpedi | 0:e4b2af8e875a | 151 | switch (itype) { |
smpedi | 0:e4b2af8e875a | 152 | case SQUARE: // square |
smpedi | 0:e4b2af8e875a | 153 | iMid = iNumPts/2-1; |
smpedi | 0:e4b2af8e875a | 154 | fpW = waveVals; |
smpedi | 0:e4b2af8e875a | 155 | fp = fpW; |
smpedi | 0:e4b2af8e875a | 156 | for (i=0; i<iMid; i++) { |
smpedi | 0:e4b2af8e875a | 157 | *fp = 0.0; |
smpedi | 0:e4b2af8e875a | 158 | fp++; |
smpedi | 0:e4b2af8e875a | 159 | } |
smpedi | 0:e4b2af8e875a | 160 | for (i=iMid; i< iNumPts; i++) { |
smpedi | 0:e4b2af8e875a | 161 | *fp = amp * 2; |
smpedi | 0:e4b2af8e875a | 162 | fp++; |
smpedi | 0:e4b2af8e875a | 163 | } |
smpedi | 0:e4b2af8e875a | 164 | fpEnd = fp-1; |
smpedi | 0:e4b2af8e875a | 165 | break; |
smpedi | 0:e4b2af8e875a | 166 | |
smpedi | 0:e4b2af8e875a | 167 | case SINE: // sine |
smpedi | 0:e4b2af8e875a | 168 | pi = 3.1415926; |
smpedi | 0:e4b2af8e875a | 169 | fddeg = ((2.0f * pi) / (float)iNumPts); |
smpedi | 0:e4b2af8e875a | 170 | fpW = waveVals; |
smpedi | 0:e4b2af8e875a | 171 | fp = fpW; |
smpedi | 0:e4b2af8e875a | 172 | fdeg = 0; |
smpedi | 0:e4b2af8e875a | 173 | for (i=0; i<iNumPts; i++) { |
smpedi | 0:e4b2af8e875a | 174 | *fp =( amp * cos(fdeg)) + amp; |
smpedi | 0:e4b2af8e875a | 175 | fp++; |
smpedi | 0:e4b2af8e875a | 176 | fdeg += fddeg; |
smpedi | 0:e4b2af8e875a | 177 | } |
smpedi | 0:e4b2af8e875a | 178 | fpEnd = fp-1; |
smpedi | 0:e4b2af8e875a | 179 | |
smpedi | 0:e4b2af8e875a | 180 | break; |
smpedi | 0:e4b2af8e875a | 181 | } |
smpedi | 0:e4b2af8e875a | 182 | |
smpedi | 0:e4b2af8e875a | 183 | } |
smpedi | 0:e4b2af8e875a | 184 |