problem with formatting 16 bits for UART

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
RiTh_4546911
Level 1
Level 1

I am trying to put 16bits output from the filter to the UART but keep getting corrupted results.

CY_ISR(filterVDAC)

{

     char transmission[16];

     uint16 c = Filter_Read16(Filter_CHANNEL_A);

     sprintf(transmission,"%d",c);

     UART_1_PutString(transmission);

}

0 Likes
1 Solution
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

> If you get the wrong result, there are two possibilities,

> one: the UART transmit the wrong data, the second maybe the filter gives wrong.

Some more things, I just remembered is,

(1) if I connect rx and tx swapped the data seems to be corrupted.

(2) if the baud rate is wrong between UART and the receiver (serial terminal),

      the data also seems to be corrupted.

(3) if the UART's tx is not connected to the receiver's rx, floating,

    also gives us seems to be corrupted data.

I'm surprised we have so many ways to get "seems to be" corrupted data.

moto

View solution in original post

4 Replies
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

If filterVDAC is called as an ISR,

sprintf() and UART_1_PutString() should be called after returning to usual funciton.

So please try something like

=========

#include "project.h"

volatile uint16_t filter_value = 0 ;

volatile int vdac_flag = 0 ;

CY_ISR(filterVDAC)

{

     filter_value = Filter_Read16(Filter_CANNEL_A) ;

     filter_flag = 1 ;

     // clear interrupt flag if required

}

int main(void)

{

  char transmission[16] ;

...

   for (  ; ; )  {

      if (filter_flag) {

        snprintf(transmission, 16, "%d\n\r", filter_value) ;

        UART_1_PutString(transmission) ;

        filter_flag = 0 ;

     }

   }

}

=========

moo

0 Likes
lock attach
Attachments are accessible only for community members.
LinglingG_46
Moderator
Moderator
Moderator
500 solutions authored 1000 replies posted 10 questions asked

1:

Your question : I am trying to put 16bits output from the filter to the UART but keep getting corrupted results.

If you get the wrong result, there are two possibilities, one: the UART transmit the wrong data, the second maybe the filter gives wrong.

So you should do some work to ensure it is the UART issue.

2: You attached one code section: But we don't know the what's the function of "Filter_Read16(Filter_CHANNEL_A)"

CY_ISR(filterVDAC)

{

    char transmission[16];

    uint16 c = Filter_Read16(Filter_CHANNEL_A);

    sprintf(transmission,"%d",c);

    UART_1_PutString(transmission);

}

3: Could you share us which device you use?

4: I give a simple project to show how to use the printf();I run the project in PSoC Creator 4.2, CY8C4146AZI-S433.

5: hope it can be helpful for you.

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

> If you get the wrong result, there are two possibilities,

> one: the UART transmit the wrong data, the second maybe the filter gives wrong.

Some more things, I just remembered is,

(1) if I connect rx and tx swapped the data seems to be corrupted.

(2) if the baud rate is wrong between UART and the receiver (serial terminal),

      the data also seems to be corrupted.

(3) if the UART's tx is not connected to the receiver's rx, floating,

    also gives us seems to be corrupted data.

I'm surprised we have so many ways to get "seems to be" corrupted data.

moto

Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

RiTh,

I'm in agreement with moto.  It is generally not a good policy to place a potentially long (time-wise) blocking function like PutString() in an interrupt.  (This also includes CyDelay()s) This could cause problems with servicing other interrupts in your system.

When your code enters and interrupt, it disables ALL OTHER interrupts until that interrupt finishes.  The potential exception to that is using nested interrupts.  However, avoid using nested interrupts unless you know that strategy's pitfalls.

The general principal of good interrupt coding is to get in and get out as quickly as possible.  When you enter an interrupt, quickly determine the reason for the interrupt and get (or put) the data.  If the data needs to be processed further, signal the main task that data is available and then finish the interrupt.

In your code fragment, your filterVDAC ISR will take a minimum of 0.868 ms to complete a 10 character transfer of data through the UART_1 port at 115.2Kbps 8N1.  It could take longer if Filter_Read16() takes significant time to process.

The best use of an interrupt is to get (or put) time-critical data.  To do this effectively with all the other interrupts the system has to process, a ISR should be tight and small.

Try moto's suggestion about removing the PutString() (and the sprintf()) from the ISR.  See if this helps.

Len

Len
"Engineering is an Art. The Art of Compromise."