View previous topic :: View next topic |
Author |
Message |
Guest
|
|
Posted: Mon Dec 27, 2004 10:32 pm |
|
|
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
|
|
Posted: Mon Jan 03, 2005 5:25 pm |
|
|
Mark,
My mistake, the code works.
Thanks, Garrett |
|
|
marquez
Joined: 05 Jan 2005 Posts: 0 Location: spain
|
dmx pic16f767 receiver |
Posted: Wed Jan 19, 2005 4:59 am |
|
|
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
|
|
Posted: Wed Jan 19, 2005 6:44 am |
|
|
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
|
|
Posted: Wed Jan 19, 2005 8:58 am |
|
|
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
|
|
|
Guest
|
|
Posted: Thu Jan 20, 2005 6:14 am |
|
|
thank you very much mark! |
|
|
|