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 CCS Technical Support

trying to contact Mark
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Guest








PostPosted: Mon Dec 27, 2004 10:32 pm     Reply with quote

Here is the latest version ...

Code:
#if defined(__PCH__)
#include <18F8720.h>
#device adc=10
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use STANDARD_IO(D)
#endif

#case

#byte SPBRG2 = 0xF6F
#byte RCSTA2 = 0xF6B
#byte TXSTA2 = 0xF6C
#byte RCREG2 = 0xF6E
#byte TXREG2 = 0xF6D
#byte TRISG  = 0xF98
#byte PIR3   = 0xFA4
#byte PIE3   = 0xFA3
#byte INTCON = 0xFF2

#bit SPEN   = RCSTA2.7
#bit RX9   = RCSTA2.6
#bit SREN   = RCSTA2.5
#bit CREN   = RCSTA2.4
#bit ADDEN   = RCSTA2.3
#bit FERR   = RCSTA2.2
#bit OERR   = RCSTA2.1
#bit RX9D   = RCSTA2.0

#bit BRGH   = TXSTA2.2
#bit SYNC    = TXSTA2.4

#bit TRISG1 = TRISG.1
#bit TRISG2 = TRISG.2

#bit RC2IF  = PIR3.5
#bit RC2IE  = PIE3.5
#bit GIE    = INTCON.7
#bit PEIE   = INTCON.6


unsigned int DMX_512_Offset = 0;
unsigned int Rx_Buffer[255];

// unsigned int MAX_BUFFER = 40;
// unsigned char levels;


#ORG 0x08, 0x136
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
                                   
  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 ;
  }rcsta2;
 

  /* 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. */ 

  /* 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 (RC2IF)
  {
   output_d(0xFF);
    /* Read the data and the Rx status reg */
    rcsta2.byte = RCSTA2;
    data = RCREG2;

    /* Check for buffer overrun error */
    if (rcsta2.bits.OERR)
    {
//      rcsta2.bits.CREN = 0;
//      rcsta2.bits.CREN = 1;
      CREN = 0;
      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 (!rcsta2.bits.FERR)
          Rx_State = WAIT_FOR_BREAK;
        break;
      case WAIT_FOR_BREAK:
        /* Check for a framing error */
        if (rcsta2.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 (rcsta2.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 (rcsta2.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 (rcsta2.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)
//            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_BUFFER)
//            Rx_State = WAIT_FOR_BREAK;
        }
        break;
      /* Unknown start code */
    }   
  }
  return;
}



int main () {

output_float(PIN_B0);

// configure USART2 RS-485 250kbps with 20MHz osc
TRISG1 = 0;
TRISG2 = 1;
SPEN   = 1;   // 1 = Serial port enabled

SPBRG2 = 0x04;
BRGH   = 1;
SYNC   = 0;

RX9   = 0;   // 1 = Selects 9-bit reception
CREN  = 1;   // 1 = Enables continuous receive
ADDEN = 0;   // 1 = Enables address detection
FERR  = 1;  // 1 = Framing error
OERR  = 1;  // 1 = Overrun error

GIE    = 1; // 1 = Enable global interrupts
PEIE   = 1; // 1 = Enable peripheral interrupts
RC2IE  = 1; // 1 = Enable receive interrupt

while (1)
   output_d(0x00);

return (0);

}


Thanks, Jerry
Guest








PostPosted: Mon Jan 03, 2005 5:25 pm     Reply with quote

Mark,

My mistake, the code works.

Thanks, Garrett
marquez



Joined: 05 Jan 2005
Posts: 0
Location: spain

View user's profile Send private message

dmx pic16f767 receiver
PostPosted: Wed Jan 19, 2005 4:59 am     Reply with quote

Hi
I would like to make a dmx pic16f767 receiver. I only would like to read the 3 first channels.
I read them ok but not always. Anyone knows why?
this is my code:


#fuses HS,NOWDT

#include <16F767.h>
#use delay(clock=16000000)
#include <string.h>
#include<lcd16.c>
#include <stdio.h>

#define BUFFER_SIZE 6
BYTE buffer[BUFFER_SIZE];
BYTE next_in = 0;
BYTE next_out = 0; //antes 0

#use rs232(baud=250000,bits=9, xmit=PIN_C6, rcv=PIN_C7)

struct PA_pin_map {
boolean unusedRA0; //bit 0
boolean unusedRA1;
boolean unusedRA2;
boolean unusedRA3;
boolean unusedRA4;
boolean unusedRA5; //bit 4
} Puerto_A;
#byte Puerto_A = 5

struct PB_pin_map {
boolean unusedRB0; //bit 0
boolean unusedRB1;
boolean unusedRB2;
boolean unusedRB3;
boolean unusedRB4;
boolean unusedRB5;
boolean unusedRB6;
boolean unusedRB7; //bit8
} Puerto_B;
#byte Puerto_B = 6

struct PC_pin_map {
boolean unusedRC0; //bit 0
boolean unusedRC1;
boolean unusedRC2;
boolean unusedRC3;
boolean unusedRC4;
boolean test_osc;
boolean unusedRC6;
boolean unusedRC7; //bit8
} Puerto_C;
#byte Puerto_C = 7

//// Declaracion de funciones ////
//////////////////////////////////////
void clear_lcd();


//// Rutina de interrupcion de la usart
#int_rda
void serial_isr() {
int t;
Puerto_C.test_osc=1;
buffer[next_in]=getc();
t=next_in;
next_in=(next_in+1) % BUFFER_SIZE;
if(next_in==next_out)
{
next_in=t; // Buffer full !!
}
Puerto_C.test_osc=0;
}

#define bkbhit (next_in!=next_out)


BYTE bgetc() {
BYTE c;
while(!bkbhit) ;
c=buffer[next_out];
next_out=(next_out+1) % BUFFER_SIZE;
return(c);
}


void main() {

BYTE kk;
BYTE chan1;
BYTE chan2;
BYTE chan3;

//Inicializacion del display y mensaje de bienvenida
lcd_init();
clear_lcd();
delay_ms(1000);

lcd_putc(" welcome\n");
lcd_putc(" Comienzo secuencia\n");
delay_ms(1000);
clear_lcd();

///////////////////////////////////////////////////

lcd_putc("waiting..\n");
delay_ms(15000);
clear_lcd();


enable_interrupts(global);
enable_interrupts(int_rda);
while(1)
{
//inicializamos los tres canales
chan1=0;
chan2=0;
chan3=0;
///////////////////////////////////////////////////
delay_ms(2000); //antes de 2000ms
lcd_putc("canales 1,2,3=>\n");

if ( bkbhit) //Comprobamos que el buffer no este lleno
{
kk=bgetc(); //El primer byte es el break
}
if ( bkbhit)
{
kk=bgetc(); //El segundo byte es el start
}
if ( bkbhit)
{
chan1=bgetc();
}
if ( bkbhit)
{
chan2=bgetc();
}
if ( bkbhit)
{
chan3=bgetc();
}

lcd_putc(chan1);
lcd_putc(chan2);
lcd_putc(chan3);
delay_ms(1000);
clear_lcd();
}


}

void clear_lcd()
{
lcd_putc("\f");
}

thanks!
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

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

PostPosted: Wed Jan 19, 2005 6:44 am     Reply with quote

Yeah, I don't see you starting after the mark or "break" signal. Kindly use the code button when posting code. It makes it difficult to read otherwise and some people aren't going to waste time trying to scan the code. I already posted proven working DMX code. Versions of it have been in our products for the past 5 years. I suggest you start with it.
marquez



Joined: 05 Jan 2005
Posts: 0
Location: spain

View user's profile Send private message

PostPosted: Wed Jan 19, 2005 8:58 am     Reply with quote

Mark wrote:
Yeah, I don't see you starting after the mark or "break" signal. Kindly use the code button when posting code. It makes it difficult to read otherwise and some people aren't going to waste time trying to scan the code. I already posted proven working DMX code. Versions of it have been in our products for the past 5 years. I suggest you start with it.

First of all thanks for your answer, Mark. Sorry for not use code button last time.
I would start with your code but can you post or send me a complete version? Sorry but I�m quite new in dmx and pics.
thanks
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

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

PostPosted: Wed Jan 19, 2005 9:05 am     Reply with quote

Go here http://www.ccsinfo.com/forum/viewtopic.php?t=21092&postdays=0&postorder=asc&start=15 and look at the dmx_rcv() function. That would be your #int_rda handler.
Guest








PostPosted: Thu Jan 20, 2005 6:14 am     Reply with quote

Mark wrote:
Go here http://www.ccsinfo.com/forum/viewtopic.php?t=21092&postdays=0&postorder=asc&start=15 and look at the dmx_rcv() function. That would be your #int_rda handler.

thank you very much mark! Smile
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
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