2 Replies Latest reply on Jan 27, 2019 6:52 PM by MoTa_728816

    ADC Read using interrupt issue

    RaSh_3782726

      Hi all,

       

      I want to make adc read using Interrupt.

      But when i debug the code the isr loop call. and did not goes into for(;;) loop.

      so the value is not getting.

       

      Here is the code.

       

       

       

      CY_ISR(ADC_SAR_2_ISR_LOC)

      {

              result = CY_GET_REG16(ADC_SAR_2_SAR_WRK0_PTR);

              dataReady = 1u;

      }

       

      int main()

      {

          LCD_Start();

          CyGlobalIntEnable; /* Enable all interrupts by the processor. */

          ADC_SAR_2_Start();

          ADC_SAR_2_IRQ_StartEx(ADC_SAR_2_ISR_LOC);

          ADC_SAR_2_StartConvert();

       

        for(;;)

          {

             

              /* Show ADC2 result on LCD*/

              if(dataReady != 0u)

              {

                 res1 = ADC_SAR_2_CountsTo_Volts(result);

                         LCD_Position(0u, 0u);

                      LCD_PrintString("ADC_Output");

                      LCD_ClearDisplay();

                      LCD_Position(1u, 2u);

                      LCD_PrintNumber(res1);

                      LCD_Position(1u, 5u);

                      LCD_PrintString("v");

                      dataReady = 0u;

              }

                     

          }

      }

        • 1. Re: ADC Read using interrupt issue
          KyTr_1955226

          I'm unsure what the problem exactly is.  Are you saying you can't get to your main for(;;) loop because it's not leaving the ISR?  Do you mean you're never getting dataready = 1 or result is not reading the result register properly?

           

          Are result and dataReady declared as volatile?  Any value that you're going to change in an ISR should be declared volatile to ensure the compiler doesn't just assume and optimize incorrectly.  It will basically force the variable to be read before any time it is used rather than assuming it already knows the value.

           

          I'd also recommend not pulling your value from the ADC inside the interrupt.  Set a flag then pull the value into your result variable inside your main for(;;) loop.  That way you can safely use ADC_IsEndConversion() to determine when your conversion has actually finished and ensure you aren't reading until then.  It also minimizes code inside your interrupt.

           

          if (dataReady){
               while (!ADC_IsEndConversion(ADC_RETURN_STATUS){};
               result = ADC_GetResult16();
               dataReady = 0;
          }
          
          1 of 1 people found this helpful
          • 2. Re: ADC Read using interrupt issue
            MoTa_728816

            Hi,

             

            I think that you need to clear interrupt flag inside the ISR,

            otherwise ISR will be called repeatedly.

             

            I modified your code as below and tested with CY8CKIT-059

            and at least program flow seems to be working.

             

            Note: As I don't have LCD, I used UART instead.

            change USE_LCD to 1 for your system.

             

            =========================

            #include "project.h"

            #include <stdio.h>

             

            #define USE_LCD 0

             

            #if !USE_LCD

                char str[128] ; /* print buffer */

            #endif

             

            volatile int dataReady = 0u ;

            uint16_t result = 0 ;

             

            CY_ISR(ADC_SAR_2_ISR_LOC)

            {

                ADC_SAR_2_IRQ_ClearPending() ;

                result = CY_GET_REG16(ADC_SAR_2_SAR_WRK0_PTR);

                dataReady = 1u;

            }

             

            int main()

            {

                float res1 = 0.0 ;

               

            #if USE_LCD

                LCD_Start();

            #else

                UART_Start() ;

            #endif

             

                CyGlobalIntEnable; /* Enable all interrupts by the processor. */

             

                ADC_SAR_2_Start();

                ADC_SAR_2_IRQ_StartEx(ADC_SAR_2_ISR_LOC);

                ADC_SAR_2_StartConvert();

             

              for(;;)

                {

                    /* Show ADC2 result on LCD*/

                    if(dataReady != 0u)

                    {

                       res1 = ADC_SAR_2_CountsTo_Volts(result);

            #if USE_LCD

                               LCD_Position(0u, 0u);

                            LCD_PrintString("ADC_Output");

                            LCD_ClearDisplay();

                            LCD_Position(1u, 2u);

                            LCD_PrintNumber(res1);

                            LCD_Position(1u, 5u);

                            LCD_PrintString("v");

            #else

                        sprintf(str, "ADC_Output %d.%02d V\n",

                            (int)res1, ((int)(res1 * 100) % 100)) ;

                        UART_PutString(str) ;

            #endif

                        dataReady = 0u;

                    }            

                }

            }

            =========================

             

            moto

            1 of 1 people found this helpful