AnsweredHot!Problem in sending the last string character over the UART, PIC16F1619

Author
Gianluca16
New Users
  • Total Posts : 5
  • Reward points : 0
  • Joined: 2019/02/12 11:10:55
  • Location: Italy
  • Status: offline
2019/02/14 05:12:07 (permalink)
0

Problem in sending the last string character over the UART, PIC16F1619

Hi everyone,
 
I am new in the forum and new to the PIC microcontrollers, I have already used microcontrollers, but never programmed the UART communication at such low level.
I am using the PIC16F1619 with the Curiosity board and I am trying to send and receive strings using the UART. To do that I connected the PIC to the computer using a UART to USB converter and Real Term. Attached you can find my code. I set the baud rate to 1200, 8 bits communication and no parity. The program works in this way: 
- I write a string on Real Term (for example 'Hello')
- Send the string all in once
- The PIC reads the string character by character and store it in an array (now I am using an array of 10 values, in future I would like to use pointers to allocate memory, to be more flexible)
- Once all the string has been read, in my case the '\n' value is found in the rx buffer, a flag is set to start the transmission
- Here the problems start. I would like to send the string back character by character and stop it when the value '\n' is found, but the transmission stops the character before '\n'.
Let's say if I write 'Hello' what I get back is 'Hell'. In attachement there is also the screenshot of the Terminal. I checked with the scope and neither the 'o' and the '\n' are sent. I am sure that they have been stored in the array because if I add in the code a '\r' before the '\n' and after the 'o' I receive the right string 'Hello', but looking with the scope is clear that neither '\r' and '\n' are sent. It seems that the character before the '\n' is not considered even if the array is scanned position by position. I do not want to use '\0', because it sends all the array values and if some rubbish is present after the end of 'Hello' it is sent as well, due to the fact that the array is 10 position long. I made a program also to debug the transmission and everything seems fine, so I do not understand this behaviour.
 
 
If anyone can help me it would be great.
Thanks in advance.
 
Gianluca

Attached Image(s)

#1
mbrowning
Just a Member
  • Total Posts : 1250
  • Reward points : 0
  • Joined: 2005/03/16 14:32:56
  • Location: Melbourne, FL
  • Status: offline
Re: Problem in sending the last string character over the UART, PIC16F1619 2019/02/14 10:28:45 (permalink)
+4 (4)
At 1200baud, it takes 8ms to send a character.
 
Your ISR sets TX_Stop_F when the last character has been put in TX1REG.
The main loop then immediately calls TX_Stop() which TURNS OFF THE UART at this point.
 
The Uart TX is double buffered, which means the last two characters are not sent.
 
Why turn the transmitter off? that makes no sense. Just clear TXIE.
 
 

Oh well - there's always next year
#2
Gianluca16
New Users
  • Total Posts : 5
  • Reward points : 0
  • Joined: 2019/02/12 11:10:55
  • Location: Italy
  • Status: offline
Re: Problem in sending the last string character over the UART, PIC16F1619 2019/02/15 04:20:40 (permalink)
0
Hi thank you for the answer.
I turned off the transmitter to avoid some useless transmissions. I tried to modify the program as you suggested, I just commented the line  -TX1STAbits.TXEN = 0;- . Unfortunately I obtained wrong answers from the microcontroller as shown in figure 1 in the attachements. I made some modifications and now it seems it works, but I still need to turn off the TX module, in attachments you can find the code. As you said the module turned off too quickly, then the transmission was interrupted. So in the  -TX_Stop()-  function I made the program waits for the register to be empty and also to add in the end the '\n' character. At last the program turns off the module, in this way it works, I also checked with the scope. I also added  -Write_Back = 0;-  in the first condition in the while in the main to avoid the program to go back into this condition. If I remove  -TX1STAbits.TXEN = 0;- I obtain what is shown in figure 1, also with my modifications. I tried also at differents baud rates, always the same. I do not know if this is the best way to do it, but it seems it works as shown in figure 2. If you have any ideas why I need to turn off the module it would be great, otherwise thanks very much for the answer and for the help.
 
Gianluca
 
 

Attached Image(s)

#3
qhb
Superb Member
  • Total Posts : 9242
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: Problem in sending the last string character over the UART, PIC16F1619 2019/02/15 05:50:17 (permalink)
+2 (2)
Gianluca16
I turned off the transmitter to avoid some useless transmissions.

Worst possible way to try to fix it.
 

I tried to modify the program as you suggested, I just commented the line  -TX1STAbits.TXEN = 0;- . Unfortunately I obtained wrong answers from the microcontroller as shown in figure 1 in the attachements. I made some modifications and now it seems it works, but I still need to turn off the TX module, in attachments you can find the code.

You're still turning the TXEN off while the last character is being transmitted. I guess you didn't understand mbrowning's explanation at all.
 

As you said the module turned off too quickly, then the transmission was interrupted. So in the  -TX_Stop()-  function I made the program waits for the register to be empty

No you didn't. You wait for TXIF, which does NOT tell you the transmission has finished. That is what the TRMT bit tells you, which is what mbrowning told you to use.
 
Try again, doing what he said, not just tweaking your already bad code.
#4
Gianluca16
New Users
  • Total Posts : 5
  • Reward points : 0
  • Joined: 2019/02/12 11:10:55
  • Location: Italy
  • Status: offline
Re: Problem in sending the last string character over the UART, PIC16F1619 2019/02/15 10:22:37 (permalink)
0
Thank you for the answer and the further explanation. I fixed my code as well as I could, but I still do not get one thing. Isn't it sufficient to check if the current value is '\n' and then clear the TXIE to end the transmission, or is it necessary to check also the TRMT? Because if I clear TXIE, no interrupts should occur anymore from this peripheral. Then the '\n' should be passed to the TSR automatically, as soon as the TSR is empty, thus the value before '\n' is sent. So when the '\n' is sent and TSR is empty again, due to the fact that the interrupts are disabled on this module, the trasmission should stop automatically without checking the TRMT, because no new characters can cause interrupts. If I understand well from the datasheet.
 
Thank you
Gianluca
#5
1and0
Access is Denied
  • Total Posts : 8744
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: Problem in sending the last string character over the UART, PIC16F1619 2019/02/15 11:43:37 (permalink)
+2 (2)
It generally easier to transmit without using the interrupt. ;)
 
 
Gianluca16
I turned off the transmitter to avoid some useless transmissions.

How and why?  Transmission is under your control.
 
#6
malaugh
Super Member
  • Total Posts : 378
  • Reward points : 0
  • Joined: 2011/03/31 14:04:42
  • Location: San Diego
  • Status: offline
Re: Problem in sending the last string character over the UART, PIC16F1619 2019/02/15 14:21:48 (permalink)
+1 (1)
Here is a quick explanation (simplified a little).   The UART Tx circuit has two registers, a Tx shift register and a Tx holding register.  When you send the first character to the UART, it gets stored in the Tx holding register, then transferred to the Tx shift register.  Now the Tx holding register is empty, and the Tx empty flag is set, so now you can immediately send another character to the holding register.  So now we have the second character in the holding register, and the first character being shifted out.  Eventually the first character in the shift register will be shifted out, the character in the holding register will be transferred to the shift register, and the holding register will be empty Now the third character can be sent to the UART.  So now the first character has been transmitted, the second character is in the shift register being transmitted, and the third character is in the holding register.  
 
if you look at the Tx empty flag, this will go active immediately after the holding register is empty, the character previously in the holding register having just been transferred to the shift register.  If you turn off the transmitter now, the character in the transmit shift register will never be sent.  the TRMT flag goes active when both holding register and shift register are empty, so now it is safe to turn off the transmitter without losing data.
#7
1and0
Access is Denied
  • Total Posts : 8744
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: Problem in sending the last string character over the UART, PIC16F1619 2019/02/16 07:38:38 (permalink)
+1 (1)
RCIF and TXIF are read-only so
PIR1bits.RCIF = 0;
PIR1bits.TXIF = 0;

are useless.
 
Looking at the code in Post #3, I don't see how you are able to get any transmission at all. That is, after a '\n' terminated string is received, TX_Start() is executed to enable the transmitter and its interrupt; but TXREG is not written to, so TXIF stays a '0' hence no transmission! Or, have I missed something? 
TXIF is set when TXEN is set.
 
post edited by 1and0 - 2019/02/16 10:44:58
#8
1and0
Access is Denied
  • Total Posts : 8744
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: Problem in sending the last string character over the UART, PIC16F1619 2019/02/16 08:25:31 (permalink)
+1 (1)
Try replacing
void TX_Stop(void) 
{
    TX_Stop_F = 0;
    while(!PIR1bits.TXIF);
    TX1REG = RX[i+1];
    while(!PIR1bits.TXIF);
    i = 0;
    TX1STAbits.TXEN = 0; // Disable the TX circuit
}

with
void TX_Stop(void) 
{
    TX_Stop_F = 0; 
    while(!PIR1bits.TXIF);
    TX1REG = RX[i+1];
    while(!TX1STAbits.TRMT);
    i = 0;
    TX1STAbits.TXEN = 0; // Disable the TX circuit 
}

#9
Gianluca16
New Users
  • Total Posts : 5
  • Reward points : 0
  • Joined: 2019/02/12 11:10:55
  • Location: Italy
  • Status: offline
Re: Problem in sending the last string character over the UART, PIC16F1619 2019/02/16 15:01:49 (permalink)
0
Thank you very much for the answers and the suggestions.
- @1and0: post #7 yes, I saw some examples where they transmit a string using the UART without interrupts, I just wanted to try with the interrupts to understand how it works. Furthermore, isn't it better to use the ISR?
post #8 I will remove RCIF = 0 and TXIF = 0.
post#9 I will try out as soon as I can your solution, waiting for the TRMT bit should help in send all the characters until the last. 
 
- @malaugh: nice explanation is clearer now the transmission process.
 
Also to answer to post #7, I tried to make a program without turning off the transmission circuit, as suggested by qhb and mbrowning. I am able to send a pre-defined string with a user defined interval of time, using a timer, without turning off the transmitter circuit, thus without clearing TXEN.
Then I used this program together with the one that receives the string and sometimes it returns the string once (correct) sometimes twice (not correct). It seems that the program goes inside the ISR two times, even if I clear the bit for this peripheral, TXIE. I do not understand why. I used a digital output and the scope, to check if the program goes inside the ISR twice and actually it does. In attachement the two codes.
 
Thanks again
Gianluca
#10
qhb
Superb Member
  • Total Posts : 9242
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: Problem in sending the last string character over the UART, PIC16F1619 2019/02/16 15:19:08 (permalink)
+3 (3)
Gianluca16
Thank you very much for the answers and the suggestions.
- @1and0: post #7 yes, I saw some examples where they transmit a string using the UART without interrupts, I just wanted to try with the interrupts to understand how it works. Furthermore, isn't it better to use the ISR?

It's better to get something working right the simple way first, then add complexity.
You only need to use transmit interrupts if you need to be doing some non-interrupt activity at the same time as the transmit is taking place. In many applications, all you are doing is fetching data to transmit, so TX interrupts don't help at all.
 

Also to answer to post #7, I tried to make a program without turning off the transmission circuit, as suggested by qhb and mbrowning. I am able to send a pre-defined string with a user defined interval of time, using a timer, without turning off the transmitter circuit, thus without clearing TXEN.
Then I used this program together with the one that receives the string and sometimes it returns the string once (correct) sometimes twice (not correct). It seems that the program goes inside the ISR two times, even if I clear the bit for this peripheral, TXIE. I do not understand why. I used a digital output and the scope, to check if the program goes inside the ISR twice and actually it does. In attachement the two codes.

UART_Tx.c is still trying to clear TXIF
Don't use "int" variables to hold flags (i.e. values that can only be 0 or 1). That is forcing an 8 bit processor to access two 8 bit locations just to check for a binary value. Use an "unsigned char" or even better a "bit" variable for this.
 
 
#11
1and0
Access is Denied
  • Total Posts : 8744
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: Problem in sending the last string character over the UART, PIC16F1619 2019/02/17 07:14:13 (permalink) ☼ Best Answerby Gianluca16 2019/02/18 08:53:50
+3 (3)
Gianluca16
Also to answer to post #7, I tried to make a program without turning off the transmission circuit, as suggested by qhb and mbrowning. I am able to send a pre-defined string with a user defined interval of time, using a timer, without turning off the transmitter circuit, thus without clearing TXEN.
Then I used this program together with the one that receives the string and sometimes it returns the string once (correct) sometimes twice (not correct). It seems that the program goes inside the ISR two times, even if I clear the bit for this peripheral, TXIE. I do not understand why. I used a digital output and the scope, to check if the program goes inside the ISR twice and actually it does.

Since you have only two interrupt sources (RX and TX) and if there's an interrupt when TXIE is cleared, then it must be caused by the RX. Try replacing your ISR
void __interrupt() ISR(void)
{
    if (PIR1bits.RCIF == 1)
    {
        // snipped
    }
    if (PIR1bits.TXIF == 1)
    {
        // snipped
    }
}

with this
void __interrupt() ISR(void)
{
    if (PIR1bits.RCIF == 1)
    {
        // snipped
    }
    else if (PIR1bits.TXIF == 1)
    {
        // snipped
    }
}

or this
void __interrupt() ISR(void)
{
    if (PIR1bits.RCIF == 1)
    {
        // snipped
    }
    if (PIR1bits.TXIF == 1 && PIE1bits.TXIE == 1)
    {
        // snipped
    }
}

#12
Gianluca16
New Users
  • Total Posts : 5
  • Reward points : 0
  • Joined: 2019/02/12 11:10:55
  • Location: Italy
  • Status: offline
Re: Problem in sending the last string character over the UART, PIC16F1619 2019/02/18 08:54:11 (permalink)
0
Thank you again for your answers. 
- @qhb: I changed it into the data type you suggested me, I will try out also the solution without interrupts.
- @ 1and0: Both of your suggestions work fine and now the communication works without any problems that's great! grin: grin Thanks a lot!! 
#13
1and0
Access is Denied
  • Total Posts : 8744
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: Problem in sending the last string character over the UART, PIC16F1619 2019/02/18 10:14:06 (permalink)
+1 (1)
Gianluca16
- @ 1and0: Both of your suggestions work fine and now the communication works without any problems that's great! grin: grin Thanks a lot!! 

Glad I can help. Smile: Smile
#14
Jump to:
© 2019 APG vNext Commercial Version 4.5