So having read up about DDS to get sufficient frequency accuracy, it seems most people typically use a 24 bit or 32 bit accumuator.
Every interrupt a fixed number/value is added to the number held in the accumulator - the accumulator is basically a 32 bit counter.
Can this be kludged in picbasic - concatenate 4 bytes into one 'pretend' 32 bit counter - then add a fixed value to it everytime an interrupt happens?
Here's what one guy does in his assembly interrupt routine for a 16f628 PIC (original source - http://www.g4jnt.com/PIC_DDS.zip )...
....it doesn't mean a lot to me, but the gist of it seems to be add the fixed number to the lowest byte, then when that byte fills up, add a 'carry bit' to the second byte of the four ....rinse repeat until the the whole 32 bits are full, then start again from zero.Code:ints ;Using divide by prescalar, Interupt service runs at at Fosc / 200 ; when set to count 25 before overflowing, ie every 50 clocks = sampling rate bcf INTCON , T0IF ;reset the interrupt flag bsf TESTSTRB ;Spare instruction needed to make up 8 clocks total, up to the point of reloading TMR0 ;So use it to pulse a test point movlw d'235' ; Load in value to count up to 256 FROM (= NNN) movwf TMR0 ;Timer restarts counting 2 cycles after here. ;Up to this point takes 8 clocks from Interrupt trigger ;So NNN = 256 - [Wanted count] + 8 / Prescale ; ie = 256 - 25 + 8 / 2 = 235 ;Below here is not time-critical, but must be less than than about 42 clocks total ; so the whole interrupt takes < 50 clocks and doesn't overrun. movf D3, W ;First output the D/A value from the LAST pass though so there is call SineTable ; no jittering due to variable timing of the addition routine movwf PORTB movf F0, W ;Now add the frequency data stored in F3/2/1/0 to D3/2/1/0 addwf D0 btfss STATUS, C ;Add lowest order byte and check for and carry at each stage goto Add1Done ; that could ripple right through to MS byte incf D1 btfsc STATUS, Z incf D2 btfsc STATUS, Z incf D3 Add1Done movf F1, W ;Add the next byte addwf D1 btfss STATUS, C goto Add2Done incf D2 btfsc STATUS, Z incf D3 Add2Done movf F2, W ;... and the next addwf D2 btfsc STATUS, C incf D3 movf F3, W ;MS Byte now added in. If it has overflowed, its is exactly what we want addwf D3 ;D0-3 are now updated ready for next pass through, with D3 only sent to D/A converter. OutInt bcf TESTSTRB ;Reset the Test Point retfie ;This interrupt takes a max of 35 clocks for worst case addition, so does leave ; a bit of scope for extra tasks or faster sampling.
If it can be donekludged in Picbasic, would anyone be gracious enough to get me started?!!
If it can't be done, I guess I could try and work out what bits of his code to put in PICBasic ASM interrupt plus other supporting code! (that'll be me gone for a few months!)




Bookmarks