Autor Tema: Invertir pwm en Atmega 8515 asembler  (Leído 34837 veces)

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

Desconectado locodelafonola

  • PIC10
  • *
  • Mensajes: 43
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #30 en: 25 de Agosto de 2015, 17:07:11 »
Bueno para solucionar todo esto..

locodelafonola

Explicame exactamente que necesitas que haga el programa. El efecto de fading esta. Ahora hay que unirlo al DMX, por eso necesito que me expliques como queres hacerlo.

Nombreame uno por uno los parametros que llegan, ejemplo:

DmxRxField[0] -> Modo, de 0 a 120 fijo, de 121 a 255 fading
DmxRxField[1] -> Color R
DmxRxField[2] -> Color G
......

Se que son 512 pero no creo que uses 512 para esto al menos por ahora.
bueno alli me gusta la cosa
DmxRxField[0] , DmxRxField[1],DmxRxField[2], dejalos como estan ., ( DmxRxField[0] ., es elcanal rojo y ya lo cambiaste).,  lo qu hay que hacer es habilitar uno nuevo (o dos) ejemplo : DmxRxField[3 ] -> Modo, de 0 a 120 fijo, de 121 a 255 fading  y si queres DmxRxField[4 ]-> raibonw_fader  
ya con esa simple sentecia tenes el comando del bufer de recepcion sin que declares mas nada (una vez que se finaliza y todo funciona como se debe ., se define en la libreria .H cuantos se usan y listo) como te explique mas arriba
y algo para clarar., estas fuciones que quiero aprender ., son la que tiene los "tachos" o lampara par 64 o 56 , de led comerciales 
si te sirve aca te subo lo que que me funciona a mi (bastante probado ) y funciona joya
Código: [Seleccionar]
int PWM_timer;  // inicializar el timer PWM
char strobo = FALSE;  // valor de strobo
unsigned int strobo_timer=0; // Contador Strobo igual a cero



    while(1) // bucle principal (LOOP)
    {

        get_dips(); // Comprobar dip-switch y descargar la dirección DMX


//************************************* PWM leds *********************************//
for (PWM_timer=0; PWM_timer<255 ; PWM_timer++)  // Loop timer general en un ciclo de llenado
{

if(DmxRxField[4]>10){ // Si el canal de luz estroboscópica es menor a  10 es siempre mayor que los LED ,el estroboscópico está apagado,
if( strobo_timer>(unsigned int)((255-DmxRxField[4])*16)){// Dmx CH4 igual a 11, es el tiempo máximo , o igual a 255 es el Tiempo min
strobo_timer=0;// Restablecer el temporizador
if(strobo){ strobo=FALSE;}else{ strobo=TRUE;} // Cambiar autorización para ILUMINACIÓN
}else{
strobo_timer+=1;
}
    }else{
strobo=TRUE; // la Stroboscopica está apagada,
}

if ( ((unsigned int)((DmxRxField[0]*DmxRxField[3])/255)>PWM_timer) && strobo ) //ROJO
{
PORTB &= ~(1<<PB2); //LED OFF
}else{
PORTB |= (1<<PB2); //LED ON
}

if ( ((unsigned int)((DmxRxField[1]*DmxRxField[3])/255)>PWM_timer) && strobo ) //VERDE
{
PORTB &= ~(1<<PB1); //LED OFF
}else{
PORTB |= (1<<PB1); //LED ON
}

   if ( ((unsigned int)((DmxRxField[2]*DmxRxField[3])/255)>PWM_timer) && strobo ) //AZUL
{
PORTB &= ~(1<<PB0); //LED OFF
}else{
PORTB |= (1<<PB0); //LED ON
    }
Tiene  los tras canales RGB , mas el DIMMERMASTER ., mas el STROBO  ., esto a mi me funciona correctamente 
« Última modificación: 25 de Agosto de 2015, 17:31:10 por locodelafonola »
yo solo se que ...nose nada

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #31 en: 25 de Agosto de 2015, 17:26:38 »
Listo los datos son:

DmxRxField[0] -> R
DmxRxField[1] -> G
DmxRxField[2] -> B
DmxRxField[3] -> Modo -> 0..63 Fijo, 64..127 Fading_Color_Fijo , 128..191 Fading Automatico, 192..255 Rainbow_Fading
DmxRxField[4] -> Velocidad

Ahora solo me queda una cosa por hacer. Pasar la funcion que es "manual" como le decis a una que use los comandos esos.

Entonces los modos van a quedar:

Fijo ->
En este modo se usan los valores RGB del DMX, ya que es el unico que realmente cumple con esa funcion

Fading Color fijo ->
En este modo se va a producir el fading pero solo del color RGB, el cual va a ser un estilo "pulsante", Unicamente en el color que se le indique desde la consola DMX. Usa el valor de Velocidad

Fading Automatico ->
En este modo va a ir alternando los colores pero no va a hacer caso a los valores RGB ya que no tiene sentido aplicarlo. Si defino solo un color de comienzo luego va a ser modificado por el mismo "fading" a no ser que quieras que sea un color unico y que se produsca el fading solo de ese color y no que vaya pasando de colores

Rainbow_Fading ->
Una extension al Fading Automatico que en ves de navegar por los colores comunes Solo R, solo G y solo B, hace uso de varios colores. Tambien hace caso a Velocidad. Pero no a RGB


En fin creo que esto es lo que buscas

La velocidad se va a controlar desde el DMX por lo cual se le quita el soporte a los DIPs sobre eso. Y PINE1/PINE2 no deberian influir en eso.

Desconectado locodelafonola

  • PIC10
  • *
  • Mensajes: 43
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #32 en: 25 de Agosto de 2015, 17:47:47 »
Listo los datos son:

DmxRxField[0] -> R
DmxRxField[1] -> G
DmxRxField[2] -> B
DmxRxField[3] -> Modo -> 0..63 Fijo, 64..127 Fading_Color_Fijo , 128..191 Fading Automatico, 192..255 Rainbow_Fading
DmxRxField[4] -> Velocidad

Ahora solo me queda una cosa por hacer. Pasar la funcion que es "manual" como le decis a una que use los comandos esos.

Entonces los modos van a quedar:

Fijo ->
En este modo se usan los valores RGB del DMX, ya que es el unico que realmente cumple con esa funcion

Fading Color fijo ->
En este modo se va a producir el fading pero solo del color RGB, el cual va a ser un estilo "pulsante", Unicamente en el color que se le indique desde la consola DMX. Usa el valor de Velocidad

Fading Automatico ->
En este modo va a ir alternando los colores pero no va a hacer caso a los valores RGB ya que no tiene sentido aplicarlo. Si defino solo un color de comienzo luego va a ser modificado por el mismo "fading" a no ser que quieras que sea un color unico y que se produsca el fading solo de ese color y no que vaya pasando de colores

Rainbow_Fading ->
Una extension al Fading Automatico que en ves de navegar por los colores comunes Solo R, solo G y solo B, hace uso de varios colores. Tambien hace caso a Velocidad. Pero no a RGB


En fin creo que esto es lo que buscas

La velocidad se va a controlar desde el DMX por lo cual se le quita el soporte a los DIPs sobre eso. Y PINE1/PINE2 no deberian influir en eso.
!!!!! grande maestro ¡¡¡¡ listo asi es corecto ., fijate en lo que subi en el mesaje anterior ., esas funciones no usan nada de desarrollo.,  todo lo que es .,  es lo que ves escrito  alli ., y funcionan dentro del Loop de WHILE ., no hay mas nada que eso para que te des idea ., pero como yo no se como se implementa eso del ASM sugeri lode las llaves ., pero esta bien asi eso es lo que busco GRACIAS MIL !!!!! 
« Última modificación: 25 de Agosto de 2015, 17:51:57 por locodelafonola »
yo solo se que ...nose nada

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #33 en: 26 de Agosto de 2015, 04:00:43 »
Código: C
  1. #define F_CPU 8000000
  2. #include<util\delay.h>
  3.  
  4. #include<stdio.h>
  5. #include<stdlib.h>
  6. #include"fading_raibow.h"
  7. #include <avr/interrupt.h>
  8. #include <avr/wdt.h>
  9.  
  10.  
  11. enum {FIXED,FADING_FIX,FADING,RAINBOW_FADING} mode;
  12.  
  13. #define OV_COUNT        14              // 161 , 7  = 0.25ms
  14. #define OV_SIZE         161             // comenzando Contador inicial
  15.  
  16. // Dato proveniente de la consola DMX
  17.  
  18. #define DMX_R                   DmxRxField[1]   //Canal R              
  19. #define DMX_G                   DmxRxField[2]   //Canal G
  20. #define DMX_B                   DmxRxField[3]   //Canal B
  21. #define DMX_Modo                DmxRxField[4]   //Seleccion de Modo
  22. #define DMX_Velocidad   DmxRxField[5]   //Seleccion de Velocidad
  23.  
  24. // Para simplificar los datos del array de colores que estoy usando.
  25. // ArrayColores contiene los valores RGB del momento
  26.  
  27. #define Rojo                    ArrayColores[0]
  28. #define Verde                   ArrayColores[1]
  29. #define Azul                    ArrayColores[2]
  30.  
  31. //*********************************//
  32.  
  33. volatile uint16_t        DmxAddress;                            // Dirección inicial
  34.  
  35. uint8_t V_out,R_out,A_out;                                              // Valores que se comparan con el PWM
  36. uint8_t V_aux,R_aux,A_aux;                                              // Valores que se cambia para actualizar el PWM
  37. uint8_t PWM_timer=0;
  38. uint8_t estado=0,estador=0;                                     // Estado de los fading
  39.  
  40. const uint8_t arraydimmer[256]={
  41.                  0,     0,    1,    1,    1,    1,    1,    2,
  42.                  2,     2,    2,    3,    3,    3,    4,    4,
  43.                  4,     5,    5,    5,    6,    6,    7,    7,
  44.                  8,     8,    9,    9,   10,   10,   11,   11,
  45.                  12,   12,   13,   13,   14,   14,   15,   15,
  46.                  16,   16,   17,   17,   18,   18,   19,   19,
  47.                  20,   20,   21,   21,   22,   22,   23,   23,
  48.                  24,   24,   25,   25,   26,   27,   28,   29,
  49.                  30,   30,   31,   32,   33,   34,   35,   36,
  50.                  36,   37,   38,   39,   40,   41,   42,   43,
  51.                  43,   44,   45,   46,   47,   48,   49,   50,
  52.                  51,   52,   52,   53,   54,   55,   56,   57,
  53.                  58,   59,   60,   61,   62,   63,   64,   65,
  54.                  66,   67,   68,   69,   70,   71,   72,   73,
  55.                  74,   75,   76,   77,   78,   79,   80,   81,
  56.                  82,   83,   84,   85,   86,   88,   89,   90,
  57.                  91,   92,   93,   94,   95,   96,   97,   98,
  58.                  99,  100,  102,  103,  104,  105,  106,  107,
  59.                  108, 109,  110,  112,  113,  114,  115,  116,
  60.                  117, 119,  120,  121,  122,  123,  124,  126,
  61.                  127, 128,  129,  130,  132,  133,  134,  135,
  62.                  136, 138,  139,  140,  141,  142,  144,  145,
  63.                  146, 147,  149,  150,  151,  152,  154,  155,
  64.                  156, 158,  159,  160,  161,  162,  164,  165,
  65.                  167, 168,  169,  171,  172,  173,  174,  176,
  66.                  177, 178,  180,  181,  182,  184,  185,  187,
  67.                  188, 189,  191,  192,  193,  195,  196,  197,
  68.                  199, 200,  202,  203,  204,  206,  207,  208,
  69.                  210, 211,  213,  214,  216,  217,  218,  220,
  70.                  221, 223,  224,  226,  227,  228,  230,  231,
  71.                  233, 234,  236,  237,  239,  240,  242,  243,
  72.                  245, 246,  248,  249,  251,  252,  254,  255
  73. };
  74.  
  75. uint8_t ArrayColores[3]={255,0,0};                      // Rojo,Verde,Azul
  76.  
  77. const uint8_t ArrayColorFading[]={                      // Indice y valor a modificar   {1,2,3} y {-1,-2,-3}
  78.                  1,     //      Rojo    ->      Amarillo
  79.                  0,     //      Amarilo ->      Verde
  80.                  2,     //      Verde   ->      Cyan
  81.                  1,     //      Cyan    ->      Azul
  82.                  0,     //      Azul    ->      Magenta
  83.                  2      //      Magenta ->      Rojo
  84. };
  85.  
  86. const uint8_t ArrayColorFadingRainbow[]={                       // Indice y valor a modificar   {Resta,Suma}
  87.                 {0,1},  //      Rojo-   ->      Verde+
  88.                 {1,2},  //      Verde-  ->      Azul+
  89.                 {2,0}   //      Azul-   ->      Rojo+
  90. };
  91.  
  92. //************* Inicialización pines / port *****************//
  93. void init_pinouts(){
  94.     #ifdef USE_DIP
  95.  
  96.     DDRC  = 0;                  // establecer DIPs
  97.     PORTC  = 0xFF;
  98.     DDRE  &= ~((1<<PE2)|(1<<PE1));
  99.     PORTE |=   (1<<PE2)|(1<<PE1);
  100.         #endif
  101.  
  102.  
  103.         DDRB |= (1<<PB0) | (1<<PB1) | (1<<PB2); // Salida pin LED
  104.         PORTB = 0;
  105.         DDRE  |= (1<<PE0);      //LED2 azul indicador
  106.     PORTE = 0;
  107.  
  108. }
  109.  
  110. // ***** inicializacion del timer****//
  111.  
  112. void init_timer(){
  113.                 TCCR0|= (1<<CS02) ;     // Precontador 256
  114.                 TIMSK|= (1<<TOIE0);     // desbordamientos de la interrupción
  115.                 TCNT0= OV_SIZE;
  116.         }
  117.  
  118.  // ************* obtener DMX dirección de inicio **************
  119.  
  120. void get_dips(void)
  121. {
  122. #ifdef USE_DIP
  123. uint16_t Temp;
  124.  
  125. if (!(PINE &(1<<PE1))){ // Modo FADING / RAINBOW_FADER
  126.         Temp=                     // DMXAdress = tiempo de retardo
  127.                 (!(PINC &(1<<PC0)) *1) +
  128.                 (!(PINC &(1<<PC1)) *2) +
  129.                 (!(PINC &(1<<PC2)) *4) +
  130.                 (!(PINC &(1<<PC3)) *8) +
  131.                 (!(PINC &(1<<PC4)) *16) +
  132.                 (!(PINC &(1<<PC5)) *32) +
  133.                 (!(PINC &(1<<PC6)) *64) +
  134.                 (!(PINC &(1<<PC7)) *128);
  135.         DmxAddress= Temp;
  136.         if (!(PINE &(1<<PE2))) // MODO FADING / OFF RAINBOW_FADER
  137.              {
  138.                 mode= FADING;
  139.         }else{
  140.                 mode= RAINBOW_FADER;
  141.  
  142.              }
  143.                 return;
  144.         }
  145. //mode= xxx; // ACA PUEDE IR OTRA FUNCION CON LOS DIPS
  146. //Temp=
  147. //      (!(PINC &(1<<PC0)) *1) +
  148. //      (!(PINC &(1<<PC1)) *2) +
  149. //      (!(PINC &(1<<PC2)) *4) +
  150. //      (!(PINC &(1<<PC3)) *8) +
  151. //      (!(PINC &(1<<PC4)) *16) +
  152. //      (!(PINC &(1<<PC5)) *32) +
  153. //      (!(PINC &(1<<PC6)) *64) +
  154. //      (!(PINC &(1<<PC7)) *128) +
  155. //      (!(PINE &(1<<PE2)) *256);
  156.  
  157.  
  158. //if (Temp != 0)
  159. //      {
  160. //      Address= Temp;
  161.  
  162. //      }
  163.  
  164. #endif
  165. }
  166.  
  167. int main(void)
  168. {
  169.  //***** Watchdog *****//
  170.         wdt_reset();
  171.         wdt_enable(WDTO_500MS); // Habilitar el watchdog (timeout = 0.5s)
  172.         wdt_reset();
  173.         cli();
  174.         init_pinouts(); // Establecer los puertos de E / S
  175.         init_timer();   // Establecer el temporizador
  176.        
  177.         mode = FIXED;           //Valores iniciales, hasta que llegue la trama del DMX
  178.         Rojo = 0;
  179.         Verde = 0;
  180.         Azul = 0;
  181.        
  182.         sei();              // habilitar las interupciones globales  ???
  183.  
  184.         while(1)        // bucle principal (LOOP)
  185.             {
  186.                 get_dips();     // Toma la direccion y la actualiza, esto es para no tener que reiniciar a cada rato el DMX
  187.                 switch(mode)
  188.                 {
  189.                 case FIXED:
  190.                                 Rojo = DMX_R;           // Colores tomados directamente del DMX para fijo
  191.                                 Verde = DMX_G;
  192.                                 Azul = DMX_B;
  193.                                 DimmerCurva();          // Actualizo colores para el PWM
  194.                                 break;
  195.                 case FADING_FIX:
  196.                                 fading_fijo();
  197.                                 break;
  198.                 case FADING:
  199.                                 fading_auto();
  200.                                 break;
  201.                 case RAINBOW_FADING:
  202.                                 rainbow_fader();
  203.                                 break;
  204.                 default:
  205.                                 break;
  206.                 }
  207.             }
  208. }
  209.  
  210. void fading_fijo(){
  211.  
  212. }
  213.  
  214.  
  215.  
  216. void fading_auto(){
  217.  
  218.                 // Valores iniciales seteados cuando se cambia de modo
  219.        
  220.                 //Espera
  221.                 delay(DMX_Velocidad);  //esperar
  222.                 //Cambio los valores, cuando se cambia de modo se procede a setear los valores iniciales
  223.                 if(estado%2)
  224.                 {       //Caso impar
  225.                         if(++ArrayColores[estado]==255) estado++;
  226.                 }
  227.                 else
  228.                 {       //Caso par
  229.                         if(--ArrayColores[estado]==0) estado++;
  230.                 }
  231.                 if(estado>=6) estado=0;
  232.                 DimmerCurva();
  233. }
  234.  
  235. void rainbow_fader(){
  236.  
  237.         int Temp_R,Temp_A,Temp_V;
  238.         Temp_R = Rojo;
  239.         Temp_A = Azul;
  240.         Temp_V = Verde;
  241.  
  242.         if (estador==0){                                                                                                        //Caso inicial, Para que comienze con los valores que debe
  243.                 Rojo = 255;
  244.                 Verde = 0;
  245.                 Azul = 0;
  246.         }
  247.         DimmerCurva();
  248.  
  249.                 ArrayColores[ArrayColorFadingRainbow[estador][1]]++;                            //Sumo
  250.                 ArrayColores[ArrayColorFadingRainbow[estador][0]]--;                            //Resto
  251.                 if(!ArrayColores[ArrayColorFadingRainbow[estador][0]]) estador++;       //Compruebo que llegue al final, es decir pase por los 255 valores, en este caso cuando llega a 0 y continuo con la otra seccion.
  252.  
  253.         Rojo = Temp_R;
  254.         Azul = Temp_A;
  255.         Verde = Temp_V;
  256.        
  257.                 if(estador>=3) estador=0; fading_auto();                                                        //En caso que pase por todos los colores y pasas por el fade comun, tal cual estaba en el otro programa
  258.  
  259. }
  260.  
  261. void DimmerCurva(){
  262.  
  263.         R_aux=arraydimmer[Rojo];
  264.         V_aux=arraydimmer[Verde];
  265.         A_aux=arraydimmer[Azul];
  266. }
  267.  
  268. void delay(uint8_t DMX_Velocidad) {
  269.  
  270.         // Se toma el valor actual de la velocidad entregada por el DMX, no hace falta esperar que termine el PWM
  271.         // Tiempo Minimo = 3us
  272.         // Tiempo Maximo = 580ms
  273.         // Dividi el tiempo en 2 partes 0..127 para tiempos de micro segundos y 128..255 para tiempos de milisegundos
  274.        
  275.         uint16_t tiempo;
  276.         if (DMX_Velocidad>127)
  277.         {       //Tiempo en milisegundos, Recta de 1ms a 508ms
  278.                 tiempo = 4*DMX_Velocidad - 511;
  279.                 //_delay_ms(tiempo);
  280.         }
  281.         else
  282.         {       //Tiempo en microsegundos de 3us a 892us, valores elegidos para que resulte mas facil multiplicarlos
  283.                 tiempo = 7*DMX_Velocidad +3;
  284.                 //_delay_us(tiempo);
  285.         }
  286. }
  287.  
  288.  
  289.  //***** inicio del ocilador Temporizador de interrupción ****//
  290.  void ISR(TIMER0_OVF_vect){
  291.  
  292.         if (R_out>=PWM_timer) { salida &= 0x06; }
  293.         if (V_out>=PWM_timer) { salida &= 0x05; }
  294.         if (A_out>=PWM_timer) { salida &= 0x03; }
  295.         if (PWM_timer==255)
  296.         {
  297.                 //Cargo los colores nuevos ya que finalizo el ciclo del PWM
  298.                 R_out = R_aux;
  299.                 V_out = V_aux;
  300.                 A_out = A_aux;
  301.                 //Observo si se cambio el modo, asi cambio el modo y seteo los valores iniciales de ser necesario
  302.                 Cambiarmodo();
  303.         }
  304.         PWM_timer++;
  305. }
  306.  
  307.  void Cambiarmodo(){
  308.          switch(DMX_Modo&0xC0)  // Tomo los 2 bits superiores del Modo que viene del DMX y le hago una AND con 1100 0000, dejando los 2 bits superiores y los demas en 0
  309.          {
  310.          case 0xC0:                                             //Caso RAINBOW_FADING de 192 a 255, los bits con mas pesos siempre se mantienen en 1100
  311.                  if(mode!=RAINBOW_FADING)       //Reviso que ya no este en este modo.
  312.                  {
  313.                          mode=RAINBOW_FADING;
  314.                          Rojo=255;                              // Set de colores iniciales            
  315.                          Verde=0;
  316.                          Azul=0;
  317.                          estado=0;                              // Set de estado inicial para el fading
  318.                          estador=0;                             // Set de estado inicial para el rainbow_fading
  319.                  }
  320.                  break;
  321.          case 0x80:                                             //Case FADING, de 128 a 191, bits de mayor peso quedan siempre en 1000
  322.                  if(mode!=FADING)                       // Si ya esta en el modo, que no lo modifique.
  323.                  {
  324.                          mode=FADING;
  325.                          Rojo=255;                              // Set de colores iniciales            
  326.                          Verde=0;
  327.                          Azul=0;
  328.                          estado=0;                              // Set de estado inicial para el fading
  329.                  }
  330.                  break;
  331.          case 0x40:                                             //Case FADING_FIX, de 64 a 127, bits de mayor peso quedan siempre en 0100
  332.                  mode=FADING_FIX;                       // Aqui no importa si esta asignadosele a cada rato , ya que no hay valores iniciales
  333.                  break;
  334.          case 0x00:                                             //Case FADING_FIX, de 64 a 127, bits de mayor peso quedan siempre en 0000
  335.                  mode=FIXED;                            // Aqui no importa si esta asignadosele a cada rato , ya que no hay valores iniciales
  336.                  break;
  337.          }
  338.  }

Ahi va mi codigo... tiene una forma distinta de aplicacion. Tiene una forma distinta de como es que funciona el programa.
Por eso tuve que modificar completamente las funciones fading_auto y rainbow_fader, ya que de intentar cambiar rapidamente de modo, implicaba grandes demoras del micro hasta que realmente pudiera hacerlo.

Si observas el while del main esta continuamente entrando al modo que le corresponde, se hace lo que se debe y vuelve a salir al while de afuera.
El PWM esta corriendo siempre y es independiente de todo. Unicamente se cambia de modo Y de color si es que termino el ciclo del PWM, para evitar glitches

Lo que llegue desde el DMX, va a cargarse segun se requiera:

Modo Fijo (FIXED):
El programa arranca en este modo y colores RGB 0,0,0
El color se carga desde los valores del DMX, y se procede a actualizar lo que va a ir en la salida. Cuando el PWM termina el ciclo procede a cargar esos nuevos valores, asi por un ciclo mas.

Modo Fading Fijo (FADING_FIXED):
Este no lo hice, no esta realizado el codigo, deberia tomar el color y hacer un fading con el color que le manda el DMX. Creo que aca deberia aplicar un alpha asi afectar a todos los colores. Como no tengo seguro como hacerlo todavia no lo hice.

Modo Fading (FADING):
Este modo cuando se selecciona cuando el PWM llega a 255, esto hace que se le asignen los valores que deben ser para que inicie el modo fading tal cual estaba en el codigo anterior. Ademas pone los estados en 0 del fading para el nuevo codigo.

Modo Rainbow_Fading (RAINBOW_FADING):
Este modo utilizaba varias formas se producia el RAINBOW completo y luego se procedia a hacer 1 sola etapa del FADING. Asi hasta completar todas las etapas de FADING.

La Velocidad en que cambian los colores esta dado por el valor del DMX, el cual se actualiza al instante.
Tambien cambie la forma, queria hacer un cambio lineal de 3us a 580ms que era lo que tenia el programa en ASM, pero hacer una ecuacion lineal para eso era ridiculo ya que me encontraba con rangos de 0.003 a 580ms o de 3us a 580000ms
Entonces procedi a dividirlo en 2 rectas. 1 para los microsegundos para cuando DMX_Velocidad es de 0 a 127 y la otra para los milisegundos cuando DMX_Velocidad es de 128 a 255. Esto valores exigian operaciones con numeros flotantes. Por lo tanto me incline a hacerlo lo mas entero posible, por eso mismo la primera recta va desde 3us a 890us y luego pasa de 1ms a 508ms. Lo unico malo es que de 127 a 128 hay un salto de 100us, pero que espero no afecte demasiado.

Consideraciones que tuve:

El DIP solo entrega la direccion nada mas, esta puesto en el while asi de esa forma uno puede cambiar a direccion del equipo mientras esta encendido.
Quite seguramente algunas cosas como para poder programar mejor, seguro que vos luego se los vas a agregar de vuelta, tal como el WDT.
Y espero no haberle errado mucho.


Los valores de Rojo,Verde,Azul los puse todos en un array llamado ArrayColores, esto me permitio crear otros arrays mas para simplificar el programa. Ejemplo:

Código: C
  1. const uint8_t ArrayColorFading[]={                      // Indice y valor a modificar   {1,2,3} y {-1,-2,-3}
  2.                  1,     //      Rojo    ->      Amarillo
  3.                  0,     //      Amarilo ->      Verde
  4.                  2,     //      Verde   ->      Cyan
  5.                  1,     //      Cyan    ->      Azul
  6.                  0,     //      Azul    ->      Magenta
  7.                  2      //      Magenta ->      Rojo
  8. };

El Fading (solo este sin rainbow) hacia:
0- Incrementaba verde hasta 255
1- Decrementaba rojo hasta 0
2- Incrementaba azul hasta 255
3- Decrementaba verde
4- Incrementaba rojo
5- Decrementa Azul

Si observas los pares 0,2,4 son todos incrementos y los impares 1,3,5 decrementos
Si observas tambien los numeros del array que cree solo hay numeros de 0 a 2, esto me indica el indice {R,G,B}  el 0 es Rojo, 1 Verde, 2 Azul.
Entonces se que si tengo un 0 en la posicion 2, entonces debo INCREMENTAR rojo.

El mismo principio se aplica al Rainbow, nomas que alli se incrementa y decrementa a la misma ves, por lo tanto procedi a crear otro array distinto para ese.
Esto ultimo es por si me preguntabas que habia realizado. No quise meterme con punteros para no complicarle la vida a nadie.

Creo que estaria todo terminado a excepcion de la funcion de fading fijo (que seguro la termino dentro de poco). todo lo demas agregado que no sea parte de la implementacion del codigo ya creo que va a pasar a ser un tema tuyo.
Si no me equivoco deberia funcionar masomenos correctamente. Me preocupan un par de detalles minusciosos pero que tal ves me este rompiendo mas la cabeza de lo que debo.
(Como crear otro valor de modo para que solo se cambie en cierta ocasion de esa forma evitar cualquier posible error)

PD: Si observas y el por que de mi enojo es que es muy distinto un programa hecho de forma lineal como teniamos, a uno realizado de la forma que esta ahora. Tal ves demasiado, a pesar que "hacen lo mismo" la aplicacion es totalmente distinta.
« Última modificación: 26 de Agosto de 2015, 04:23:59 por KILLERJC »

Desconectado locodelafonola

  • PIC10
  • *
  • Mensajes: 43
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #34 en: 27 de Agosto de 2015, 01:11:18 »
 hola
Código: C
  1. #define F_CPU 8000000
  2. #include<util\delay.h>
  3.  
  4. #include<stdio.h>
  5. #include<stdlib.h>
  6. #include"fading_raibow.h"
  7. #include <avr/interrupt.h>
  8. #include <avr/wdt.h>
  9.  
  10.  
  11. enum {FIXED,FADING_FIX,FADING,RAINBOW_FADING} mode;
  12.  
  13. #define OV_COUNT        14              // 161 , 7  = 0.25ms
  14. #define OV_SIZE         161             // comenzando Contador inicial
  15.  
  16. // Dato proveniente de la consola DMX
  17.  
  18. #define DMX_R                   DmxRxField[1]   //Canal R              
  19. #define DMX_G                   DmxRxField[2]   //Canal G
  20. #define DMX_B                   DmxRxField[3]   //Canal B
  21. #define DMX_Modo                DmxRxField[4]   //Seleccion de Modo
  22. #define DMX_Velocidad   DmxRxField[5]   //Seleccion de Velocidad
  23.  
  24. // Para simplificar los datos del array de colores que estoy usando.
  25. // ArrayColores contiene los valores RGB del momento
  26.  
  27. #define Rojo                    ArrayColores[0]
  28. #define Verde                   ArrayColores[1]
  29. #define Azul                    ArrayColores[2]
  30.  
  31. //*********************************//
  32.  
  33. volatile uint16_t        DmxAddress;                            // Dirección inicial
  34.  
  35. uint8_t V_out,R_out,A_out;                                              // Valores que se comparan con el PWM
  36. uint8_t V_aux,R_aux,A_aux;                                              // Valores que se cambia para actualizar el PWM
  37. uint8_t PWM_timer=0;
  38. uint8_t estado=0,estador=0;                                     // Estado de los fading
  39.  
  40. const uint8_t arraydimmer[256]={
  41.                  0,     0,    1,    1,    1,    1,    1,    2,
  42.                  2,     2,    2,    3,    3,    3,    4,    4,
  43.                  4,     5,    5,    5,    6,    6,    7,    7,
  44.                  8,     8,    9,    9,   10,   10,   11,   11,
  45.                  12,   12,   13,   13,   14,   14,   15,   15,
  46.                  16,   16,   17,   17,   18,   18,   19,   19,
  47.                  20,   20,   21,   21,   22,   22,   23,   23,
  48.                  24,   24,   25,   25,   26,   27,   28,   29,
  49.                  30,   30,   31,   32,   33,   34,   35,   36,
  50.                  36,   37,   38,   39,   40,   41,   42,   43,
  51.                  43,   44,   45,   46,   47,   48,   49,   50,
  52.                  51,   52,   52,   53,   54,   55,   56,   57,
  53.                  58,   59,   60,   61,   62,   63,   64,   65,
  54.                  66,   67,   68,   69,   70,   71,   72,   73,
  55.                  74,   75,   76,   77,   78,   79,   80,   81,
  56.                  82,   83,   84,   85,   86,   88,   89,   90,
  57.                  91,   92,   93,   94,   95,   96,   97,   98,
  58.                  99,  100,  102,  103,  104,  105,  106,  107,
  59.                  108, 109,  110,  112,  113,  114,  115,  116,
  60.                  117, 119,  120,  121,  122,  123,  124,  126,
  61.                  127, 128,  129,  130,  132,  133,  134,  135,
  62.                  136, 138,  139,  140,  141,  142,  144,  145,
  63.                  146, 147,  149,  150,  151,  152,  154,  155,
  64.                  156, 158,  159,  160,  161,  162,  164,  165,
  65.                  167, 168,  169,  171,  172,  173,  174,  176,
  66.                  177, 178,  180,  181,  182,  184,  185,  187,
  67.                  188, 189,  191,  192,  193,  195,  196,  197,
  68.                  199, 200,  202,  203,  204,  206,  207,  208,
  69.                  210, 211,  213,  214,  216,  217,  218,  220,
  70.                  221, 223,  224,  226,  227,  228,  230,  231,
  71.                  233, 234,  236,  237,  239,  240,  242,  243,
  72.                  245, 246,  248,  249,  251,  252,  254,  255
  73. };
  74.  
  75. uint8_t ArrayColores[3]={255,0,0};                      // Rojo,Verde,Azul
  76.  
  77. const uint8_t ArrayColorFading[]={                      // Indice y valor a modificar   {1,2,3} y {-1,-2,-3}
  78.                  1,     //      Rojo    ->      Amarillo
  79.                  0,     //      Amarilo ->      Verde
  80.                  2,     //      Verde   ->      Cyan
  81.                  1,     //      Cyan    ->      Azul
  82.                  0,     //      Azul    ->      Magenta
  83.                  2      //      Magenta ->      Rojo
  84. };
  85.  
  86. const uint8_t ArrayColorFadingRainbow[]={                       // Indice y valor a modificar   {Resta,Suma}
  87.                 {0,1},  //      Rojo-   ->      Verde+
  88.                 {1,2},  //      Verde-  ->      Azul+
  89.                 {2,0}   //      Azul-   ->      Rojo+
  90. };
  91.  
  92. //************* Inicialización pines / port *****************//
  93. void init_pinouts(){
  94.     #ifdef USE_DIP
  95.  
  96.     DDRC  = 0;                  // establecer DIPs
  97.     PORTC  = 0xFF;
  98.     DDRE  &= ~((1<<PE2)|(1<<PE1));
  99.     PORTE |=   (1<<PE2)|(1<<PE1);
  100.         #endif
  101.  
  102.  
  103.         DDRB |= (1<<PB0) | (1<<PB1) | (1<<PB2); // Salida pin LED
  104.         PORTB = 0;
  105.         DDRE  |= (1<<PE0);      //LED2 azul indicador
  106.     PORTE = 0;
  107.  
  108. }
  109.  
  110. // ***** inicializacion del timer****//
  111.  
  112. void init_timer(){
  113.                 TCCR0|= (1<<CS02) ;     // Precontador 256
  114.                 TIMSK|= (1<<TOIE0);     // desbordamientos de la interrupción
  115.                 TCNT0= OV_SIZE;
  116.         }
  117.  
  118.  // ************* obtener DMX dirección de inicio **************
  119.  
  120. void get_dips(void)
  121. {
  122. #ifdef USE_DIP
  123. uint16_t Temp;
  124.  
  125. if (!(PINE &(1<<PE1))){ // Modo FADING / RAINBOW_FADER
  126.         Temp=                     // DMXAdress = tiempo de retardo
  127.                 (!(PINC &(1<<PC0)) *1) +
  128.                 (!(PINC &(1<<PC1)) *2) +
  129.                 (!(PINC &(1<<PC2)) *4) +
  130.                 (!(PINC &(1<<PC3)) *8) +
  131.                 (!(PINC &(1<<PC4)) *16) +
  132.                 (!(PINC &(1<<PC5)) *32) +
  133.                 (!(PINC &(1<<PC6)) *64) +
  134.                 (!(PINC &(1<<PC7)) *128);
  135.         DmxAddress= Temp;
  136.         if (!(PINE &(1<<PE2))) // MODO FADING / OFF RAINBOW_FADER
  137.              {
  138.                 mode= FADING;
  139.         }else{
  140.                 mode= RAINBOW_FADER;
  141.  
  142.              }
  143.                 return;
  144.         }
  145. //mode= xxx; // ACA PUEDE IR OTRA FUNCION CON LOS DIPS
  146. //Temp=
  147. //      (!(PINC &(1<<PC0)) *1) +
  148. //      (!(PINC &(1<<PC1)) *2) +
  149. //      (!(PINC &(1<<PC2)) *4) +
  150. //      (!(PINC &(1<<PC3)) *8) +
  151. //      (!(PINC &(1<<PC4)) *16) +
  152. //      (!(PINC &(1<<PC5)) *32) +
  153. //      (!(PINC &(1<<PC6)) *64) +
  154. //      (!(PINC &(1<<PC7)) *128) +
  155. //      (!(PINE &(1<<PE2)) *256);
  156.  
  157.  
  158. //if (Temp != 0)
  159. //      {
  160. //      Address= Temp;
  161.  
  162. //      }
  163.  
  164. #endif
  165. }
  166.  
  167. int main(void)
  168. {
  169.  //***** Watchdog *****//
  170.         wdt_reset();
  171.         wdt_enable(WDTO_500MS); // Habilitar el watchdog (timeout = 0.5s)
  172.         wdt_reset();
  173.         cli();
  174.         init_pinouts(); // Establecer los puertos de E / S
  175.         init_timer();   // Establecer el temporizador
  176.        
  177.         mode = FIXED;           //Valores iniciales, hasta que llegue la trama del DMX
  178.         Rojo = 0;
  179.         Verde = 0;
  180.         Azul = 0;
  181.        
  182.         sei();              // habilitar las interupciones globales  ???
  183.  
  184.         while(1)        // bucle principal (LOOP)
  185.             {
  186.                 get_dips();     // Toma la direccion y la actualiza, esto es para no tener que reiniciar a cada rato el DMX
  187.                 switch(mode)
  188.                 {
  189.                 case FIXED:
  190.                                 Rojo = DMX_R;           // Colores tomados directamente del DMX para fijo
  191.                                 Verde = DMX_G;
  192.                                 Azul = DMX_B;
  193.                                 DimmerCurva();          // Actualizo colores para el PWM
  194.                                 break;
  195.                 case FADING_FIX:
  196.                                 fading_fijo();
  197.                                 break;
  198.                 case FADING:
  199.                                 fading_auto();
  200.                                 break;
  201.                 case RAINBOW_FADING:
  202.                                 rainbow_fader();
  203.                                 break;
  204.                 default:
  205.                                 break;
  206.                 }
  207.             }
  208. }
  209.  
  210. void fading_fijo(){
  211.  
  212. }
  213.  
  214.  
  215.  
  216. void fading_auto(){
  217.  
  218.                 // Valores iniciales seteados cuando se cambia de modo
  219.        
  220.                 //Espera
  221.                 delay(DMX_Velocidad);  //esperar
  222.                 //Cambio los valores, cuando se cambia de modo se procede a setear los valores iniciales
  223.                 if(estado%2)
  224.                 {       //Caso impar
  225.                         if(++ArrayColores[estado]==255) estado++;
  226.                 }
  227.                 else
  228.                 {       //Caso par
  229.                         if(--ArrayColores[estado]==0) estado++;
  230.                 }
  231.                 if(estado>=6) estado=0;
  232.                 DimmerCurva();
  233. }
  234.  
  235. void rainbow_fader(){
  236.  
  237.         int Temp_R,Temp_A,Temp_V;
  238.         Temp_R = Rojo;
  239.         Temp_A = Azul;
  240.         Temp_V = Verde;
  241.  
  242.         if (estador==0){                                                                                                        //Caso inicial, Para que comienze con los valores que debe
  243.                 Rojo = 255;
  244.                 Verde = 0;
  245.                 Azul = 0;
  246.         }
  247.         DimmerCurva();
  248.  
  249.                 ArrayColores[ArrayColorFadingRainbow[estador][1]]++;                            //Sumo
  250.                 ArrayColores[ArrayColorFadingRainbow[estador][0]]--;                            //Resto
  251.                 if(!ArrayColores[ArrayColorFadingRainbow[estador][0]]) estador++;       //Compruebo que llegue al final, es decir pase por los 255 valores, en este caso cuando llega a 0 y continuo con la otra seccion.
  252.  
  253.         Rojo = Temp_R;
  254.         Azul = Temp_A;
  255.         Verde = Temp_V;
  256.        
  257.                 if(estador>=3) estador=0; fading_auto();                                                        //En caso que pase por todos los colores y pasas por el fade comun, tal cual estaba en el otro programa
  258.  
  259. }
  260.  
  261. void DimmerCurva(){
  262.  
  263.         R_aux=arraydimmer[Rojo];
  264.         V_aux=arraydimmer[Verde];
  265.         A_aux=arraydimmer[Azul];
  266. }
  267.  
  268. void delay(uint8_t DMX_Velocidad) {
  269.  
  270.         // Se toma el valor actual de la velocidad entregada por el DMX, no hace falta esperar que termine el PWM
  271.         // Tiempo Minimo = 3us
  272.         // Tiempo Maximo = 580ms
  273.         // Dividi el tiempo en 2 partes 0..127 para tiempos de micro segundos y 128..255 para tiempos de milisegundos
  274.        
  275.         uint16_t tiempo;
  276.         if (DMX_Velocidad>127)
  277.         {       //Tiempo en milisegundos, Recta de 1ms a 508ms
  278.                 tiempo = 4*DMX_Velocidad - 511;
  279.                 //_delay_ms(tiempo);
  280.         }
  281.         else
  282.         {       //Tiempo en microsegundos de 3us a 892us, valores elegidos para que resulte mas facil multiplicarlos
  283.                 tiempo = 7*DMX_Velocidad +3;
  284.                 //_delay_us(tiempo);
  285.         }
  286. }
  287.  
  288.  
  289.  //***** inicio del ocilador Temporizador de interrupción ****//
  290.  void ISR(TIMER0_OVF_vect){
  291.  
  292.         if (R_out>=PWM_timer) { salida &= 0x06; }
  293.         if (V_out>=PWM_timer) { salida &= 0x05; }
  294.         if (A_out>=PWM_timer) { salida &= 0x03; }
  295.         if (PWM_timer==255)
  296.         {
  297.                 //Cargo los colores nuevos ya que finalizo el ciclo del PWM
  298.                 R_out = R_aux;
  299.                 V_out = V_aux;
  300.                 A_out = A_aux;
  301.                 //Observo si se cambio el modo, asi cambio el modo y seteo los valores iniciales de ser necesario
  302.                 Cambiarmodo();
  303.         }
  304.         PWM_timer++;
  305. }
  306.  
  307.  void Cambiarmodo(){
  308.          switch(DMX_Modo&0xC0)  // Tomo los 2 bits superiores del Modo que viene del DMX y le hago una AND con 1100 0000, dejando los 2 bits superiores y los demas en 0
  309.          {
  310.          case 0xC0:                                             //Caso RAINBOW_FADING de 192 a 255, los bits con mas pesos siempre se mantienen en 1100
  311.                  if(mode!=RAINBOW_FADING)       //Reviso que ya no este en este modo.
  312.                  {
  313.                          mode=RAINBOW_FADING;
  314.                          Rojo=255;                              // Set de colores iniciales            
  315.                          Verde=0;
  316.                          Azul=0;
  317.                          estado=0;                              // Set de estado inicial para el fading
  318.                          estador=0;                             // Set de estado inicial para el rainbow_fading
  319.                  }
  320.                  break;
  321.          case 0x80:                                             //Case FADING, de 128 a 191, bits de mayor peso quedan siempre en 1000
  322.                  if(mode!=FADING)                       // Si ya esta en el modo, que no lo modifique.
  323.                  {
  324.                          mode=FADING;
  325.                          Rojo=255;                              // Set de colores iniciales            
  326.                          Verde=0;
  327.                          Azul=0;
  328.                          estado=0;                              // Set de estado inicial para el fading
  329.                  }
  330.                  break;
  331.          case 0x40:                                             //Case FADING_FIX, de 64 a 127, bits de mayor peso quedan siempre en 0100
  332.                  mode=FADING_FIX;                       // Aqui no importa si esta asignadosele a cada rato , ya que no hay valores iniciales
  333.                  break;
  334.          case 0x00:                                             //Case FADING_FIX, de 64 a 127, bits de mayor peso quedan siempre en 0000
  335.                  mode=FIXED;                            // Aqui no importa si esta asignadosele a cada rato , ya que no hay valores iniciales
  336.                  break;
  337.          }
  338.  }

Ahi va mi codigo... tiene una forma distinta de aplicacion. Tiene una forma distinta de como es que funciona el programa.
Por eso tuve que modificar completamente las funciones fading_auto y rainbow_fader, ya que de intentar cambiar rapidamente de modo, implicaba grandes demoras del micro hasta que realmente pudiera hacerlo.

Si observas el while del main esta continuamente entrando al modo que le corresponde, se hace lo que se debe y vuelve a salir al while de afuera.
El PWM esta corriendo siempre y es independiente de todo. Unicamente se cambia de modo Y de color si es que termino el ciclo del PWM, para evitar glitches

Lo que llegue desde el DMX, va a cargarse segun se requiera:

Modo Fijo (FIXED):
El programa arranca en este modo y colores RGB 0,0,0
El color se carga desde los valores del DMX, y se procede a actualizar lo que va a ir en la salida. Cuando el PWM termina el ciclo procede a cargar esos nuevos valores, asi por un ciclo mas.

Modo Fading Fijo (FADING_FIXED):
Este no lo hice, no esta realizado el codigo, deberia tomar el color y hacer un fading con el color que le manda el DMX. Creo que aca deberia aplicar un alpha asi afectar a todos los colores. Como no tengo seguro como hacerlo todavia no lo hice.

Modo Fading (FADING):
Este modo cuando se selecciona cuando el PWM llega a 255, esto hace que se le asignen los valores que deben ser para que inicie el modo fading tal cual estaba en el codigo anterior. Ademas pone los estados en 0 del fading para el nuevo codigo.

Modo Rainbow_Fading (RAINBOW_FADING):
Este modo utilizaba varias formas se producia el RAINBOW completo y luego se procedia a hacer 1 sola etapa del FADING. Asi hasta completar todas las etapas de FADING.

La Velocidad en que cambian los colores esta dado por el valor del DMX, el cual se actualiza al instante.
Tambien cambie la forma, queria hacer un cambio lineal de 3us a 580ms que era lo que tenia el programa en ASM, pero hacer una ecuacion lineal para eso era ridiculo ya que me encontraba con rangos de 0.003 a 580ms o de 3us a 580000ms
Entonces procedi a dividirlo en 2 rectas. 1 para los microsegundos para cuando DMX_Velocidad es de 0 a 127 y la otra para los milisegundos cuando DMX_Velocidad es de 128 a 255. Esto valores exigian operaciones con numeros flotantes. Por lo tanto me incline a hacerlo lo mas entero posible, por eso mismo la primera recta va desde 3us a 890us y luego pasa de 1ms a 508ms. Lo unico malo es que de 127 a 128 hay un salto de 100us, pero que espero no afecte demasiado.

Consideraciones que tuve:

El DIP solo entrega la direccion nada mas, esta puesto en el while asi de esa forma uno puede cambiar a direccion del equipo mientras esta encendido.
Quite seguramente algunas cosas como para poder programar mejor, seguro que vos luego se los vas a agregar de vuelta, tal como el WDT.
Y espero no haberle errado mucho.


Los valores de Rojo,Verde,Azul los puse todos en un array llamado ArrayColores, esto me permitio crear otros arrays mas para simplificar el programa. Ejemplo:

Código: C
  1. const uint8_t ArrayColorFading[]={                      // Indice y valor a modificar   {1,2,3} y {-1,-2,-3}
  2.                  1,     //      Rojo    ->      Amarillo
  3.                  0,     //      Amarilo ->      Verde
  4.                  2,     //      Verde   ->      Cyan
  5.                  1,     //      Cyan    ->      Azul
  6.                  0,     //      Azul    ->      Magenta
  7.                  2      //      Magenta ->      Rojo
  8. };

El Fading (solo este sin rainbow) hacia:
0- Incrementaba verde hasta 255
1- Decrementaba rojo hasta 0
2- Incrementaba azul hasta 255
3- Decrementaba verde
4- Incrementaba rojo
5- Decrementa Azul

Si observas los pares 0,2,4 son todos incrementos y los impares 1,3,5 decrementos
Si observas tambien los numeros del array que cree solo hay numeros de 0 a 2, esto me indica el indice {R,G,B}  el 0 es Rojo, 1 Verde, 2 Azul.
Entonces se que si tengo un 0 en la posicion 2, entonces debo INCREMENTAR rojo.

El mismo principio se aplica al Rainbow, nomas que alli se incrementa y decrementa a la misma ves, por lo tanto procedi a crear otro array distinto para ese.
Esto ultimo es por si me preguntabas que habia realizado. No quise meterme con punteros para no complicarle la vida a nadie.

Creo que estaria todo terminado a excepcion de la funcion de fading fijo (que seguro la termino dentro de poco). todo lo demas agregado que no sea parte de la implementacion del codigo ya creo que va a pasar a ser un tema tuyo.
Si no me equivoco deberia funcionar masomenos correctamente. Me preocupan un par de detalles minusciosos pero que tal ves me este rompiendo mas la cabeza de lo que debo.
(Como crear otro valor de modo para que solo se cambie en cierta ocasion de esa forma evitar cualquier posible error)

PD: Si observas y el por que de mi enojo es que es muy distinto un programa hecho de forma lineal como teniamos, a uno realizado de la forma que esta ahora. Tal ves demasiado, a pesar que "hacen lo mismo" la aplicacion es totalmente distinta.
bueno amigo alli compile y agregue algunas cosas que faltaban al juntako con DMX
pero me largo error ., y calculo que los errores tiene el mismo origen que es el PWM en e lIRS
y te vuelvo a repetir en DMX se tiene que ejecitar en WHILE o FOR pero fuera del IRS
la razon es que te afecta la recepcion del USAT como te explique antes  
aca te subo las tres librerias  la de recepcion" lib_dmx_in.c " ," lib_dmx_in.h" y "fading_raibow.c "
LIB_DMX_IN.C
Código: [Seleccionar]
#include "lib_dmx_in.h"
#include "lib_indicator.h"
// ********************* definiciones locales*********************
 
enum {IDLE, BREAK, STARTB, STARTADR};// estados DMX

    
    
  uint8_t gDmxState;
uint8_t *gDmxPnt;
uint16_t DmxCount;  
                                                                                                                                                                                              
//volatile uint8_t gDmxState;
 
 
// *************** DMX recepción de inicialización ****************
void init_DMX_RX(void)
{
#ifdef USE_DIP
 
DDRC  = 0; // establecer DIPs
PORTC  = 0xFF;
DDRE  &= ~((1<<PE2)|(1<<PE1));
PORTE |=   (1<<PE2)|(1<<PE1);
 
#endif
 
DDRD  |= (1<<2);
PORTD &= ~(1<<2);
UBRRH  = 0; // Habilitar recepción
UBRRL  = ((F_OSC/4000)-1);// 250kBaud, 8N2
UCSRC  = (1<<URSEL)|(3<<UCSZ0)|(1<<USBS);
UCSRB  = (1<<RXEN)|(1<<RXCIE);
gDmxState= IDLE;

uint8_t i;
for (i=0; i<DMX_CHANNELS; i++)
{
DmxRxField[i]= 0;
}

}
 
 
 
// ************* obtener DMX dirección de inicio **************
void get_dips(void)
{
#ifdef USE_DIP
uint16_t Temp;
 
if (!(PINE &(1<<PE1))){ // Modo Manual
Temp=  // DMXAdress = tiempo de retardo
(!(PINC &(1<<PC0)) *1) +
(!(PINC &(1<<PC1)) *2) +
(!(PINC &(1<<PC2)) *4) +
(!(PINC &(1<<PC3)) *8) +
(!(PINC &(1<<PC4)) *16) +
(!(PINC &(1<<PC5)) *32) +
(!(PINC &(1<<PC6)) *64) +
(!(PINC &(1<<PC7)) *128);
DmxAddress= Temp;
if (!(PINE &(1<<PE2))) // Manual,
    {
mode= FADING;
}else{
mode= RAINBOW_FADER;

     }
UCSRB &= ~(1<<RXCIE);// Receptor Desactivar si la dirección de inicio = 0

return;

 }
mode=DMX;
Temp=
(!(PINC &(1<<PC0)) *1) +
(!(PINC &(1<<PC1)) *2) +
(!(PINC &(1<<PC2)) *4) +
(!(PINC &(1<<PC3)) *8) +
(!(PINC &(1<<PC4)) *16) +
(!(PINC &(1<<PC5)) *32) +
(!(PINC &(1<<PC6)) *64) +
(!(PINC &(1<<PC7)) *128) +
(!(PINE &(1<<PE2)) *256);
 
if (Temp != 0)
{
DmxAddress= Temp;
if (!(UCSRB &(1<<RXCIE)))// Si el receptor esta desabilitado -> habilitar y esperar descanso
{
gDmxState= IDLE;
UCSRB |= (1<<RXCIE);

}
}
else
{
UCSRB &= ~(1<<RXCIE); // Receptor Desactivar si la dirección de inicio = 0

uint8_t i;
for (i=0; i<sizeof(DmxRxField); i++)
{
DmxRxField[i]= 0;
}
}
 
#endif
}
 
 
 
// *************** DMX recepción ISR ****************//
ISR (UART_RX_vect)
{
static  uint16_t DmxCount;
uint8_t  USARTstate= UCSRA; // Obtener estado antes de los datos!
uint8_t  DmxByte   = UDR; // Obtener los datos
uint8_t  DmxState  = gDmxState;// Cargar una sola vez de SRAM para aumentar la velocidad
IndFlags |= (1<<SIGNAL_COMING);// Recibir somedata
if (DmxState == BREAK)
{
UCSRA &= ~(1<<FE); // Cambiar Posible FE: a causa de MAB
if (DmxByte == 0)
{
gDmxState= STARTB;// Código de inicio normal detectado
gDmxPnt= ((uint8_t*)DmxRxField +1);
}
else
{
gDmxState= IDLE;
}
}

else if (USARTstate &(1<<FE)) // Comprobar para el descanso de la señal
{
UCSRA &= ~(1<<FE); // Restablecer bandera
if (DmxByte == 0) // Los datos de descanso debe ser 0
{
gDmxState= BREAK;
DmxCount= DmxAddress; // Restablecer contador de fotogramas
}
else
{
gDmxState= IDLE; // Bien es FE -> esperar descanso
}
}

else if (DmxState == STARTB)
{
if (--DmxCount == 0)// Dirección inicial alcanzada?
{
gDmxState= STARTADR;
DmxRxField[0]= DmxByte;
}
}

else if (DmxState == STARTADR)
{
uint8_t *DmxPnt;
DmxPnt= gDmxPnt;
*DmxPnt= DmxByte;
if (++DmxPnt >= (DmxRxField + DMX_CHANNELS )) // los (CHANNEL) canales recibidos?
{
Flags |= (1<<EVAL_DMX);// Conjunto de datos listo -> eval en principal (MAIN)
gDmxState= IDLE;
}
else
{
gDmxPnt= DmxPnt;
}
}
}

 aca LIB_DMX_IN.H
Código: [Seleccionar]
#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>
#define DMX_CHANNELS    (13)
#define  USE_DIP
#define  F_OSC (8000) // Frec oscilador. en kHz (8MHz típico o 16MHz)
enum {EVAL_DMX, IND};
volatile uint8_t Flags;
enum {FIXED,FADING_FIX,FADING,RAINBOW_FADING} mode;

volatile uint16_t DmxAddress; // Dirección inicial
volatile int  color_number;// numero de la tabla de Color del sonido / manual actual
volatile uint8_t DmxRxField[DMX_CHANNELS]; // Conjunto de vals DMX (cruda)
extern void    init_DMX_RX(void);
extern void    get_dips(void);
extern void    set_color(int color);

aca el MAIN o FADING_RAIBOW.C
Código: [Seleccionar]
  // #define F_CPU 8000000
    #include<util\delay.h>
    #include "lib_dmx_in.h"
    #include<stdio.h>
    #include<stdlib.h>
   // #include"fading_raibow.h"
    #include <avr/interrupt.h>
    #include <avr/wdt.h>
 //************************************************************//    
    volatile uint8_t DmxRxField[DMX_CHANNELS];
    uint8_t DmxBuf[DMX_CHANNELS];
 //**********************************************************//    
    #define OV_COUNT 14 // 161 , 7  = 0.25ms
    #define OV_SIZE 161 // comenzando Contador inicial
    
    // Dato proveniente de la consola DMX
    
    #define DMX_R DmxRxField[1] //Canal R
    #define DMX_G DmxRxField[2] //Canal G
    #define DMX_B DmxRxField[3] //Canal B
    #define DMX_Modo DmxRxField[4] //Seleccion de Modo
    #define DMX_Velocidad DmxRxField[5] //Seleccion de Velocidad
    
    // Para simplificar los datos del array de colores que estoy usando.
    // ArrayColores contiene los valores RGB del momento
    
    #define Rojo ArrayColores[0]
    #define Verde ArrayColores[1]
    #define Azul ArrayColores[2]
    
    //*********************************//
    
    volatile uint16_t DmxAddress; // Dirección inicial
    
    uint8_t V_out,R_out,A_out; // Valores que se comparan con el PWM
    uint8_t V_aux,R_aux,A_aux; // Valores que se cambia para actualizar el PWM
    uint8_t PWM_timer=0;
    uint8_t estado=0,estador=0; // Estado de los fading
    
    const uint8_t arraydimmer[256]={
     0,     0,    1,    1,    1,    1,    1,    2,
     2,     2,    2,    3,    3,    3,    4,    4,
     4,     5,    5,    5,    6,    6,    7,    7,
     8,     8,    9,    9,   10,   10,   11,   11,
     12,   12,   13,   13,   14,   14,   15,   15,
     16,   16,   17,   17,   18,   18,   19,   19,
     20,   20,   21,   21,   22,   22,   23,   23,
     24,   24,   25,   25,   26,   27,   28,   29,
     30,   30,   31,   32,   33,   34,   35,   36,
     36,   37,   38,   39,   40,   41,   42,   43,
     43,   44,   45,   46,   47,   48,   49,   50,
     51,   52,   52,   53,   54,   55,   56,   57,
     58,   59,   60,   61,   62,   63,   64,   65,
     66,   67,   68,   69,   70,   71,   72,   73,
     74,   75,   76,   77,   78,   79,   80,   81,
     82,   83,   84,   85,   86,   88,   89,   90,
     91,   92,   93,   94,   95,   96,   97,   98,
     99,  100,  102,  103,  104,  105,  106,  107,
     108, 109,  110,  112,  113,  114,  115,  116,
     117, 119,  120,  121,  122,  123,  124,  126,
     127, 128,  129,  130,  132,  133,  134,  135,
     136, 138,  139,  140,  141,  142,  144,  145,
     146, 147,  149,  150,  151,  152,  154,  155,
     156, 158,  159,  160,  161,  162,  164,  165,
     167, 168,  169,  171,  172,  173,  174,  176,
     177, 178,  180,  181,  182,  184,  185,  187,
     188, 189,  191,  192,  193,  195,  196,  197,
     199, 200,  202,  203,  204,  206,  207,  208,
     210, 211,  213,  214,  216,  217,  218,  220,
     221, 223,  224,  226,  227,  228,  230,  231,
     233, 234,  236,  237,  239,  240,  242,  243,
     245, 246,  248,  249,  251,  252,  254,  255
    };
    
    uint8_t ArrayColores[3]={255,0,0}; // Rojo,Verde,Azul
    
    const uint8_t ArrayColorFading[]={ // Indice y valor a modificar {1,2,3} y {-1,-2,-3}
     1, // Rojo -> Amarillo
     0, // Amarilo -> Verde
     2, // Verde -> Cyan
     1, // Cyan -> Azul
     0, // Azul -> Magenta
     2 // Magenta -> Rojo
    };
    
    const uint8_t ArrayColorFadingRainbow[]={ // Indice y valor a modificar {Resta,Suma}
     {0,1}, // Rojo- -> Verde+
     {1,2}, // Verde- -> Azul+
     {2,0} // Azul- -> Rojo+
    };
    
    //************* Inicialización pines / port *****************//
    void init_pinouts(){
        #ifdef USE_DIP
    
        DDRC  = 0; // establecer DIPs
        PORTC  = 0xFF;
        DDRE  &= ~((1<<PE2)|(1<<PE1));
        PORTE |=   (1<<PE2)|(1<<PE1);
     #endif
    
    
     DDRB |= (1<<PB0) | (1<<PB1) | (1<<PB2); // Salida pin LED
     PORTB = 0;
     DDRE  |= (1<<PE0); //LED2 azul indicador
        PORTE = 0;
    
    }
    
    // ***** inicializacion del timer****//
    
    void init_timer(){
     TCCR0|= (1<<CS02) ; // Precontador 256
     TIMSK|= (1<<TOIE0); // desbordamientos de la interrupción
     TCNT0= OV_SIZE;
     }
    
        
    int main(void)
    {
     //***** Watchdog *****//
     wdt_reset();
     wdt_enable(WDTO_500MS); // Habilitar el watchdog (timeout = 0.5s)
     wdt_reset();
     cli();
     init_pinouts(); // Establecer los puertos de E / S
     init_timer(); // Establecer el temporizador
     init_DMX_RX(); // Inicializar recpcion DMX
     mode = FIXED; //Valores iniciales, hasta que llegue la trama del DMX
     Rojo = 0;
     Verde = 0;
     Azul = 0;
    
     sei();    // habilitar las interupciones globales  ???
    
     while(1) // bucle principal (LOOP)
        {
             get_dips(); // Toma la direccion y la actualiza, esto es para no tener que reiniciar a cada rato el DMX
             switch(mode)
             {
             case FIXED:
             Rojo = DMX_R; // Colores tomados directamente del DMX para fijo
             Verde = DMX_G;
             Azul = DMX_B;
             DimmerCurva(); // Actualizo colores para el PWM
             break;
             case FADING_FIX:
             fading_fijo();
             break;
             case FADING:
             fading_auto();
             break;
             case RAINBOW_FADING:
             rainbow_fader();
             break;
             default:
             break;
             }
        }
    }
    
    void fading_fijo(){
    
    }
    
    
    
    void fading_auto(){
    
     // Valores iniciales seteados cuando se cambia de modo
    
     //Espera
     delay(DMX_Velocidad);  //esperar
     //Cambio los valores, cuando se cambia de modo se procede a setear los valores iniciales
     if(estado%2)
     { //Caso impar
     if(++ArrayColores[estado]==255) estado++;
     }
     else
     { //Caso par
     if(--ArrayColores[estado]==0) estado++;
     }
     if(estado>=6) estado=0;
     DimmerCurva();
    }
    
    void rainbow_fader(){
    
         int Temp_R,Temp_A,Temp_V;
         Temp_R = Rojo;
         Temp_A = Azul;
         Temp_V = Verde;
    
         if (estador==0){ //Caso inicial, Para que comienze con los valores que debe
             Rojo = 255;
             Verde = 0;
             Azul = 0;
         }
         DimmerCurva();
    
       ArrayColores[ArrayColorFadingRainbow[estador][1]]++; //Sumo
       ArrayColores[ArrayColorFadingRainbow[estador][0]]--; //Resto
       if(!ArrayColores[ArrayColorFadingRainbow[estador][0]]) estador++; //Compruebo que llegue al final, es decir pase por los 255 valores, en este caso cuando llega a 0 y continuo con la otra seccion.
    
         Rojo = Temp_R;
         Azul = Temp_A;
         Verde = Temp_V;
        
       if(estador>=3) estador=0; fading_auto(); //En caso que pase por todos los colores y pasas por el fade comun, tal cual estaba en el otro programa
    
    }
    
    void DimmerCurva(){
    
         R_aux=arraydimmer[Rojo];
         V_aux=arraydimmer[Verde];
         A_aux=arraydimmer[Azul];
    }
    
    void delay(uint8_t DMX_Velocidad) {
    
     // Se toma el valor actual de la velocidad entregada por el DMX, no hace falta esperar que termine el PWM
     // Tiempo Minimo = 3us
     // Tiempo Maximo = 580ms
     // Dividi el tiempo en 2 partes 0..127 para tiempos de micro segundos y 128..255 para tiempos de milisegundos
    
     uint16_t tiempo;
     if (DMX_Velocidad>127)
     { //Tiempo en milisegundos, Recta de 1ms a 508ms
     tiempo = 4*DMX_Velocidad - 511;
     //_delay_ms(tiempo);
     }
     else
     { //Tiempo en microsegundos de 3us a 892us, valores elegidos para que resulte mas facil multiplicarlos
     tiempo = 7*DMX_Velocidad +3;
     //_delay_us(tiempo);
     }
    }
    
    
     //***** inicio del ocilador Temporizador de interrupción ****//
     void ISR(TIMER0_OVF_vect){
          
     if (R_out>=PWM_timer) { salida &= 0x06; }
     if (V_out>=PWM_timer) { salida &= 0x05; }
     if (A_out>=PWM_timer) { salida &= 0x03; }
     if (PWM_timer==255)
     {
     //Cargo los colores nuevos ya que finalizo el ciclo del PWM
     R_out = R_aux;
     V_out = V_aux;
     A_out = A_aux;
     //Observo si se cambio el modo, asi cambio el modo y seteo los valores iniciales de ser necesario
     Cambiarmodo();
     }
     PWM_timer++;
    }
    
     void Cambiarmodo(){
     switch(DMX_Modo&0xC0) // Tomo los 2 bits superiores del Modo que viene del DMX y le hago una AND con 1100 0000, dejando los 2 bits superiores y los demas en 0
     {
     case 0xC0: //Caso RAINBOW_FADING de 192 a 255, los bits con mas pesos siempre se mantienen en 1100
     if(mode!=RAINBOW_FADING) //Reviso que ya no este en este modo.
     {
     mode=RAINBOW_FADING;
     Rojo=255; // Set de colores iniciales
     Verde=0;
     Azul=0;
     estado=0; // Set de estado inicial para el fading
     estador=0; // Set de estado inicial para el rainbow_fading
     }
     break;
     case 0x80: //Case FADING, de 128 a 191, bits de mayor peso quedan siempre en 1000
     if(mode!=FADING) // Si ya esta en el modo, que no lo modifique.
     {
     mode=FADING;
     Rojo=255; // Set de colores iniciales
     Verde=0;
     Azul=0;
     estado=0; // Set de estado inicial para el fading
     }
     break;
     case 0x40: //Case FADING_FIX, de 64 a 127, bits de mayor peso quedan siempre en 0100
     mode=FADING_FIX; // Aqui no importa si esta asignadosele a cada rato , ya que no hay valores iniciales
     break;
     case 0x00: //Case FADING_FIX, de 64 a 127, bits de mayor peso quedan siempre en 0000
     mode=FIXED; // Aqui no importa si esta asignadosele a cada rato , ya que no hay valores iniciales
     break;
     }
     }
 aca los errores
Código: [Seleccionar]
Build started 26.8.2015 at 22:08:44
avr-gcc.exe  -mmcu=atmega8515 -Wall -gdwarf-2 -std=gnu99       -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT fading_raibow.o -MF dep/fading_raibow.o.d  -c  ../fading_raibow.c
../fading_raibow.c:87: warning: braces around scalar initializer
../fading_raibow.c:87: warning: (near initialization for 'ArrayColorFadingRainbow[0]')
../fading_raibow.c:87: warning: excess elements in scalar initializer
../fading_raibow.c:87: warning: (near initialization for 'ArrayColorFadingRainbow[0]')
../fading_raibow.c:88: warning: braces around scalar initializer
../fading_raibow.c:88: warning: (near initialization for 'ArrayColorFadingRainbow[1]')
../fading_raibow.c:88: warning: excess elements in scalar initializer
../fading_raibow.c:88: warning: (near initialization for 'ArrayColorFadingRainbow[1]')
../fading_raibow.c:89: warning: braces around scalar initializer
../fading_raibow.c:89: warning: (near initialization for 'ArrayColorFadingRainbow[2]')
../fading_raibow.c:89: warning: excess elements in scalar initializer
../fading_raibow.c:89: warning: (near initialization for 'ArrayColorFadingRainbow[2]')
../fading_raibow.c: In function 'main':
../fading_raibow.c:145: warning: implicit declaration of function 'DimmerCurva'
../fading_raibow.c:148: warning: implicit declaration of function 'fading_fijo'
../fading_raibow.c:151: warning: implicit declaration of function 'fading_auto'
../fading_raibow.c:154: warning: implicit declaration of function 'rainbow_fader'
../fading_raibow.c: At top level:
../fading_raibow.c:162: warning: conflicting types for 'fading_fijo'
../fading_raibow.c:148: warning: previous implicit declaration of 'fading_fijo' was here
../fading_raibow.c:168: warning: conflicting types for 'fading_auto'
../fading_raibow.c:151: warning: previous implicit declaration of 'fading_auto' was here
../fading_raibow.c: In function 'fading_auto':
../fading_raibow.c:173: warning: implicit declaration of function 'delay'
../fading_raibow.c: At top level:
../fading_raibow.c:187: warning: conflicting types for 'rainbow_fader'
../fading_raibow.c:154: warning: previous implicit declaration of 'rainbow_fader' was here
../fading_raibow.c: In function 'rainbow_fader':
../fading_raibow.c:201: error: subscripted value is neither array nor pointer
../fading_raibow.c:202: error: subscripted value is neither array nor pointer
../fading_raibow.c:203: error: subscripted value is neither array nor pointer
../fading_raibow.c: At top level:
../fading_raibow.c:213: warning: conflicting types for 'DimmerCurva'
../fading_raibow.c:145: warning: previous implicit declaration of 'DimmerCurva' was here
../fading_raibow.c:220: warning: conflicting types for 'delay'
../fading_raibow.c:173: warning: previous implicit declaration of 'delay' was here
../fading_raibow.c:242: error: two or more data types in declaration specifiers
../fading_raibow.c: In function '__vector_7':
../fading_raibow.c:244: error: 'salida' undeclared (first use in this function)
../fading_raibow.c:244: error: (Each undeclared identifier is reported only once
../fading_raibow.c:244: error: for each function it appears in.)
../fading_raibow.c:254: warning: implicit declaration of function 'Cambiarmodo'
../fading_raibow.c: At top level:
../fading_raibow.c:259: warning: conflicting types for 'Cambiarmodo'
../fading_raibow.c:254: warning: previous implicit declaration of 'Cambiarmodo' was here
make: *** [fading_raibow.o] Error 1
Build failed with 7 errors and 30 warnings...
bueno espero que te alla aclarado eso ., o al menos hice el intento de explicartelo  
yo solo se que ...nose nada

Desconectado locodelafonola

  • PIC10
  • *
  • Mensajes: 43
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #35 en: 27 de Agosto de 2015, 01:14:13 »
 
Bueno aca te subo para que veas (en el otro mensaje no me entraba) es para que veas,  es un proyecto que estoy armando ., son lo tres led y dos motores PAP (funciona con 8 y 16 bits )., me funciona perfecto
El problema lo tengo con los motores (todos recuperados )., pero las vueltas y los pasos son ditintos en todos ., pero de funcionar.,  funciona perfectamente
El motivo es para que veas como trabajan los IRS  ., si te fijas NO hay ningun PWM en los IRS ( uso los dos timer del integado ) todos los PWM estan en el WHILIE
Aparte probe con la libreria reformada ., compilo sin error ( tuve que declarar FADING y RAIBOW_FADER
y desabilita perfectamente la recepcion al poner el mini-dips N°10 en ON la consola DMX dice "desabilitado"
o sea que esa parte esta perfecta ., cuando la coloco en OFF mi montaje funciona perfectamente ., de la otra manera ., como es obio ., no funciona PORQUE NO HAY NADA
 
Código: [Seleccionar]
/**** A P P L I C A T I O N   N O T E   ************************************
*
* Title : DMX512 2 axis microstep controller
* Version : v1.1
* Last updated : 03.04.08
* Target : Transceiver Rev.3.01 [ATmega8515]
* Clock : 8MHz
*
* written by hendrik hoelscher, www.hoelscher-hi.de
***************************************************************************
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version2 of
 the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 General Public License for more details.

 If you have no copy of the GNU General Public License, write to the
 Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

 For other license models, please contact the author.

;***************************************************************************/
#include<stdio.h>
#include "lib_indicator.h"
#include "lib_dmx_in.h"
#include <stdlib.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <avr/wdt.h>
#include <util/delay.h>
 //*********************************//
 uint8_t count= 1; //counter für soft PWM
uint8_t IndiCnt= 1; //counter für LED indicator
uint8_t DmxBuf[DMX_CHANNELS];    enum {FIXED,FADING_FIX,FADING,RAINBOW_FADING} mode;
//*** Inicialización pines / port ***//
void init_pinouts(){                   
//DDRA=  0xFF; // salidas bajas
    //PORTA= 0;
    DDRB |= (1<<PB0) | (1<<PB1) | (1<<PB2); // Salida pin LED
    PORTB= 0;
    DDRD |= (1<<PD2); // El selector de la transmisión de salida colocación
    PORTD |= (1<<PD2); // Establecer el estado de la RX 0 - entrada de transmisión

// Temporizador de inicialización para evitar cortar efecto estroboscópico
#define OV_COUNT 14 // 161 metros, 7 no repleta? = 0.25ms
#define OV_SIZE 161 // Worth ?? comenzando Contador inicial
volatile int timer_counter=0;// Contador del temporizador
 // ***** inicializacion del timer****//
void init_timer(){
TCCR0|= (1<<CS02) ; // Precontador 256
TIMSK|= (1<<TOIE0); // desbordamientos de la interrupción
TCNT0= OV_SIZE;
}
// Restablecer el temporizador
void reset_timer(){
TCNT0= OV_SIZE; // Worth ?? comenzando Contador inicial
timer_counter=0;
}
 // *** establecer valor de WHILE y sound_time ***//
enum {FALSE=0, TRUE=1};
volatile char sound_time=TRUE;



//

uint16_t  Accel;
volatile uint8_t   Flags;
uint16_t  IndCnt= 1000;
volatile uint8_t   BasePat;



struct axis{ //all private data for X and Y axes
   uint16_t   Ist; //current position
   uint16_t   Soll; //destination pos
   uint16_t   Max; //max position
           uint8_t   State; //status flags
   int8_t   Speed;      //current speed (raw)
   uint16_t   StpRate;
   uint8_t   TopPat; //PWM pattern
   };
   
struct axis X;
struct axis Y;


enum {TICK, POS_CHANGED};
enum {POS};

#define OFFSET (4)
#define IND_TIME (2200)

#define X_MAX_H (1) //EEPROM usage
#define X_MAX_L (2)
#define Y_MAX_H (3)
#define Y_MAX_L (4)
#define ACC_H (5)
#define ACC_L (6)


const uint8_t bStep[] PROGMEM = { //halfsteps (DCBA DCBA)
0b00010001,
0b01010101,
0b01000100,
0b01100110,
0b00100010,
0b10101010,
0b10001000,
0b10011001,
0b00010001
};
const uint8_t buStep[] PROGMEM = { //1/8 steps
    0b00010001,

0b01010001,
0b01010001,
0b01010001,

0b01010101,

0b01010100,
0b01010100,
0b01010100,

0b01000100,

0b01100100,
0b01100100,
0b01100100,

0b01100110,

0b01100010,
0b01100010,
0b01100010,

0b00100010,

0b10100010,
0b10100010,
0b10100010,

0b10101010,

0b10101000,
0b10101000,
0b10101000,

0b10001000,

0b10011000,
0b10011000,
0b10011000,

0b10011001,

0b10010001,
0b10010001,
0b10010001,

0b00010001
};



const uint8_t Step[] PROGMEM = { //halfsteps
0b00010001,
0b00110011,
0b00100010,
0b01100110,
0b01000100,
0b11001100,
0b10001000,
0b10011001,
0b00010001
};
const uint8_t uStep[] PROGMEM = { //1/8 steps
0b00010001,

0b00110001,
0b00110001,
0b00110001,

0b00110011,

0b00110010,
0b00110010,
0b00110010,

0b00100010,

0b01100010,
0b01100010,
0b01100010,

0b01100110,

0b01100100,
0b01100100,
0b01100100,

0b01000100,

0b11000100,
0b11000100,
0b11000100,

0b11001100,

0b11001000,
0b11001000,
0b11001000,

0b10001000,

0b10011000,
0b10011000,
0b10011000,

0b10011001,

0b10010001,
0b10010001,
0b10010001,

0b00010001
};

const uint16_t uAngle[] PROGMEM = {
0xF0, 176, 90, 41, 0xF0, 41, 90, 176
};



const uint16_t Ramp[] PROGMEM = {//acceleration, deceleration (step durations)
27145, 20829, 17560, 15471, 13987, 12862, 11972, 11244, 10635, 10115, 9665,  9270,  8920,  8606,
8324,  8068,  7834,  7619,  7421,  7238,  7067,  6908,  6760,  6620,  6489,  6366,  6249,  6138,
6033,  5933,  5839,  5748,  5662,  5579,  5500,  5424,  5351,  5281,  5214,  5149,  5087,  5026,
4968,  4912,  4858,  4805,  4754,  4705,  4657,  4611,  4566,  4522
};




// *************** Stepper Homing ****************
void home_stepper(void)
{
//postion reset (homing)
uint8_t tmp, tmpA= 0, tmpB= 0;
X.Ist= (X.Max>>1) +20 +OFFSET;
Y.Ist= (Y.Max>>1) +20 +OFFSET;
uint16_t delay;
while ((X.Ist != OFFSET) || (Y.Ist != OFFSET))
   {
if (X.Ist > OFFSET)
{
if (PIND &(1<<PD4))
{
if (PIND &(1<<PD6)) tmpA= pgm_read_byte(&Step[(--X.Ist &7)]); //move through full range (open loop)
else         tmpA= pgm_read_byte(&bStep[(--X.Ist &7)]);
tmpA &= 0b00001111;
}
else X.Ist= OFFSET; //Anschlag detected (closed loop reference)
}
if (Y.Ist > OFFSET)
{
if (PIND &(1<<PD5))
{
if (PIND &(1<<PD6)) tmpB= pgm_read_byte(&Step[(--Y.Ist &7)]);
else         tmpB= pgm_read_byte(&bStep[(--Y.Ist &7)]);
tmpB &= 0b11110000;
}
else Y.Ist= OFFSET;
}
tmp= tmpA;
tmp |= tmpB;
PORTA= tmp;
wdt_reset();
delay= Accel>>1;
while (delay != 0)
{
_delay_us(35);
delay--;
}
}

}




// *************** Initialization ****************
void init_system(void)
{
wdt_reset();
wdt_enable(WDTO_500MS); //enable watchdog (Timeout= 0.5s)
wdt_reset();

DDRA=  0xFF; //low outputs
PORTA= 0;

DDRD=  0b10000110; //DMX, spare, LED1
PORTD= 0b01111010;

TCCR1A = (1<<WGM10);
TCCR1B = (1<<CS10)|(1<<WGM12); //set T1 @clock freq, 8bit fast PWM
TIMSK |= (1<<TOIE1)|(1<<OCIE1A)|(1<<OCIE1B); //enable compare and overflow interrupts (u-step, system)


if (eeprom_read_byte(0) == 1)
{
X.Max= (uint16_t)(eeprom_read_byte(X_MAX_H)<<8) +(uint16_t)eeprom_read_byte(X_MAX_L);
Y.Max= (uint16_t)(eeprom_read_byte(Y_MAX_H)<<8) +(uint16_t)eeprom_read_byte(Y_MAX_L);
Accel= (uint16_t)(eeprom_read_byte(ACC_H)<<8)   +(uint16_t)eeprom_read_byte(ACC_L);
}
else
{
X.Max= 1600;
Y.Max= 1600;
Accel= 256;
}

     home_stepper();
init_pinouts(); // Establecer los puertos de E / S
init_timer(); // Establecer el temporizador
     init_DMX_RX();


}

// *************** Stepper speed control ****************
void check_speed(struct axis* Stp)
    {
    if (abs(Stp->Soll -Stp->Ist) <= abs(Stp->Speed)) //decel speed short before target position
    {
    if      (Stp->Speed < 0) Stp->Speed++;
    else if (Stp->Speed > 0) Stp->Speed--;
    }

    else if (Stp->Ist < Stp->Soll)//shall move in positive direction
   {
   if (Stp->Speed < 50) Stp->Speed++; //accel speed
   }

   else if (Stp->Ist > Stp->Soll) //shall move in negative direction
  {
  if (Stp->Speed > -50) Stp->Speed--; //accel speed
  }

  if      (Stp->Speed > 0) Stp->Ist++;
  else if (Stp->Speed < 0) Stp->Ist--;

  uint32_t tmp= (uint32_t)pgm_read_word(&Ramp[abs(Stp->Speed)]);
   Stp->StpRate= (tmp * Accel)>>16;
  }
//*************** PROGRAMA PRINCIPAL ************//
int main(void)

{
cli();
init_system(); // iniciar sistema
sei();
int PWM_timer;  // inicializar el timer PWM
char strobo = FALSE;  // valor de strobo
unsigned int strobo_timer=0; // Contador Strobo igual a cero

while(1) // bucle principal (LOOP)
    {
    get_dips(); // establecer direccion de inicio
     //************************************* PWM leds *********************************//
for (PWM_timer=0; PWM_timer<255 ; PWM_timer++)  // Loop timer general en un ciclo de llenado
{

if(DmxRxField[4]>20){ // Si el canal de luz stroboscópica es menor a  10 es siempre mayor que los LED ,el estroboscópico está apagado,
if( strobo_timer>(unsigned int)((255-DmxRxField[4])*16)){// Dmx CH4 igual a 11, es el tiempo máximo , o igual a 255 es el Tiempo min
strobo_timer=0;// Restablecer el temporizador
if(strobo){ strobo=FALSE;}else{ strobo=TRUE;} // Cambio habilitacion para ILUMINACIÓN
}else{
strobo_timer+=1; // base de tiempo strobo
}
}else{
strobo=TRUE; // la Stroboscopica está apagada,
}

if ( ((unsigned int)((DmxRxField[0]*DmxRxField[3])/255)>PWM_timer) && strobo ) //ROJO
{
PORTB &= ~(1<<PB0); //LED OFF
}else{
PORTB |= (1<<PB0); //LED ON
}

if ( ((unsigned int)((DmxRxField[1]*DmxRxField[3])/255)>PWM_timer) && strobo ) //VERDE
{
PORTB &= ~(1<<PB1); //LED OFF
}else{
PORTB |= (1<<PB1); //LED ON
}

if ( ((unsigned int)((DmxRxField[2]*DmxRxField[3])/255)>PWM_timer) && strobo ) //AZUL
{
PORTB &= ~(1<<PB2); //LED OFF
}else{
PORTB |= (1<<PB2); //LED ON

if (Flags &(1<<TICK))
     {
Flags &= ~(1<<TICK);
wdt_reset();
if (IndCnt-- == 0)
{
IndCnt= IND_TIME;
indicate();
}
     if (X.StpRate-- == 0)
{
      uint32_t tmp= ((uint32_t)DmxRxField[5]<<8) +(uint32_t)DmxRxField[6];
     tmp= OFFSET +((tmp * X.Max)>>16);
     if (tmp != X.Soll)
{
X.Soll= tmp;
IndFlags |= (1<<DATA_REFRESHED);
}
check_speed(&X);
Flags |= (1<<POS_CHANGED);
}
if (Y.StpRate-- == 0)
{
uint32_t tmp= ((uint32_t)DmxRxField[7]<<8) +(uint32_t)DmxRxField[8];
     tmp= OFFSET +((tmp * Y.Max)>>16);
     if (tmp != Y.Soll)
{
Y.Soll= tmp;
IndFlags |= (1<<DATA_REFRESHED);
}
check_speed(&Y);
Flags |= (1<<POS_CHANGED);
}

if (Flags &(1<<POS_CHANGED))
{
Flags &= ~(1<<POS_CHANGED);
uint8_t PatBuf;
if (PIND &(1<<PD6))
{
PatBuf= pgm_read_byte(&uStep[(X.Ist &31)]);//get new X pattern
}
else PatBuf= pgm_read_byte(&buStep[(X.Ist &31)]);
OCR1A= pgm_read_word(&uAngle[(X.Ist &0b111)]);
X.TopPat = (PatBuf>>4);
PatBuf= (PatBuf &0b00001111);
uint8_t Ytmp;
    if (PIND &(1<<PD6))
{
Ytmp= pgm_read_byte(&uStep[(Y.Ist &31)]);//get new Y pattern
}
else Ytmp= pgm_read_byte(&buStep[(Y.Ist &31)]);
OCR1B= pgm_read_word(&uAngle[(Y.Ist &0b111)]);
Y.TopPat = (Ytmp &0b11110000);
PatBuf |= (Ytmp<<4);
BasePat= PatBuf;
}
if (count == 0xFF)
{ // Llamado con 122Hz
count= 1;
   Flags |= (1<<IND);       // señalizar
   }
      else count++;
       }
}
  }
}
 
 //***** inicio del ocilador Temporizador de interrupción ****//
ISR(TIMER0_OVF_vect){
int count;
switch(mode){
case FADING;
count = OV_COUNT + DmxAddress;
break;
case RAINBOW_FADER;
count = OV_COUNT + DmxAddress * 10;
break;
default:
count = OV_COUNT;
     }
if(timer_counter>=count){
timer_counter=0;

if (mode==RAINBOW_FADER){

    indicate(); // señalizar con led azul
         }
  }else{ timer_counter++; }
if (Flags &(1<<EVAL_DMX)) // Universo DMX se actualiza
{
Flags &= ~(1<<EVAL_DMX);
IndFlags |= (1<<VALID_DMX); // Señal DMX Válida llegada
uint8_t i;
for (i=0; i<DMX_CHANNELS; i++)
{
if (DmxRxField[i] != DmxBuf[i]) // Un valor DMX ha cambiado?
{
DmxBuf[i]= DmxRxField[i];
IndFlags |= (1<<DATA_REFRESHED); // Sí -> borrar y actualizar dato!
}
}

}

if (Flags &(1<<IND)) // indicador LED, DIP
{
Flags &= ~(1<<IND);
    wdt_reset(); // Restablecer perro guardián

if (--IndiCnt == 0)
{
IndiCnt= 8;
indicate(); // señalizar con led azul
}
}
}




// *************** ISRs ****************
ISR (TIMER1_OVF_vect)
{ //half step
Flags |= (1<<TICK); //tick system
PORTA= BasePat;
}


ISR (TIMER1_COMPA_vect) //X-axis µ-Stepping
{
uint8_t buf;
buf  = PORTA;
buf &= 0b11110000;
buf |= X.TopPat;
PORTA= buf;
}


ISR (TIMER1_COMPB_vect) //Y-Axis µ-Stepping
{
uint8_t buf;
buf  = PORTA;
buf &= 0b00001111;
buf |= Y.TopPat;
PORTA= buf;
}
ac se ve claramente como funcionan los IRS en DMX  .,toma en consideracion que estan los dos timer usandose
yo solo se que ...nose nada

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #36 en: 27 de Agosto de 2015, 02:54:46 »
Citar
pero me largo error ., y calculo que los errores tiene el mismo origen que es el PWM en e lIRS

Ninguno de los errores/warning es debido a eso. Si lees claramente que dice cada uno.

Citar
y te vuelvo a repetir en DMX se tiene que ejecitar en WHILE o FOR pero fuera del IRS
la razon es que te afecta la recepcion del USAT como te explique antes  

Estas muy equivocado. Obviamente puedo hacer un "PWM" en el while. haciendo un for como vos pedis, es TOTALMENTE posible, pero practicamente insano hacerlo. tratar de que cada vuelta del for dure exactamente lo mismo para todos los modos, o posibilidades com oque tome un salto o no es realmente para sacarse el sombrero el que lo hace asi, vuelvo a decir, se puede, pero olvidate que alguien se va a complicar tanto para hacerlo cuando lo puede hacer mas facil, no se como estaras pensandolo vos pero yo me estoy fijando hasta la diferencia en micro segundos. Y lo pienso hasta el punto de ASM y ciclos de reloj.

A continuacion voy a darte una comparacion entre los 2:

Para darte un ejemplo, supongamos un PWM de 2 bits, es decir tenes 25% 50% 75% 100% duty. Esto para ser mucho mas simple y no de 8 bits con 255 pasos.
Que tenga un periodo de 1 segundo la señal de PWM ( Si tiene un periodo, este periodo es FIJO ), Cada seccion deberia poner a 0 o dejarla a 1 a la señal cada 0.25s

Nuestro caso es que tenemos un timer que lo hace cada 0.25s, entonces cuando ocurre eso nos fijamos y listo. si tuvieramos 25% de duty seleccionado, a los 0.25s exactamente verias la señal irse de 1 a 0. Genial. Se cumple con lo previsto
Cambiamos de modo. esto NO afecta al timer. sigue ejecutandose con su periodo inalterable y su duty perfecto.

Ahora imaginate un for(), en el que el primer paso por el for (valores tomados al azar pero que si lo haces en los 255 vas a ver que hay diferencia), le toma 200 instrucciones, el segundo paso le toma 240, el tercero le toma 210, el cuarto 220.

Bueno genial tenemos nuestro periodo, por que va a durar 200+240+210+220 (870) instrucciones, la primer vuelta para vos seria un 25% si usamos la logica que esta planteada. PERO realmente no es un 25% de duty sino que es 200/870 un 23%
Y bueno pero es una diferencia de 2%, nadie lo va a notar. Pero eso es por que yo seleccione valores cercanos, si esa primer vuelta hubiera sido de 50 instrucciones ( y no 200, ahora el total seria de 740 instrucciones ) tu duty (que vos supones de 25%) es de solo 50/740 = 7%. Ahora tenes un error de 18%.

Ahora si vos me aseguras que ese que lo hizo en C ( un lenguaje en el que no tiene control sobre la cantidad de instrucciones en ASM que se traduce en ciclos y tiempo a utilizar ) conto 1 por 1 las instrucciones de ASM por cada vuelta y por cada condicion si es que entra a algun IF o no, o lo que se le ocurra al compilador poner realmente tengo que creer que estas mintiendo.

Sigamos analizando el ejemplo que te di antes. Supone que dentro de ese for() tenes varios modos, no solo 1, tal cual tenemos en nuestro ejemplo FADING, FIJO, etc. el modo anterior duraba en total 740 instrucciones, ahora vamos a un modo mucho mas simple como es el de tener un valor fijo de color. Esto deberia llevar unas 20+20+20+20= 80 ( si todos iguales por que no se pregunta nada, simplemente se asigna y listo), Genial al no tener IF ni nada es fijo en cada una de las vueltas, lo cual mi 25% de duty es realmente mi 25%. Pero tengo que ahora dura un total de 80 instrucciones hacer todo el ciclo. Y exactamente aca le cambie el periodo/frecuencia de mi PWM. Que deberia ser un valor FIJO.

Peor aun y siendo mas estricto, una ves que se termino de hacer las 4 (o 255 si haces de 8 bits) vueltas del for. hay que hacer varias instrucciones mas hasta volver a entrar al for, esto puede tener una duracion fija o varaible, Supongamos que es fija. Analizemos los casos que presentamos ya

50+240+210+230= 740
20+20+20+20=80

Pero ahora tenemos eso y que supongamos sean unos 30 instrucciones mas entre que termina todo el for y vuelve a entrar a otro for

740 + 30
80 + 30

Aun mas GENIAL. estamos modificando aun mas el periodo de la señal, y sorpresa, ya nuestro 100% de duty ni siquiera es 100%.

740/770 = 96%
80/110 = 72%

Y ya no estamos hablando de DMX o lo que sea, sino que estamos hablando ya de no saber que es un PWM ( tanto Software como Hardware ). Por eso te vengo diciendo que es un error de concepto.

------------------

Ya con esto te explique claramente el por que NO debe usarse el for como vos opinas o crees para crear un PWM al menos no para algo tan complejo, lo que esta en ese codigo me parece es una aberracion como esta ejecutado el PWM.
Estoy mas que seguro que cualquier persona aca deberia decirte exactamente lo mismo. Sino sos libre de preguntar en

http://www.todopic.com.ar/foros/index.php?board=8.0

Y pregunta si un PWM deberia hacerse con un for(), por si crees que estoy loco ( aunque un poco no lo niego )
Espero que hasta con este ejemplo veas lo mal que esta aplicado por mas que vos creas que esta bien.

Citar
la razon es que te afecta la recepcion del USAT como te explique antes  

JAMAS, la UART deberia recibir el dato completo pasarlo a un buffer ( en el caso del ATmega8515 es el UDR) y luego seguir recibiendo el otro envio sin molestia al procesador. Cuando se ubica el dato en el buffer, ocurren 2 cosas, se sigue recibiendo datos por la UART y se activa la interrupcion de la UART el cual ubica el dato en donde corresponde, si existen 2 interrupciones juntas como la de la UART y el timer, se atenderia primero una y luego la otra (a no ser que tengan prioridades es una condicion de carrera y no se puede decir cual es primero).Sin afectar a nadie. Si tomara demasiado tiempo la interrupcion de la UART entonces estaria modificando los valores del periodo de la señal. Pero nada mas

Normalmente una interrupcion deberia contener el minimo de codigo para realizar lo que deba y continuar.
El ultimo codigo que me pasaste claramente usa los timers para los motores, estara bien o estara mal? Eso depende. Pero tranquilamente podria haber usado 1 timer al menos y con eso controlar todo.


--------------------------------------------------------


Otra cosa mas a recalcar con respecto a esto:

Citar
Aparte probe con la libreria reformada ., compilo sin error ( tuve que declarar FADING y RAIBOW_FADER

Que compile significa que el codigo esta bien escrito. NADA MAS
Que funcione como debe el codigo es otra cosa, podes tener un codigo que esta bien escrito semanticamente y sintacticamente pero no haga lo que uno trato de hacer estrictamente hablando.

Para terminar esto una consideracion mas.

El programa que te pase  si posee errores como que puse Array[] en ves de Array [3][2] y algunos mas ( que en realidad son 7 errores ) mas unos warning por no tener los prototipos de funciones.
En fin ese programa se abstrae completamente de lo que es el DMX, el DMX deberia funcionar tranquilamente aparte del programa y no afectarlo en ningun motivo.
Se podria separar en 2 partes independientes entre una y otra.
- Hacer el fading con los tiempos que deben ser. (Aqui uso los valores del DMX, y cuando me refiero a valores me refiero a cualquier cosa, podria haber definido 3 registros que me lleguen por SPI y aun asi funcionaria igual)
- Hacer el PWM por software (El cual se actualiza cuando debe y no depende de nadie, toma los valores y hace su trabajo)

El codigo del DMX deberia hacer lo mismo, solamente tomar los valores de la UART y ubicarlos donde deberia. FIN
Con eso tenes una independencia entre cada uno de los codigos, tal ves no se llegue a tal grado de independencia pero aun asi se logra bastante.

Es tu decisión final de como vas a terminar haciendolo al programa y el objetivo de mi post fue hacerte ver (con ejemplos) que estaba mal tu idea de como es un PWM por software. Aun asi sos libre de hacerlo como quieras.
Estoy por igual para responder cualquier duda que se te presente.
« Última modificación: 27 de Agosto de 2015, 09:20:45 por KILLERJC »

Desconectado locodelafonola

  • PIC10
  • *
  • Mensajes: 43
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #37 en: 27 de Agosto de 2015, 22:05:56 »
hola bueno
la verdad que no sabria que desirte amigo. por que eres la primer persona ., que me enseña desde 2013 que empece con los microsy la programacion
En ningun momento pongo en duda o contradigo lo que dices., 
porque me regalas tu experiencia y tu tiempo al compartir lo que apendio
pero le aclaro que no pongo en duda lo que dice.,(y explica con tanto detalle)
y le cuento por que .,yo aprendi solo y adquiri los conosimientos de acuerdo a lo que vi lei y razone
pero son trabjos de otras persionas ., yo jamas podria hacer eso ni mucho menos ( tengo muchisimo que aprender
yo lo pocoque se lo lo se por http://www.hoelscher-hi.de/hendrik/light/ressources.htm alli tiene varios ejemplos para mirar ., y tambien del mismo autor  http://www.hoelscher-hi.de/hendrik/light/openrdm.htm en la parte que dice DMX (a la izquierda) son ejemplos practicos con monyajes y librerias
tambien esta este señor http://www.ulrichradig.de/home/index.php/dmx (aunque aqui hat muchas cosa que no comprendo)
Pero principal inconveniente que tengo ., si yo  a medias se el español ., menos otros idiomas ., como el aleman , ingles , ruso o polaco
Por mas que use el traductor del navegador.,  las explicaciones me resultan incoerentes y menos entendible ., por no ser tecnico
Ahora al mirar los ejemplos de la red., los configuro como estan., si ellos se equivocan ., por supuesto que yo tambien
le suplico que le pegue una mirada ., talvez de esa manera me pueda explicar mejor
porque yo le digo sinseramente no ew visto ningun PWM en el IRS solo los COUNT que los manejan (hay otras formas como la de los motores pero no son PWM)
siseramente he quedado muy confundido ., pero es el precio que paga la ignorancia de las masa
todo lo que usted me explico lo encuentro razonable y logico
es lo otro lo que ya no entiendo
yo solo se que ...nose nada

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #38 en: 27 de Agosto de 2015, 22:24:26 »
Si, los comentarios cuando son en otro idioma son dificiles de agarrar, lo bueno es que el codigo funciona de la misma forma.
Puede que estes confundido por que ya habias asumido que se realizaba asi. Creo que con el ejemplo que te di aunque tal ves exagerado ves cual es la diferencia entre uno y otro. Y el por que se realiza de esa forma.

Por si las dudas, revise las paginas que me pasaste por si alguno cometia el error de hacerlo con un for, y saque estos ejemplos

De las paginas que me pasaste:
http://www.ulrichradig.de/home/index.php/avr/avr-rgb-leds

El codigo tiene esto:


Código: C
  1. ISR (TIMER0_OVF0_vect)
  2. {
  3.         if (pwm_counter++ > 63)
  4.         {
  5.                 PORTB = 0x00;
  6.                 pwm_counter = 0;
  7.         }
  8.         if (pwm_counter > pwm_r) PORTB |= LED_R;
  9.         if (pwm_counter > pwm_g) PORTB |= LED_G;
  10.         if (pwm_counter > pwm_b) PORTB |= LED_B;       
  11. }

Ese no usa DMX, es solo un PWM pero que recibe datos desde la UART, pero ahora vamos a ver un proyecto que usa DMX y realiza un "PWM" parecido ya que en realidad es un control de angulo de fase, pero tiene el mismo principio.
http://www.ulrichradig.de/home/index.php/avr/dmx-dimmer
Aqui lo que usa el codigo:

Ademas del ISR de la UART, tiene esta (Notaras la aplicacion que es identica o igual):
Código: C
  1. ISR (TIMER2_COMPA_vect)
  2. //############################################################################
  3. {
  4.         phase_off_count++;
  5.        
  6.         if(phase_off_count > 90) phase_off_count = 0;
  7.        
  8.         #if SSR_RELAIS1
  9.                 if(phase_off_count>val1)
  10.                 {
  11.                         SSR1_ON
  12.                 }
  13.                 else
  14.                 {
  15.                         SSR1_OFF
  16.                 }
  17.         #endif
  18.        
  19.         #if SSR_RELAIS2
  20.                 if(phase_off_count>val2)
  21.                 {
  22.                         SSR2_ON
  23.                 }
  24.                 else
  25.                 {
  26.                         SSR2_OFF
  27.                 }
  28.         #endif
  29.        
  30.         #if SSR_RELAIS3
  31.                 if(phase_off_count>val3)
  32.                 {
  33.                         SSR3_ON
  34.                 }
  35.                 else
  36.                 {
  37.                         SSR3_OFF
  38.                 }
  39.         #endif
  40.  
  41.         if(dmx_lost<DMX_LOST_TIMEOUT)
  42.         {
  43.                 dmx_lost++;
  44.         }
  45. }

de AVRFreaks:

http://www.avrfreaks.net/projects/8-channel-soft-pwm-dmx-receiver?skey=dmx%20pwm

DMX y un PWM por software de 8 canales ( es decir 8 salidas), Usa el Timer0

Código: C
  1. // Interrupt Service Routine
  2. SIGNAL (SIG_TIMER0_OVF)
  3. {
  4.   static unsigned char pinlevelB=0xFF; // was portmask
  5.   static unsigned char softcount=0xFF;
  6.  
  7.   PORTB = pinlevelB;            // update outputs
  8.  
  9.   if(++softcount == 0){         // increment modulo 256 counter and update
  10.                                 // the compare values only when counter = 0.
  11.     compare[0] = compbuff[0];   // verbose code for speed
  12.     compare[1] = compbuff[1];
  13.     compare[2] = compbuff[2];
  14.     compare[3] = compbuff[3];
  15.     compare[4] = compbuff[4];
  16.     compare[5] = compbuff[5];
  17.     compare[6] = compbuff[6];
  18.     compare[7] = compbuff[7];  // last element should equal CHMAX - 1
  19.  
  20.     pinlevelB = 0xFF;     // set all port pins high
  21.  
  22.   }
  23.   // clear port pin on compare match (executed on next interrupt)
  24.   if(compare[0] == softcount) CH0_CLEAR;
  25.   if(compare[1] == softcount) CH1_CLEAR;
  26.   if(compare[2] == softcount) CH2_CLEAR;
  27.   if(compare[3] == softcount) CH3_CLEAR;
  28.   if(compare[4] == softcount) CH4_CLEAR;
  29.   if(compare[5] == softcount) CH5_CLEAR;
  30.   if(compare[6] == softcount) CH6_CLEAR;
  31.   if(compare[7] == softcount) CH7_CLEAR;
  32.  
  33. } // end of ISR ...
  34.  
  35.  
  36. // *************** DMX Reception ISR ****************
  37. ISR (USART_RX_vect)

No busque muchos proyectos para encontrar eso, directamente busque aquellos con las siglas DMX y PWM, los primeros que abri me encontre con eso. Con esto quiero decirte que no estoy buscando si o si la excusa sino que realmente fueron los primeros que abri.

De la primer pagina que me pasaste ( http://www.hoelscher-hi.de/hendrik/light/dmxled.htm ) ya estan en ASM. pero incluso busque a la izquierda LED y abri el zip para encontrar esto:

Código: ASM
  1. ;interrupt vectors
  2. .org 0 
  3.         rjmp init               ;reset vector address
  4.         reti                    ;External Interrupt0 Vector Address
  5.         reti                    ;External Interrupt1 Vector Address
  6.         reti                    ;Input Capture1 Interrupt Vector Address
  7.         rjmp strobe             ;Output Compare1A Interrupt Vector Address
  8.         reti                    ;Output Compare1B Interrupt Vector Address
  9.         reti                    ;Overflow1 Interrupt Vector Address
  10.         rjmp pwm                ;Overflow0 Interrupt Vector Address
  11.         reti                    ;SPI Interrupt Vector Address
  12.         rjmp get_byte   ;UART Receive Complete Interrupt Vector Address

Utiliza la interrupcion ( por overflow ) del timer0 para generar el PWM. Y la interrupcion de la UART para los datos que llegan.
Y ahora que lo veo tiene un codigo parecido o el mismo al que inicio este hilo. En el que el PWM esta realizado con la interrupcion del Timer0 y aplicado de la misma forma que en todos los demas.

Es decir un contador que cuando llega a un punto se retea , en nuestro caso 255, algunos lo hacen con menos resolucion es decir pasos mas grandes y lo hacen 64. Eso depende de cada uno y el grado de variacion que va a poder tener.

Citar
es lo otro lo que ya no entiendo

Como te dije, sos libre de preguntar que si se la respuesta te la voy a intentar contestar, si no la conozco voy a buscarla, si realmente no me queda claro o no lo se, no me queda otra que decirte que no lo conozco, tal cual hice con lo de DMX. El cual no conocia como era el protocolo hasta que stk500 me dio ese empuje con la Nota de Applicacion.
« Última modificación: 27 de Agosto de 2015, 22:34:16 por KILLERJC »

Desconectado locodelafonola

  • PIC10
  • *
  • Mensajes: 43
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #39 en: 28 de Agosto de 2015, 02:09:04 »
!!!! perfecto mi amigo mas claro imposible ¡¡¡¡
la verdad que talvez habria convenido traducir la primer libreria de este hilo, porque son las mismas librerias DMX ., que yo uso (esta en ASM y la mia en C., pero son del mismo autor)
bueno aca te paso los errores que me da ahora en el primer caso NO ES el PWM ., sino que falta definir la funcion lo que es la palabra "salida" alli tengo tres errores
Código: [Seleccionar]
//***** inicio del ocilador Temporizador de interrupción ****//
     // void ISR(TIMER0_OVF_vect){
           ISR(TIMER0_OVF_vect){
      if (R_out>=PWM_timer) { salida &= 0x06; }
        if (V_out>=PWM_timer) { salida &= 0x05; }
    if (A_out>=PWM_timer) { salida &= 0x03; }
    if (PWM_timer==255)
    {
 
y los errores son estos
Código: [Seleccionar]
../fading_raibow.c:244: error: 'salida' undeclared (first use in this function)
../fading_raibow.c:244: error: (Each undeclared identifier is reported only once
../fading_raibow.c:244: error: for each function it appears in.)
La verdad que mire y pense la compilacion.,  y se que alli queres definir los puertos de salida ., estoy en la duda si te referis a PORTB (PORTB0 ,PORTB1 y PORTB2) 
bueno los otros errores que me larga son aca (lo escribiste antes pero no entendi como cambialos
Código: [Seleccionar]
DimmerCurva();
     
        ArrayColores[ArrayColorFadingRainbow[estador][1]]++; //Sumo
        ArrayColores[ArrayColorFadingRainbow[estador][0]]--; //Resto
        if(!ArrayColores[ArrayColorFadingRainbow[estador][0]]) estador++; //Compruebo que llegue al final, es decir pase por los 255 valores, en este caso cuando llega a 0 y continuo con la otra seccion.
     
        Rojo = Temp_R;
        Azul = Temp_A;
        Verde = Temp_V;
       
        if(estador>=3) estador=0; fading_auto(); //En caso que pase por todos los colores y pasas por el fade comun, tal cual estaba en el otro programa
     
    }
esto es lo que dice el compilador
Código: [Seleccionar]
../fading_raibow.c:201: error: subscripted value is neither array nor pointer
../fading_raibow.c:202: error: subscripted value is neither array nor pointer
../fading_raibow.c:203: error: subscripted value is neither array nor pointer
Espero que pueda compilar., asi probar y trato de hacer un video ., (por ahora pruebo con tras led de 5mm de 30°
pero ya compre 2 led de 20w rgb y estoy esperando que me lleguen
yo solo se que ...nose nada

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #40 en: 28 de Agosto de 2015, 02:34:12 »
../fading_raibow.c:201: error: subscripted value is neither array nor pointer
../fading_raibow.c:202: error: subscripted value is neither array nor pointer
../fading_raibow.c:203: error: subscripted value is neither array nor pointer

Esos imagino que fueron por que lo defini mal, si observas este es el codigo que tengo:

Código: C
  1. const uint8_t ArrayColorFadingRainbow[]={                       // Indice y valor a modificar   {Resta,Suma}
  2.                 {0,1},  //      Rojo-   ->      Verde+
  3.                 {1,2},  //      Verde-  ->      Azul+
  4.                 {2,0}   //      Azul-   ->      Rojo+
  5. };

Cambialo por :

Código: C
  1. const uint8_t ArrayColorFadingRainbow[3][2]={                   // Indice y valor a modificar   {Resta,Suma}
  2.                 {0,1},  //      Rojo-   ->      Verde+
  3.                 {1,2},  //      Verde-  ->      Azul+
  4.                 {2,0}   //      Azul-   ->      Rojo+
  5. };

Citar
La verdad que mire y pense la compilacion.,  y se que alli queres definir los puertos de salida ., estoy en la duda si te referis a PORTB (PORTB0 ,PORTB1 y PORTB2)

Con respecto a salida, fue un error de copy paste, tome el codigo que habia puesto anteriormente en el post y lo pegue, Vos elegis que salidas vas a usar ahi. Basicamente ahi lo que deberia hacer es poner a 0 cada una de los pin de salida. Si supongamos tenes el PORTB0 como salida del rojo

Código: C
  1. if (R_out>=PWM_timer) { PORTB &= ~(1<<PB0); }  // AND 1111 1110 (0xFE) , pone a 0 PORTB0

Desconectado locodelafonola

  • PIC10
  • *
  • Mensajes: 43
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #41 en: 28 de Agosto de 2015, 16:19:43 »
Bueno amigo ., alli probe ., no me funciona., los sintomas son
  • las llaves mini-dips no funcionan., o sea no produce ningun cambio
  • tampoco hay cambio  a la funcion DMX ., (al no cambiar no funciona)
  • los led (encienden los tres) ocila su encendido (pestañeo)  tambien enciende PE0
  • en el traceo de avrstudio ., pasa de las nini-dips  a switch(mode)
si nesesita otra indicacion que pueda aportar para guiarlo  ., aviceme
asi quedo el codigo
Código: [Seleccionar]
  // #define F_CPU 8000000
    #include<util\delay.h>
    #include "lib_dmx_in.h"
    #include<stdio.h>
    #include<stdlib.h>
  
    #include <avr/interrupt.h>
    #include <avr/wdt.h>
 //************************************************************//    
    volatile uint8_t DmxRxField[DMX_CHANNELS];
    uint8_t DmxBuf[DMX_CHANNELS];
 //**********************************************************//    
  
    
    // Dato proveniente de la consola DMX
    
    #define DMX_R DmxRxField[1] //Canal R
    #define DMX_G DmxRxField[2] //Canal G
    #define DMX_B DmxRxField[3] //Canal B
    #define DMX_Modo DmxRxField[4] //Seleccion de Modo
    #define DMX_Velocidad DmxRxField[5] //Seleccion de Velocidad
    
    // Para simplificar los datos del array de colores que estoy usando.
    // ArrayColores contiene los valores RGB del momento
    
    #define Rojo ArrayColores[0]
    #define Verde ArrayColores[1]
    #define Azul ArrayColores[2]
    
    //*********************************//
    
    volatile uint16_t DmxAddress; // Dirección inicial
    
    uint8_t V_out,R_out,A_out; // Valores que se comparan con el PWM
    uint8_t V_aux,R_aux,A_aux; // Valores que se cambia para actualizar el PWM
    uint8_t PWM_timer=0;
    uint8_t estado=0,estador=0; // Estado de los fading
    
    const uint8_t arraydimmer[256]={
     0,     0,    1,    1,    1,    1,    1,    2,
     2,     2,    2,    3,    3,    3,    4,    4,
     4,     5,    5,    5,    6,    6,    7,    7,
     8,     8,    9,    9,   10,   10,   11,   11,
     12,   12,   13,   13,   14,   14,   15,   15,
     16,   16,   17,   17,   18,   18,   19,   19,
     20,   20,   21,   21,   22,   22,   23,   23,
     24,   24,   25,   25,   26,   27,   28,   29,
     30,   30,   31,   32,   33,   34,   35,   36,
     36,   37,   38,   39,   40,   41,   42,   43,
     43,   44,   45,   46,   47,   48,   49,   50,
     51,   52,   52,   53,   54,   55,   56,   57,
     58,   59,   60,   61,   62,   63,   64,   65,
     66,   67,   68,   69,   70,   71,   72,   73,
     74,   75,   76,   77,   78,   79,   80,   81,
     82,   83,   84,   85,   86,   88,   89,   90,
     91,   92,   93,   94,   95,   96,   97,   98,
     99,  100,  102,  103,  104,  105,  106,  107,
     108, 109,  110,  112,  113,  114,  115,  116,
     117, 119,  120,  121,  122,  123,  124,  126,
     127, 128,  129,  130,  132,  133,  134,  135,
     136, 138,  139,  140,  141,  142,  144,  145,
     146, 147,  149,  150,  151,  152,  154,  155,
     156, 158,  159,  160,  161,  162,  164,  165,
     167, 168,  169,  171,  172,  173,  174,  176,
     177, 178,  180,  181,  182,  184,  185,  187,
     188, 189,  191,  192,  193,  195,  196,  197,
     199, 200,  202,  203,  204,  206,  207,  208,
     210, 211,  213,  214,  216,  217,  218,  220,
     221, 223,  224,  226,  227,  228,  230,  231,
     233, 234,  236,  237,  239,  240,  242,  243,
     245, 246,  248,  249,  251,  252,  254,  255
    };
    
    uint8_t ArrayColores[3]={255,0,0}; // Rojo,Verde,Azul
    
    const uint8_t ArrayColorFading[]={ // Indice y valor a modificar {1,2,3} y {-1,-2,-3}
     1, // Rojo -> Amarillo
     0, // Amarilo -> Verde
     2, // Verde -> Cyan
     1, // Cyan -> Azul
     0, // Azul -> Magenta
     2 // Magenta -> Rojo
    };
    
     const uint8_t ArrayColorFadingRainbow[3][2]={ // Indice y valor a modificar {Resta,Suma}
     {0,1}, // Rojo- -> Verde+
     {1,2}, // Verde- -> Azul+
     {2,0} // Azul- -> Rojo+
    };
    
    //************* Inicialización pines / port *****************//
    void init_pinouts(){
        #ifdef USE_DIP
    
        DDRC  = 0; // establecer DIPs
        PORTC  = 0xFF;
        DDRE  &= ~((1<<PE2)|(1<<PE1));
        PORTE |=   (1<<PE2)|(1<<PE1);
     #endif
    
    
     DDRB |= (1<<PB0) | (1<<PB1) | (1<<PB2); // Salida pin LED
     PORTB = 0;
     DDRE  |= (1<<PE0); //LED2 azul indicador
        PORTE = 0;
    
    }
    
    // ***** inicializacion del timer****//
    
    void init_timer(){
     TCCR0|= (1<<CS02) ; // Precontador 256
     TIMSK|= (1<<TOIE0); // desbordamientos de la interrupción
    
     }
    
        
    int main(void)
    {
     //***** Watchdog *****//
     wdt_reset();
     wdt_enable(WDTO_500MS); // Habilitar el watchdog (timeout = 0.5s)
     wdt_reset();
     cli();
     init_pinouts(); // Establecer los puertos de E / S
     init_timer(); // Establecer el temporizador
     init_DMX_RX(); // Inicializar recpcion DMX
     mode = FIXED; //Valores iniciales, hasta que llegue la trama del DMX
     Rojo = 0;
     Verde = 0;
     Azul = 0;
    
     sei();    // habilitar las interupciones globales  ???
    
     while(1) // bucle principal (LOOP)
        {
             get_dips(); // Toma la direccion y la actualiza, esto es para no tener que reiniciar a cada rato el DMX
             switch(mode)
             {
             case FIXED:
             Rojo = DMX_R; // Colores tomados directamente del DMX para fijo
             Verde = DMX_G;
             Azul = DMX_B;
             DimmerCurva(); // Actualizo colores para el PWM
             break;
             case FADING_FIX:
             fading_fijo();
             break;
             case FADING:
             fading_auto();
             break;
             case RAINBOW_FADING:
             rainbow_fader();
             break;
             default:
             break;
             }
        }
    }
    
    void fading_fijo(){
    
    }
    
    
    
    void fading_auto(){
    
     // Valores iniciales seteados cuando se cambia de modo
    
     //Espera
     delay(DMX_Velocidad);  //esperar
     //Cambio los valores, cuando se cambia de modo se procede a setear los valores iniciales
     if(estado%2)
     { //Caso impar
     if(++ArrayColores[estado]==255) estado++;
     }
     else
     { //Caso par
     if(--ArrayColores[estado]==0) estado++;
     }
     if(estado>=6) estado=0;
     DimmerCurva();
    }
    
    void rainbow_fader(){
    
         int Temp_R,Temp_A,Temp_V;
         Temp_R = Rojo;
         Temp_A = Azul;
         Temp_V = Verde;
    
         if (estador==0){ //Caso inicial, Para que comienze con los valores que debe
             Rojo = 255;
             Verde = 0;
             Azul = 0;
         }
         DimmerCurva();
    
       ArrayColores[ArrayColorFadingRainbow[estador][1]]++; //Sumo
       ArrayColores[ArrayColorFadingRainbow[estador][0]]--; //Resto
       if(!ArrayColores[ArrayColorFadingRainbow[estador][0]]) estador++; //Compruebo que llegue al final, es decir pase por los 255 valores, en este caso cuando llega a 0 y continuo con la otra seccion.
    
         Rojo = Temp_R;
         Azul = Temp_A;
         Verde = Temp_V;
        
       if(estador>=3) estador=0; fading_auto(); //En caso que pase por todos los colores y pasas por el fade comun, tal cual estaba en el otro programa
    
    }
    
    void DimmerCurva(){
    
         R_aux=arraydimmer[Rojo];
         V_aux=arraydimmer[Verde];
         A_aux=arraydimmer[Azul];
    }
    
    void delay(uint8_t DMX_Velocidad) {
    
     // Se toma el valor actual de la velocidad entregada por el DMX, no hace falta esperar que termine el PWM
     // Tiempo Minimo = 3us
     // Tiempo Maximo = 580ms
     // Dividi el tiempo en 2 partes 0..127 para tiempos de micro segundos y 128..255 para tiempos de milisegundos
    
     uint16_t tiempo;
     if (DMX_Velocidad>127)
     { //Tiempo en milisegundos, Recta de 1ms a 508ms
     tiempo = 4*DMX_Velocidad - 511;
     //_delay_ms(tiempo);
     }
     else
     { //Tiempo en microsegundos de 3us a 892us, valores elegidos para que resulte mas facil multiplicarlos
     tiempo = 7*DMX_Velocidad +3;
     //_delay_us(tiempo);
     }
    }
    
    
     //***** inicio del ocilador Temporizador de interrupción ****//
          ISR(TIMER0_OVF_vect){
          
     if (R_out>=PWM_timer) { PORTB &= ~(1<<PB0); }  // AND 1111 1110 (0xFE) , pone a 0 PORTB0
      if (V_out>=PWM_timer) { PORTB &= ~(1<<PB1); }  // AND 1111 1110 (0xFE) , pone a 0 PORTB0
     if (R_out>=PWM_timer) { PORTB &= ~(1<<PB2); }  // AND 1111 1110 (0xFE) , pone a 0 PORTB0
     if (PWM_timer==255)
     {
     //Cargo los colores nuevos ya que finalizo el ciclo del PWM
     R_out = R_aux;
     V_out = V_aux;
     A_out = A_aux;
     //Observo si se cambio el modo, asi cambio el modo y seteo los valores iniciales de ser necesario
     Cambiarmodo();
     }
     PWM_timer++;
    }
    
     void Cambiarmodo(){
     switch(DMX_Modo&0xC0) // Tomo los 2 bits superiores del Modo que viene del DMX y le hago una AND con 1100 0000, dejando los 2 bits superiores y los demas en 0
     {
     case 0xC0: //Caso RAINBOW_FADING de 192 a 255, los bits con mas pesos siempre se mantienen en 1100
     if(mode!=RAINBOW_FADING) //Reviso que ya no este en este modo.
     {
     mode=RAINBOW_FADING;
     Rojo=255; // Set de colores iniciales
     Verde=0;
     Azul=0;
     estado=0; // Set de estado inicial para el fading
     estador=0; // Set de estado inicial para el rainbow_fading
     }
     break;
     case 0x80: //Case FADING, de 128 a 191, bits de mayor peso quedan siempre en 1000
     if(mode!=FADING) // Si ya esta en el modo, que no lo modifique.
     {
     mode=FADING;
     Rojo=255; // Set de colores iniciales
     Verde=0;
     Azul=0;
     estado=0; // Set de estado inicial para el fading
     }
     break;
     case 0x40: //Case FADING_FIX, de 64 a 127, bits de mayor peso quedan siempre en 0100
     mode=FADING_FIX; // Aqui no importa si esta asignadosele a cada rato , ya que no hay valores iniciales
     break;
     case 0x00: //Case FADING_FIX, de 64 a 127, bits de mayor peso quedan siempre en 0000
     mode=FIXED; // Aqui no importa si esta asignadosele a cada rato , ya que no hay valores iniciales
     break;
     }
     }
la libreria de dmx .C
Código: [Seleccionar]
#include "lib_dmx_in.h"
//#include "lib_indicator.h"
// ********************* definiciones locales*********************
 
enum {IDLE, BREAK, STARTB, STARTADR};// estados DMX

    
    
  uint8_t gDmxState;
uint8_t *gDmxPnt;
uint16_t DmxCount;  
                                                                                                                                                                                              
//volatile uint8_t gDmxState;
 
 
// *************** DMX recepción de inicialización ****************
void init_DMX_RX(void)
{
#ifdef USE_DIP
 
DDRC  = 0; // establecer DIPs
PORTC  = 0xFF;
DDRE  &= ~((1<<PE2)|(1<<PE1));
PORTE |=   (1<<PE2)|(1<<PE1);
 
#endif
 
DDRD  |= (1<<2);
PORTD &= ~(1<<2);
UBRRH  = 0; // Habilitar recepción
UBRRL  = ((F_OSC/4000)-1);// 250kBaud, 8N2
UCSRC  = (1<<URSEL)|(3<<UCSZ0)|(1<<USBS);
UCSRB  = (1<<RXEN)|(1<<RXCIE);
gDmxState= IDLE;

uint8_t i;
for (i=0; i<DMX_CHANNELS; i++)
{
DmxRxField[i]= 0;
}

}
 
 
 
// ************* obtener DMX dirección de inicio **************
void get_dips(void)
{
#ifdef USE_DIP
uint16_t Temp;
 
if (!(PINE &(1<<PE1))){ // Modo Manual
Temp=  // DMXAdress = tiempo de retardo
(!(PINC &(1<<PC0)) *1) +
(!(PINC &(1<<PC1)) *2) +
(!(PINC &(1<<PC2)) *4) +
(!(PINC &(1<<PC3)) *8) +
(!(PINC &(1<<PC4)) *16) +
(!(PINC &(1<<PC5)) *32) +
     (!(PINC &(1<<PC6)) *64) +
(!(PINC &(1<<PC7)) *128);
DmxAddress= Temp;
if (!(PINE &(1<<PE2))) // Manual,
    {
mode= FADING;
}else{
mode= RAINBOW_FADING;

     }
UCSRB &= ~(1<<RXCIE);// Receptor Desactivar si la dirección de inicio = 0

return;

 }
mode=DMX;
Temp=
(!(PINC &(1<<PC0)) *1) +
(!(PINC &(1<<PC1)) *2) +
(!(PINC &(1<<PC2)) *4) +
(!(PINC &(1<<PC3)) *8) +
(!(PINC &(1<<PC4)) *16) +
(!(PINC &(1<<PC5)) *32) +
(!(PINC &(1<<PC6)) *64) +
(!(PINC &(1<<PC7)) *128) +
(!(PINE &(1<<PE2)) *256);
 
if (Temp != 0)
{
DmxAddress= Temp;
if (!(UCSRB &(1<<RXCIE)))// Si el receptor esta desabilitado -> habilitar y esperar descanso
{
gDmxState= IDLE;
UCSRB |= (1<<RXCIE);

}
}
else
{
UCSRB &= ~(1<<RXCIE); // Receptor Desactivar si la dirección de inicio = 0

uint8_t i;
for (i=0; i<sizeof(DmxRxField); i++)
{
DmxRxField[i]= 0;
}
}
 
#endif
}
 
 
 
// *************** DMX recepción ISR ****************//
ISR (UART_RX_vect)
{
static  uint16_t DmxCount;
uint8_t  USARTstate= UCSRA; // Obtener estado antes de los datos!
uint8_t  DmxByte   = UDR; // Obtener los datos
uint8_t  DmxState  = gDmxState;// Cargar una sola vez de SRAM para aumentar la velocidad
  
if (DmxState == BREAK)
{
UCSRA &= ~(1<<FE); // Cambiar Posible FE: a causa de MAB
if (DmxByte == 0)
{
gDmxState= STARTB;// Código de inicio normal detectado
gDmxPnt= ((uint8_t*)DmxRxField +1);
}
else
{
gDmxState= IDLE;
}
}

else if (USARTstate &(1<<FE)) // Comprobar para el descanso de la señal
{
UCSRA &= ~(1<<FE); // Restablecer bandera
if (DmxByte == 0) // Los datos de descanso debe ser 0
{
gDmxState= BREAK;
DmxCount= DmxAddress; // Restablecer contador de fotogramas
}
else
{
gDmxState= IDLE; // Bien es FE -> esperar descanso
}
}

else if (DmxState == STARTB)
{
if (--DmxCount == 0)// Dirección inicial alcanzada?
{
gDmxState= STARTADR;
DmxRxField[0]= DmxByte;
}
}

else if (DmxState == STARTADR)
{
uint8_t *DmxPnt;
DmxPnt= gDmxPnt;
*DmxPnt= DmxByte;
if (++DmxPnt >= (DmxRxField + DMX_CHANNELS )) // los (CHANNEL) canales recibidos?
{
Flags |= (1<<EVAL_DMX);// Conjunto de datos listo -> eval en principal (MAIN)
gDmxState= IDLE;
}
else
{
gDmxPnt= DmxPnt;
}
}
}

y la libreria dmx.H
Código: [Seleccionar]
#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>
#define DMX_CHANNELS    (13)
#define  USE_DIP
#define  F_OSC (8000) // Frec oscilador. en kHz (8MHz típico o 16MHz)
enum {EVAL_DMX, IND};
volatile uint8_t Flags;
enum {FIXED,FADING_FIX,FADING,RAINBOW_FADING,DMX} mode;
volatile uint16_t DmxAddress; // Dirección inicial
volatile int  color_number;// numero de la tabla de Color del sonido / manual actual
volatile uint8_t DmxRxField[DMX_CHANNELS]; // Conjunto de vals DMX (cruda)
extern void    init_DMX_RX(void);
extern void    get_dips(void);
extern void    set_color(int color);

yo solo se que ...nose nada

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #42 en: 28 de Agosto de 2015, 20:31:48 »
Ya voy a ver cual es el problema. Se me ocurren algunas cosas que puede haber mal.

Citar
las llaves mini-dips no funcionan., o sea no produce ningun cambio
tampoco hay cambio  a la funcion DMX ., (al no cambiar no funciona)

Algun conflicto en como se toman los datos, ademas veo que usas el "mode" ahi dentro del codigo del DMX, el cual no deberias, la libreria de DMX deberia ser totalmente ajena a como es el programa principal, sino cada vez que compilas un codigo tenes que reformar la libreria, tambien cada uno de los codigos hace uso de variables que no me parecen estar bien definidas. Ya que el .hex lo esta definiendo en el main.c y en la libreria de DMX .c y poseen un scope de file por lo que a no ser que se use un extern no podrias acceder a la otra. Por otro lado tampoco deberias. Tampoco se por que estan definidas las funciones con "extern" en el .h.
En fin ya voy a verla y lo modifico y ves como queda.

Una pregunta El DIP
Los bits de 0 a 6 es la direccion y el 7 lo queres poner manual/dmx ?
Por que si es asi tengo que reformar el programa :P un poquito

Citar
los led (encienden los tres) ocila su encendido (pestañeo)  tambien enciende PE0

Yo le quite todo el soporte a PE0 , antes encendia y apagaba a cada ratito. simplmente opte por quitarlo. debe encenderse al comienzo del programa sino no se por que lo hace.
Con respecto a que los leds pestañeen puede ser que este mal configurado el tiempo del timer. ya que no le preste atencion a los tiempos de carga ni preescalers.
Otra causa puede ser el WDT, se podria quitar para probar inicialmente el codigo. Tenes que recordar que hay delays que duran hasta 580ms y vos tenes un WDT de 0.5s ( si es que llega a ese tiempo )

Citar
en el traceo de avrstudio ., pasa de las nini-dips  a switch(mode)
Realmente no se por que.
Ahora simplemente tengo que ver todos los codigos para ver que esta pasando.
« Última modificación: 28 de Agosto de 2015, 20:38:29 por KILLERJC »

Desconectado locodelafonola

  • PIC10
  • *
  • Mensajes: 43
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #43 en: 28 de Agosto de 2015, 23:10:03 »
hola
bueno yo tambientenia dudas de eso y compile con otra libria dmx_in  pero paso lo mismo ., el pin N° 10 no desabilita ni habilita
no se enque parte de tu codigo esta esa llave talves como compilo tenga dos funciones y no una
la libreria que probe que te dije  es esta
 
Código: [Seleccionar]
/**** A P P L I C A T I O N   N O T E   ************************************
*
* Title : DMX512 reception library
* Version : v1.3
* Last updated : 13.04.09
* Target : Transceiver Rev.3.01 [ATmega8515]
* Clock : 8MHz, 16MHz
*
*
***************************************************************************
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version2 of
 the License, or (at your option) any later version.

;***************************************************************************/

#include "lib_dmx_in.h"

// ********************* local definitions *********************

enum {IDLE, BREAK, STARTB, STARTADR}; //DMX states

volatile uint8_t gDmxState;


// *************** DMX Reception Initialisation ****************
void init_DMX_RX(void)
{
#ifdef USE_DIP
DDRC   = 0; //set up DIPs
PORTC  = 0xFF;
DDRE  &= ~((1<<PE2)|(1<<PE1));
PORTE |=   (1<<PE2)|(1<<PE1);
#endif

DDRD  |= (1<<2);
PORTD &= ~(1<<2);
UBRRH  = 0; //enable reception
UBRRL  = ((F_OSC/4000)-1); //250kbaud, 8N2
UCSRC  = (1<<URSEL)|(3<<UCSZ0)|(1<<USBS);
UCSRB  = (1<<RXEN)|(1<<RXCIE);
gDmxState= IDLE;
}



// ************* get DMX start address **************
void get_dips(void)
{
#ifdef USE_DIP
uint16_t Temp= (0xFF-PINC);//invert DIP state
if (!(PINE &(1<<2)))
{
Temp += 256; //9th bit
}
if (Temp != 0)
{
DmxAddress= Temp;
if (!(UCSRB &(1<<RXCIE))) //if receiver was disabled -> enable and wait for break
{
gDmxState= IDLE;
UCSRB |= (1<<RXCIE);
}
}
else
{
UCSRB &= ~(1<<RXCIE);//disable Receiver if start address = 0
uint8_t i;
for (i=0; i<sizeof(DmxRxField); i++)
{
DmxRxField[i]= 0;
}
}
#endif
}



// *************** DMX Reception ISR ****************
ISR (UART_RX_vect)
{
static  uint16_t DmxCount;
uint8_t  USARTstate= UCSRA;//get state before data!
uint8_t  DmxByte   = UDR;//get data
uint8_t  DmxState  = gDmxState; //just load once from SRAM to increase speed
 
if (USARTstate &(1<<FE))//check for break
{
UCSRA &= ~(1<<FE); //reset flag (necessary for simulation in AVR Studio)
DmxCount =  DmxAddress; //reset channel counter (count channels before start address)
gDmxState= BREAK;
}

else if (DmxState == BREAK)
{
if (DmxByte == 0) gDmxState= STARTB;//normal start code detected
else   gDmxState= IDLE;
}

else if (DmxState == STARTB)
{
if (--DmxCount == 0) //start address reached?
{
DmxCount= 1;//set up counter for required channels
DmxRxField[0]= DmxByte;//get 1st DMX channel of device
gDmxState= STARTADR;
}
}

else if (DmxState == STARTADR)
{
DmxRxField[DmxCount++]= DmxByte;//get channel
if (DmxCount >= sizeof(DmxRxField)) //all ch received?
{
gDmxState= IDLE; //wait for next break
}
}
}

corregi lo dela libreria .H  quedo asi
Código: [Seleccionar]
#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>
#define DMX_CHANNELS    (13)
#define  USE_DIP
#define  F_OSC (8000) // Frec oscilador. en kHz (8MHz típico o 16MHz)
enum {FIXED,FADING_FIX,FADING,RAINBOW_FADING,DMX} mode;
volatile uint16_t DmxAddress; // Dirección inicial
enum {EVAL_DMX, IND};
volatile uint8_t Flags;
volatile uint8_t DmxRxField[DMX_CHANNELS]; // Conjunto de vals DMX (cruda)
extern void    init_DMX_RX(void);
extern void    get_dips(void);


Y hace lo mismo .,
En cuanto a lo MINI-DIPS si te fijas el la ultima libreria que subi (es distinta a la otra ., esta es la original sin reformas) prestale atencion a los dips., porque esta dedinidos a GND ., ojo (la otra tambien ) pero eran del PINC0 a PINC7 y PINE1 , PINE2 tiene dos posiciones definidas !!!!pero ojo son 9 llaves la de dmx NO 8 ¡¡¡
la llave N° 10 no se usa como direccion sino que se usa como conmutador , (en off DMX y en on (lo que quiera hacer manual ) ., si o si es reservada funcion DMX NO se TOCA porque es la que desabilita la recepcion """ if (!(UCSRB &(1<<RXCIE)))   //if receiver was disabled -> enable and wait for break """ ., sin pasa lo que ahora.,  no funciana dmx (peroesta habilitado
Esa era mi incitencia ., que usaras las llaves del primer array ., porque el segundo era para dmx .,y se leen con la funcion GEP_dip ., asi de facil (se use o no la recepcion de DMX., igual te las lee   
el WDT lo desgrabe de la configuracion de fuses """"" wdt_enable(WDTO_500MS);""" y son 500ms .,pero no es alli el problema ., pero hace el mismo defecto .(fijate que no esta puesto o conectado el pin RESET del uC)
cualquier otro dato que nesesites te lo aporto
« Última modificación: 29 de Agosto de 2015, 14:59:15 por locodelafonola »
yo solo se que ...nose nada

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #44 en: 31 de Agosto de 2015, 03:44:30 »
Por fin termine el codigo, no se que tal estara ya que no se TODOS los errores que pueden salir, debido a que no lo compile :P. A partir de aca creo que estas solo pero no voy a poder dedicarle mucho tiempo como ya lo hice, por que necesito dedicarme a otras cosas que tengo que hacer. Pero cuando tenga un tiempo te doy una mano.

main.c
Código: C
  1. /*
  2.  *  DMX_RGB FADING/FIXED/RAINBOW
  3.  *
  4.  *  Created on: 23/08/2015
  5.  *  Author:
  6.  */
  7.  
  8.  
  9.  
  10. /*
  11.  *  SECCION DE INCLUDES
  12.  *
  13.  */
  14.  
  15. // Include para la definicion de las variables
  16. #include <stdint.h>
  17.  
  18. // Include liberias del micro, Interrupcion / WDT / delay
  19.  
  20. #include <util\delay.h>
  21. #include <avr/interrupt.h>
  22. //#include <avr/wdt.h>
  23.  
  24.  
  25. // Include funcione de DMX
  26. #include "dmx.h"
  27.  
  28. /*
  29.  *
  30.  *  PROTOTIPOS DE FUNCIONES
  31.  *
  32.  *
  33.  */
  34.  
  35. // Funciones de inicializacion de modulos
  36. void vInitPinout(void);
  37. void vInitTimer0(void);
  38.  
  39. //Funciones Auxiliares
  40. void DimmerCurva(void);
  41. void delay(void);
  42. void Cambiarmodo(void);
  43.  
  44. // Modos
  45. void fixed_color(void);
  46. void fading_fijo(void);
  47. void fading_auto(void);
  48. void rainbow_fader(void);
  49.  
  50. /*
  51.  *
  52.  *
  53.  * DEFINICION DE VARIABLES
  54.  *
  55.  *
  56.  */
  57.  
  58. enum {FIXED,FADING_FIX,FADING,RAINBOW_FADING} mode,last_mode;
  59.  
  60. // Dato proveniente de la consola DMX
  61.  
  62. extern uint8_t DmxRxField[DMX_CHANNELS];        // Valores externos tomados desde la libreria.
  63.  
  64. #define DMX_R                   DmxRxField[1]   //Canal R
  65. #define DMX_G                   DmxRxField[2]   //Canal G
  66. #define DMX_B                   DmxRxField[3]   //Canal B
  67. #define DMX_Modo                DmxRxField[4]   //Seleccion de Modo
  68. #define DMX_Velocidad   DmxRxField[5]   //Seleccion de Velocidad
  69.  
  70. // Para simplificar los datos del array de colores que estoy usando.
  71. // ArrayColores contiene los valores RGB del momento
  72.  
  73. #define Rojo                    ArrayColores[0]
  74. #define Verde                   ArrayColores[1]
  75. #define Azul                    ArrayColores[2]
  76.  
  77. // Definicion de salidas para los colores
  78.  
  79. #define DDR_PWM                 DDRB
  80. #define PORT_PWM                PORTB
  81. #define PWM_R                   PB0
  82. #define PWM_G                   PB1
  83. #define PWM_B                   PB2
  84.  
  85. //*********************************//
  86.  
  87. uint8_t V_out,R_out,A_out;                                              // Valores que se comparan con el PWM
  88. uint8_t V_aux,R_aux,A_aux;                                              // Valores que se cambia para actualizar el PWM
  89. uint8_t PWM_timer=0,Alpha;
  90. uint8_t estado=0,estador=0;                                     // Estado de los fading
  91.  
  92. const uint8_t arraydimmer[256]={
  93.                  0,     0,    1,    1,    1,    1,    1,    2,
  94.                  2,     2,    2,    3,    3,    3,    4,    4,
  95.                  4,     5,    5,    5,    6,    6,    7,    7,
  96.                  8,     8,    9,    9,   10,   10,   11,   11,
  97.                  12,   12,   13,   13,   14,   14,   15,   15,
  98.                  16,   16,   17,   17,   18,   18,   19,   19,
  99.                  20,   20,   21,   21,   22,   22,   23,   23,
  100.                  24,   24,   25,   25,   26,   27,   28,   29,
  101.                  30,   30,   31,   32,   33,   34,   35,   36,
  102.                  36,   37,   38,   39,   40,   41,   42,   43,
  103.                  43,   44,   45,   46,   47,   48,   49,   50,
  104.                  51,   52,   52,   53,   54,   55,   56,   57,
  105.                  58,   59,   60,   61,   62,   63,   64,   65,
  106.                  66,   67,   68,   69,   70,   71,   72,   73,
  107.                  74,   75,   76,   77,   78,   79,   80,   81,
  108.                  82,   83,   84,   85,   86,   88,   89,   90,
  109.                  91,   92,   93,   94,   95,   96,   97,   98,
  110.                  99,  100,  102,  103,  104,  105,  106,  107,
  111.                  108, 109,  110,  112,  113,  114,  115,  116,
  112.                  117, 119,  120,  121,  122,  123,  124,  126,
  113.                  127, 128,  129,  130,  132,  133,  134,  135,
  114.                  136, 138,  139,  140,  141,  142,  144,  145,
  115.                  146, 147,  149,  150,  151,  152,  154,  155,
  116.                  156, 158,  159,  160,  161,  162,  164,  165,
  117.                  167, 168,  169,  171,  172,  173,  174,  176,
  118.                  177, 178,  180,  181,  182,  184,  185,  187,
  119.                  188, 189,  191,  192,  193,  195,  196,  197,
  120.                  199, 200,  202,  203,  204,  206,  207,  208,
  121.                  210, 211,  213,  214,  216,  217,  218,  220,
  122.                  221, 223,  224,  226,  227,  228,  230,  231,
  123.                  233, 234,  236,  237,  239,  240,  242,  243,
  124.                  245, 246,  248,  249,  251,  252,  254,  255
  125. };
  126.  
  127. uint8_t ArrayColores[3]={255,0,0};                      // Rojo,Verde,Azul
  128.  
  129. const uint8_t ArrayColorFading[6]={                     // Indice y valor a modificar   {0,1,2} = {R,G,B} ; indice par = incremento ; indice impar = decremento
  130.                  1,     //      Rojo    ->      Amarillo
  131.                  0,     //      Amarilo ->      Verde
  132.                  2,     //      Verde   ->      Cyan
  133.                  1,     //      Cyan    ->      Azul
  134.                  0,     //      Azul    ->      Magenta
  135.                  2      //      Magenta ->      Rojo
  136. };
  137.  
  138. const uint8_t ArrayColorFadingRainbow[3][2]={                   // Indice y valor a modificar   {Decremento,Incremento}
  139.                 {0,1},  //      Rojo-   ->      Verde+
  140.                 {1,2},  //      Verde-  ->      Azul+
  141.                 {2,0}   //      Azul-   ->      Rojo+
  142. };
  143.  
  144. /*
  145.  *
  146.  *
  147.  *  CODIGOS DE INICIALIZACION DE MODULOS
  148.  *
  149.  *
  150.  */
  151.  
  152. //************* Inicialización pines / port *****************//
  153. void vInitPinout(void){
  154.  
  155.         // Configuracion de las llaves DIP para el DMX
  156.  
  157.     // Configuracion de salidas
  158.         DDR_PWM |= (1<<PWM_R) | (1<<PWM_G) | (1<<PWM_B);                // Salida pin LEDs , PB0 = Rojo, PB1 = Verde, PB2 = Azul
  159.         PORT_PWM = 0;
  160.         DDRE  |= (1<<PE0);                              // LED indicador de funcionamiento en PE0
  161.     PORTE = 0;
  162.  
  163. }
  164.  
  165. // ***** inicializacion del timer****//
  166.  
  167. void vInitTimer0(void){
  168.                 TCCR0= (1<<CS00) ;      // Preescaler 1:1
  169.                 TIMSK|= (1<<TOIE0);     // desbordamientos de la interrupción
  170. }
  171.  
  172. /*
  173.  *
  174.  *
  175.  *  PROGRAMA PRINCIPAL
  176.  *
  177.  *
  178.  */
  179.  
  180. int main(void)
  181. {
  182.  
  183.         vInitPinout();          // Establecer los puertos de E / S
  184.         vInitTimer0();          // Establecer el timer
  185.         vInit_DMX_RX();         // Iniciar la UART y puertos para la llave DIP
  186.  
  187.         last_mode = mode = FIXED;               //Valores iniciales, hasta que llegue la trama del DMX
  188.         Rojo = 0;
  189.         Verde = 0;
  190.         Azul = 0;
  191.  
  192.         sei();              // habilitar las interupciones, Timer/UART(DMX) habilitados
  193.  
  194.         while(1)        // bucle principal (LOOP)
  195.             {
  196.                         if(!bGetDips()){last_mode=mode=FADING;}         // Pregunto si esta activo el DMX y Toma la direccion y la actualiza, tambien desabilita el DMX de ser necesario
  197.                 if(last_mode!=mode){Cambiarmodo();}                     // Caso que desde el DMX se pida cambiar el modo, cambia unicamente cuando termino la rutina
  198.                 switch(last_mode)
  199.                 {
  200.                 case FIXED:
  201.                                 fixed_color();
  202.                                 break;
  203.                 case FADING_FIX:
  204.                                 fading_fijo();
  205.                                 break;
  206.                 case FADING:
  207.                                 fading_auto();
  208.                                 break;
  209.                 case RAINBOW_FADING:
  210.                                 rainbow_fader();
  211.                                 break;
  212.                 default:
  213.                                 break;
  214.                 }
  215.             }
  216. }
  217.  
  218. /*
  219.  *
  220.  *
  221.  *  MODOS DE OPERACION
  222.  *
  223.  *  fixed_color() - Color fijo, tomado desde el DMX.
  224.  *  fading_fijo() - Produce el efecto de fading con el color tomado del DMX, pero solo ese color, de 0 a 255.
  225.  *  fading_auto() - Comienza la ejecucion de fading de distintos colores, solo toma en cuenta la velocidad, solo 1 color a la ves.
  226.  *  rainbow_fading() - Agregado al  fading_auto(), en caso que se seleccione este, se modificaran 2 colores en ves de 1.
  227.  */
  228.  
  229. void fixed_color(void){
  230.         Rojo = DMX_R;           // Colores tomados directamente del DMX para fijo
  231.         Verde = DMX_G;
  232.         Azul = DMX_B;
  233.         DimmerCurva();          // Actualizo colores para el PWM
  234. }
  235.  
  236. void fading_fijo(void){
  237.         Rojo = DMX_R * (Alpha/255);             // Colores tomados directamente del DMX para fijo
  238.         Verde = DMX_G * (Alpha/255);
  239.         Azul = DMX_B * (Alpha/255);
  240.         DimmerCurva();
  241.         Alpha++;
  242.         delay();
  243. }
  244.  
  245.  
  246.  
  247. void fading_auto(void){
  248.  
  249.                 // Valores iniciales seteados cuando se cambia de modo
  250.  
  251.                 //Espera
  252.                 delay();  //esperar
  253.                 //Cambio los valores, cuando se cambia de modo se procede a setear los valores iniciales
  254.                 if(estado%2)
  255.                 {       //Caso impar
  256.                         if(++ArrayColores[estado]==255) estado++;
  257.                 }
  258.                 else
  259.                 {       //Caso par
  260.                         if(--ArrayColores[estado]==0) estado++;
  261.                 }
  262.                 if(estado>=6) estado=0;
  263.                 DimmerCurva();
  264. }
  265.  
  266. void rainbow_fader(void){
  267.  
  268.         int Temp_R,Temp_A,Temp_V;
  269.         Temp_R = Rojo;
  270.         Temp_A = Azul;
  271.         Temp_V = Verde;
  272.  
  273.         if (estador==0){                                                                                                        //Caso inicial, Para que comienze con los valores que debe
  274.                 Rojo = 255;
  275.                 Verde = 0;
  276.                 Azul = 0;
  277.         }
  278.         DimmerCurva();
  279.  
  280.                 ArrayColores[ArrayColorFadingRainbow[estador][1]]++;                            //Sumo
  281.                 ArrayColores[ArrayColorFadingRainbow[estador][0]]--;                            //Resto
  282.                 if(!ArrayColores[ArrayColorFadingRainbow[estador][0]]) estador++;       //Compruebo que llegue al final, es decir pase por los 255 valores, en este caso cuando llega a 0 y continuo con la otra seccion.
  283.  
  284.         Rojo = Temp_R;
  285.         Azul = Temp_A;
  286.         Verde = Temp_V;
  287.  
  288.                 if(estador>=3) estador=0; fading_auto();                                                        //En caso que pase por todos los colores y pasas por el fade comun, tal cual estaba en el otro programa
  289.  
  290. }
  291.  
  292. /*
  293.  *
  294.  *
  295.  *  UTILIDADES
  296.  *
  297.  *
  298.  * DimmerCurva() - Actualiza los colores para que el PWM tome los valores nuevos
  299.  * delay() - Demora introducida para modificar la velocidad de los efectos
  300.  * Cambiarmodo() - Funcion usada que toma el valor del DMX, traduciendolo y efectua el cambio.
  301.  */
  302.  
  303. void DimmerCurva(void){
  304.  
  305.         R_aux=arraydimmer[Rojo];
  306.         V_aux=arraydimmer[Verde];
  307.         A_aux=arraydimmer[Azul];
  308. }
  309.  
  310. void delay(void) {
  311.  
  312.         // Se toma el valor actual de la velocidad entregada por el DMX, no hace falta esperar que termine el PWM
  313.         // Tiempo Minimo = 3us
  314.         // Tiempo Maximo = 580ms
  315.         // Dividi el tiempo en 2 partes 0..127 para tiempos de micro segundos y 128..255 para tiempos de milisegundos
  316.  
  317.         uint16_t tiempo;
  318.         if (DMX_Velocidad>127)
  319.         {       //Tiempo en milisegundos, Recta de 1ms a 508ms
  320.                 tiempo = 4*DMX_Velocidad - 511;
  321.                 //_delay_ms(tiempo);
  322.         }
  323.         else
  324.         {       //Tiempo en microsegundos de 3us a 892us, valores elegidos para que resulte mas facil multiplicarlos
  325.                 tiempo = 7*DMX_Velocidad +3;
  326.                 //_delay_us(tiempo);
  327.         }
  328. }
  329.  
  330.  
  331. void Cambiarmodo(void){
  332.  
  333.          last_mode=mode;
  334.  
  335.          switch(mode)   // Tomo los 2 bits superiores del Modo que viene del DMX y le hago una AND con 1100 0000, dejando los 2 bits superiores y los demas en 0
  336.          {
  337.          case RAINBOW_FADING:           //Caso RAINBOW_FADING de 192 a 255, los bits con mas pesos siempre se mantienen en 1100
  338.                  Rojo=255;                              // Set de colores iniciales
  339.                  Verde=0;
  340.                  Azul=0;
  341.                  estado=0;                              // Set de estado inicial para el fading
  342.                  estador=0;                             // Set de estado inicial para el rainbow_fading
  343.                  break;
  344.          case FADING:                           //Case FADING, de 128 a 191, bits de mayor peso quedan siempre en 1000
  345.                  Rojo=255;                              // Set de colores iniciales
  346.                  Verde=0;
  347.                  Azul=0;
  348.                  estado=0;                              // Set de estado inicial para el fading
  349.                  break;
  350.          default:                                       //Case FADING_FIX, de 64 a 127, y FIXED, de 0 a 63. Bits de mayor peso quedan siempre en 01 y 00
  351.                  break;
  352.          }
  353.  }
  354.  
  355. void SetMode(void){
  356.  
  357.          switch(DMX_Modo&0xC0)  // Tomo los 2 bits superiores del Modo que viene del DMX y le hago una AND con 1100 0000, dejando los 2 bits superiores y los demas en 0
  358.          {
  359.          case 0xC0:                                             //Caso RAINBOW_FADING de 192 a 255, los bits con mas pesos siempre se mantienen en 1100
  360.                  mode=RAINBOW_FADING;
  361.                  break;
  362.          case 0x80:                                             //Case FADING, de 128 a 191, bits de mayor peso quedan siempre en 1000
  363.                  mode=FADING;
  364.                  break;
  365.          case 0x40:                                             //Case FADING_FIX, de 64 a 127, bits de mayor peso quedan siempre en 0100
  366.                  mode=FADING_FIX;                       // Aqui no importa si esta asignadosele a cada rato , ya que no hay valores iniciales
  367.                  break;
  368.          case 0x00:                                             //Case FADING_FIX, de 64 a 127, bits de mayor peso quedan siempre en 0000
  369.                  mode=FIXED;                            // Aqui no importa si esta asignadosele a cada rato , ya que no hay valores iniciales
  370.                  break;
  371.          }
  372.  }
  373.  
  374.  /*
  375.   *
  376.   *
  377.   *  ESPACIO PARA INTERRUPCIONES
  378.   *
  379.   *
  380.   *  Timer0 - Por Overflow - Para el PWM por software
  381.   *  UART - RX - Para el DMX
  382.   */
  383.  
  384.  
  385.  void ISR(TIMER0_OVF_vect){
  386.  
  387.         if (!PWM_timer) PORT_PWM |= ((1<<PWM_R)|(1<<PWM_R)|(1<<PWM_R));         // Si es 0 el PWM_timer pone a 1 las salidas
  388.         if (R_out>=PWM_timer) { PORT_PWM &= ~(1<<PWM_R); }                                      // Cuando se cumple el tiempo las pone a 0, es decir cuando tenga 255 es el maximo que van a estar encendidas
  389.         if (V_out>=PWM_timer) { PORT_PWM &= ~(1<<PWM_G); }
  390.         if (A_out>=PWM_timer) { PORT_PWM &= ~(1<<PWM_B); }
  391.         if (PWM_timer==255)
  392.         {
  393.                 //Cargo los colores nuevos ya que finalizo el ciclo del PWM
  394.                 R_out = R_aux;
  395.                 V_out = V_aux;
  396.                 A_out = A_aux;
  397.                 //Observo si se cambio el modo, si cambio el modo cargo el nuevo modo y espero que el programa principal termine lo que estaba haciendo para comenzar con el nuevo modo
  398.                 SetMode();
  399.         }
  400.         PWM_timer++;
  401. }
  402.  
  403.  
  404.  void ISR (UART_RX_vect)
  405.  {
  406.          vHook_DMX_UART();
  407.  }

dmx.h
Código: C
  1. /*
  2.  *  dmx.h
  3.  *
  4.  *  Created on: 30/08/2015
  5.  *      Author:
  6.  */
  7.  
  8. #ifndef DMX_H_
  9. #define DMX_H_
  10.  
  11. // Definiciones para el DMX
  12.  
  13. #define         F_OSC   (8000)                          // Frec oscilador, para setear la UART
  14. #define         DMX_CHANNELS  6                         // Cantidad de canales usados en el DMX
  15.  
  16. // Habilita el uso del DIP en caso no NO estar habilitado es necesario definir una direccion
  17.  
  18. #define         USE_DIP
  19. #define         DMX_ADDRESS     0x1FF
  20.  
  21. // Definicion de pines para el DIP del DMX
  22.  
  23. #define         PORT_DIP_C      PORTC                   // Puerto Completo
  24. #define         DDR_DIP_C       DDRC
  25. #define         PIN_DIP_C       PINC
  26.  
  27. #define         PORT_DIP_I      PORTE                   // Puerto incompleto , Pines que faltan para completar el DIP
  28. #define         DDR_DIP_I       DDRE
  29. #define         PIN_DIP_I       PINE
  30.  
  31. #define         PIN_DIP_ADD     PE2                             // Pin que tiene el bit de mayor peso de la direccion
  32. #define         PIN_DIP_MAN     PE1                             // Pin que tiene la seleccion Manual/DMX
  33.  
  34. // Prototipos de funciones
  35.  
  36. void    vInit_DMX_RX(void);
  37. uint1_t bGetDips(void);
  38.  
  39. #endif /* DMX_H_ */

dmx.c
Código: C
  1. /*
  2.  *    dmx.c
  3.  *
  4.  *   Para que funcione este codigo en otros proyectos es necesario crear 1 funcion en el main
  5.  *   Esta funcion es para el ISR de la UART y que llame a vHook_DMX_UART()
  6.  *
  7.  */
  8.  
  9.  
  10.  
  11. #include "dmx.h"
  12. #include <avr/io.h>
  13. #include <stdint.h>
  14.  
  15. // ********************* definiciones locales*********************
  16.  
  17. enum {IDLE, BREAK, STARTB, STARTADR};// estados DMX
  18. enum {EVAL_DMX, IND};
  19.  
  20. uint8_t         gDmxState;
  21. uint8_t         *gDmxPnt;
  22. uint8_t         Flags;
  23. uint8_t         DmxRxField[DMX_CHANNELS];       // Conjunto de vals DMX (cruda)
  24.  
  25. uint16_t        DmxCount;
  26. uint16_t        DmxAddress; // Dirección inicial
  27.  
  28.  
  29. // *************** DMX recepción de inicialización ****************
  30. void vInit_DMX_RX(void)
  31. {
  32.  
  33.         #ifdef USE_DIP
  34.     // Configuracion de salidas
  35.         DDR_DIP_C  = 0;                                                                         // Todas entradas port completo
  36.         PORT_DIP_C  = 0xFF;                                                                     // Activo Pull-up
  37.         DDR_DIP_I  &= ~((1<<PIN_DIP_ADD)|(1<<PIN_DIP_MAN));     // Port Incompleto, solo esas entradsa
  38.         PORT_DIP_I |=   (1<<PIN_DIP_ADD)|(1<<PIN_DIP_MAN);  // Activo sus Pull-up
  39.         #endif
  40.  
  41.         // Configuracion de la UART
  42.     DDRD  |= (1<<2);
  43.     PORTD &= ~(1<<2);
  44.     UBRRH  = 0; // Habilitar recepción
  45.     UBRRL  = ((F_OSC/4000)-1);// 250kBaud, 8N2
  46.     UCSRC  = (1<<URSEL)|(3<<UCSZ0)|(1<<USBS);
  47.     UCSRB  = (1<<RXEN)|(1<<RXCIE);
  48.     gDmxState= IDLE;
  49.  
  50.     uint8_t i;
  51.     for (i=0; i<DMX_CHANNELS; i++) DmxRxField[i]=0;
  52. }
  53.  
  54.  
  55.  
  56. // ************* obtener DMX dirección de inicio **************
  57. uint1_t bGetDips(void)
  58. {
  59.         uint8_t i;
  60.         uint16_t Temp;
  61.  
  62.         #ifdef USE_DIP
  63.         Temp= (!(PIN_DIP_I &(1<<PIN_DIP_ADD)) *256) + PIN_DIP_C;                        //Tomo la direccion desde los DIPs PORT_INCOPLETO:PORT_COMPLETO_7-0 (9 bits)
  64.         i = (PIN_DIP_I &(1<<PIN_DIP_MAN));
  65.         #else
  66.         Temp= DMX_ADDRESS;
  67.         i=0;
  68.         #endif
  69.  
  70.         if (!i && Temp != 0)                                    //Si es Manual deshabilito DMX, si PIN_DIP_MAN=0 activo DMX solo si la direccion es distinta de 0.
  71.         {
  72.                 DmxAddress= Temp;
  73.                 if (!(UCSRB &(1<<RXCIE)))                                                                               // Si el receptor esta desabilitado -> habilitar y setear modo de DMX en espera (IDLE).
  74.                 {
  75.                         gDmxState= IDLE;
  76.                         UCSRB |= (1<<RXCIE);
  77.                 }
  78.                 return 1;
  79.         }
  80.         else
  81.         {
  82.                 UCSRB &= ~(1<<RXCIE);                                                                                   // Manual o Direccion=0, Deshabilito la UART y limpio los valores del DMX ( no se para que )
  83.                 for (i=0; i<DMX_CHANNELS; i++) DmxRxField[i]=0;
  84.                 return 0;
  85.         }
  86. }
  87.  
  88.  
  89. // *************** DMX recepción ISR ****************//
  90. void vHook_DMX_UART(void)
  91. {
  92. static  uint16_t DmxCount;
  93.                 uint8_t  USARTstate= UCSRA;     // Obtener estado antes de los datos!
  94.                 uint8_t  DmxByte   = UDR;       // Obtener los datos
  95.                 uint8_t  DmxState  = gDmxState;// Cargar una sola vez de SRAM para aumentar la velocidad
  96.  
  97.         if (DmxState == BREAK)
  98.         {
  99.         UCSRA &= ~(1<<FE);      // Cambiar Posible FE: a causa de MAB
  100.         if (DmxByte == 0)
  101.                 {
  102.                 gDmxState= STARTB;// Código de inicio normal detectado
  103.                 gDmxPnt= ((uint8_t*)DmxRxField +1);
  104.                 }
  105.         else
  106.                 {
  107.                 gDmxState= IDLE;
  108.                 }
  109.         }
  110.  
  111. else if (USARTstate &(1<<FE)) // Comprobar para el descanso de la señal
  112.         {
  113.         UCSRA &= ~(1<<FE);      // Restablecer bandera
  114.         if (DmxByte == 0)       // Los datos de descanso debe ser 0
  115.                 {
  116.                 gDmxState= BREAK;
  117.                 DmxCount= DmxAddress;    // Restablecer contador de fotogramas
  118.                 }
  119.         else
  120.                 {
  121.                 gDmxState= IDLE;         // Bien es FE -> esperar descanso
  122.                 }
  123.         }
  124.  
  125. else if (DmxState == STARTB)
  126.         {
  127.         if (--DmxCount == 0)// Dirección inicial alcanzada?
  128.                 {
  129.                 gDmxState= STARTADR;
  130.                 DmxRxField[0]= DmxByte;
  131.                 }
  132.         }
  133.  
  134. else if (DmxState == STARTADR)
  135.         {
  136.         uint8_t *DmxPnt;
  137.         DmxPnt= gDmxPnt;
  138.         *DmxPnt= DmxByte;
  139.         if (++DmxPnt >= (DmxRxField + DMX_CHANNELS )) // los (CHANNEL) canales recibidos?
  140.                 {
  141.                 Flags |= (1<<EVAL_DMX);// Conjunto de datos listo -> eval en principal (MAIN)
  142.                 gDmxState= IDLE;
  143.                 }
  144.         else
  145.                 {
  146.                 gDmxPnt= DmxPnt;
  147.                 }
  148.         }
  149. }


Creo que esta lo suficientemente documentado con los comentarios que hay. Y espero que funcione a la primera, seria lo ideal.
Luego contas como te fue y si lo solucionaste o diste marcha atras :)

Hay muchas cosas que cambie, hice nuevas funciones, modifique funciones, etc.
Como por ejemplo, ahora los pines para los DIPs se configuran desde dmx.h , ahi tenes el puerto completo (PORTC) y el puerto incompleto (PORTE) para formar la direccion, aunque intente darle un poco de flexibilidad si es que moves las llaves a otro puerto. Aun asi todavia el del puerto incompleto es el bit de mayor peso de los 9. Esta tambien separado cual es el pin que hace que pase a ser manual o no.

Ahora la funcion de ISR se encuentra en el main. y se llama a la funcion del DMX
Al actualizar la direccion del DMX si se cumple que la direccion es 0 o que esta en manual retorna un valor dejandolo en fading_auto.
Cambie la velocidad del timer, tenia preescaler 1/256 lo puse con 1/1 como estaba en el ejemplo que pasaste.
Modifique un poco el codigo del PWM por soft, de esa forma se pone a 1 cuando comienza en 0 y luego se desactiva de ser necesario. ( Aunque no es lo ideal y que tenia pensado hacer )
Tambien se puede modificar las salidas modificando los define al comienzo del main.
Y ya no recuerdo mas que otras cositas toque. Parece un programa corto pero no lo es tanto. xD

Tambien modifique le codigo para cuando no queres usar el DIP y que tenga una direccion FIJA, esto te va a inhabilitar que puedas pasarlo de Manual a DMX o viceversa. Aunque se puede modificar eso con facilidad para dejar que se pueda usar 1 llave sola y no le preste atencion a lo demas.
« Última modificación: 31 de Agosto de 2015, 05:07:26 por KILLERJC »