hola señores del foro.
He tratado de programar yo mismo., Pero no he tenido éxito. debido a mi falta de experiencia.,
a pesar de conseguir el mando de los tres canales de salida DMX.
He tratado de implementar un ejemplo que encontré en internet., de este señor ., http://www.ulrichradig.de/home/index.php/avr/atmega8-experimentierboard/avr---dmx
aqui esta el ejemplo
PHP:
/*------------------------------------------------------------------------------
Copyright: Radig Ulrich mailto: mail@ulrichradig.de
Author: Radig Ulrich
Remarks:
known Problems: none
Version: 18.12.2011
Description: DMX_3Kanal_Dimmer
Dieses Programm ist freie Software. Sie können es unter den Bedingungen der
GNU General Public License, wie von der Free Software Foundation veröffentlicht,
weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder
(nach Ihrer Option) jeder späteren Version.
Die Veröffentlichung dieses Programms erfolgt in der Hoffnung,
daß es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE,
sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT
FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License.
Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
Programm erhalten haben.
Falls nicht, schreiben Sie an die Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
------------------------------------------------------------------------------*/
#include <avr/interrupt.h>
#include <avr/io.h>
#include <stdio.h>
#define F_CPU 12000000
#define LED_R_PIN_OUT DDRD |= (1<<PD5);
#define LED_G_PIN_OUT DDRD |= (1<<PD4);
#define LED_B_PIN_OUT DDRD |= (1<<PD3);
#define LED_R_ON PORTD |= (1<<PD4);
#define LED_R_OFF PORTD &= ~(1<<PD4);
#define LED_B_ON PORTD |= (1<<PD5);
#define LED_B_OFF PORTD &= ~(1<<PD5);
#define LED_G_ON PORTD |= (1<<PD3);
#define LED_G_OFF PORTD &= ~(1<<PD3);
#define DMX_BAUD 250000
#define DMX_LOST_TIMEOUT 8000
volatile unsigned int dmx_lost = DMX_LOST_TIMEOUT;
volatile unsigned int dmx_adresse = 0;
volatile unsigned char dmx_buffer[6];
volatile unsigned char led_kanal[3];
//############################################################################
//DMX Senderoutine
ISR (USART_RX_vect)
//############################################################################
{
static unsigned int dmx_channel_rx_count = 0;
static unsigned char dmx_valid = 0;
unsigned char tmp = 0;
tmp = UDR;
if(UCSRA&(1<<FE))
{
if(dmx_channel_rx_count > 1)
{
dmx_lost = 0;
}
dmx_channel_rx_count = 0;
dmx_buffer[0] = tmp;
if(dmx_buffer[0] == 0)
{
dmx_valid = 1;
dmx_channel_rx_count++;
}
else
{
dmx_valid = 0;
}
return;
}
if(dmx_valid)
{
if(dmx_channel_rx_count == dmx_adresse) dmx_buffer[1] = tmp;
if(dmx_channel_rx_count == dmx_adresse+1) dmx_buffer[2] = tmp;
if(dmx_channel_rx_count == dmx_adresse+2) dmx_buffer[3] = tmp;
if(dmx_channel_rx_count == dmx_adresse+3) dmx_buffer[4] = tmp;
if(dmx_channel_rx_count == dmx_adresse+4) dmx_buffer[5] = tmp;
if(dmx_channel_rx_count < 514)
{
dmx_channel_rx_count++;
}
return;
}
}
//############################################################################
//Hier wird die Zeit gezählt (Tick 1ms)
ISR (TIMER0_COMPA_vect)
//############################################################################
{
static unsigned char pwm_counter = 0;
pwm_counter++;
if(pwm_counter == 255)
{
pwm_counter = 0;
}
if(pwm_counter >= led_kanal[0])
{
LED_R_OFF;
}
else
{
LED_R_ON;
}
if(pwm_counter >= led_kanal[1])
{
LED_G_OFF;
}
else
{
LED_G_ON;
}
if(pwm_counter >= led_kanal[2])
{
LED_B_OFF;
}
else
{
LED_B_ON;
}
if(dmx_lost<DMX_LOST_TIMEOUT)
{
dmx_lost++;
}
}
//############################################################################
//Hauptprogramm
int main (void)
//############################################################################
{
unsigned int dmx_adresse_tmp;
unsigned long strobe_counter = 0;
unsigned char tmp1,tmp2,tmp3;
//Init usart DMX-BUS
UBRRH = (unsigned char)(F_CPU / (DMX_BAUD * 16L) - 1)>>8;
UBRRL = (unsigned char)(F_CPU / (DMX_BAUD * 16L) - 1);
UCSRB|=(1 << RXEN | 1<< RXCIE);
UCSRC|=(1<<USBS); //USBS0 2 Stop bits
//Timer0 Timecounter für DMX Ausfall und PWM
TCCR0A |= (1<<WGM01);
TCCR0B |= (1<<CS00);
TIMSK |= (1<<OCIE0A);
OCR0A = F_CPU/1024/100 - 1; //Tick 1ms
PORTB |= 0xFF;
PORTD |= (1<<PD6);
DDRD |=(1<<PD2);
PORTD &=~(1<<PD2);
LED_R_PIN_OUT;
LED_G_PIN_OUT;
LED_B_PIN_OUT;
LED_R_ON;
for(unsigned long tmp = 0;tmp<500000;tmp++)asm("nop");
LED_R_OFF;
LED_G_ON;
for(unsigned long tmp = 0;tmp<500000;tmp++)asm("nop");
LED_G_OFF;
LED_B_ON;
for(unsigned long tmp = 0;tmp<500000;tmp++)asm("nop");
LED_B_OFF;
sei();//Globale Interrupts Enable
//Endlosschleife
while(1)
{
dmx_adresse_tmp = 0;
if(!(PIND&(1<<PD6))) dmx_adresse_tmp |= 0x01;
if(!(PINB&(1<<PB0))) dmx_adresse_tmp |= 0x02;
if(!(PINB&(1<<PB1))) dmx_adresse_tmp |= 0x04;
if(!(PINB&(1<<PB2))) dmx_adresse_tmp |= 0x08;
if(!(PINB&(1<<PB3))) dmx_adresse_tmp |= 0x10;
if(!(PINB&(1<<PB4))) dmx_adresse_tmp |= 0x20;
if(!(PINB&(1<<PB5))) dmx_adresse_tmp |= 0x40;
if(!(PINB&(1<<PB6))) dmx_adresse_tmp |= 0x80;
if(!(PINB&(1<<PB7))) dmx_adresse_tmp |= 0x0100;
if(dmx_adresse != dmx_adresse_tmp) dmx_adresse = dmx_adresse_tmp;
if(dmx_lost==DMX_LOST_TIMEOUT)
{
dmx_buffer[1] = 0;
dmx_buffer[2] = 0;
dmx_buffer[3] = 0;
dmx_buffer[4] = 0;
}
tmp1 = dmx_buffer[1]*dmx_buffer[4]/255;
tmp2 = dmx_buffer[2]*dmx_buffer[4]/255;
tmp3 = dmx_buffer[3]*dmx_buffer[4]/255;
if(dmx_buffer[5]<10)
{
led_kanal[0] = tmp1;
led_kanal[1] = tmp2;
led_kanal[2] = tmp3;
}
else
{
strobe_counter++;
if(strobe_counter > (256 - dmx_buffer[5]))
{
led_kanal[0] = tmp1;
led_kanal[1] = tmp2;
led_kanal[2] = tmp3;
}
else
{
led_kanal[0] = 0;
led_kanal[1] = 0;
led_kanal[2] = 0;
}
if(strobe_counter > (2 * (256 - dmx_buffer[5])))
{
strobe_counter = 0;
led_kanal[0] = 0;
led_kanal[1] = 0;
led_kanal[2] = 0;
}
}
}
}
La parte ., que usa este señor para implemetar estas funciones es esta
if(dmx_lost==DMX_LOST_TIMEOUT){
dmx_buffer[1] = 0;
dmx_buffer[2] = 0;
dmx_buffer[3] = 0;
dmx_buffer[4] = 0;
}
tmp1 = dmx_buffer[1]*dmx_buffer[4]/255;
tmp2 = dmx_buffer[2]*dmx_buffer[4]/255;
tmp3 = dmx_buffer[3]*dmx_buffer[4]/255;
if(dmx_buffer[5]<10)
{
led_kanal[0] = tmp1;
led_kanal[1] = tmp2;
led_kanal[2] = tmp3;
}
else
{
strobe_counter++;
if(strobe_counter > (256 - dmx_buffer[5]))
{
led_kanal[0] = tmp1;
led_kanal[1] = tmp2;
led_kanal[2] = tmp3;
}
else
{
led_kanal[0] = 0;
led_kanal[1] = 0;
led_kanal[2] = 0;
}
if(strobe_counter > (2 * (256 - dmx_buffer[5])))
{
strobe_counter = 0;
led_kanal[0] = 0;
led_kanal[1] = 0;
led_kanal[2] = 0;
}
}
}
}
tambien tiene inplementado como definicones esta parte ., en el inicio del "MAIN"
unsigned long strobe_counter = 0;unsigned char tmp1,tmp2,tmp3;
bien hasta alli lo tengo claro., y sin problemas
perooooo !!!! ., cuando quiero adaptar a mi compilacion me aparecen los problemas
mi compilacion "MAIN" es esta
PHP:
#include<util\delay.h>
#include<stdio.h>
#include<stdlib.h>
#include <avr/wdt.h>
#include "lib_dmx_in.h"
#include "lib_indicator.h"
uint8_t count= 1; // Counter for soft PWM
uint8_t IndCnt= 1; // Counter for LED indicator
uint8_t DmxBuf[DMX_CHANNELS];
void init_system(void)
{
//Watchdog
wdt_reset();
wdt_enable(WDTO_500MS); //enable watchdog (Timeout= 0.5s)
wdt_reset();
//Ports
DDRB |= (1<<PB0) | (1<<PB1) | (1<<PB2);
PORTB= 0;
DDRD= 0b10000110; //DMX, spare, LED1
PORTD= 0b01111010;
//Timer0
TCCR0= (1<<CS02);
TIMSK= (1<<TOIE0);
init_DMX(); // Initialize DMX channels
init_ind(); // Initialize LED indicator
}
int main(void)
{
cli();
init_system();
sei();
int PWM_timer;
while(1)
{
for (PWM_timer=0; PWM_timer<255 ; PWM_timer++) // Timer applied right through a series of fill
{
if (DmxRxField[0]>PWM_timer) //red
{
PORTB &= ~(1<<PB0); //LED OFF
}else{
PORTB |= (1<<PB0); //LED ON
}
if (DmxRxField[1]>PWM_timer) //green
{
PORTB &= ~(1<<PB1); //LED OFF
}else{
PORTB |= (1<<PB1); //LED ON
}
if (DmxRxField[2]>PWM_timer) //blue
{
PORTB &= ~(1<<PB2); //LED OFF
}else{
PORTB |= (1<<PB2); //LED ON
}
if (Flags &(1<<EVAL_DMX)) // DMX universe was refreshed
{
Flags &= ~(1<<EVAL_DMX);
IndFlags |= (1<<VALID_DMX); // Valid DMX signal arrived
uint8_t i;
for (i=0; i<DMX_CHANNELS; i++)
{
if (DmxRxField[i] != DmxBuf[i]) // A DMX value has changed?
{
DmxBuf[i]= DmxRxField[i];
IndFlags |= (1<<DATA_REFRESHED); // Yes -> blink!
}
}
}
}
if (Flags &(1<<IND)) // LED indicator, DIPs
{
Flags &= ~(1<<IND);
wdt_reset(); //reset watchdog
get_dips();
if (--IndCnt == 0)
{
IndCnt= 8;
indicate();
}
}
}
}
la cuestion es que este señor usa las dos de timer ., TCCR0A |= (1<<WGM01); y TCCR0B |= (1<<CS00); ., o sea de timer0 ., con configuraciones separadas
en cambio en mi libreria uso una solo timer para las tres salidas ., con una configuracion mas simple y a la vez mas efectiva
ademas tengo un manejo distinto de la USART., (que no influye en nada .,en niguno de los dos casos planteados ).,
pero que mi compilacion permite., por un lado la deteccion corecta de la señal DMX (señal correcta y direccion DMX equivocada o D+ y D- invertida ) .,
y por otro la transmicion ., que si funciona ., pero que no esta implementada en este caso ., !!!por ahora¡¡¡ (adjunto el proyeto completo ., por si alguno le sirve ., funciona perfecto )
aclaro que estas funciones son activas dentro del programa y que los pines de salida son los tres anteriores
o sea el canal 4 es un dimer general ., trabaja con los tres canales anteriores en conjunto.,
asi podemos atenuar el brillo de un color definido., por los tres valores anteriores
en el caso del strobo canal 5 ., el minimo es (dmx_buffer[5]<10) y el maximo (strobe_counter > (256 - dmx_buffer[5])) que es valor del potenciometro virtual
y el resultado de lo que se implementa es (strobe_counter > (2 * (256 - dmx_buffer[5])))
bueno espero que puedan guiarme para implementar estas funciones en mi proyecto
Adjuntos
Última edición: