software interrupt

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

cross mob
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Hey everyone, I want monitor a number of current channels like the note here: http://www.cypress.com/file/102911/download

   

However, I cant use the timer to trigger the interrupt, because I dont know how long my program run, so there's a chance the interrupt will be triggered again before my program finish. So I'd like to use the software interrupt in order to switch between different input channels.

   

In my ADC Feedback1, I got 2 signals which are voltage from the sense resistors, I want to sequencially monitor them and add them together to display to an LCD. 

   

Follow the above conversation, I used the ISR component, then used the Control register to trigger the interrupt. Inside the interrupt routine, I only did 1 single task is to switch the inputs of the AMux from one to the other. But it doesnt do what I expected. No current is updated on the LCD, Iload = 0.

   

I checked the Ichanel, it's actually increase from 1 to 2. Could you please point out to me what went wrong...

   

I got the project to run perfectly fine with a signal channel...but I dont think it's a good idea to have extra ADC to monitor extra channel...just because I want to monitor at least 4 channel.

   

Please see the attachment for my whole project

0 Likes
3 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

lchannel has to be 0 and 1 , not one and two.

   

Declare lchannel as volatile because it is changed in an interrupt handler!!!

   

You are using ADC_StartConvert() within a loop, take it outsides except when you want to really stop the conversion.

   

                averageVolts = voltSamples >> 8;

   


You'd better use

   

                averageVolts = voltSamples / MAX_SAMPLE;   //  This is not an optimum, but it is correct at least

   

Your 5% display smoothing does not work when V_display larger than Vin

   

You are using global variables extensively. This does neither save code space nor execution time, but may lead to careless mistakes. Local variables will have the advantage of saving ram usage.

   

There is a better API to introduce an interrupt handler: Isr_StartEx(). So you do not need to modify a generated file, but you can keep the handler code in your own file (as main.c).

   

And do not think I suffer from paranoia,  but a statement like

   

            if(sampleCount == MAX_SAMPLE)

   


is more unsafe than

   

            if(sampleCount >= MAX_SAMPLE)

   

but will perform the same in your case, except when sampleCount happens to be larger than MAX_SAMPLE

   

 

   

Bob

0 Likes
Anonymous
Not applicable

Thanks for all the investigation Bob. This is what I found:

   

"lchannel has to be 0 and 1 , not one and two". YES I thought it's start from 1 so...my mistake.

   

"There is a better API to introduce an interrupt handler: Isr_StartEx(). So you do not need to modify a generated file, but you can keep the handler code in your own file (as main.c). Declare lchannel as volatile because it is changed in an interrupt handler!!! "--my interrupt still not working. I am just confusing that whether the method using the control reg module to trigger the interrupt work? I hardly can find any example about software interrupt on PSoC. Do you know any, Bob?

   

"Your 5% display smoothing does not work when V_display larger than Vin" Is there any other way that you can think of to stop the LCD from fluctuating around....I cant control the signal from the input ( load voltage in this case) so I think this will stop it from jumping around if there's no adjustment from the user. 

   

"You are using ADC_StartConvert() within a loop, take it outsides except when you want to really stop the conversion.

   

                averageVolts = voltSamples >> 8;

   

You'd better use

   

                averageVolts = voltSamples / MAX_SAMPLE;   //  This is not an optimum, but it is correct at least

   

And do not think I suffer from paranoia,  but a statement like

   

            if(sampleCount == MAX_SAMPLE)

   

is more unsafe than

   

            if(sampleCount >= MAX_SAMPLE)

   

but will perform the same in your case, except when sampleCount happens to be larger than " Yeah I know my code is not very tidy, thank you for pointing out. I hope my lecture was detailed like you so I could be a better coder :)) I will fix them all up and...yeah, just hope to get better in time. 

   

Thanks for your help 😉

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Usually you use a timer to display data every 200 to 500ms. Do not display from interrupt handler directly, just set a flag and react in the main-loop accordingly. You may of course program a sliding average algorithm to smooth the signal or to eliminate noise.

   

Check the ADC reference: when you are using a development kit (which one??) there will be a cap already connected to buffer Vref. Look into your kit's schematic and use "internal Vref buffered".

   

There is an API named isr_SetPending() which will act as a real software interrupt, but the isr component must still be connected to an internal signal as from your control-register.

   

 

   

Bob

0 Likes