Dmx.c

Z MAM wiki

Přejít na: navigace, hledání
/*
 * main.c
 *
 *  Created on: 19-feb-2009
 *      Author: Jan
 */


//Includes
#include "avr/io.h"
#include "inttypes.h"
#include "stdio.h"
#include "util/delay.h"
#include "avr/interrupt.h"
#include "usart.h"
#include "avr/wdt.h"



//Defines
#define F_CPU 16000000			//16Mhz crystal used for baud rate 0.0% error
#define LED_PORT	PORTA			//Port where the LED's are located .. Duh! :P
#define LED_DDR		DDRA			//Data Direction Register of the LED's..
#define DMX_ADDRESS_DDR		DDRB	//DDR where the "usual" Dipswitch is on for the channel setting
#define DMX_ADDRESS_PORT	PORTB	//Port with the "usual" Dipswitch for the channel setting
#define DMX_ADDRESS_PIN		PINA	//Pins where the "usual" Dipswitch for the channel setting

//RS485 chip used: SN75176B: The chip got a Read Enable and Transmit Enable pins.
//Receiving:
#define RS485R_PORT	PORTC	//RS485 PORT for  Read Enable (Receiving)
#define RS485R_DDR	DDRC	//RS485 DDR  for  Read Enable (Receiving)
#define RS485R_RE	PC0		//Active Low Read Enable  (for reading) used Tain DMX Receiver

//Transmitting:
/*	This is a Receiver.. Why should you need the transmitting part ?
 *	#define RS485D_PORT	PORTC	//RS485 PORT for  Data Enable (Transmitting)
 *	#define RS485D_DDR	DDRC	//RS485 DDR  for  Data Enable (Transmitting)
 *	#define RS485D_DE	PC1		//Active High Data Enable (for writing) used in DMX Transmitter
*/


//Functions
void Init_Ports();	//Initialize IO Pins

//Variables
//every variable gets a prefix: vuchr: Volatile Unsigned Char.. a way to get your code cleaner
volatile unsigned char vuchrDMX_Break,UART_Status,DMX_Data;			//"Boolean" which holds the break detection
volatile unsigned int  vintDMX_ChCounter;							//For counting the data packets


//Main Loop
int main(){
	Init_Ports();								//Call the Init_Ports() fTaunction.
	USART_Init(3);								//USART init (250Kbps, 8 databits, 2 stopbits)
												//Calculate the USART_Init parameter:
	DDRD |= (PD7>>1);												//=(F_CPU)/(16*Baudrate).. For 16Mhz crystal and 250000bps => 3

	wdt_disable();								//Disable the Watchdog so the controller won't reset on infinite loops.
	sei(); 										//Enable all interrupts
	RS485R_PORT &=~(1<<RS485R_RE);				//RS485: Receive Enabled is active (Low)
	for(;;){
	//Infinite loop
	//We have plenty of time to do other things ! :)
	//TODO:Write a very powerful DMX powered program ! :D

	PORTD = 0;
	_delay_ms(500);
	PORTD = 255;
	_delay_ms(500);

	}

	return 0;
}



//Functions
void Init_Ports(){					//DDR = 0 => Input
									//DDR = 255 => Output
	LED_DDR = 255; 					//Output
	DMX_ADDRESS_DDR=0; 				//Input
	RS485R_DDR |=(1<<RS485R_RE);	//Data direction register: Read Enable is an output
	RS485R_PORT |=(1<<RS485R_RE);	//Make Read Enable high because it is (active low)
}


//Interrupts
ISR(USART_RXC_vect){				//We are using the UART for receiving
UART_Status = UCSRA;				//Read the status from the UCSRA register
DMX_Data = UDR;						//Read data from UDR data register

if ( UART_Status & (1<<FE)){				//If we detect a frame error=> RX_line low for longer then 8 bits (Break condition)
	vuchrDMX_Break=1;						//Houston, we have a break..
	vintDMX_ChCounter=0;					//Reset the Channel Counter.. and let the story begin again.
}

else if(vuchrDMX_Break==1){					//If a break was detected..

	if(vintDMX_ChCounter==DMX_ADDRESS_PIN){	//If the counted channels = our address , this data is for Me !!! :D
		LED_PORT = DMX_Data;				//Put the data on the LEDS
	}
	vintDMX_ChCounter++;					//Increase the Channel Counter..
}

}
Osobní nástroje