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

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

Desconectado stk500

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 4923
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #45 en: 31 de Agosto de 2015, 04:09:40 »
joder Killer !!! como te lo hace!!
ahora mismo estoy liado con un projectos pero cuando tenga Tiempo lo voy a probar y te comento.
Podria poner una emplanacion de los pines que usas y funciones?
asi podria hacer un Esquemas subirlo por aqui. no cree?

Saludos

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #46 en: 31 de Agosto de 2015, 04:23:51 »
Realmente stk, estoy haciendolo todo en el "aire" no tengo nada concreto. No utilizo el compilador de Atmel, no tengo placa para probarlo. No tengo nada.
Solo agarre un editor como es el Code Composer Studio, basado en elipse, cree 3 archivos y lo hice desde alli y los codigos que me dio locodelafonola, por mas que no puedo compilarlo me iba a ayudar a quitar algunos errores de tipeo.

En fin todo comenzo por que locodelafonola queria pasar una funcion que estaba en ASM a C. El cual accedi a ayudar. Yo a todo esto sin conocimiento de DMX, sin conocimiento del circuito y por si fuera poco sin haber tocado nunca un micro de Atmel.
Comence a pasarlo cuando tuvimos el primer problema. El programa pasado del ASM al C no permitia un "correcto" manejo y cambio de modos. Ya que si usabamos el codigo de antes al intentar cambiar de modo el programa tenia que terminar el modo anterior y eso podia llevar unos cuantos segundos. Por eso mismo reescribi las funciones para que pueda ser usado y cambiado desde la interrupcion, con un delay maximo de unos 580ms que es el maximo delay que podia ocurrir en el ASM aproximadamente.
Con esto quiero decir. No hay nada concreto, no tome ningun valor y dije "voy a comenzar desde aqui" o "tiene que cumplir estos valores", sino que el pasarlo desde uno a otro termino con ese codigo por lo cual no se que tan exacto o correcto funcionara. No se si habra que modificar el valor del timer para el PWM eso no lo se, tambien otra cosa que puede necesitar modificarse es la formula de delay. No me puse a hacer las matematicas ni nada por el estilo. Pero la programacion es la programacion y solo afectara unos pequeños detalles o partes del codigo, asi que es lo mismo.

Con respecto al HW, locodelafonola colgo el esquema en la 2da pagina, sino aqui te proveo del link:
http://www.todopic.com.ar/foros/index.php?topic=44880.msg373782#msg373782
El cual pertenece al codigo antiguo sino me equivoco. pero que tome como referencia para lo demas.

Aca tambien los modos (Aunque esta explicado en los comentarios):
http://www.todopic.com.ar/foros/index.php?topic=44880.msg373824#msg373824
Los modos a excepcion del fijo y fading de un solo color que los cree yo como para "agregarle" algo mas, los demas son traducidos del programa que dio en ASM.

Hay muchas cosas que se pueden hacer para que quede mas limpio y ordenado, como todas las definiciones y declaraciones de variables podrian tranquilamente ir en un .h
Tambien las funciones que declare como auxiliares y modos en otro archivo, asi de esa forma solo queda el main() y los ISR en el main.c y queda un poco mas ordenado.

Pero hacer eso aqui en el foro significa 5/6 partes de codigo que deberian luego unirse y pienso que es mas comlpejo hacerlo que solo 3. Asi que lo deje asi.
« Última modificación: 31 de Agosto de 2015, 04:30:51 por KILLERJC »

Desconectado stk500

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 4923
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #47 en: 31 de Agosto de 2015, 04:41:10 »
Ok!  :)


Desconectado stk500

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 4923
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #48 en: 31 de Agosto de 2015, 08:02:52 »
estoy probando tu codigo killer y me sale 3 Errores y 3 Avisos, los aviso no le doy importancia ya que no lo Optimos tu codigo.
Mira la imagen

ojos hay que definir el CPU- Crystal , le he puesto 8Mhz
Saludos

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #49 en: 31 de Agosto de 2015, 08:24:09 »
bueno no veo que puede ser en algunos casos por que parece que esta corrido el tema del numero de lineas. Pero por lo que parece es:

por haber puesto:

void ISR (xxxx)
en ves de
ISR (xxx)

Parece que ya ISR define un tipo. Eso quitaria 2 errores, los de las lineas 385/404 que tenes

Me falto definir en el .h la funcion vHook_DMX_UART, esto quitaria el warning en la linea 406, ademas permite usarlo
No se por que el warning de la linea 196, esta definido en el .h

Ahi cambie los uint1_t por bool y agregue la libreria stdbool.h
Para solucionar el error de la linea 37 en el .h

Agregue un define F_CPU 8000000

Dejo el codigo de nuevo, vas a tener que ponerle nuevamente la frecuencia del cristal o acomodarlo si es que lo puse mal (me refiero a la linea que puse antes).

Y la proxima copialo y pegalo asi puedo leerlo completo al error y me guio un poco mas, por ejemplo el primer warning no se de que es.

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

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. uint8_t bGetDips(void);
  38. void    vHook_DMX_UART(void);
  39.  
  40. #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. uint8_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. }

Una cosa que no me di cuenta fue el maximo de _delay_ms()
Creo que lo mejor va a ser reemplazarlo por:

__builtin_avr_delay_cycles(unsigned long)
« Última modificación: 31 de Agosto de 2015, 13:23:32 por KILLERJC »

Desconectado locodelafonola

  • PIC10
  • *
  • Mensajes: 43
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #50 en: 31 de Agosto de 2015, 11:54:38 »
hola
a mi el unico error que me larga es
Código: [Seleccionar]
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 lib_dmx_in.o -MF dep/lib_dmx_in.o.d  -c  ../lib_dmx_in.c
In file included from ../lib_dmx_in.c:11:
../lib_dmx_in.h:58: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'bGetDips'
make: *** [lib_dmx_in.o] Error 1
Build failed with 1 errors and 0 warnings...
yo solo se que ...nose nada

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #51 en: 31 de Agosto de 2015, 12:06:30 »
parece que no tiene soporte para devolver un booleano. es decir un true false.
Es simple arreglarlo, cambiar el bool por un uint8_t en dmx.h y dmx.c y listo. se arreglaria con eso.

EDIT: Ya actualize el ultimo codigo, para no poner TODO de vuelta.
« Última modificación: 31 de Agosto de 2015, 12:10:20 por KILLERJC »

Desconectado locodelafonola

  • PIC10
  • *
  • Mensajes: 43
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #52 en: 31 de Agosto de 2015, 12:50:18 »
bueno alli lo solucione
la parte de .H creo nque estarabien asi., o me estoy equivocando
Código: [Seleccionar]
  // Prototipos de funciones
     
    void    vInit_DMX_RX(void);
extern void bGetDips(void);
    void vHook_DMX_UART(void);
     
puse eso , saque esto
Código: [Seleccionar]
// Prototipos de funciones
 
void    vInit_DMX_RX(void);
uint8_t bGetDips(void);
void vHook_DMX_UART(void);
 
otro cosa que cambie fue esto
Código: [Seleccionar]
// ************* obtener DMX dirección de inicio **************
void  bGetDips(void)
{
uint8_t i;
uint16_t Temp;
 
y saque esto
Código: [Seleccionar]
// ************* obtener DMX dirección de inicio **************
uint8_t bGetDips(void)
{
uint8_t i;
uint16_t Temp;
 
Ahora el error que me aparece es este ., y no entiendo bien esa funcion
yo solo se que ...nose nada

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #53 en: 31 de Agosto de 2015, 12:58:03 »
no se de donde sacaste ese codigo que pusiste.

Pero yo modifique el codigo para ponerle el uint8_t
Antes daba error por que tenia un

bool   bGetDips(void);

Ya que imagino que no estaba definido bool, o que no lo soporta el compilador.

Lo que hiciste esta mal. no hay necesidad de definirlo como extern, realmente nunca vi la necesidad de definir como extern una funcion cuando estas usando el .h para acceder a la misma.
Tambien estas usando un void cuando la funcion esta devolviendo un valor. Ese es otro error.
Usa el codigo que puse al ultimo. Yo lo habia modificado para arreglar eso.

Seguro que hay muchos mas errores con respecto al funcionamiento pero al menos error de sintaxis/compilacion no deberia haber.
« Última modificación: 31 de Agosto de 2015, 13:12:13 por KILLERJC »

Desconectado locodelafonola

  • PIC10
  • *
  • Mensajes: 43
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #54 en: 31 de Agosto de 2015, 13:12:35 »
no se de donde sacaste ese codigo que pusiste.

Pero yo modifique el codigo para ponerle el uint8_t
Antes daba error por que tenia un

bool   bGetDips(void);

Ya que imagino que no estaba definido bool, o que no lo soporta el compilador.

Lo que hiciste esta mal. no hay necesidad de definirlo como extern ( realmente nunca vi la necesidad de definir como extern una funcion ) cuando estas usando el .h para acceder a la misma.
Tambien estas usando un void cuando la funcion esta devolviendo un valor. Ese es otro error.
Usa el codigo que puse al ultimo. Yo lo habia modificado para arreglar eso.

Seguro que hay muchos mas errores con respecto al funcionamiento pero al menos error de sintaxis/compilacion no deberia haber.
cuando llamas una variable de otra libreria., se tiene que usar  la sentecia extern ., y el inicio de la funcion es void., fijate en la librias originales ., lo IRS son los que no se llaman ., de esa manera el compilador no me dice error
yo solo se que ...nose nada

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Invertir pwm en Atmega 8515 asembler
« Respuesta #55 en: 31 de Agosto de 2015, 13:23:00 »
Citar
cuando llamas una variable de otra libreria., se tiene que usar  la sentecia extern ., y el inicio de la funcion es void., fijate en la librias originales ., lo IRS son los que no se llaman ., de esa manera el compilador no me dice error

Justamente una variable. Y esa variable no debe estar definida en el .h por eso mismo yo puse en el main.c:

extern uint8_t DmxRxField[DMX_CHANNELS];   // Valores externos tomados desde la libreria.

Pero en el .h tenemos definidos los prototipos nomas de las funciones. Luego el Linker va a ser capaz de ubicar el dmx.c si es que las rutas de acceso estan bien configuradas y agarrar la funcion necesaria. no hay necesidad de marcarla como extern como ya dije.

Ahora si tu programa no posee realmente un .h, como por ejemplo omitieramos el dmx.h, entonces ahi si en el main.c pondrias:

extern    void    vInit_DMX_RX(void);
extern    uint8_t    bGetDips(void);
extern    void   vHook_DMX_UART(void);

Ahora... el por que no poner void y ponerle uin8_t o int como mas te guste. La libreria original es esa libreria y su funcion no devuelve nada, yo modifique simplemente la funcion para que sea un poco mas flexible para mi.
Ya que necesito saber si es que realmente esta en manual o no la llave. entonces hago que retorne un valor.
El por que no poner void Es por que la funcion esta devolviendo un valor, si te fijas en bGetDips() hay 2 instrucciones que dicen:

return 1;
return 0;

Si defino a esa funcion como void no puedo devolver ese valor. como era un 1 o 0, entonces me bastaba con 1 bit, pero veo que el compilador se vuelve loco cuando usas "bool" que es lo que C posee y te tira error. entonces prefiero pasar un valor de 8 bits y dejar de complicarme la vida, aunque solo necesite 1 bit solo.

Entonces si yo en mi main.c hago:

a = bGetDips();

en "a" voy a tener el valor 1 o 0 dependiendo si esta activo o no. para eso lo hice. Sino deberia haber creado otra funcion que me indicara si esta o no activo.

Si por ejemplo yo quisera que mi funcion me devuelva una variable un float deberia ser:

Código: C
  1. float fGetPi()
  2. {
  3.    return 3.14159;
  4. }
  5.  
  6. main() {
  7.   float Pi;
  8.   Pi = fGetPi();
  9. }

Si quisiera que me devuelva una estructura

Código: C
  1. struct Coords {
  2.    uint8_t x,
  3.    uint8_t y
  4. };
  5.  
  6. struct Coords sGetCoordenadas() {
  7.   struct Coords a;
  8.   a.x = 10;
  9.   a.y = 20;
  10.   return a;
  11. }
  12.  
  13. main() {
  14.   struct Coords MiCoordenada;
  15.   MiCoordenada = sGetCoordenada();
  16.   // MiCoordenada.x va a ser igual a 10 e y igual a 20
  17. }
« Última modificación: 31 de Agosto de 2015, 13:37:54 por KILLERJC »

Desconectado holik

  • PIC10
  • *
  • Mensajes: 2
Re:Invertir pwm en Atmega 8515 asembler
« Respuesta #56 en: 27 de Mayo de 2016, 12:51:34 »
Que tal caballeros del foro me acabo de inscribir y es el primer mensaje, e estado leyendo el post y me intereso mucho el proyecto, me parece que lo podría implementar para modificar unas luces led que no tienen DMX y poder crearle secuencias y efectos nuevos al estilo de las luces comerciales.
Me pregunto si ya alguno de los dos caballeros tiene trabajando el código en alguno de los compiladores y claro saber si ya esta trabajando en físico.
en mi opinión es un excelente proyecto que quedo quieto y me gustaría ponerlo en practica.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Invertir pwm en Atmega 8515 asembler
« Respuesta #57 en: 27 de Mayo de 2016, 14:57:02 »
Yo no lo toque mas por que fue simplemente un desafio de pasar el ASM a C, pero no se si locodelafonola siguio con el proyecto, ya que a el no le funcionaba el codigo que habia presentado, puedo tener errores ya que jamas lo compile.

El codigo esta y puede ser modificado, asi ver tambien que es lo que esta fallando y arreglarlo. Alguien con un poco de experiencia en C podria hacerlo.

Desconectado locodelafonola

  • PIC10
  • *
  • Mensajes: 43
Re:Invertir pwm en Atmega 8515 asembler
« Respuesta #58 en: 28 de Mayo de 2016, 04:39:51 »
hola
Que tal caballeros del foro me acabo de inscribir y es el primer mensaje, e estado leyendo el post y me intereso mucho el proyecto, me parece que lo podría implementar para modificar unas luces led que no tienen DMX y poder crearle secuencias y efectos nuevos al estilo de las luces comerciales.
Me pregunto si ya alguno de los dos caballeros tiene trabajando el código en alguno de los compiladores y claro saber si ya esta trabajando en físico.
en mi opinión es un excelente proyecto que quedo quieto y me gustaría ponerlo en practica.
 
bueno .,  si presisas algunos de los dos codigos que subi ., te los puedo facilitar cimpletos
he probado los dos ., y armado con exito en lo fisico
eso si son compilaciones en ASM ( nunca pude hacer funcionar lo del C)
querido amigo KILLERJC 
Yo no lo toque mas por que fue simplemente un desafio de pasar el ASM a C, pero no se si locodelafonola siguio con el proyecto, ya que a el no le funcionaba el codigo que habia presentado, puedo tener errores ya que jamas lo compile.

El codigo esta y puede ser modificado, asi ver tambien que es lo que esta fallando y arreglarlo. Alguien con un poco de experiencia en C podria hacerlo.
yo sigo muy agradesido ., por el tiempo y la enseñanza que pusiste ., en este codigo
lastima ., que recien ahora .,  entiendo un poco mas como funciona ., como por ejemplo que las librerias de DMX ., ya estaban ., pero no entendia como asociarlas
y lo que hoy se ., es que solo tendriamos que haberlos enfocado .,  en las funciones de las llaves .,  nada mas
porque  los valores de señal de cada canal ., ya estan separados y guardadas ., en el bufer (DmxRxField (x) ., donde la x coresponde al numero de canal
cualquier cosa siempre ando en el foro ., y si hay que seguir con esto ., soy materia dispuesta ., tengo la parte fisica para probar y compilacion para aportar
tambien nuevas ideas que fui probando ., funciones simples sobre todo
y vuelvo ., a dar las gracias ., al amigo KILLERJC ., es muy dificil ., que alguien se tome el tiempo de enseñar ( y menos a alguien de 53 años y bastante ignorante en esto ) y que hace poco empezo con los micros ., gracias amigo por tu tiempo y dedicacion
.... juan
yo solo se que ...nose nada

Desconectado holik

  • PIC10
  • *
  • Mensajes: 2
Re:Invertir pwm en Atmega 8515 asembler
« Respuesta #59 en: 31 de Mayo de 2016, 12:48:19 »
Gracias a los dos caballeros por responder, en cuanto al ofrecimiento de "locodelafonola" estaría agradecido por códigos y librerías que me pueda facilitar vi en el mensaje numero 35 un código que subió de control RGB y motores PAP ese codigo seria para un estilo de luz Movie Head estoy en lo correcto? solo faltaría control de un servo adicional o PAP para controlar una plantilla te figuras y quedaría perfecto!
Volviendo al tema también estaría agradecido por material de lo que se trabajo poder manipular efectos ya preestablecidos en el código y asignados a un canal en especifico por medio de DMX.
esto para lo que les comentaba de actualizar luces led que no tienen DMX al estilo de miniflower o duomoon led.