- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
}
}
}
Solved! Go to Solution.
- Labels:
-
PSoC 5 Device Programming
-
PSoC 5LP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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