schneiderj 0 Posted January 28, 2010 Report Share Posted January 28, 2010 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 : 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 Quote Link to post Share on other sites
Dave 0 Posted January 28, 2010 Report Share Posted January 28, 2010 ...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 Quote Link to post Share on other sites
schneiderj 0 Posted January 28, 2010 Author Report Share Posted January 28, 2010 (edited) 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 January 28, 2010 by schneiderj Quote Link to post Share on other sites
schneiderj 0 Posted January 30, 2010 Author Report Share Posted January 30, 2010 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 Quote Link to post Share on other sites
Reynard 0 Posted January 30, 2010 Report Share Posted January 30, 2010 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 Quote Link to post Share on other sites
schneiderj 0 Posted January 30, 2010 Author Report Share Posted January 30, 2010 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 Quote Link to post Share on other sites
schneiderj 0 Posted February 1, 2010 Author Report Share Posted February 1, 2010 (edited) 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 February 1, 2010 by schneiderj Quote Link to post Share on other sites
Ian Harris 0 Posted February 1, 2010 Report Share Posted February 1, 2010 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 Quote Link to post Share on other sites
schneiderj 0 Posted February 3, 2010 Author Report Share Posted February 3, 2010 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 Quote Link to post Share on other sites
Reynard 0 Posted February 4, 2010 Report Share Posted February 4, 2010 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 Quote Link to post Share on other sites
schneiderj 0 Posted February 8, 2010 Author Report Share Posted February 8, 2010 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 FormulaSYNC 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 Quote Link to post Share on other sites
schneiderj 0 Posted February 23, 2010 Author Report Share Posted February 23, 2010 Sorry to come back with this, but I am unable to find an issue. If synchronization loss is the probleme how can I verify that correctly ? Any idea to help me ? Jean-Marie Quote Link to post Share on other sites
schneiderj 0 Posted March 16, 2010 Author Report Share Posted March 16, 2010 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 Quote Link to post Share on other sites
Pavel 0 Posted March 16, 2010 Report Share Posted March 16, 2010 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 Quote Link to post Share on other sites
schneiderj 0 Posted March 17, 2010 Author Report Share Posted March 17, 2010 Hi Pavel, I will try your new driver this week end if I find some free time, with application I am currently developing. Jean-Marie Quote Link to post Share on other sites
joli 0 Posted March 17, 2010 Report Share Posted March 17, 2010 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 Quote Link to post Share on other sites
Pavel 0 Posted March 18, 2010 Report Share Posted March 18, 2010 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 Quote Link to post Share on other sites
joli 0 Posted March 23, 2010 Report Share Posted March 23, 2010 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 Quote Link to post Share on other sites
davidb 0 Posted March 23, 2010 Report Share Posted March 23, 2010 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 Quote Link to post Share on other sites
Pavel 0 Posted March 23, 2010 Report Share Posted March 23, 2010 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 Quote Link to post Share on other sites
joli 0 Posted March 24, 2010 Report Share Posted March 24, 2010 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 Quote Link to post Share on other sites
Pavel 0 Posted March 25, 2010 Report Share Posted March 25, 2010 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 Quote Link to post Share on other sites
davidb 0 Posted March 31, 2010 Report Share Posted March 31, 2010 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 Quote Link to post Share on other sites
Pavel 0 Posted March 31, 2010 Report Share Posted March 31, 2010 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 Quote Link to post Share on other sites
khals 0 Posted October 12, 2013 Report Share Posted October 12, 2013 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 Quote Link to post Share on other sites
JorgeF 0 Posted October 12, 2013 Report Share Posted October 12, 2013 (edited) 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 October 12, 2013 by JorgeF Quote Link to post Share on other sites
khals 0 Posted October 13, 2013 Report Share Posted October 13, 2013 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 Quote Link to post Share on other sites
Recommended Posts
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.