4 Replies Latest reply on Mar 12, 2020 4:10 AM by LePo_1062026

    problem with formatting 16 bits for UART

    RiTh_4546911

      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);

      }

        • 1. Re: problem with formatting 16 bits for UART
          MoTa_728816

          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

          • 2. Re: problem with formatting 16 bits for UART
            LinglingG_46

            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.

            • 3. Re: problem with formatting 16 bits for UART
              MoTa_728816

              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

              1 of 1 people found this helpful
              • 4. Re: problem with formatting 16 bits for UART
                LePo_1062026

                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

                1 of 1 people found this helpful