SINE GENERATOR

Hola! Tengo este codigo que genera una señal sinusoidal en el pin 11 PWM Lo que me interesa es si alguien puede modificar el codigo para que en en otro pin me salga otros pulsos sincronisados con el 11. Con otras palavras .... tenemos el arry sine256[] = {127,130,133,136,139,143,146,149.... y nesesito por ejemplo en el pin 4 como un reloj sincronizado con el sinus. Por ejemplo valor 127 .... pin 4 (0, 1) valor 130 (0, 1) por cada valor del sinus un pulso de 1 y 0

aqui le dejo el codigo!

include "avr/pgmspace.h"

// table of 256 sine values / one sine period / stored in flash memory PROGMEM prog_uchar sine256[] = {127,130,133,136,139,143,146,149,152,155,158,161,164,167,170,173,176,178,181,184,187,190,192,195,198, 200,203,205,208,210,212,215,217,219,221,223,225,227,229,231,233,234,236,238,239,240,242,243,244,245,247,248,249,249,250,251,252,252, 253,253,253,254,254,254,254,254,254,254,253,253,253,252,252,251,250,249,249,248,247,245,244,243,242,240,239,238,236,234,233,231,229, 227,225,223,221,219,217,215,212,210,208,205,203,200,198,195,192,190,187,184,181,178,176,173,170,167,164,161,158,155,152,149,146,143, 139,136,133,130,127,124,121,118,115,111,108,105,102,99,96,93,90,87,84,81,78,76,73,70,67,64,62,59,56,54,51,49,46,44,42,39,37,35,33,31, 29,27,25,23,21,20,18,16,15,14,12,11,10,9,7,6,5,5,4,3,2,2,1,1,1,0,0,0,0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,16,18,20,21,23,25, 27,29,31,33,35,37,39,42,44,46,49,51,54,56,59,62,64,67,70,73,76,78,81,84,87,90,93,96,99,102,105,108,111,115,118,121,124};

define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))

define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

double dfreq; // const double refclk=31372.549; // =16MHz / 510 const double refclk=31376.6; // measured

// variables used inside interrupt service declared as voilatile volatile byte icnt; // var inside interrupt volatile byte icnt1; // var inside interrupt volatile byte c4ms; // counter incremented all 4ms volatile unsigned long phaccu; // pahse accumulator volatile unsigned long tword_m; // dds tuning word m

void setup() { pinMode(11, OUTPUT); // pin11= PWM output / frequency output Setup_timer2(); // disable interrupts to avoid timing distortion cbi (TIMSK0,TOIE0); // disable Timer0 !!! delay() is now not available sbi (TIMSK2,TOIE2); // enable Timer2 Interrupt

dfreq=181.2; // initial output frequency = 1000.o Hz tword_m=pow(2,32)*dfreq/refclk; // calulate DDS new tuning word

} void loop() { } //****************************************************************** // timer2 setup // set prscaler to 1, PWM mode to phase correct PWM, 16000000/510 = 31372.55 Hz clock void Setup_timer2() {

// Timer2 Clock Prescaler to : 1 sbi (TCCR2B, CS20); cbi (TCCR2B, CS21); cbi (TCCR2B, CS22);

// Timer2 PWM Mode set to Phase Correct PWM cbi (TCCR2A, COM2A0); // clear Compare Match sbi (TCCR2A, COM2A1);

sbi (TCCR2A, WGM20); // Mode 1 / Phase Correct PWM cbi (TCCR2A, WGM21); cbi (TCCR2B, WGM22); }

//****************************************************************** // Timer2 Interrupt Service at 31372,550 KHz = 32uSec // this is the timebase REFCLOCK for the DDS generator // FOUT = (M (REFCLK)) / (2 exp 32) // runtime : 8 microseconds ( inclusive push and pop) ISR(TIMER2_OVF_vect) { phaccu=phaccu+tword_m; // soft DDS, phase accu with 32 bits icnt=phaccu >> 24; // use upper 8 bits for phase accu as frequency information // read value fron ROM sine table and send to PWM DAC OCR2A=pgm_read_byte_near(sine256 + icnt); if(icnt1++ == 125) { // increment variable c4ms all 4 milliseconds c4ms++; icnt1=0; } }

Hola,

¿Qué es lo que no entiendes del código para no poder hacerlo tu mismo? Mira este tutorial que está muy bien (en inglés): http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=50106

Saludos

;)

Hola Igor! Me vuelvo loquito entre los timers... si me puedes ayudar modificame el codigo y segurisimo te voy agradeser mucho! lo unico que necesito es un clock a uno de los pines que quieres tu y un pino por el start. Es decir ... empiesa el sinus .. un pulso 1 al pin 6 por ejemplo y luego 0 asta que se termina el sinus y otro pin que cambia a 0 y 1 por cada valor del sinus. te dejo tambien mi mess proy2002@yahoo.com para una larga colaboratcion y no lo haces por nada. Igual como se va leyendo una memoria eprom donde tenemos el clock el counter y los datos paralelos que salga de la memoria. Entonses me interesa el START , El CLOCK , y los valores del sinus existe en el pin 11. Mucha Gracia!

[quote author=Igor R link=topic=74711.msg563036#msg563036 date=1318080285] Hola,

¿Qué es lo que no entiendes del código para no poder hacerlo tu mismo? Mira este tutorial que está muy bien (en inglés): http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=50106

Saludos

;)

[/quote]

Que buen tutorial Igor, (lastima lo del ingles, aunque con el google traductor y un poco de concentración es fácil) haber si hago un hueco y me pongo definitivamente con el tema de los timers. Muchas gracias

profy: Hola Igor! Me vuelvo loquito entre los timers... si me puedes ayudar modificame el codigo y segurisimo te voy agradeser mucho!

Profy deja de echarle jeta y trabajalo tu, ¿que te está costando? no pasa nada así se aprende. ¿Que tienes dudas puntuales tras consultar la página que ha puesto Igor? Pregúntalas seguro que Igor o algún otro te responde. Pero no creo que alguien te haga el código.

Ya ni preguntar dudas para intentar hacerlo uno mismo, directamente pedir que alguien te haga el código :0

profy: Hola Igor! Me vuelvo loquito entre los timers... si me puedes ayudar modificame el codigo y segurisimo te voy agradeser mucho! lo unico que necesito es un clock a uno de los pines que quieres tu y un pino por el start. Es decir ... empiesa el sinus .. un pulso 1 al pin 6 por ejemplo y luego 0 asta que se termina el sinus y otro pin que cambia a 0 y 1 por cada valor del sinus. te dejo tambien mi mess proy2002@yahoo.com para una larga colaboratcion y no lo haces por nada. Igual como se va leyendo una memoria eprom donde tenemos el clock el counter y los datos paralelos que salga de la memoria. Entonses me interesa el START , El CLOCK , y los valores del sinus existe en el pin 11. Mucha Gracia!

para que te hagan tu trabajo te recomiendo esta web http://www.freelancer.com/ o esta http://www.guru.com/

Pero mira que sois…

Hay que publicar directamente la cuenta de paypal, hombre.

Si quereis en castellano un mini manual de introducción, escribí esto sobre el timer 2 => http://real2electronics.blogspot.com/2011/01/timer-2.html

;)

Hola, gracias, Igor, me ha gustado el tutorial de avrfreaks, tan claro y didáctico. Ya sé lo que voy a empollarme este invierno: los timer, los puertos, las operaciones a nivel de bits... todo eso que suelo ver en el código de algunos programas, pero que nunca lo entendí detalladamente.

Hola a todos! Primero tengo que agradecerle muchisimo a Igor porque de verdad me ayudo mucho. No puedo decir que controlo los timers, despues de una noche de estudio pero he entendido leyendo su publicacion de que se trata y he echo los primeros pasos en cambiar mi codigo. AQUI http://www.carpinteriaaluminioypvc.com/SINE_PULSE.jpg tienes una foto del osciloscopio y mas abajo le dejo el codigo, mas limpio y mas simple.

include "avr/pgmspace.h"

// table of 256 sine values / one sine period / stored in flash memory PROGMEM prog_uchar sine256[] = { 127,130,133,136,139,143,146,149,152,155,158,161,164,167,170,173,176,178,181,184,187,190,192,195,198,200,203,205,208,210,212,215,217,219,221,223,225,227,229,231,233,234,236,238,239,240, 242,243,244,245,247,248,249,249,250,251,252,252,253,253,253,254,254,254,254,254,254,254,253,253,253,252,252,251,250,249,249,248,247,245,244,243,242,240,239,238,236,234,233,231,229,227,225,223, 221,219,217,215,212,210,208,205,203,200,198,195,192,190,187,184,181,178,176,173,170,167,164,161,158,155,152,149,146,143,139,136,133,130,127,124,121,118,115,111,108,105,102,99,96,93,90,87,84,81,78, 76,73,70,67,64,62,59,56,54,51,49,46,44,42,39,37,35,33,31,29,27,25,23,21,20,18,16,15,14,12,11,10,9,7,6,5,5,4,3,2,2,1,1,1,0,0,0,0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,16,18,20,21,23,25,27,29,31, 33,35,37,39,42,44,46,49,51,54,56,59,62,64,67,70,73,76,78,81,84,87,90,93,96,99,102,105,108,111,115,118,121,124

};

define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))

define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

double dfreq; // const double refclk=31372.549; // =16MHz / 510 const double refclk=31376.6; // measured

// variables used inside interrupt service declared as voilatile volatile byte puls; volatile byte icnt; // var inside interrupt

volatile byte c4ms; // counter incremented all 4ms volatile unsigned long phaccu; // pahse accumulator volatile unsigned long tword_m; // dds tuning word m

void setup() { pinMode (4, OUTPUT); pinMode (7, OUTPUT); pinMode(11, OUTPUT); // pin11= PWM output / frequency output Setup_timer2();

// disable interrupts to avoid timing distortion cbi (TIMSK0,TOIE0); // disable Timer0 !!! delay() is now not available sbi (TIMSK2,TOIE2); // enable Timer2 Interrupt

dfreq=40; // initial output frequency = 1000.o Hz tword_m=pow(2,32)*dfreq/refclk; // calulate DDS new tuning word

} void loop() {

} //****************************************************************** // timer2 setup // set prscaler to 1, PWM mode to phase correct PWM, 16000000/510 = 31372.55 Hz clock void Setup_timer2() {

// Timer2 Clock Prescaler to : 1 sbi (TCCR2B, CS20); cbi (TCCR2B, CS21); cbi (TCCR2B, CS22);

// Timer2 PWM Mode set to Phase Correct PWM cbi (TCCR2A, COM2A0); // clear Compare Match sbi (TCCR2A, COM2A1);

sbi (TCCR2A, WGM20); // Mode 1 / Phase Correct PWM cbi (TCCR2A, WGM21); cbi (TCCR2B, WGM22); }

//****************************************************************** // Timer2 Interrupt Service at 31372,550 KHz = 32uSec // this is the timebase REFCLOCK for the DDS generator // FOUT = (M (REFCLK)) / (2 exp 32) // runtime : 8 microseconds ( inclusive push and pop) ISR(TIMER2_OVF_vect) {

sbi(PORTD,7); // Test / set PORTD,7 high to observe timing with a oscope cbi(PORTD,4); phaccu=phaccu+tword_m; // soft DDS, phase accu with 32 bits icnt=phaccu >> 24; // use upper 8 bits for phase accu as frequency information // read value fron ROM sine table and send to PWM DAC OCR2A=pgm_read_byte_near(sine256 + icnt); //if (bitRead(icnt++,7) == 0){sbi(PORTD,7);} if(icnt >= 192) {cbi(PORTD,7);} if (icnt % 2 == 0) // verificando paridad { sbi (PORTD,4); }

// reset PORTD,7 }

Hola profy,

Me alegro que vayas progresando en tu proyecto.

Ánimo!

;)