|
|
View previous topic :: View next topic |
Author |
Message |
Guest Guest
|
DMX problems receiving characters |
Posted: Thu Oct 26, 2006 6:11 pm |
|
|
I am using an 18F6520 at 16Mhz to receive DMX. I am using a hardware UART and an SN75176 level convertor. I am not getting valid level data. I am not attempting to detect the start of a DMX packet yet I am only resetting the port (cycling CREN) when I get an Overrun. I always get 0x82 as the level data no matter what level I send. The rcsta byte changes with different levels, ie. when sending 1>512@0 I get FERR (0xD4 for rcsta), when sending levels above zero I get 0xD1. Does anyone have any ideas what I am doing wrong or how to trouble shoot this further?
Below are relavent sections of code
Code: |
#use rs232(baud=9600,parity=N,xmit=PIN_G1,rcv=PIN_G2,bits=8, ERRORS, STREAM=Serial)
#use rs232(baud=250000,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9, STREAM=DMX)
#int_rda //DMX receive interupt service routine
void DMX_isr()
{
while (PIR1bits.RCIF)
{
fputc(DMX_rcsta, Serial);
fputc(data, Serial);
if (rcsta.OERR) //Overrun
{
rcsta.CREN = 0;
rcsta.CREN = 1;
}
}
return;
}
|
|
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Thu Oct 26, 2006 9:06 pm |
|
|
You code never reads the data value from the uart. You also can't transmit those data byte inside the ISR. You will always get an overrun error. |
|
|
Guest Guest
|
reading data from uart |
Posted: Fri Oct 27, 2006 8:41 am |
|
|
So do I need to use fgetc to read from the uart? Then put read data into a buffer and send from the buffer between interrupts? Thank you for the help. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
|
Guest Guest
|
Thanks |
Posted: Fri Oct 27, 2006 6:37 pm |
|
|
Thanks Mark! Its funny how it works when you actually read the value from the uart! Better a stupid mistake than a hardware problem. Thank you again for your help. |
|
|
spradecom.rnd
Joined: 27 Apr 2010 Posts: 16 Location: Mumbai
|
DMX receiving problem |
Posted: Wed Aug 11, 2010 12:13 am |
|
|
I wrote a code like the others based on Mark's code found in this forum, following the same ideas, but it doesn't work. The first problem is that the usart never generates a FERR error to detect the break. Second problem is about baud rate. Is this Code: | #USE RS232(baud=250000,rcv=PIN_C7,xmit=PIN_C6) | enough for setting baud rate or do we have to separately initialize using SPBRg reg ?
Here is my code
Code: |
#include <16F1938.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
//#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#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(clock =16000000)
#USE RS232(baud=250000,rcv=PIN_C7,xmit=PIN_C6)
//-----------Register Definition---------------------
//----------------------------------------------------
/************************************************************************
* Registrers 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
//----------------------------------------------------
#byte BAUDCON = 0x19F
#bit ABDEN = BAUDCON.0
#bit WUE = BAUDCON.1
#bit BRG16 = BAUDCON.3
#bit SCKP = BAUDCON.4
#bit RCIDL = BAUDCON.6
#bit ABDOVF = BAUDCON.7
/************************************************************************
* Function Decleration *
************************************************************************/
void Interrupt_USART_Rx(void);
void togglea1(void);
void togglea0(void);
//---------------------------------------------------------------------
/************************************************************************
* Global Variables *
************************************************************************/
#define MAX_PWMS 3
/*Rx Buffer for dmx stream */
//int8 Rx_Buffer[512];
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;
union
{
unsigned char fullbyte;
struct {
unsigned char RX9D:1; //bit0
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; //bit7
} bits ;
}rcsta;
static int8 *ptr_Rx;
static unsigned int DMX_512_Count = 0;
while(RCIF)
{
//togglea1();
rcsta.fullbyte = RCSTA;
// read data - reading data also clears 'rcif' flag
// and reading 'rcreg' will cause the second 'rcsta' to be loaded if there is one
data = RCREG;
if (rcsta.bits.OERR) //check for overrun
{
//If there Overrun then reset the reception
CREN = 0;
CREN = 1;
// received a buffer overun so, wait for a good data byte before looking for
// a break signal
// togglea1();
Rx_State = WAIT_FOR_NEXT_BYTE;
return;
}
switch (Rx_State)
{
case WAIT_FOR_NEXT_BYTE:
if (!rcsta.bits.FERR)
//togglea1();
Rx_State = WAIT_FOR_BREAK;
break;
case WAIT_FOR_BREAK:
/* If we did receive a framing error, make sure that the data is 0.
This means that we did Receive the break signal for at least 44us. */
if (rcsta.bits.FERR) // frame eror bit
{
togglea1();
if (!data)
//togglea1();
Rx_State = WAIT_FOR_START;
}
break;
case WAIT_FOR_START:
// check for a framing error. if we receive one we will have to wait
// until we receive a good data byte before we begin looking for our break signal
if (rcsta.bits.FERR)
// togglea1();
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 reception buffer */
ptr_Rx = Rx_Buffer;
Rx_State = RECEIVE_DATA;
}
}
break;
case RECEIVE_DATA:
if (rcsta.bits.FERR)
{
if (!data)
Rx_State = WAIT_FOR_START;
else
Rx_State = WAIT_FOR_NEXT_BYTE;
}
else
{
/* Store the data received in the reception buffer */
*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=0x03;
BRG16 = 0 ;
BRGH=1;
SYNC=0;
SPEN=1;
RX9=1; // 9 bit reception
//RX9D=1;
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);
}
void togglea0(void)
{
output_high(PIN_A0);
delay_ms(100);
output_low(PIN_A0);
delay_ms(100);
} |
|
|
|
|
|
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
|