Autor Tema: ATMEGA162 IRS timer1 y timer3 conflicto en puertos  (Leído 308 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado locodelafonola

  • PIC10
  • *
  • Mensajes: 42
ATMEGA162 IRS timer1 y timer3 conflicto en puertos
« en: 06 de Febrero de 2020, 20:10:53 »
Hola estoy con un problema que creo que mi logica para resolverlo esta muy equivocada
Por eso busco su consejo o sujerencias
Mi desorientacion es que las librerias por sepado funcionan a la perfeccion
El problema  se genera cuando las junto  la del timer1 funciona perfectamente pero la del timer3 tiene el comando pero no interviene sobre timer3
Es para reparar un equipo de iluminacion que dejo de funcionar el microprocesador (creo que por demaciado viejo)
Eleji el atmega162 porque es compatible pin a pin con el viejo micro y la placa solo hay que cambir o sacar algunas cosas minimas (cambio de cristal y condensadores y array de resistencias)
Aca pongo el codigo que crea conficto que es la parte que me tiene en la duda
Código: [Seleccionar]
       
            if (DmxRxField[8] != STROBOBuf)
            {
    if (DmxRxField[8] <= 11)
{
ETIMSK &= ~(1<<OCIE3B); //disable firing ISR
}
    else if (DmxRxField[8] < 211 )
    {
uint16_t TimeBuf;
TimeBuf= pgm_read_word(&FreqTableA[DmxRxField[8] -11]);
if (TCNT3 >= (TimeBuf -310)) TCNT3= TimeBuf -310;
cli();
OCR3A= TimeBuf; //set quench time
OCR3B= TimeBuf -300; //set time to start firing
sei();
if (!(ETIMSK &(1<<OCIE3B)))
{
ETIFR   = (1<<OCF3B);
ETIMSK |= (1<<OCIE3B); //enable firing ISR
TCNT3= 0;
}
   }
     else
   {
if (STROBOBuf < 211)
{
ETIMSK &= ~(1<<OCIE3B); //disable firing ISR
TCNT3  = 0;
    PORTB |= (1<<PB0);// //enable strobe
    PORTB |= (1<<PB1);//
                    PORTB |= (1<<PB2);//
OCR3A  = 300; //set on time
}
}
STROBOBuf= DmxRxField[8];
}

    }

 };
}     

// *************** ISRs ****************
ISR (TIMER1_OVF_vect)
{



               
 
 
  unsigned int DimmMaster;
static unsigned char pwm_counter = 0;
pwm_counter++;



if(pwm_counter == 255)
{
pwm_counter = 0;

}           


            DimmMaster=DmxRxField[4];
            DimmMaster=DimmMaster*DmxRxField[7];

            DimmMaster=(DimmMaster>>8);
            if ((unsigned char)(DimmMaster)>pwm_counter) //ROJO  //RED 
            {
                PORTB &= ~(1<<PB0);                //LED OFF (APAGADO)
            }else{
                PORTB |= (1<<PB0);                //LED ON  (ENCENDIDO)       
            }
           

            DimmMaster=DmxRxField[5];
            DimmMaster=DimmMaster*DmxRxField[7];

            DimmMaster=(DimmMaster>>8);
            if ((unsigned char)(DimmMaster)>pwm_counter)  //VERDE  //GREEN     
            {
                PORTB &= ~(1<<PB1);                //LED OFF (APAGADO)
            }else{
                PORTB |= (1<<PB1);                //LED ON  (ENCENDIDO)       
            }


            DimmMaster=DmxRxField[6];
            DimmMaster=DimmMaster*DmxRxField[7];

            DimmMaster=(DimmMaster>>8);

            if ((unsigned char)(DimmMaster)>pwm_counter) //AZUL  //BLUE 
            {
                PORTB &= ~(1<<PB2);                //LED OFF (APAGADO)
            }else{
                PORTB |= (1<<PB2);                //LED ON  (ENCENDIDO)       
            }
 
 






}
ISR (TIMER3_COMPA_vect)
{

//disable strobe


PORTB &= ~(1<<PB0);
PORTB &= ~(1<<PB1);
PORTB &= ~(1<<PB2);

}

ISR (TIMER3_COMPB_vect)
{

//enable strobe


PORTB |= (1<<PB0);
PORTB |= (1<<PB1);
PORTB |= (1<<PB2);

}
He puesto solo tres salidas de los led para no tener tanto codigo pero en realidad el eqipo lleva 18 salidas led
Para orientar un poco la parte de comando funciona perfectamente
El PWM tambien funciona como debe ser tambien lo hace el DIMMER-MASTER
El comando de la funcion STROBO tambien es correcta porque me lo indca la señalizacion de la USART pero la interupcion o apagado de los led no se produce
Si tienen alguna duda o pregunta respondere gratamente
Desde a muchas gracias a todos los que se interecen en ayudar
yo solo se que ...nose nada

Desconectado locodelafonola

  • PIC10
  • *
  • Mensajes: 42
Re:ATMEGA162 IRS timer1 y timer3 conflicto en puertos
« Respuesta #1 en: 07 de Febrero de 2020, 21:03:06 »
hola por aca de nuevo
Vieendo como resolver mi problema me di cuenta que estaba equivocado en mi planteamiento
Cuando se tiene varias salidas led pence que el STROBO intrumpia el puerto de salida del led
Y estaba equivocado incluso usando registro de desplazamiento como el HC595
El strobo que funciona bien sin afectar las funciones adicionales hace la interupcion en la IRS del timer elegido
Hace tiempo con el amigo KILLERJC integrante del foro
Amablemente intervino en el tema http://www.todopic.com.ar/foros/index.php?topic=44880.0
Donde el codigo que funciona perfectamente usa este sistema
Alli se usa timer0 para el PWM (9 salidas led) y timer1 para el strobo
En ese codigo usa unas banderas (Flags) para la interupcion del pwm y realizar el apagado de los led segun la frecuencia del strobo
Es muy similar al desarrollo que compile pero por ser muy novato en ASM no lo desifro bien
Donde me confunde las condicionales de las banderas para usarlo en C las condicionales que conozco y que uso son esta por ejeplo
Código: [Seleccionar]
(Flags &(1<<BLACK_OUT));
(Flags &= ~(1<<BLACK_OUT);
(Flags |= (1<<BLACK_OUT);
No se si habra otra condicional para las banderas porque son esas solas las que he usado
Y por aca entiendo yo que trabaja la banderan en el PWM ASM
Código: [Seleccionar]
     pwm:
in      SREGbuf, SREG
push tempL

  sbrc Flags, BLACK_OUT ;en blanco por estroboscopico? ;blanked by strobe?
rjmp pwm_bo_exit

Este seria el comando del strobo muy parecido al que yo coloque en C
Código: [Seleccionar]
strobe:
in      SREGbuf, SREG
push tempL
push tempH

sbrs Flags, BLACK_OUT
rjmp str_blank
cbr Flags, (1<<BLACK_OUT) ;habilitar pwm ;enable pwm
ldi tempL,  low(FLASH_DURATION) ;tiempo de flash de carga;load flash time
ldi tempH, high(FLASH_DURATION)
rjmp str_exit
str_blank:
sbr Flags, (1<<BLACK_OUT)
lds tempL, StrobeFreqL
lds tempH, StrobeFreqH

str_exit:
out OCR1AH, tempH
out OCR1AL, tempL
pop tempH
pop tempL
out     SREG, SREGbuf
reti
Y aca la configuracion del timer1 para la funcion strobo
Código: [Seleccionar]
eval_strobe_freq:
lds tempL, DMX_FIELD ;get 1st DMX ch
cpi tempL, 246
brlo esf_1
ldi tempL, 245
    esf_1:
lds tempH, StrobeBuf
cp tempL, tempH
brne esf_2 ;only eval if changed
ret
esf_2:
sts StrobeBuf, tempL
cpi tempL, 30
brlo esf_no_strobe
cpi tempL, 245
brsh esf_sync

subi tempL, 30 ;0-200 allowed
ldi ZL, low(RATE*2) ;get freq from table
ldi ZH, high(RATE*2)
add ZL, tempL
adc ZH, null
add ZL, tempL
adc ZH, null
lpm tempL, Z+
lpm tempH, Z
cli
sts StrobeFreqL, tempL ;atomic store
sts StrobeFreqH, tempH

in tempL, TIMSK
sbr tempL, (1<<OCIE1A) ;Habilita irq ;enable irq
out TIMSK, tempL
in tempL, TIFR
sbr tempL, (1<<OCF1A) ;Habilita irq ;enable irq
out TIFR, tempL
reti


esf_no_strobe:
in tempL, TIMSK
cbr tempL, (1<<OCIE1A);ddesabilita irq ;disable irq
out TIMSK, tempL
cbr Flags, (1<<BLACK_OUT);habilitar pwm ;enable pwm
ret

esf_sync:
in tempL, TIMSK
sbrs tempL, OCIE1A ;sólo cuando es estroboscópico;only when strobing
ret
cli
sbr Flags, (1<<BLACK_OUT) ;en blanco!;blank!

lds ZH, StrobeFreqH
lds ZL, StrobeFreqL
out OCR1AH, ZH
out OCR1AL, ZL
sbiw ZH:ZL, 20
out TCNT1H, ZH
out TCNT1L, ZL
reti

Las tablas de las frecuencias de interupcion o apagado son parecidas
Código: [Seleccionar]
.org RATE
.dw 65532, 60407, 56368, 53017, 50170, 47708, 45546, 43626, 41904, 40345, 38925, 37623, 36423, 35311, 34277, 33311
.dw 32406, 31555, 30753, 29996, 29278, 28596, 27948, 27331, 26741, 26177, 25637, 25120, 24623, 24145, 23685, 23242
.dw 22814, 22402, 22003, 21617, 21244, 20882, 20531, 20191, 19861, 19540, 19228, 18924, 18629, 18341, 18061, 17788
.dw 17521, 17261, 17007, 16760, 16517, 16281, 16049, 15823, 15601, 15384, 15172, 14964, 14760, 14560, 14364, 14172
.dw 13983, 13798, 13617, 13438, 13263, 13091, 12922, 12756, 12593, 12432, 12274, 12119, 11966, 11815, 11667, 11522
.dw 11378, 11237, 11098, 10960, 10825, 10692, 10561, 10431, 10304, 10178, 10054, 9931,  9811,  9691,  9574,  9458
.dw 9343,  9230,  9119,  9008,  8899,  8792,  8686,  8581,  8477,  8375,  8273,  8173,  8074,  7976,  7880,  7784
.dw 7690,  7596,  7504,  7412,  7322,  7232,  7144,  7056,  6969,  6884,  6799,  6715,  6631,  6549,  6467,  6387
.dw 6307,  6227,  6149,  6071,  5994,  5918,  5843,  5768,  5694,  5620,  5548,  5475,  5404,  5333,  5263,  5193
.dw 5125,  5056,  4988,  4921,  4855,  4789,  4723,  4658,  4594,  4530,  4466,  4404,  4341,  4279,  4218,  4157
.dw 4097,  4037,  3978,  3919,  3860,  3802,  3744,  3687,  3631,  3574,  3518,  3463,  3408,  3353,  3299,  3245
.dw 3191,  3138,  3085,  3033,  2981,  2929,  2878,  2827,  2777,  2726,  2677,  2627,  2578,  2529,  2480,  2432
.dw 2384,  2337,  2289,  2242,  2196,  2149,  2103,  2057,  2012,  1967,  1922,  1877,  1833,  1789,  1745,  1701
.dw 1658,  1615,  1572,  1530,  1488,  1446,  1350,  1250,  1100,  1050,  1000,  950,   900,   850,   800,   750
.dw 700,   650,   600,   550,   500,   450,   400,   350,   300,   250,   200,   150

Esto  lo que he visto hasta ahora y que puedo usa o tomar de ejemplo que funciona de forma correcta
Se que se me estan escapndo mas puntos importantes de ese codigo
Pero como dije no entiendo el ASM correctamente por mas que intento
Si algien tiene o aporta alguna sugerencia es bienvenida y desde ya muchas gracias
yo solo se que ...nose nada