Jump to content

Recommended Posts

Hello

 

I have a communication between a 18F4520 and an electronic system through a RS232.

The answer of tje "slave" is correct as show by my logic analyser.

 

The char* send by the 18F is "status" and answer is "02 REMOTE STOP". You can see that in the following screen image :

REMOTE%20STOP.JPG

 

But in the debug mode, I can see that the Reponse is not what I was expecting, instead I have "?02 REMOxx STOP" with x represent the undefined character .

 

My code is :

 

	// initialisation de la connexion par envoi de la commande status
while(ConnexionRS232)
{
	strcpy(Commande, "status"); 
	strcpy(ReponseAttendue, "02 REMOTE STOP"); 
	strcpy(Reponse, RS232liaison(Commande));
	delay_ms(500);
	strcpy(Reponse, strstr( Reponse, ReponseAttendue));
	if(strstr( Reponse, ReponseAttendue) != NULL )
	{
		ConnexionRS232 = 0;
	}
	lcd_clear();
	lcd_gotoxy(0,0);
	lprintf(ReponseAttendue);
	lcd_gotoxy(0,1);
	lprintf(Reponse);

}

 

I am unable to seewhere is that problem coming from. Any idea ?

 

Thanks

Jean-Marie

Share this post


Link to post
Share on other sites
...

I am unable to seewhere is that problem coming from. Any idea ?

Consider baud rate accuracy, with RS232 comms the two ends are not synchronised with a common clock, they both free run at their own speed. If the clock is slightly wrong on one or both ends then there is potential for them to go in and out of phase. This could explain initially data is good (in phase), then goes bad (out of phase) and then good again(in phase).

Check accurately timing of the serial data.

 

Regards

Dave

Share this post


Link to post
Share on other sites

Thanks Dave. Thats could explain de problem.

 

How can I check that accuracy ? With my LogicAnalyser by increasing the sampling rate probably...

 

Jean-Marie

 

Edit : with the data's I have on my computer (sampled at 100 kHz for a 9600 baud rate for the serie connection), I found for the data's send by the PIC

  • 1 char take 1.04 ms
  • 7 char take 7.27 ms

 

For the data's send by the cryostat :

  • 1 char take 1.04 ms
  • 7 char take 7.28 ms

Edited by schneiderj

Share this post


Link to post
Share on other sites

Hello again,

 

I have found the documentation of the cryostat I am using. The RS232 parameter are :

  • baud rate : 9600 (could be modified)
  • Parity : even (could be modified)
  • Handshake hardware (could be software)
  • data bits 7 (could not modified)
  • stop bit : 1 (could not modified)

 

And if I understand correctly the 18F4520 data sheet I can only set data bits to 8 or 9.

 

Is there a way to solve that issue ?

 

Jean-Marie

Share this post


Link to post
Share on other sites

Hi Jean-Marie,

 

You are not giving us many clues here.

 

Looking at the waveforms the remote device is set to: 8 bits no parity, Xon/Xoff handshaking.

 

You are sending 7 charaters ("status" + another). I don't know whether this is some kind of checksum (sum, LPC or CRC).

 

How does your program handle the none printable characters (DC1 and DC3). What does lprintf do with them. Do you filter them out.

 

Cheers

 

Reynard

Share this post


Link to post
Share on other sites

Thanks reynard for your answer.

 

You are sending 7 charaters ("status" + another). I don't know whether this is some kind of checksum (sum, LPC or CRC).

 

I try other interpreter combination :

http://schneiderj.net/Electronique/Images/...%208%20bits.JPG

http://schneiderj.net/Electronique/Images/...20interpret.JPG

 

And only 8 bits with no parity or 7 bits with taking no care of parity interpret correctly the message. 7 bits and odd give locks like what I observe with MPLAB during debugging.

How does your program handle the none printable characters (DC1 and DC3). What does lprintf do with them. Do you filter them out.

I did not take care of the first non printable character : it is the software control byte.

I use the character <CR> to determine the end of the message. The next one is not considered.

 

Jean-Marie

Share this post


Link to post
Share on other sites

I am continuing to try to find where is the problem coming.

By disabling the glitches option, I till have the same value in the LogicAnalyseur.

 

I take a look with the oscilo with sampling at 125 k. The baud rate is found at almost 9600 in the two directions.

 

Now instead from the PC I send the string "03 REMOTE STOP". Pic read "03 REMOOE STOP"

 

If I send :

 

  • UUUUUUUUUUUUU read UUUUUUUUUUUUU
  • 11111111111111 read 11111111111111
  • 03 R111TE STOP read 03 R1111E STOP
  • 0123456789 read 0123456689

 

All the time it is the character eight which take the value of the seven one. Does that can come from an error of the library ?

 

Jean-Marie

Edited by schneiderj

Share this post


Link to post
Share on other sites

Are you running your PIC with an external crystal or using the internal rc oscillator? Obviously the crystal is going to give you better results.

 

cheers

Ian.

 

 

I am continuing to try to find where is the problem coming.

By disabling the glitches option, I till have the same value in the LogicAnalyseur.

 

I take a look with the oscilo with sampling at 125 k. The baud rate is found at almost 9600 in the two directions.

 

Now instead from the PC I send the string "03 REMOTE STOP". Pic read "03 REMOOE STOP"

 

If I send :

 

  • UUUUUUUUUUUUU read UUUUUUUUUUUUU
  • 11111111111111 read 11111111111111
  • 03 R111TE STOP read 03 R1111E STOP
  • 0123456789 read 0123456689

 

All the time it is the character eight which take the value of the seven one. Does that can come from an error of the library ?

 

Jean-Marie

Share this post


Link to post
Share on other sites
Are you running your PIC with an external crystal or using the internal rc oscillator? Obviously the crystal is going to give you better results.

 

Thanks for your suggestion. I am using external oscillator with the following reference : http://fr.farnell.com/jsp/search/productde...amp;Ntt=1611820

 

I think that a quit good reference for what I am doing.

What did you thinks ?

 

Jean-Marie

Share this post


Link to post
Share on other sites

Hi Jean-Marie,

 

You have told us practically nothing about how your serial comms is configured or operate.

 

Are you polling or interrupt driven ? What are your program values at 20MHz ?

 

Do you have something like this:

 

BRG16 = 1.

 

BRGH = 0, SPBRG = 129 which should give 9615 baud 0.16% error.

BRGH = 1, SPBRG = 520 which should give 9596 baud -0.03% error.

 

Cheers

 

Reynard

Share this post


Link to post
Share on other sites

Hello Reynard,

 

You are write. In fact I use the Boostc librairy without knowing a lot about its implementation ! That save time, but now I think I have loose time !

 

In the Boostc library I was unable to find BRG16 nor BAUDCON (RS232_driver.h).

 

I found that :

TXSTA = 0xA4, thus BRGH = 1 and SYNC = 0

 

From the datasheet :

BRG/EUSART Mode Baud Rate Formula

SYNC BRG16 BRGH

 

0 0 1 8-Bit/Asynchronous FOSC/[16 (n + 1)]

 

From the driver we have : UART_INIT<USART_ARGS>( 1, ((20000000 / (9600 * 16L)) - 1L) );

by the way, if I did not make confusion I have SPBRG = 129.

 

For the moment I could not verify that on the harware, as I am unable to linke my project with MPLAB.

I will let you know,

 

Jean-Marie

Share this post


Link to post
Share on other sites

Hello !

 

Me again... I have write my own driver for EUSART communication.

And with it I did not have the problem I had with the Boostc driver.

 

Hop that can help some one else.

 

Jean-Marie

Share this post


Link to post
Share on other sites
Me again... I have write my own driver for EUSART communication.

And with it I did not have the problem I had with the Boostc driver.

 

We are in process of rewriting the uart driver that is included into SourceBoost. Will make it available soon. Anybody wants to beta test it?

 

Regards,

Pavel

Share this post


Link to post
Share on other sites
Me again... I have write my own driver for EUSART communication.

And with it I did not have the problem I had with the Boostc driver.

 

We are in process of rewriting the uart driver that is included into SourceBoost. Will make it available soon. Anybody wants to beta test it?

 

Regards,

Pavel

 

Hi Pavel

 

I am very interested in testing this driver

 

Regards,

joli

Share this post


Link to post
Share on other sites
I am very interested in testing this driver

 

Driver release candidate can be found here http://forum.sourceboost.com/index.php?showtopic=4534

 

Regards,

Pavel

As i understand by looking to the driver code, this is to use with RTOS (novo)!?

If is the case, i'm sorry but right now is impossible to alocate time to do the necessary and apropriated tests.

Anyway, thank you.

 

joli

Share this post


Link to post
Share on other sites
As i understand by looking to the driver code, this is to use with RTOS (novo)!?

If is the case, i'm sorry but right now is impossible to alocate time to do the necessary and apropriated tests.

Anyway, thank you.

 

joli

I am sure the driver isn't intended for exclusive use with NOVO, it just happens that the demo code demonstrates the use of the driver with NOVO - killing two birds with one stone! Perhaps another simple demo is called for to demonstrate the driver without using the RTOS?

 

Regards

 

davidb

Share this post


Link to post
Share on other sites
As i understand by looking to the driver code, this is to use with RTOS (novo)!?

If is the case, i'm sorry but right now is impossible to alocate time to do the necessary and apropriated tests.

Anyway, thank you.

 

joli

I am sure the driver isn't intended for exclusive use with NOVO, it just happens that the demo code demonstrates the use of the driver with NOVO - killing two birds with one stone! Perhaps another simple demo is called for to demonstrate the driver without using the RTOS?

 

This is a general purpose driver and it does not depend on Novo RTOS. Don't let sample code confuse you. All driver API (that consists of only 5 calls) is described in the accompanying manual and can be used from any code.

 

Regards,

Pavel

Share this post


Link to post
Share on other sites
As i understand by looking to the driver code, this is to use with RTOS (novo)!?

If is the case, i'm sorry but right now is impossible to alocate time to do the necessary and apropriated tests.

Anyway, thank you.

 

joli

I am sure the driver isn't intended for exclusive use with NOVO, it just happens that the demo code demonstrates the use of the driver with NOVO - killing two birds with one stone! Perhaps another simple demo is called for to demonstrate the driver without using the RTOS?

 

Regards

 

davidb

That would be an interesting ideia.

 

Regards,

joli

Share this post


Link to post
Share on other sites
I am sure the driver isn't intended for exclusive use with NOVO, it just happens that the demo code demonstrates the use of the driver with NOVO - killing two birds with one stone! Perhaps another simple demo is called for to demonstrate the driver without using the RTOS?

 

OK here is same sample modified not to use Novo (untested). It uses 2 UARTs and just forwards data received from UART1 to UART2. Enjoy:

 

/********************************************************************
BoostC/BoostC++ sample code

Asynchronous UART sample code that receives data from UART1 
and forwards it to UART2. Code also flashes heartbeat LED
connected to PORTD pin 0

BoostC/BoostC++ compilers are available from www.sourceboost.com

Author(s) Pavel Baranov
Copyright(C) 2010 Pavel Baranov

This code can be used free of charge in both commercial and 
non-commercial projects as long as this copyright notice and 
this entire statement is left unchanged. This software is provided
"as is", without warranty of any kind.

********************************************************************/

//System headers
#include <system.h>

//Target PIC18F8722 configuration word
#pragma DATA _CONFIG4L, _DEBUG_OFF_4L & _LVP_OFF_4L & _STVREN_OFF_4L & _XINST_OFF_4L
#pragma DATA _CONFIG2H, _WDT_OFF_2H & _WDTPS_128_2H
#pragma DATA _CONFIG2L, _PWRT_OFF_2L & _BOREN_OFF_2L
#pragma DATA _CONFIG1H, _FCMEN_OFF_1H & _OSC_HS_1H

//Set clock frequency
#pragma CLOCK_FREQ	10000000

//UART Tx and Rx data
#define TX_BUFFER_SIZE	8
#define RX_BUFFER_SIZE	8

//TX and RX buffers and helper variables
static unsigned char txBuffer[TX_BUFFER_SIZE], txHead, txTail;
static unsigned char rxBuffer[RX_BUFFER_SIZE], rxHead, rxTail, rxCnt;

//Because we use 2 UARTs we have to use UART driver in multiple port mode
#include "uart_driver.h"

//Helper defines for uart driver calls
#define uart1Init					rs232Init<PIE1,TX1IE,PIE1,RC1IE,RCSTA,CREN,RCSTA,SPEN>
#define uart1TxInterruptHandler		rs232TxInterruptHandler<PIR1,TX1IF,TXREG1,sizeof(txBuffer),TXSTA,TXEN,TXSTA,TRMT>
#define uart1RxInterruptHandler		rs232RxInterruptHandler<PIR1,RC1IF,RCREG1,sizeof(rxBuffer),RCSTA,CREN,RCSTA,OERR,RCSTA,FERR>
#define uart1Rx						rs232Rx<sizeof(rxBuffer)>
#define uart1Tx						rs232Tx<sizeof(txBuffer),TXSTA,TXEN>

#define uart2Init					rs232Init<PIE3,TX2IE,PIE3,RC2IE,RCSTA2,CREN,RCSTA2,SPEN>
#define uart2TxInterruptHandler		rs232TxInterruptHandler<PIR3,TX2IF,TXREG2,sizeof(txBuffer),TXSTA2,TXEN,TXSTA2,TRMT>
#define uart2RxInterruptHandler		rs232RxInterruptHandler<PIR3,RC2IF,RCREG2,sizeof(rxBuffer),RCSTA2,CREN,RCSTA2,OERR,RCSTA2,FERR>
#define uart2Rx						rs232Rx<sizeof(rxBuffer)>
#define uart2Tx						rs232Tx<sizeof(txBuffer),TXSTA2,TXEN>

//////////////////////////////////////////////
// High priority interrupt
// handles system time
//////////////////////////////////////////////
void interrupt( void )
{
//Handle timer0 interrupt
if( intcon.T0IF )
{
	// update system time every 1s
	static unsigned char nDivider = 0;
	if( 39 == ++nDivider )
	{
		nDivider = 0;
		latd ^= 1;
	}
	clear_bit( intcon, T0IF ); //clear timer 0 interrupt bit
}
}

//////////////////////////////////////////////
// Low priority interrupt
// handles UART send and receive
//////////////////////////////////////////////
void interrupt_low( void )
{
uart2TxInterruptHandler( txBuffer, txTail, txHead );
uart1RxInterruptHandler( rxBuffer, rxHead, rxCnt );
}

//////////////////////////////////////////////
// Program entry point
//////////////////////////////////////////////
void main( void )
{
//Disable watchdog
wdtcon.SWDTEN = 0;

//Configure and initialise port D
trisd = 0x00, portd = 0x00;

//Set Timer0 mode
set_bit( t0con, TMR0ON ); //enable timer0
clear_bit( t0con, T0CS ); //configure timer0 as a timer
//Set Timer0 resolution
set_bit( t0con, T08BIT ); //set timer0 8 bit wide
//Set prescaler assignment
clear_bit( t0con, PSA ); //prescaler is assigned
//Set prescaler rate
set_bit( t0con, T0PS2 ); //prescaler rate 1:256
set_bit( t0con, T0PS1 );
set_bit( t0con, T0PS0 );
//Set timer0 source edge selection
set_bit( t0con, T0SE ); //increment on high-to-low transition on RA4/T0CKI pin

//Configure serial port speed and interrupt
ipr1.RCIP = 0, ipr1.TXIP = 0, ipr3.RCIP = 0, ipr3.TXIP = 0; //use low priority interrupt
txsta.BRGH = 1, txsta2.BRGH = 1;	   //high speed
spbrg = 64, spbrg2 = 64;	  //9600kbps/10Mhz

//Configure UART1 pins
trisc.7 = 1;
trisc.6 = 0;
//Configure UART2 pins
trisg.2 = 1;
trisg.1 = 0;

//Init uart driver
uart1Init();
uart2Init();

//Configure interrupts
rcon.IPEN = 1;				 //enable priority level interrupts
intcon.TMR0IE = 1;			 //enable timer 0 interrupt
intcon.GIEH = intcon.GIEL = 1; //Enable high and low priority interruptr

//Endless loop
while( 1 )
{
	if( rxCnt )
	{
		//read one byte received from UART1
		unsigned char data = uart1Rx( rxBuffer, rxTail, rxCnt );
		//write received byte into UART2
		uart2Tx( data, txBuffer, txHead );
	}
}
}

// End of code

 

Regards,

Pavel

Share this post


Link to post
Share on other sites

Pavel,

 

I know you state your code is untested and I haven't tested it either but I spotted an error in the following section:

	//Configure serial port speed and interrupt
ipr1.RCIP = ipr1.TXIP = ipr3.RCIP = ipr3.TXIP = 0; //use low priority interrupt
txsta.BRGH = txsta2.BRGH = 1;	   //high speed
txsta.BRGH = txsta2.BRGH = 64;	  //9600kbps/10Mhz

I believe the last line should read:

	spbrg = spbrg2 = 64;	  //9600kbps/10Mhz

 

Although not strictly incorrect as is I would probably rewrite the whole section as follows:

	//Configure serial port speed and interrupt
ipr1.RCIP =  0; //use low priority interrupt
ipr1.TXIP =  0; //use low priority interrupt
ipr3.RCIP =  0; //use low priority interrupt
ipr3.TXIP = 0; //use low priority interrupt
txsta.BRGH =  1;	   //high speed
txsta2.BRGH = 1;	   //high speed
spbrg = 64;	  //9600kbps/10Mhz
spbrg2 = 64;	  //9600kbps/10Mhz

This avoids the code bloat associated with the x = y = z; type of assignment.

 

Regards

 

davidb

Share this post


Link to post
Share on other sites
I know you state your code is untested and I haven't tested it either but I spotted an error in the following section...

 

Thanks for pointing this out. Yes these are errors. Original code in the above post is now corrected.

 

Regards,

Pavel

Share this post


Link to post
Share on other sites

Hi,

 

I am trying to setup UART communication for PIC16f4455 and have written some code following the example provided by Pavel. The code compiles however I cannot see the correct values transmitted using terminal, at the moment i am just trying to transmit a byte. I would really appreciate if someone could have a look at my code and put me in the right direction. I have attached the code below.

 

Kind regards,

 

UART.c

Share this post


Link to post
Share on other sites

Hi

 

I noticed the following possible sources of problems:

- You don't have an ISR for the low priority interrupts.

- You are enabling the UART interrupts before setting up the UART.

- You are not clearing the interrupt flags before enabling interrupts or at least globaly enable them.

- Also the TIMER0 interrupt is enabled but I don't see any handling for it. Unless it is handled in "uart1TxInterruptHandler()".

- You are globally enabling interrupt prior to finish setting them up.

 

This won't be a problem, but as some meaning.

- Your comments don't match the statements where they are, also there is some repeated code and some unexplained one to.

This looks like a bad case of "copy/cut/paste and stitch". Better review it in full and organize de configuration in a logical sequence.

 

HIH

 

Best regards

Jorge

 

PS: You shouldn't steal such an old topic, open a new one. Leave the old ones as is for documentation and reference.

Edited by JorgeF

Share this post


Link to post
Share on other sites

Hi

 

I noticed the following possible sources of problems:

- You don't have an ISR for the low priority interrupts.

- You are enabling the UART interrupts before setting up the UART.

- You are not clearing the interrupt flags before enabling interrupts or at least globaly enable them.

- Also the TIMER0 interrupt is enabled but I don't see any handling for it. Unless it is handled in "uart1TxInterruptHandler()".

- You are globally enabling interrupt prior to finish setting them up.

 

This won't be a problem, but as some meaning.

- Your comments don't match the statements where they are, also there is some repeated code and some unexplained one to.

This looks like a bad case of "copy/cut/paste and stitch". Better review it in full and organize de configuration in a logical sequence.

 

HIH

 

Best regards

Jorge

 

PS: You shouldn't steal such an old topic, open a new one. Leave the old ones as is for documentation and reference.

Hi Jorge,

 

Thank you very much for the reply and thanks for the kind advice. I am new to this and in the process of learning so I used other UART examples and tried to setup one for my PIC. I will amend my code according to your suggestions and if I need help I will open another topic.

 

Kind regards

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...