Parallel out sine wave from custom sine table
dmwilson86
Posts: 27
Okay, so I've been trying to output a discrete signal to a resistor dac on pins p0-p8 for three days to no avail. I'm hoping someone can tell me my fatal mistakes, I'm desperate. Thanks.
con _CLKMODE = XTAL1 + PLL16X _XINFREQ = 5_000_000 obj var long cog1 pub main cog1:=cognew(@sinwave, 0) +1 dat org sinwave mov DIRA, #$FF mov t1, #0 mov sin, #0 mov acc, #0 mov ptr, #sintab :loop add ptr, #128 movs :set, ptr :set mov outa, 0-0 testn acc,#255 wz if_z mov acc,#0 if_z mov ptr, #sintab if_nz add acc, #1 if_nz add ptr, #1 jmp #:loop sin long 0 t1 long 0 acc long 0 ptr long 0 sintab long 128, 132, 135, 138, 141, 144, 147, 150, 153, 157, 160, 163, 166, 169, 172, 175, 177, 180, 183, 186 long 189, 192, 194, 197, 200, 202, 205, 207, 210, 212, 214, 217, 219, 221, 223, 225, 227, 229, 231, 233 long 235, 237, 238, 240, 241, 243, 244, 246, 247, 248, 249, 250, 251, 252, 253, 253, 254, 255, 255, 256 long 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 255, 255, 254, 253, 253, 252, 251, 250, 249, 248 long 247, 246, 244, 243, 241, 240, 238, 237, 235, 233, 231, 229, 227, 225, 223, 221, 219, 217, 214, 212 long 210, 207, 205, 202, 200, 197, 194, 192, 189, 186, 183, 180, 177, 175, 172, 169, 166, 163, 160, 157 long 153, 150, 147, 144, 141, 138, 135, 132, 129, 125, 122, 119, 116, 113, 110, 107, 104, 100, 97, 94 long 91, 88, 85, 82, 80, 77, 74, 71, 68, 65, 63, 60, 57, 55, 52, 50, 47, 45, 43, 40 long 38, 36, 34, 32, 30, 28, 26, 24, 22, 20, 19, 17, 16, 14, 13, 11, 10, 9, 8, 7 long 6, 5, 4, 4, 3, 2, 2, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 2, 2 long 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 16, 17, 19, 20, 22, 24, 26, 28 long 30, 32, 34, 36, 38, 40, 43, 45, 47, 50, 52, 55, 57, 60, 63, 65, 68, 71, 74, 77 long 80, 82, 85, 88, 91, 94, 97, 100, 104, 107, 110, 113, 116, 119, 122, 125
Comments
Also, the table only has 236 entries. As for testn, this will do a binary AND of !255 == $FFFFFF00 against acc. As acc is 0 it will always result in the Z flag being set which keeps acc at 0. Maybe you meant to use cmp & Co (or do the reset for if_nz)?
As for checking, add labels at the appropriate locations, press F9 and place the cursor on the label you're interested in. The status line will give you info as to object location and cog offset.
Edit: @kuroneko
You have beaten me by a few seconds
Your algorithms are too complicated, what's with all this checking for sin_tab_end?
Why not use the simple Direct Digital Synthesis (DDS) technique?
1) Have sine table of 256 longs.
2) Have 32 bit counter, call it "phase" that maintains he current position in the wave.
3) Use only the top 8 bits of phase to index the sin table for the current sample value.
4) Add a small amount "delta" to the phase value on every iteration.
5) Changing the value of delta changes your frequency with a very high resolution.
With this there is no need to check for end of table, the 8 bits of phase used to index the table will just wrap around to the table as required.
If you arrange for the table to start at location zero in your code you save a few instructions as you don't need to add any base offset address of the table when you access it.
A guy called Jesper did this in 6 lines of AVR code in his miniDDS project: www.myplace.nu/avr/minidds/index.htm
I know you are not normally happy with just "it works"