CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

DMX Receiver using Mark's code

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ChrisSnow
Guest







DMX Receiver using Mark's code
PostPosted: Fri Sep 14, 2007 4:29 am     Reply with quote

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
Ken Johnson



Joined: 23 Mar 2006
Posts: 197
Location: Lewisburg, WV

View user's profile Send private message

PostPosted: Fri Sep 14, 2007 6:33 am     Reply with quote

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
ChrisSnow
Guest







PostPosted: Fri Sep 14, 2007 11:08 am     Reply with quote

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
arunb



Joined: 08 Sep 2003
Posts: 492
Location: India

View user's profile Send private message Send e-mail

RE:
PostPosted: Fri Sep 14, 2007 11:47 pm     Reply with quote

Just for my knowledge isn't DMX same as RS485 ???

thanks
arunb
spradecom.rnd



Joined: 27 Apr 2010
Posts: 16
Location: Mumbai

View user's profile Send private message Send e-mail Visit poster's website

Problem with DMX receive code
PostPosted: Sat Aug 07, 2010 12:27 am     Reply with quote

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.
djprosound



Joined: 03 Aug 2010
Posts: 4

View user's profile Send private message

PostPosted: Sun Aug 08, 2010 10:30 pm     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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