Loading...
Pages: [1]   Go Down
Author Topic: Interrupciones vs delay(),while(), for(),etc  (Read 252 times)
0 Members and 1 Guest are viewing this topic.
Chile
Offline Offline
Newbie
*
Karma: 0
Posts: 5
Arduino Special Projects
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Estimada comunidad estoy realizando con harto entusiasmo un proyecto para poder emitir señales PSK31 por radio ya que hay muchos programas en Windows y Android para decodificar. He googleado por un montón de partes y encontre uno que me pareció excelente porque no requiere de mucho hardware adicional, solo una adaptación de impedancias del Arduino Diecimilia al micrófono de una radio.
Lo principal es que el programa funciona con PWM con interrupciones propias del ATMega168 para poder mantener la cronometría de cada bit.
El problema con el que me topo es que genera una señal continua de una palabra (definida por mi), pero quiero hacer que se genere la cantidad de veces que yo desee. Esto es porque no domino bien el tema de las interrupciones vs los distintos comandos del código Arduino como delay(), while(),etc. Lo que quiereo conseguir es mantener un control en el loop() para que no sea continua sino algo como (int i=0; i <= 10; i++). Alguien sabe como poder controlar sin desestabilizar las interrupciones?
Desde ya agradecido por cualquier ayuda y por supuesto una vez que resuelva estos inconvenientes, mantendré actualizado el proyecto. smiley

Code:
#include "avr/pgmspace.h"

// Tabla de 256 valores para construir una onda senoidal almacenada en memoriaflash
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

};
// Palabra "MAFARI" codificada en Varicode
PROGMEM prog_uchar msg[] = {1,0,1,1,1,0,1,1, 0,0, 1,1,1,1,1,0,1, 0,0, 1,1,0,1,1,0,1,1, 0,0, 1,1,1,1,1,0,1, 0,0, 1,0,1,0,1,1,1,1, 0,0, 1,1,1,1,1,1,1, 0,0, 0,0, 1, 0,0};  //Mauricio
byte ptr = 0;

#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=31335.6;      // medido

// variables usadas dentro del servicio de interrupcion declaradas como volatile
volatile byte icnt;              // variable dentro de interrupcion
volatile byte icnt1;             // variable dentro de interrupcion
volatile byte c4ms;              // countador incrementado todo 4ms
volatile unsigned long phaccu;   // Acumulador de fase
volatile unsigned long tword_m;  // dds tuning word m
volatile byte offset;

void setup()
{
  pinMode(11, OUTPUT);     // pin 11= Salida PWM   / frequencia de salida
  Setup_timer2();
  // disabilita interrupciones para evitar distorsion por temporizacion
  cbi (TIMSK0,TOIE0);              // desabilita Timer0 !!! delay() no esta disponible
  sbi (TIMSK2,TOIE2);              // habilita interrupcione Timer2

  dfreq=1000.0;                    // Frequencia Incial de Tx = 1000 Hz
  tword_m=pow(2,32)*dfreq/refclk;  // calulate DDS new tuning word
}


void loop()
{
//Es aqui donde quiero poner un control para emitir mi mensaje la cant. de veces que yo desee y no en forma continua.
  byte sig; // Byte para asignar el valor del bit de la letra que se esta enviando
  if (c4ms >= 8) {      // timer / wait for 32ms = 31.25 baud
      c4ms=0;
      sig = pgm_read_byte_near(msg + ptr); //Aqui se rescata el bit de la letra que esta enviando
      ptr++;
      if (ptr > 62)  ptr=0;
      if (sig == 0) { //Aqui se analiza si el valor del bit es cero o no
          offset = offset + 128; //Si el valor del bit es cero entonces cambia de fase para producir el efecto PSK
    }
  }
}
//******************************************************************
// 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
  TCCR2B = 0<<CS22 | 0<<CS21 | 1<<CS20;

// Timer2 PWM Mode set to Phase Correct PWM
  TCCR2A = 1<<COM2A1 | 0<<COM2A0;

    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
  icnt = icnt + offset; 
  OCR2A=pgm_read_byte_near(sine256 + icnt); // read value from ROM sine table and send to PWM DAC   

  if(icnt1++ == 125) {  // increment variable c4ms all 4 milliseconds (125)
    c4ms++;
    icnt1=0;
   }
}
Logged

Aficionado a la automatizacion con Arduino

Pages: [1]   Go Up
Print
 
Jump to: