10 votos

Necesita ayuda para entender AVR ATMEGA / ATTINY temporizador de espejo de salida

Estoy tratando de usar el Timer1 del microcontrolador AVR de Atmel, ya sea en el AtMega328 como se utiliza en el Arduino, o el ATTiny85, a la salida dos señales de reloj que son imágenes especulares el uno del otro. La frecuencia estoy tratando de generar es una variable de 1 MHz a 2 MHz o más que son demasiado altos para ello el uso de código para cambiar los pines de salida a menos que quiero hacer casi nada en el controlador. Lo quiero para usar el temporizador de salida directamente sobre los pasadores. Estoy usando GCC toolchain de manera enunciativa más no limitativa por arduino bibliotecas o idioma.

Timer1 en el Atmega328 tiene dos pines asociados con ella y puedo conseguir dos idénticos 1MHz a 2 mhz señales de ellos. Aunque la hoja de datos parece decir yo puedo tener una forma de onda invertida, es confuso para mí. Yo también soy capaz de obtener dos señales que son diferentes ciclos de trabajo a 1 MHz, utilizando la configuración de PWM con el Timer1, pero ambas señales ir de alta, al mismo tiempo, el más corto va de baja antes. Esto no sirve para mi proyecto. Yo ni siquiera es necesario el ancho de pulso PWM variación, sólo tengo dos idénticos "reloj" del tipo de las señales de fase opuesta, eso es todo.

No estoy pidiendo a nadie a escribir el código para hacer esto, necesito que alguien me diga que el modo de la señal del temporizador debe darme una simple forma de onda invertida en uno de los dos pines asociados con el temporizador. Si es posible quiero evitar usando un dispositivo de inversión de circuito para una de las salidas, a menos de que es la única opción.

Si esto es posible en todos los en el ATTiny, que será aún mejor. El ATTiny también tiene 2 pines asociados con un temporizador, pero no estoy seguro de que tiene las mismas opciones que el ATMega.

Ya tengo un canal de 20 MHz de cristal y los condensadores conectados en la placa PCB y 20 MHz de reloj está funcionando de forma fiable en el ATMega328. En ATTiny85 PCB tengo una de 8 MHz de cristal y que también está trabajando de forma fiable.

Por favor, ayudar. Gracias.


ACTUALIZACIÓN: Hay algunos supuestos no válidos en las respuestas y comentarios hasta el momento, así que tal vez debería aclarar: tenga en cuenta que en mi post original me han dicho que yo estoy usando un 20 MHz, 8 MHz, y también que yo no necesita PWM.

El único modo de que le da un nivel suficientemente alto de la frecuencia de salida parece ser la CTC modo porque PWM modos no están trabajando para 2 MHz de salida. Es allí una manera de invertir, ya sea de Temporizador de 1 salida, o la salida B, en modo CTC?

Ahora he cambiado a un estándar de Arduino Uno (ATMega328, 16 MHz) en lugar de mi propio canal de 20 MHz de la junta para revisar mi código, y este es mi código para un buen constante de 2 MHz de reloj en modo CTC de los pines 9 y 10, el Temporizador 1 pines de salida:

#define tick 9
#define tock 10

void setup() {
  pinMode(tick, OUTPUT);  
  pinMode(tock, OUTPUT); 

  TCCR1A = _BV(COM1A0) | _BV(COM1B0) ;   // activate both output pins 
  TCCR1B = _BV(WGM12)| 1;                // set CTC mode, prescaler mode 1

  // various frustrating attempts to invert OC1B failed. What do I put here?

  OCR1A = 3;                             // set the counter max for 2 MHz

}

void loop() {
}

El osciloscopio trazas para ambos pines son idénticos y en sincronía, ¿cómo puedo conseguir cualquiera de las dos señales invertidas? El modo de invertir en la hoja de datos parece no hacer nada en modo CTC. Estoy leyendo la hoja de datos mal, o se me ven obligados a utilizar una frecuencia más baja y el modo PWM después de todo?

Para agregar una "recompensa" pregunta a mi consulta original:
Entonces, ¿qué cambios debo hacer para que mi código de arriba, a hacer es dar a la perfección señales invertidas en el pin 9 y 11 en la frecuencia más alta posible para un joven de 16 MHz, ya que es de 2 MHz o no?

Voy a seguir con un estándar de Arduino Uno, por ahora, así que no hay ningún error, el modo de ser introducidas por mi casero de la junta, y de modo que cualquier persona con un arduino puede probar mi código de arriba y confirmar que funciona como he mencionado, y no como lo que necesito!

10voto

JW. Puntos 145

Desde el ATtiny85 de Hoja de datos:

El modo de operación, es decir, el comportamiento del Temporizador/Contador y el Salida de Comparar los pines, se define por la combinación de la forma de Onda Modo de generación (WGM0[2:0]) y Comparar el modo de Salida (COM0x[1:0]) bits. Al Comparar la Salida de los bits de modo de no afectar la secuencia de conteo, mientras que la forma de Onda del modo de Generación de los tbis. El COM0x[1:0] bits controlar si la salida PWM generada debe ser invertida o no (invertida o no invertido PWM).

Tabla 11-5 muestra cómo establecer el Modo.

Mode   WGM  WGM  WGM  Timer/Counter Mode    TOP      Update of    TOV Flag
c0     02   01   00   of Operation                   OCRx at      Set on
==========================================================================
0      0    0    0    Normal                0xFF     Immediate    MAX(1)
1      0    0    1    PWM, Phase Correct    0xFF     TOP          BOTTOM
2      0    1    0    CTC                   OCRA     Immediate    MAX
3      0    1    1    Fast PWM              0xFF     BOTTOM       MAX
4      1    0    0    Reserved              –        –            –
5      1    0    1    PWM, Phase Correct    OCRA     TOP          BOTTOM
6      1    1    0    Reserved              –        –            –
7      1    1    1    Fast PWM              OCRA     BOTTOM       TOP

Quieres un modo PWM Rápido (por lo que sea el modo 3 o modo 7). Si se desea variar el ciclo de trabajo, y parece que usted, desea el modo 7 y variar el ciclo de trabajo mediante el establecimiento de OCRA.

Tabla 11-3 muestra cómo establecer la comparación del modo de salida para el modo PWM Rápido.

COM0A1/   COM0A0/
COM0B1    COM0B0     Description
===============================================================================
0         0          Normal port operation, OC0A/OC0B disconnected.
0         1          Reserved
1         0          Clear OC0A/OC0B on Compare Match, set OC0A/OC0B at BOTTOM
                     (non-inverting mode)
1         1          Set OC0A/OC0B on Compare Match, clear OC0A/OC0B at BOTTOM
                     (inverting mode)

Es decir, puede establecer la OC0A de salida para ir de baja cuando el valor del Temporizador == OCR0A y alta cuando el valor del Temporizador == 0x00 mediante el establecimiento de COM0A1:COM0A0 = 0b10. O viceversa mediante el establecimiento de COM0A1:COM0A0 = 0b11. Y de la misma manera para OC0B, OCR0B, COM0B0, COM0B1.

La frecuencia PWM está determinado por la e/S de Reloj (8MHz suena como para los de usted) y el temporizador predivisor de configuración. Y la ecuación es dada como f_clk_IO / (N * 256) para el modo PWM Rápido.

Así que usted puede utilizar OC0A "normal" de la polaridad y la OC0B para "invertida" de la polaridad mediante el establecimiento de OCR0A y OCR0B el mismo valor y la configuración de COM0A1:COM0A0 = 0b10 y COM0B1:COM0B0 a 0b11.

ACTUALIZACIÓN

Dado que usted quiere alternar la salida tan rápido como sea posible y usted está utilizando la Mega328 operativo a 16MHz, la CTC modo de operación le permitirá obtener una frecuencia de conmutación de:

f_OCnA = f_clk_IO / (2 * N * [1 + OCRnA) = 16e6 / (2 * 1 * [1 + 1]) = 4MHz

El modo PWM Rápido te permitirá cambiar el pin:

f_OCnxPWM = f_clk_IO / (N * [1 + TOP]) = 16e6 / (1 * [1 + 1]) = 8MHz

Así que todavía piensan que usted quiere que el modo PWM Rápido. Específicamente el Modo 3 con OCR0A = OCR0B = 0x80 para el 50% de ciclo de trabajo. Y establecer COM0A bits a 0 x 3 y COM0B bits a 0 x 2 para hacer de las dos formas de onda en OC0A y OC0B inversiones de uno a otro.

Actualización #2 Más de la Mega328 Probar este código de Arduino:

#define tick 9
#define tock 10

void setup(){

  pinMode(tick, OUTPUT);  
  pinMode(tock, OUTPUT); 

  // Setup Waveform Generation Mode 15
  // OC1A Compare Output Mode = inverting mode
  // OC1B Compare Output Mode = non-inverting mode
  // Timer Prescaler = 1
  // TOP = OCR1A = 1

  //COM1A[1:0] = 0b11, COM1B[1:0] = 0b10, WGM1[1:0] = 0b11
  TCCR1A = _BV(COM1A1) | _BV(COM1A0) | _BV(COM1B1) | _BV(WGM11) | _BV(WGM10);

  //WGM1[3:2] = 0b11, CS1[2:0] = 0b001
  TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10);

  OCR1A = 0x0001;
  OCR1B = 0x0001;
}

void loop(){

}

1voto

matt Puntos 21

ATtinyX5 familia ha PLL en el interior, el uso de big boy.

Yo uso interno de PLL para poder reloj de CPU demasiado y han 16Mhz sin XTAL. Esto es precioso puesto que usted acaba de 5 pines. (No cuento pin reset). También un PLL ed PWM (OCR1B) se ejecuta con un XTAL de pines es opcional cortesía de salida. Usted sólo necesita ajustar los fusibles para 16Mhz Xtalless ATtiny... O simplemente dejar que la CPU ejecute en 8Mhz pero PWM con 64Mhz reloj sin necesidad de cambiar los fusibles..

Usted puede tener hasta 64 Mhz reloj de PWM (pero 1 bits de resolución). O 125Khz @ 8 bits de resolución. Usted puede reducir PWM resolución y aumentar la velocidad a través de la disminución OCR1C registro.

Para 1 Mhz usted necesita para establecer OCR1C a 63. Para 2 Mhz usted necesita para establecer OCR1C a 31. Para 4 Mhz que usted necesita para establecer OCR1C a 15. ...

Sólo habilitar PLL con este código:

PLLCSR |= (1 << PLLE);           //Start PLL
while( !(PLLCSR & (1<<PLOCK)) ); //Wait for PLL lock
//PLLCSR |= (1<<LSM );           //Low Speed PLL that clocks 32Mhz, not 64Mhz
PLLCSR |= (1 << PCKE);           //Enable PLL

Ahora usted tiene 64 Mhz en "OCR1B0/OCR1A0" PWMs.

También, usted puede ajustar OCR1[A/B]0 & XOCR1[A/B]0 para el espejo de salida.

if(0){ //Synch mode
     //OCR1A & XOCR1A enable for Synch operation but not allow odd PWM values!
     TCCR1 |= (1 << PWM1A) | (0 << COM1A1) | (1 << COM1A0); 
     //Also ATtinyX5 has "Dead Time Generator", use it ;)
     DTPS1 = 3;   //8x Prescaler for dead time generator (maximum)
     DT1A = 0xff; //Clk dead on both channels (maximum)
     }
   else
     TCCR1 |= (1 << PWM1A) | (1 << COM1A1) | (0 << COM1A0);  //ONLY OCR1A enabled

Usted necesita saber, Tiempo Muerto de los generadores de comer PWM outout si establece OCR1A=1. Usted necesita mayor que los valores de tiempo muerto.

Saludos,

Erdem

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X