añadir canal master RGB y canal strobo para compilar en atmega 8515

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

  • DMX dimer led foro.rar
    38.3 KB · Visitas: 2
Última edición:
Atrás
Arriba