AVR Atmega8 USART y ADC y PWM

0

He creado 2 PWM diferentes usando el temporizador 1 y 2 en ATmega8, que se usa para controlar un motor lineal. Estoy usando un sensor de efecto Hall para detectar cambios en el voltaje cuando el motor lineal se mueve hacia la izquierda y hacia la derecha. Este cambio de voltaje se alimenta a un pin ADC en el ATmega8 para convertirlo en digital. Luego, básicamente, utilizo las funciones USART del ATmega8 para mostrar el voltaje que básicamente detecta el sensor de efecto Hall.

Estoy ejecutando el ADC en modo de ejecución libre con interrupciones para detectar continuamente un valor de efecto Hall.

El problema que tengo en este momento es que tan pronto como se llama a la interrupción para leer el valor de adc, tengo una función en la interrupción que involucra transmitir el valor de adc a la pantalla .......

Actualmente, lo que sucede es que tan pronto como lo hago, el PWM deja de funcionar, es como si el programa se atascara en la interrupción en un bucle infinito.

Sin embargo, si elimino la función de transmisión en serie, el PWM comienza a funcionar de nuevo, lo que me confunde.

//TRANSMISSION FUNCTION

 void USARTWriteChar(uint8_t data) {            //Wait untill the transmitter is ready

    while(!(UCSRA & (1<<UDRE)))
      {
    //Do nothing
      }

     UDR=data;
  }

//Main function containing PWM

  while (1)
   {
    OCR1A = Push1;                                  // Output compare register A Time 1  
    OCR1B = 0;
    _delay_ms(400);                                 // set on time A    



    OCR1A = 0;                                      
    OCR1B = 0; 
    _delay_ms(400);                                    // set dead time B

}

 //Interrupt function   

  ISR(ADC_vect) {
   read = ADCH;
   USARTWriteChar(read);    
 }

Estoy ejecutando el ATmega8 a una frecuencia de reloj de 8Mhz con BAUD de 9600.

Sin embargo, cuando quito USARTWriteChar (lectura); (aún manteniendo rad = ADCH) desde el ISR, el PWM funciona, lo que significa que la interrupción del ADC no está causando problemas, pero el USART es por algunas razones.

    
pregunta subz

1 respuesta

2

Nunca escriba o lea desde un UART desde un controlador de interrupciones. Asumo que sucede lo siguiente:

  • La interrupción se produce porque hay un nuevo valor disponible
  • Empiezas a escribir en la UART
  • Se produce una nueva interrupción
  • La escritura en el UART está terminada, la interrupción ya se ha activado y nuevamente estás en la rutina de interrupción.
  • Por lo tanto, tu bucle principal morirá de hambre

Lo que debes hacer:

  • Si su Atmega tiene un PWM de hardware, úselo para generar la señal PWM
  • En su rutina de interrupción, solo establezca un indicador de que hay nuevos datos disponibles (almacenarlos en alguna variable) y escriba esos datos solo en la rutina principal en su UART
respondido por el Tom L.

Lea otras preguntas en las etiquetas