Arduino UNO Timer problema

0

Parece que estoy enfrentando un problema extraño aquí. Primera vez trabajando con temporizadores AVR. Básicamente, lo que estoy tratando de lograr es configurar timer2 (con preescala val @ 1024) y usar el modo CTC (con val 78) para obtener tics de temporizador de 5 ms.

Cada 5 ms, solo muestro el framebuffer actual en una fila de LED y cada 1 seg (usando un contador para mantener un registro de 200 tics del temporizador) actualiza el búfer del marco.

mi código es

void setup()
{
  pinMode(dataPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(latchPin, OUTPUT);
  pinMode(row1, OUTPUT); pinMode(row2, OUTPUT); pinMode(row3, OUTPUT); pinMode(row4, OUTPUT); pinMode(row5, OUTPUT); 

  digitalWrite(row1,LOW); digitalWrite(row2,LOW); digitalWrite(row3,LOW); digitalWrite(row4,LOW); digitalWrite(row5,LOW);
  digitalWrite(latchPin,HIGH);
  digitalWrite(clockPin,LOW);

  Serial.begin(9600);
  Serial.println("Program initialized ...");

  //create string map + display the initial frame buffer
  //create_string_map("hello!");
  //generate the first frame_buffer
  Serial.println("1");
  //create_frame_buffer(0);
  Serial.println("2");
  //update_frame_buffer();
  Serial.println("3");

  //disable global interrupts
  cli();
  //init timer2
  TCCR2A = 0;
  TCCR2B = 0;
  //set ctc mode
  TCCR2B |= (1 << WGM12);
  //set CTC value
  OCR2A = 78;
  //set prescaler @ 1024
  TCCR2B |= (1<<CS10);
  TCCR2B |= (1<<CS12);
  //enable timer
  TIMSK2 |= (1<<TOIE2);
  sei();
}


//install the ISR
ISR(TIMER2_OVF_vect)
{
  timer_counter++;
  //disable timer
  TIMSK2 |= (0<<TOIE2);
  if(timer_counter==200) //200 = 1 sec
  {
    //reset timer_counter
    timer_counter=0;
    //update frame
    /*Serial.println("Frame update event ...");
    string_map_col_counter++;
    if(string_map_col_counter>=30){string_map_col_counter=0;}
    create_frame_buffer(string_map_col_counter);
    update_frame_buffer();
    display_and_hold_frame();*/
    Serial.println("1 second tick");
  }
  else
  {
    //display_and_hold_frame();
    Serial.println("timer tick"); 
  }
  //enable timer
  TIMSK2 |= (1<<TOIE2);
}

Como ves, he comentado la mayoría de las cosas porque estoy tratando de solucionar el problema. cuando abro el puerto serie, la única salida que obtengo es "prog" y simplemente se detiene allí.

Lo único en lo que puedo pensar es que el error del temporizador está configurado con tics demasiado rápido, por lo que el serial.println nunca tiene tiempo para terminar. pero como puede ver, comienzo el temporizador DESPUÉS de todas estas declaraciones de impresión en serie.

también cuando presiono el botón de reinicio en la placa, ¿se borran todas las configuraciones del temporizador a bordo o se recuerdan las reinicializaciones de b / w? Cualquier idea de lo que podría estar causando esto.

    
pregunta Ankit

2 respuestas

1

A 9600 bps, se tarda más de 1 ms en transmitir un carácter, por lo que obtener solo "Prog" en 5 ms suena correcto. Intente aumentar la velocidad del puerto en serie y / o enviar mensajes más cortos (por ejemplo, solo un carácter por cada temporizador).

No sé mucho sobre cómo funciona internamente el módulo Arduino Serial, pero supongo que simplemente estás sobrecargando su búfer de transmisión con todas las cosas que estás imprimiendo, y es simplemente "renunciar".

    
respondido por el Dave Tweed
0

Sospecho que puede deberse a que no pareces borrar la interrupción en tu ISR, por lo que el bucle principal se ejecuta hasta la primera interrupción y luego permanece interrumpiendo para que no ocurra nada más.
Además, no es la mejor práctica utilizar la función Serial.println en el ISR (en caso de que se bloquee), establecería una bandera y la utilizaría el código principal. En general, usted desea que sus interrupciones sean lo más pequeñas / rápidas posibles.

Acabo de notar que configuró el temporizador después de las llamadas a la salida en serie, por lo que, a menos que sea una función de no bloqueo con un búfer, lo anterior no debería detenerlo, al menos dar salida a las primeras líneas. Asegúrese de que su interrupción esté despejada de todos modos (si no se borra automáticamente)
Trataré de encontrar el código para la biblioteca Serial y ver qué está pasando. ¿Hay algo más en tu código que pueda marcar la diferencia? Si es así, agrégalo a la pregunta.
EDITAR - de acuerdo con esta página , ya que v1.0 la escritura en serie no es bloqueable con (I pienso Vi en otro lugar) un búfer de 64 bytes, por lo que el problema anterior puede ser el problema, después de todo.
EDIT 2: eché un vistazo a (lo que creo que es) la fuente disponible here , y el serial del hardware tiene un búfer de 64 bytes (o 16 bytes para ciertas variantes, parece), por lo que se llena con cualquier cosa hasta 64 bytes en una hora no se bloqueará (consulte la función HardwareSerial::write ).

    

Lea otras preguntas en las etiquetas