![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
ChrisSnow Guest
|
DMX Receiver using Mark's code |
Posted: Fri Sep 14, 2007 4:29 am |
|
|
Hi,
I'm fairly new to CCS and am struggling to get my code to work.
I have looked over a lot of stuff on here about DMX so I don't think I'm too far off.
The header in marks code appears to be different to the standard one so i have added the missing sections to my code (RCSTA ETC).
I'm using V 4.038. and a 18F4520.
Heres my code.
Code: |
#include <18F4520>
#device ICD=TRUE
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP ,CCP2B3
#use delay(clock = 4000000)
#case
#USE RS232(baud=250000,rcv=PIN_C7,xmit=PIN_C6)
#ZERO_RAM
unsigned char PIR1;
#locate PIR1=0x0F9E
struct {
unsigned char TMR1IF:1;
unsigned char TMR2IF:1;
unsigned char CCP1IF:1;
unsigned char SSPIF:1;
unsigned char TXIF:1;
unsigned char RCIF:1;
unsigned char ADIF:1;
unsigned char PSPIF:1;
} PIR1bits ;
#locate PIR1bits=0x0F9E
unsigned char RCON;
#locate RCON=0x0FD0
struct
{
unsigned char BOR:1;
unsigned char POR:1;
unsigned char PD:1;
unsigned char TO:1;
unsigned char RI:1;
unsigned char UNUSED1:1;
unsigned char LWRT:1;
unsigned char IPEN:1;
} RCONbits ;
#locate RCONbits=0x0FD0
unsigned char RCREG;
#locate RCREG=0x0FAE
unsigned char RCSTA;
#locate RCSTA=0x0FAB
struct {
unsigned char RX9D:1;
unsigned char OERR:1;
unsigned char FERR:1;
unsigned char ADDEN:1;
unsigned char CREN:1;
unsigned char SREN:1;
unsigned char RX9:1;
unsigned char SPEN:1;
} RCSTAbits ;
#locate RCSTAbits=0x0FAB
void Interrupt_USART_Rx(void);
#define MAX_PWMS 10
#define DMX_512_Offset 0
/* Rx buffer for DMX stream */
int8 Rx_Buffer[MAX_PWMS];
/* current levels - 0 to 255 */
int8 DMX_Levels[MAX_PWMS];
void main()
{
setup_adc_ports( NO_ANALOGS );
RCONbits.IPEN = 1;
/* Initialize the Rx_Buffer and DMX_Levels to off */
memset(DMX_Levels,0,MAX_PWMS);
memset(Rx_Buffer,0,MAX_PWMS);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
setup_ccp2(CCP_PWM);
setup_timer_2(T2_DIV_BY_4, 127, 1);
while(1)
{
set_pwm2_duty(DMX_Levels[1]);
}
}
#int_rda
void Interrupt_USART_Rx(void)
{
#define WAIT_FOR_NEXT_BYTE 0
#define WAIT_FOR_BREAK 1
#define WAIT_FOR_START 2
#define WAIT_FOR_DATA 3
#define RECEIVE_DATA 4
/* Data that we are receiving */
char data;
/* State machine for determining the begining of the DMX stream */
static char Rx_State = WAIT_FOR_BREAK;
/* Duplicate of the RCSTA reg used due to the double buffering of the
fifo. Reading the RCREG reg will cause the second RCSTA reg to be
loaded if there is one. */
union
{
unsigned char byte;
struct {
unsigned char RX9D:1;
unsigned char OERR:1;
unsigned char FERR:1;
unsigned char ADDEN:1;
unsigned char CREN:1;
unsigned char SREN:1;
unsigned char RX9:1;
unsigned char SPEN:1;
} bits ;
}rcsta;
/* DMX frame counter */
static unsigned int DMX_512_Count=0;
/* receive buffer index */
static char Rx_Index = 0;
/* Keep reading the data so long as it is present. */
while (PIR1bits.RCIF)
{
/* Read the data and the Rx status reg */
rcsta.byte = RCSTA;
data = RCREG;
/* Check for buffer overrun error */
if (rcsta.bits.OERR)
{
RCSTAbits.CREN=0;
RCSTAbits.CREN=1;
/* we just received a buffer overrun so lets wait
for a good data byte before we look for the break signal. */
Rx_State = WAIT_FOR_NEXT_BYTE;
return;
}
switch (Rx_State)
{
case WAIT_FOR_NEXT_BYTE:
if (!rcsta.bits.FERR)
Rx_State = WAIT_FOR_BREAK;
break;
case WAIT_FOR_BREAK:
/* Check for a framing error */
if (rcsta.bits.FERR)
{
/* If we did receive a framing error, make sure that the data is 0.
This means that we did Rx the break signal for at least 44us. */
if (!data)
Rx_State = WAIT_FOR_START;
}
break;
case WAIT_FOR_START:
/* Check for a framing error. If we receive one then we need to wait
until we receive a good data byte before we begin looking for our
Break signal */
if (rcsta.bits.FERR)
Rx_State = WAIT_FOR_NEXT_BYTE;
/* The start code for our data packet should always start with 0. */
else
{
if (!data)
{
/* Initialize our index to our Rx buffer. */
Rx_Index = 0;
/* Here we determine where in the DMX stream we should begin
receiving data based on our DMX offset address. */
if (DMX_512_Offset == 1)
Rx_State = RECEIVE_DATA;
else
{
Rx_State = WAIT_FOR_DATA;
DMX_512_Count = 1;
}
}
else
{
Rx_State = WAIT_FOR_BREAK;
}
}
break;
case WAIT_FOR_DATA:
/* Check for a framing error. If we receive one then we need to wait
until we receive a good data byte before we begin looking for our
Break signal */
if (rcsta.bits.FERR)
/* This could be a break signal indicating the start of the DMX stream */
if (!data)
Rx_State = WAIT_FOR_START;
else
Rx_State = WAIT_FOR_NEXT_BYTE;
else
{
/* Keep track of the number of bytes received so that we will know
when to start receiving the data */
DMX_512_Count++;
if (DMX_512_Count == DMX_512_Offset)
Rx_State = RECEIVE_DATA;
}
break;
case RECEIVE_DATA:
/* check for framing error - if we receive a framing error then this
might be the begining of the next packet or a true framing error. */
if (rcsta.bits.FERR)
{
/* if this is the beginging of the next frame then data must = 0
else this is a framing error. */
if (!data)
Rx_State = WAIT_FOR_START;
else
Rx_State = WAIT_FOR_NEXT_BYTE;
}
else
{
/* Store the data received in the Rx buffer */
if (Rx_Buffer[Rx_Index] != data)
DMX_Levels[Rx_Index] |= 0x80;
Rx_Buffer[Rx_Index] = data;
/* Point to the next byte */
++Rx_Index;
/* Check to see if we have received all of our data */
if (Rx_Index >= MAX_PWMS-1)
Rx_State = WAIT_FOR_BREAK;
}
break;
// default:
/* Unknown start code */
}
}
return;
}
|
It doesnt seem to recieve anything however the interrupt does get called and Rx_State does go from 0-2 but never to the recieve function.
Any help would be greatly appreciated.
Thanks
Chris Snow |
|
![](templates/subSilver/images/spacer.gif) |
Ken Johnson
Joined: 23 Mar 2006 Posts: 197 Location: Lewisburg, WV
|
|
Posted: Fri Sep 14, 2007 6:33 am |
|
|
I didn't check your code (sorry), but at 40MHz, you need the H4 fuse (4X PLL), assuming you have a 10MHz crystal.
Also, I'd download the latest compiler - seems pretty solid to me (other opinions?)
Ken |
|
![](templates/subSilver/images/spacer.gif) |
ChrisSnow Guest
|
|
Posted: Fri Sep 14, 2007 11:08 am |
|
|
Im confused
#use delay(clock = 4000000)
Isnt that 4Mhz? ,
I'm using a 4Mhz oscilator
Trying various things at the moment and not getting far, if the code "works" then i will have to look into the transmitter.
I cant seem to find a simple example on here as to how to recieve DMX,
If anyone can see a problem please point me in the right direction.
Thanks
Chris |
|
![](templates/subSilver/images/spacer.gif) |
arunb
Joined: 08 Sep 2003 Posts: 492 Location: India
|
RE: |
Posted: Fri Sep 14, 2007 11:47 pm |
|
|
Just for my knowledge isn't DMX same as RS485 ???
thanks
arunb |
|
![](templates/subSilver/images/spacer.gif) |
spradecom.rnd
Joined: 27 Apr 2010 Posts: 16 Location: Mumbai
|
Problem with DMX receive code |
Posted: Sat Aug 07, 2010 12:27 am |
|
|
I am new to CCS and also microcontroller. I have taken help from MARKs DMX receiver. But my code is not working. Can anybody tell me where I am making mistake? I am using PIC16F1938. CCS v4.108. I am using SUN DMX Transmitter.
Here is my code:
Code: |
#include <16F1938.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
//#FUSES EC //external clock
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES MCLR //Master Clear pin enabled
#FUSES NOCPD //No EE protection
#FUSES NOBROWNOUT //No brownout reset
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES WDT_SW
#FUSES NOCLKOUT
#FUSES NOWRT //Program memory not write protected
#FUSES NOVCAP
#FUSES PLL
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES BORV19
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NODEBUG //No Debug mode for ICD
#use delay(int=4000000)
//-----------Register Definition---------------------
//----------------------------------------------------
/************************************************************************
* Registros USART *
************************************************************************/
#word SPBRG = 0x19B
//#word MCU_SPBRG = 0x19B
#byte RCSTA = 0x19D
//#byte MCU_RCSTA = 0x19D
#byte TXSTA = 0x19E
//#byte MCU_TXSTA = 0x19E
#byte RCREG = 0x199
//#byte MCU_RCREG = 0x199
#byte PIR1 = 0x011
//#byte MCU_PIR1 = 0x011
#byte PIE1 = 0x091
//#byte MCU_PIE1 = 0x091
#byte INTCON = 0x00B
//#byte MCU_INTCON = 0x00B
#bit SPEN = RCSTA.7 //Serial port enable bit
#bit RX9 = RCSTA.6 // 9-bit receive enable
#bit SREN = RCSTA.5
#bit CREN = RCSTA.4 // Continuos receive enable bit
#bit ADDEN = RCSTA.3
#bit FERR = RCSTA.2 //Frame error bit
#bit OERR = RCSTA.1 //Overrun error bit
#bit RX9D = RCSTA.0
#bit BRGH = TXSTA.2
#bit SYNC = TXSTA.4
#bit RCIF = PIR1.5
#bit RCIE = PIE1.5
#bit GIE = INTCON.7
#bit PEIE = INTCON.6
//----------------------------------------------------
/************************************************************************
* Function Decleration *
************************************************************************/
void Interrupt_USART_Rx(void);
void togglea1(void);
//---------------------------------------------------------------------
/************************************************************************
* Global Variables *
************************************************************************/
#define MAX_PWMS 3
/*Rx Buffer for dmx stream */
int8 Rx_Buffer[MAX_PWMS];
/*Current levels -0 to 255 */
int8 DMX_Levels[MAX_PWMS];
int1 Check_levels=0;
#include <main.h>
#int_RDA
void RDA_isr(void)
{
void Interrupt_USART_Rx(void)
{
#define WAIT_FOR_NEXT_BYTE 0
#define WAIT_FOR_BREAK 1
#define WAIT_FOR_START 2
#define RECEIVE_DATA 3
static int8 Rx_State = WAIT_FOR_BREAK;
int8 data;
static int8 *ptr_Rx;
while (RCIF)
{
togglea1();
//output_high(PIN_A1);
//delay_ms(200);
data = RCREG;
if (OERR)
{
CREN = 0;
CREN = 1;
Rx_State = WAIT_FOR_NEXT_BYTE;
return;
}
switch (Rx_State)
{
case WAIT_FOR_NEXT_BYTE:
if (!FERR)
Rx_State = WAIT_FOR_BREAK;
break;
case WAIT_FOR_BREAK:
if (FERR) //Miramos si hay un error de trama
{
if (!data)
Rx_State = WAIT_FOR_START;
}
break;
case WAIT_FOR_START:
if (FERR)
Rx_State = WAIT_FOR_NEXT_BYTE;
else
{
if (!data)
{
ptr_Rx = Rx_Buffer;
Rx_State = RECEIVE_DATA;
}
}
break;
case RECEIVE_DATA:
if (FERR)
{
if (!data)
Rx_State = WAIT_FOR_START;
else
Rx_State = WAIT_FOR_NEXT_BYTE;
}
else
{
*ptr_Rx=data;
ptr_Rx++;
if(ptr_Rx > &Rx_Buffer[MAX_PWMS-1] )
{
Check_levels=1;
Rx_State= WAIT_FOR_BREAK;
}
}
break;
}
}
return;
}
}
void main()
{
int8 i;
SPBRG=0x00; // SPBRG=0 implica que a 4Mhz el baudrate=250.000
BRGH=1;
SYNC=0;
SPEN=1;
RX9=1; // 9 bit reception
CREN=1; // enable reception
ADDEN=0;
FERR=1;
OERR=1;
delay_ms(3000);
setup_adc_ports(NO_ANALOGS| VSS_VDD);
setup_adc(ADC_CLOCK_DIV_2);
setup_spi(SPI_SS_DISABLED);
setup_lcd(LCD_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_16,255,1);
setup_ccp1(CCP_PWM);
setup_ccp2(CCP_PWM);
setup_ccp4(CCP_PWM);
set_pwm1_duty(0);
set_pwm2_duty(0);
set_pwm4_duty(0);
setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
//TODO: User Code
//set_pwm1_duty(127);
//set_pwm2_duty(127);
//set_pwm4_duty(127);
delay_ms(1000);
GIE=1; // enable all interrupts
PEIE=1; // enable peripheral interrupts
RCIE=1; // enable receive interrupt
while (TRUE)
{
// set_pwm1_duty(700);
//set_pwm2_duty(700);
//set_pwm4_duty(700);
//--------------------------------------
if (Check_levels)
{
Check_levels=0;
DMX_Levels[0]=Rx_Buffer[0];
DMX_Levels[1]=Rx_Buffer[1];
DMX_Levels[2]=Rx_Buffer[2];
set_pwm1_duty(DMX_Levels[0]);
set_pwm2_duty(DMX_Levels[1]);
set_pwm4_duty(DMX_Levels[2]);
}
//----------------------------------------
}
}
//----------------------------
void togglea1(void)
{
output_high(PIN_A1);
delay_ms(200);
output_low(PIN_A1);
delay_ms(200);
} |
I am not able to receive any data. |
|
![](templates/subSilver/images/spacer.gif) |
djprosound
Joined: 03 Aug 2010 Posts: 4
|
|
Posted: Sun Aug 08, 2010 10:30 pm |
|
|
I didn't read all the code but... in DMX the 9th bit is used as on of the two stop bits. So define RX9D with it's address and set it (´1´).
Emi |
|
![](templates/subSilver/images/spacer.gif) |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|