4

I need to generate a sine wave to fill a char table of size 1024. The word size on the microcontroller is 16-bit and floating-point operations are not available.

The sine wave itself will oscillate between the value of 0 to 255, with 127 being the center point.

Any ideas?

sj755
  • 3,944
  • 14
  • 59
  • 79
  • 3
    Can you generate the table on the host and store it as a table of constants? Then just link it in. – mtrw Dec 06 '11 at 08:08
  • @mtrw 256 values? I suppose I could generate the C code from a program on my PC. However, I'm looking for a working algorithm. I'll will consider this easier option as a last resort for sure. Thanks. – sj755 Dec 06 '11 at 08:19
  • 2
    I don't understand the need for an algorithm. If you have a table anyway, you've accepted the space hit. It makes no difference if the space is initialized at runtime or linktime. But if you don't want a table at all, then yes, you need an algorithm. CORDIC is the usual way to go. – mtrw Dec 06 '11 at 08:39
  • 1
    mtrw, I kind of agree with you, but it could be that he has very little flash but more RAM. Then the space hit is not important. Otherwise it's just strange to not use an array... :) – Prof. Falken Dec 06 '11 at 08:49
  • mtrw, do you have very little flash to spare for a 1024 or 256 byte array? Keep in mind that the CORDIC implementation will also take up some space... – Prof. Falken Dec 06 '11 at 08:49

4 Answers4

6

You only actually need to store one quarter of the sine wave -- you can lookup the other three quarters from the first quadrant. So you only need 256 bytes.

To generate the values on the micro controller, implement CORDIC. You can store one value, and generate the whole sine wave from that.

Prof. Falken
  • 24,226
  • 19
  • 100
  • 173
Anthony Blake
  • 5,328
  • 2
  • 25
  • 24
4

Create a precomputed array on your PC. You only have to create a fourth of the array if ROM (or equivalent, such as flash or code segment) space is at a premium, then mirror this part out to the other 768 bytes of the array.

Prof. Falken
  • 24,226
  • 19
  • 100
  • 173
2

Write a sin table generator in your favorite language using float.
Scale and round the results to desired ranges 1024/-127..+128 (you may do that right away). From the table, generate a source file in ASM or C, what ever works better for you.
Make sure the generated table in marked "const" in C or make go to a approbiate section in ASM so it goes to FLASH rather than RAM.
Include the file in your project.

Now intsin(x)1 is:

int intsin(int x)
limit x // 0..360° or 2PI
scale to 1024
read table at x
return x

You can improve resolution by using the table for the first quadrant only. You can than use positive values only, too (0..255). Then your intsin(x) would need to determine the quadrant and mirror the first quadrant results.

Marek Grzenkowicz
  • 17,024
  • 9
  • 81
  • 111
TheJoke
  • 21
  • 1
1

You just generate table on your PC and use it on your MCU. As somebody said you just need a quater period, but to answer your question fully, here are all 1024 chars:

  for k := 0 to 1023 do
      buffer[k] := (round(128+127*sin(2*pi*k/1024)));


128, 129, 130, 130, 131, 132, 133, 133, 134, 135, 136, 137, 137, 138, 139, 140, 140, 
141, 142, 143, 144, 144, 145, 146, 147, 147, 148, 149, 150, 150, 151, 152, 153, 
154, 154, 155, 156, 157, 157, 158, 159, 160, 160, 161, 162, 163, 163, 164, 165, 
166, 166, 167, 168, 169, 169, 170, 171, 172, 172, 173, 174, 174, 175, 176, 177, 
177, 178, 179, 179, 180, 181, 182, 182, 183, 184, 184, 185, 186, 186, 187, 188, 
189, 189, 190, 191, 191, 192, 193, 193, 194, 195, 195, 196, 197, 197, 198, 199, 
199, 200, 200, 201, 202, 202, 203, 204, 204, 205, 206, 206, 207, 207, 208, 209, 
209, 210, 210, 211, 212, 212, 213, 213, 214, 214, 215, 216, 216, 217, 217, 218, 
218, 219, 219, 220, 221, 221, 222, 222, 223, 223, 224, 224, 225, 225, 226, 226, 
227, 227, 228, 228, 229, 229, 230, 230, 230, 231, 231, 232, 232, 233, 233, 234, 
234, 234, 235, 235, 236, 236, 237, 237, 237, 238, 238, 239, 239, 239, 240, 240, 
240, 241, 241, 241, 242, 242, 242, 243, 243, 243, 244, 244, 244, 245, 245, 245, 
246, 246, 246, 246, 247, 247, 247, 248, 248, 248, 248, 249, 249, 249, 249, 250, 
250, 250, 250, 250, 251, 251, 251, 251, 251, 252, 252, 252, 252, 252, 252, 253, 
253, 253, 253, 253, 253, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 
254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254, 
254, 254, 254, 254, 254, 254, 254, 254, 254, 253, 253, 253, 253, 253, 253, 253, 
252, 252, 252, 252, 252, 252, 251, 251, 251, 251, 251, 250, 250, 250, 250, 250, 
249, 249, 249, 249, 248, 248, 248, 248, 247, 247, 247, 246, 246, 246, 246, 245, 
245, 245, 244, 244, 244, 243, 243, 243, 242, 242, 242, 241, 241, 241, 240, 240, 
240, 239, 239, 239, 238, 238, 237, 237, 237, 236, 236, 235, 235, 234, 234, 234, 
233, 233, 232, 232, 231, 231, 230, 230, 230, 229, 229, 228, 228, 227, 227, 226, 
226, 225, 225, 224, 224, 223, 223, 222, 222, 221, 221, 220, 219, 219, 218, 218, 
217, 217, 216, 216, 215, 214, 214, 213, 213, 212, 212, 211, 210, 210, 209, 209, 
208, 207, 207, 206, 206, 205, 204, 204, 203, 202, 202, 201, 200, 200, 199, 199, 
198, 197, 197, 196, 195, 195, 194, 193, 193, 192, 191, 191, 190, 189, 189, 188, 
187, 186, 186, 185, 184, 184, 183, 182, 182, 181, 180, 179, 179, 178, 177, 177, 
176, 175, 174, 174, 173, 172, 172, 171, 170, 169, 169, 168, 167, 166, 166, 165, 
164, 163, 163, 162, 161, 160, 160, 159, 158, 157, 157, 156, 155, 154, 154, 153, 
152, 151, 150, 150, 149, 148, 147, 147, 146, 145, 144, 144, 143, 142, 141, 140, 
140, 139, 138, 137, 137, 136, 135, 134, 133, 133, 132, 131, 130, 130, 129, 128, 
127, 126, 126, 125, 124, 123, 123, 122, 121, 120, 119, 119, 118, 117, 116, 116, 
115, 114, 113, 112, 112, 111, 110, 109, 109, 108, 107, 106, 106, 105, 104, 103, 
102, 102, 101, 100, 99, 99, 98, 97, 96, 96, 95, 94, 93, 93, 92, 91, 
90, 90, 89, 88, 87, 87, 86, 85, 84, 84, 83, 82, 82, 81, 80, 79, 
79, 78, 77, 77, 76, 75, 74, 74, 73, 72, 72, 71, 70, 70, 69, 68, 
67, 67, 66, 65, 65, 64, 63, 63, 62, 61, 61, 60, 59, 59, 58, 57, 
57, 56, 56, 55, 54, 54, 53, 52, 52, 51, 50, 50, 49, 49, 48, 47, 
47, 46, 46, 45, 44, 44, 43, 43, 42, 42, 41, 40, 40, 39, 39, 38, 
38, 37, 37, 36, 35, 35, 34, 34, 33, 33, 32, 32, 31, 31, 30, 30, 
29, 29, 28, 28, 27, 27, 26, 26, 26, 25, 25, 24, 24, 23, 23, 22, 
22, 22, 21, 21, 20, 20, 19, 19, 19, 18, 18, 17, 17, 17, 16, 16, 
16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 
10, 10, 10, 10, 9, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 
6, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 3, 
3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 
4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 
7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 
11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 
16, 17, 17, 17, 18, 18, 19, 19, 19, 20, 20, 21, 21, 22, 22, 22, 
23, 23, 24, 24, 25, 25, 26, 26, 26, 27, 27, 28, 28, 29, 29, 30, 
30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 37, 37, 38, 38, 
39, 39, 40, 40, 41, 42, 42, 43, 43, 44, 44, 45, 46, 46, 47, 47, 
48, 49, 49, 50, 50, 51, 52, 52, 53, 54, 54, 55, 56, 56, 57, 57, 
58, 59, 59, 60, 61, 61, 62, 63, 63, 64, 65, 65, 66, 67, 67, 68, 
69, 70, 70, 71, 72, 72, 73, 74, 74, 75, 76, 77, 77, 78, 79, 79, 
80, 81, 82, 82, 83, 84, 84, 85, 86, 87, 87, 88, 89, 90, 90, 91, 
92, 93, 93, 94, 95, 96, 96, 97, 98, 99, 99, 100, 101, 102, 102, 103, 
104, 105, 106, 106, 107, 108, 109, 109, 110, 111, 112, 112, 113, 114, 115, 116, 
116, 117, 118, 119, 119, 120, 121, 122, 123, 123, 124, 125, 126, 126, 127
avra
  • 3,690
  • 19
  • 19