Mike, K8LH
- 23rd October 2010, 15:51
Have you considered using DDS (Direct Digital Synthesis) for those relatively low frequencies?
Off the top of my head, if you use an 8,388,608 Hz crystal, a 200-cycle PWM period (prescale 1:1, PR2 = 199), and 24-bit phase accumulators, you can produce both square wave outputs and a 200-level PWM sine wave output (1.2 to 20.0 Hz) with 0.01-Hz frequency resolution (more actually).
The example C program excerpt below uses a 256 element sine[] table of 0..200 duty cycle values for the PWM module while the square wave outputs simply use the most significant bit of their phase accumulator. ISR overhead is less than 40 cycles in Assembler on a 12F1822 but I'm not sure what you would get in PBP.
Best luck... Regards, Mike
;
; u24 accum1 = 0; // 24 bit phase accumulator for SQ1 output
; u24 accum2 = 0; // 24 bit phase accumulator for SQ2 output
; u24 accum3 = 0; // 24 bit phase accumulator for SIN output
;
; u24 phase1 = 90000<<4; // phase offset, (900.00-Hz * 100)<<4
; u24 phase2 = 40000<<4; // phase offset, (400.00-Hz * 100)<<4
; u24 phase3 = 1031<<4; // phase offset, ( 10.31-Hz * 100)<<4
;
; u08 sine[] = { 100,102,104,107,109,112,114,117,119,121,124,126,12 9,131,133,135,
; 138,140,142,144,147,149,151,153,155,157,159,161,16 3,165,167,168,
; 170,172,174,175,177,178,180,181,183,184,185,187,18 8,189,190,191,
; 192,193,194,194,195,196,197,197,198,198,198,199,19 9,199,199,199,
; 200,199,199,199,199,199,198,198,198,197,197,196,19 5,194,194,193,
; 192,191,190,189,188,187,185,184,183,181,180,178,17 7,175,174,172,
; 170,168,167,165,163,161,159,157,155,153,151,149,14 7,144,142,140,
; 138,135,133,131,129,126,124,121,119,117,114,112,10 9,107,104,102,
; 099,097,095,092,090,087,085,082,080,078,075,073,07 0,068,066,064,
; 061,059,057,055,052,050,048,046,044,042,040,038,03 6,034,032,031,
; 029,027,025,024,022,021,019,018,016,015,014,012,01 1,010,009,008,
; 007,006,005,005,004,003,002,002,001,001,001,000,00 0,000,000,000,
; 000,000,000,000,000,000,001,001,001,002,002,003,00 4,005,005,006,
; 007,008,009,010,011,012,014,015,016,018,019,021,02 2,024,025,027,
; 029,031,032,034,036,038,040,042,044,046,048,050,05 2,055,057,059,
; 061,064,066,068,070,073,075,078,080,082,085,087,09 0,092,095,097 };
;
;
; // 12F1822 DDS interrupt engine (Mike, K8LH)
; //
; // 1 square wave output on GP0 (400.00, 900.00, or 1600.00 Hz)
; // 1 square wave output on GP1 (400.00, 900.00, or 1600.00 Hz)
; // 1 sine wave output on GP2/CCP1 (1.20 to 20.00 Hz)
;
; void interrupt() // 200-cycles (10485.76-Hz)
; { pir1.TMR2IF = 0; // clear TMR2 interrupt flag
; accum1 += phase1; // add phase1 to accum1
; accum2 += phase2; // add phase2 to accum2
; accum3 += phase3; // add phase3 to accum3
; shadow = gpio & 0xFC; // clr GPIO shadow b0 & b1
; shadow.0 = accum1.23; // sq wave 1 output bit
; shadow.1 = accum2.23; // sq wave 2 output bit
; gpio = shadow; // update sq wave outputs
; ccpr1l = sine[accum3>>16]; // set sine wave duty cycle
; } //
;
Powered by vBulletin® Version 4.1.7 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.