Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Thread

float in interrupt function?

float in interrupt function?

2005-04-08 by ed_hage

I am using a LPC2106-board from Olimex to drive two motors via PWM.

I have a simple interrupt-function for the PWM which reads the duty
cycle variable and then sets the DC. This does not work. In the
example beneath MR6 does give a good duty cycle (but is fixed!! so no
pracitcal use), and when I use the float DC1 (as in MR4) it does not
work. This is probably a problem which I may encounter more using
floats etc. What is the best known method to deal with this? (I am
newby in programming embedded ... as you might have guessed.

// single edge PWM 
//global
float DC1 = 0.800;

void IRQMotorOut (void)
{
  PWM_MR4 =  ((unsigned long) (DC1 * PWM_MR0));  
  PWM_MR6 = 0.8*PWM_MR0; 
  PWM_IR = PWM_RESET_MR0; //clear flag
  VICVectAddr = 0;
}

RE: [lpc2000] float in interrupt function?

2005-04-08 by Dan Beadle

In general, try to keep interrupt functions short and sweet.  Floating
brings in many more cycles, for very little benefit in cases like this.

 

You can get almost the same results with simple fixed point math.  As long
as MR0 is below 2^28 (2^28 x 8 will not exceed 2^31, the max integer) (which
it probably is unless your motor is VERY slow), you can simply multiply by 8
then divide by 10.

 

PWM_MR4 = PWM_MR0*8;

PWM_MR4 /=10;

 

If you put the *8/10 on two lines, you guarantee that the 8/10 does not
truncate to 0.

 

The in-line integer math will run much faster.  And then you don't have to
worry about library calls from interrupts, library reentrancy, etc. 

 

  _____  
Show quoted textHide quoted text
From: ed_hage [mailto:ed_hage@...] 
Sent: Friday, April 08, 2005 12:58 PM
To: lpc2000@yahoogroups.com
Subject: [lpc2000] float in interrupt function?

 


I am using a LPC2106-board from Olimex to drive two motors via PWM.

I have a simple interrupt-function for the PWM which reads the duty
cycle variable and then sets the DC. This does not work. In the
example beneath MR6 does give a good duty cycle (but is fixed!! so no
pracitcal use), and when I use the float DC1 (as in MR4) it does not
work. This is probably a problem which I may encounter more using
floats etc. What is the best known method to deal with this? (I am
newby in programming embedded ... as you might have guessed.

// single edge PWM 
//global
float DC1 = 0.800;

void IRQMotorOut (void)
{
  PWM_MR4 =  ((unsigned long) (DC1 * PWM_MR0));  
  PWM_MR6 = 0.8*PWM_MR0; 
  PWM_IR = PWM_RESET_MR0; //clear flag
  VICVectAddr = 0;
}






  _____  

Yahoo! Groups Links

*	To visit your group on the web, go to:
http://groups.yahoo.com/group/lpc2000/
  
*	To unsubscribe from this group, send an email to:
lpc2000-unsubscribe@yahoogroups.com
<mailto:lpc2000-unsubscribe@yahoogroups.com?subject=Unsubscribe> 
  
*	Your use of Yahoo! Groups is subject to the Yahoo!
<http://docs.yahoo.com/info/terms/>  Terms of Service. 



[Non-text portions of this message have been removed]

Re: [lpc2000] float in interrupt function?

2005-04-08 by Robert Adsett

At 07:58 PM 4/8/05 +0000, ed_hage wrote:
>I have a simple interrupt-function for the PWM which reads the duty
>cycle variable and then sets the DC. This does not work. In the
>example beneath MR6 does give a good duty cycle (but is fixed!! so no
>pracitcal use), and when I use the float DC1 (as in MR4) it does not
>work. This is probably a problem which I may encounter more using
>floats etc. What is the best known method to deal with this? (I am
>newby in programming embedded ... as you might have guessed.


Two methods are available
         - The complex way is to save the floating point state, init a new 
floating point state, do your calculations and restore the floating point 
state.  Even if it's possible it's messy and take a while.
         - The more usual method is to use fractional or fixed point 
arithmetic (slight variations on a theme).  In your case


>   PWM_MR6 = 0.8*PWM_MR0;


Becomes

         PWM_MR6 = (8 * PWM_MR0) /10;

The brackets are important and you need to make sure the intermediate 
multiply cannot overflow (by working in the next size integer type if 
necessary.

Robert

" 'Freedom' has no meaning of itself.  There are always restrictions,   be 
they legal, genetic, or physical.  If you don't believe me, try to chew a 
radio signal. "  -- Kelvin Throop, III
http://www.aeolusdevelopment.com/

Re: float in interrupt function?

2005-04-08 by ed_hage

Hello Dan,

thank you for the info.
That is a good and simple way to avoid floats. 

The only thing that I can not get done is to use a global variable to
multiply (the global is being updated by other functions like
controller-function).

I changed to the following but it still does not work:

//global
int DC1 = 80; // 80%

void IRQMotorOut (void)
{
  PWM_MR4 = PWM_MR0 / 100; 
  PWM_MR4 *= DC1;   // 0<DC1<100 [%] 
  PWM_IR = PWM_RESET_MR0; //clear flag
  PWM_TCR = (1<<1);
  PWM_TCR=(1<<0);
  VICVectAddr = 0;
}

What could I be doing wrong?

--- In lpc2000@yahoogroups.com, "Dan Beadle" <dan.beadle@i...> wrote:
> In general, try to keep interrupt functions short and sweet.  Floating

> 
> PWM_MR4 = PWM_MR0*8;
> 
> PWM_MR4 /=10;
> 
> The in-line integer math will run much faster.  And then you don't
have to
Show quoted textHide quoted text
> worry about library calls from interrupts, library reentrancy, etc. 
> 
>  
> float DC1 = 0.800;
> 
> void IRQMotorOut (void)
> {
>   PWM_MR4 =  ((unsigned long) (DC1 * PWM_MR0));  
>   PWM_MR6 = 0.8*PWM_MR0; 
>   PWM_IR = PWM_RESET_MR0; //clear flag
>   VICVectAddr = 0;
> }
>

Re: [lpc2000] Re: float in interrupt function?

2005-04-08 by Robert Adsett

At 10:01 PM 4/8/05 +0000, ed_hage wrote:
>thank you for the info.
>That is a good and simple way to avoid floats.
>
>The only thing that I can not get done is to use a global variable to
>multiply (the global is being updated by other functions like
>controller-function).
>
>I changed to the following but it still does not work:
>
>//global
>int DC1 = 80; // 80%
>
>void IRQMotorOut (void)
>{
>   PWM_MR4 = PWM_MR0 / 100;
>   PWM_MR4 *= DC1;   // 0<DC1<100 [%]
>   PWM_IR = PWM_RESET_MR0; //clear flag
>   PWM_TCR = (1<<1);
>   PWM_TCR=(1<<0);
>   VICVectAddr = 0;
>}
>
>What could I be doing wrong?

Your order of arithmetic is wrong.  Change to:

PWM_MR4 = (PWM_MR0 *DC1)/100;

or if PWM_MR0 *DC1 will EVER overflow 32bits

PWM_MR4 = (PWM_MR0 *(long long)DC1)/100;

An optimization note:

If you change your divisor to a factor of 2 the division can become a right 
shift.  Much faster on the ARM since it does not have a HW divide operation.

Robert

" 'Freedom' has no meaning of itself.  There are always restrictions,   be 
they legal, genetic, or physical.  If you don't believe me, try to chew a 
radio signal. "  -- Kelvin Throop, III
http://www.aeolusdevelopment.com/

RE: [lpc2000] Re: float in interrupt function?

2005-04-08 by Dan Beadle

What is the value of MR0?  By dividing first, you are losing precision
(unless the lower 7 bits are all zeroes).

 

For example if MRC has 1289 decimal in it and you divide by 100, you have
12, then multiply by 80, you get 960, not 1031 that you should get.
Multiply by 8 and then divide by 10 yields the correct result.

 

And for 80%, just use 8/10 - not 80/100.

 

 

What do you mean by "does not work". Are you getting PWM output with the
wrong values? Or just no output?

 

 

  _____  
Show quoted textHide quoted text
From: Robert Adsett [mailto:subscriptions@...] 
Sent: Friday, April 08, 2005 3:08 PM
To: lpc2000@yahoogroups.com
Subject: Re: [lpc2000] Re: float in interrupt function?

 

At 10:01 PM 4/8/05 +0000, ed_hage wrote:
>thank you for the info.
>That is a good and simple way to avoid floats.
>
>The only thing that I can not get done is to use a global variable to
>multiply (the global is being updated by other functions like
>controller-function).
>
>I changed to the following but it still does not work:
>
>//global
>int DC1 = 80; // 80%
>
>void IRQMotorOut (void)
>{
>   PWM_MR4 = PWM_MR0 / 100;
>   PWM_MR4 *= DC1;   // 0<DC1<100 [%]
>   PWM_IR = PWM_RESET_MR0; //clear flag
>   PWM_TCR = (1<<1);
>   PWM_TCR=(1<<0);
>   VICVectAddr = 0;
>}
>
>What could I be doing wrong?

Your order of arithmetic is wrong.  Change to:

PWM_MR4 = (PWM_MR0 *DC1)/100;

or if PWM_MR0 *DC1 will EVER overflow 32bits

PWM_MR4 = (PWM_MR0 *(long long)DC1)/100;

An optimization note:

If you change your divisor to a factor of 2 the division can become a right 
shift.  Much faster on the ARM since it does not have a HW divide operation.

Robert

" 'Freedom' has no meaning of itself.  There are always restrictions,   be 
they legal, genetic, or physical.  If you don't believe me, try to chew a 
radio signal. "  -- Kelvin Throop, III
http://www.aeolusdevelopment.com/




  _____  

Yahoo! Groups Links

*	To visit your group on the web, go to:
http://groups.yahoo.com/group/lpc2000/
  
*	To unsubscribe from this group, send an email to:
lpc2000-unsubscribe@yahoogroups.com
<mailto:lpc2000-unsubscribe@yahoogroups.com?subject=Unsubscribe> 
  
*	Your use of Yahoo! Groups is subject to the Yahoo!
<http://docs.yahoo.com/info/terms/>  Terms of Service. 



[Non-text portions of this message have been removed]

Re: float in interrupt function?

2005-04-08 by ed_hage

> 
> What do you mean by "does not work". Are you getting PWM output with the
> wrong values? Or just no output?
> 
I get a 100% dutycycle as output (constant high).

Re: float in interrupt function?

2005-04-08 by ed_hage

> >The only thing that I can not get done is to use a global variable to
> >multiply (the global is being updated by other functions like
> >controller-function).
> >
> >I changed to the following but it still does not work:
> >
> >//global
> >int DC1 = 80; // 80%
> >
> >void IRQMotorOut (void)
> >{
> >   PWM_MR4 = PWM_MR0 / 100;
> >   PWM_MR4 *= DC1;   // 0<DC1<100 [%]
> >   PWM_IR = PWM_RESET_MR0; //clear flag
> >   PWM_TCR = (1<<1);
> >   PWM_TCR=(1<<0);
> >   VICVectAddr = 0;
> >}
> >
> Your order of arithmetic is wrong.  Change to:
> 
> PWM_MR4 = (PWM_MR0 *DC1)/100;
> 
Yes, correct. I loose precision when I first devide and then
multiply.I altered  it as you specified here but still the problem
seems to be using the variable DC1. The outpui-value is continuously
high (100% DC). It does not seem to be allowed to use DC1 in this
function!!!?

I use gnu-arm 3.4.3.

RE: [lpc2000] Re: float in interrupt function?

2005-04-08 by Dan Beadle

I would first try hard coding MR4.    

 

I assume that you are in the Single Edge mode.  Verify that with fixed
numbers you have everything else set up, then come back to making MR4
variable based on MR0.

 

There are some details to setup - you have to set the PINSEL register to
make your pin and output on PWM.

 

Here is a code snippet from a project I am working on.  You PINSEL1 will
have to be a little different.

 

            PINSEL1 = 0x1540040E;                        // AIN, PWM5, MAT1,
MAT0

            PWMMR0 = PCLKFREQ/40000;             // Set 40khz.

            PWMMR5 = PWMMR0 / 2;                     // Set toggle point...

            PWMMCR = 2;                                      // Reset timer
on MR0

            PWMPCR = 0x2000;                              // Single Edge
mode, PWM5 Output...

            PWMPR  = 0;

            PWMTCR = 3;

            PWMTCR = 1;                                       // Start the
timer..

 

            PWMLER = 0x7f;                                   // Enable the
transfer...

 

This puts out 40khZ on PIN P0.21 (assuming 11.059 mhz clock, PLL not
enabled)

 

Hope this helps.

 

  _____  
Show quoted textHide quoted text
From: ed_hage [mailto:ed_hage@...] 
Sent: Friday, April 08, 2005 4:06 PM
To: lpc2000@yahoogroups.com
Subject: [lpc2000] Re: float in interrupt function?

 



> >The only thing that I can not get done is to use a global variable to
> >multiply (the global is being updated by other functions like
> >controller-function).
> >
> >I changed to the following but it still does not work:
> >
> >//global
> >int DC1 = 80; // 80%
> >
> >void IRQMotorOut (void)
> >{
> >   PWM_MR4 = PWM_MR0 / 100;
> >   PWM_MR4 *= DC1;   // 0<DC1<100 [%]
> >   PWM_IR = PWM_RESET_MR0; //clear flag
> >   PWM_TCR = (1<<1);
> >   PWM_TCR=(1<<0);
> >   VICVectAddr = 0;
> >}
> >
> Your order of arithmetic is wrong.  Change to:
> 
> PWM_MR4 = (PWM_MR0 *DC1)/100;
> 
Yes, correct. I loose precision when I first devide and then
multiply.I altered  it as you specified here but still the problem
seems to be using the variable DC1. The outpui-value is continuously
high (100% DC). It does not seem to be allowed to use DC1 in this
function!!!?

I use gnu-arm 3.4.3.






  _____  

Yahoo! Groups Links

*	To visit your group on the web, go to:
http://groups.yahoo.com/group/lpc2000/
  
*	To unsubscribe from this group, send an email to:
lpc2000-unsubscribe@yahoogroups.com
<mailto:lpc2000-unsubscribe@yahoogroups.com?subject=Unsubscribe> 
  
*	Your use of Yahoo! Groups is subject to the Yahoo!
<http://docs.yahoo.com/info/terms/>  Terms of Service. 



[Non-text portions of this message have been removed]

Re: float in interrupt function?

2005-04-09 by ed_hage

--- In lpc2000@yahoogroups.com, "Dan Beadle" <dan.beadle@i...> wrote:
> I would first try hard coding MR4.    
> 
>  
Hello Dan,

That's the point. I have it already running hard coded! I have a
simular setup in a PWM_Init () function and I get great 5% DC on my
output-pin  when I have the following:

PWM_MR4 = (PWM_MR0 * 5) / 100; 

Also tried (DC1 defined in the function):
int DC1 = 5;
PWM_MR4 = (PWM_MR0 * DC1) / 100; 

and that works, but what I want and does not work is defining DC1 as a
global (outside the function) so I can change it with other functions.
How can I solve this problem 

(we have evolved to a problem that has nothing to do with floats
anymore ;-} )

Re: float in interrupt function?

2005-04-09 by ed_hage

Latest update:

When I reassign a value to DC1 in the function it works, example:

int DC1 = 90;

void IRQfunction (void)
{
  DC1 = 20;
  PWM_MR4 = (PWM_MR0 * DC1) / 100; 
  ... etc

Now I get a 20% DC, but when I comment out DC1 =20; I should get a 90%
DC (as specified before) but then I get a constant high output!!
How can I get the global to work?

(P.S. I also posted this question on the gnuarm group because I
suspect this may not be a typical LPC problem but maybe a gnu-issue)
Show quoted textHide quoted text
> That's the point. I have it already running hard coded! I have a
> simular setup in a PWM_Init () function and I get great 5% DC on my
> output-pin  when I have the following:
> 
> PWM_MR4 = (PWM_MR0 * 5) / 100; 
> 
> Also tried (DC1 defined in the function):
> int DC1 = 5;
> PWM_MR4 = (PWM_MR0 * DC1) / 100; 
> 
> and that works, but what I want and does not work is defining DC1 as a
> global (outside the function) so I can change it with other functions.
> How can I solve this problem 
> 
> (we have evolved to a problem that has nothing to do with floats
> anymore ;-} )

Re: float in interrupt function?

2005-04-09 by charlesgrenz

Hi guys, just a thought, try this instead

volatile unsigned long DC1 = 90;

void IRQfunction(void)
{
   DC1 = 20;

}

regards,
Charles

--- In lpc2000@yahoogroups.com, "ed_hage" <ed_hage@y...> wrote:
Show quoted textHide quoted text
> 
> Latest update:
> 
> When I reassign a value to DC1 in the function it works, example:
> 
> int DC1 = 90;
> 
> void IRQfunction (void)
> {
>   DC1 = 20;
>   PWM_MR4 = (PWM_MR0 * DC1) / 100; 
>   ... etc
> 
> Now I get a 20% DC, but when I comment out DC1 =20; I should get a 90%
> DC (as specified before) but then I get a constant high output!!
> How can I get the global to work?
> 
> (P.S. I also posted this question on the gnuarm group because I
> suspect this may not be a typical LPC problem but maybe a gnu-issue)
>  
> > That's the point. I have it already running hard coded! I have a
> > simular setup in a PWM_Init () function and I get great 5% DC on my
> > output-pin  when I have the following:
> > 
> > PWM_MR4 = (PWM_MR0 * 5) / 100; 
> > 
> > Also tried (DC1 defined in the function):
> > int DC1 = 5;
> > PWM_MR4 = (PWM_MR0 * DC1) / 100; 
> > 
> > and that works, but what I want and does not work is defining DC1 as a
> > global (outside the function) so I can change it with other functions.
> > How can I solve this problem 
> > 
> > (we have evolved to a problem that has nothing to do with floats
> > anymore ;-} )

Re: float in interrupt function?

2005-04-09 by ed_hage

I don't want to define DC1 = 20 inside the IRQfunction. That works
already. I want to use the value of DC1 = 90 instead that is defined a
a global,

Already changed int to unsigned long because I also have defined some
other variables that way which I can manipulate with another
IRQfunction. But the results are the same.

--- In lpc2000@yahoogroups.com, "charlesgrenz" <charles.grenz@s...> wrote:
> 
> Hi guys, just a thought, try this instead
> 
> volatile unsigned long DC1 = 90;
> 
> void IRQfunction(void)
> {
>    DC1 = 20;
> 
> }
> 
> regards,
> Charles
> 
> --- In lpc2000@yahoogroups.com, "ed_hage" <ed_hage@y...> wrote:
> > 
> > Latest update:
> > 
> > When I reassign a value to DC1 in the function it works, example:
> > 
> > int DC1 = 90;
> > 
> > void IRQfunction (void)
> > {
> >   DC1 = 20;
> >   PWM_MR4 = (PWM_MR0 * DC1) / 100; 
> >   ... etc
> > 
> > Now I get a 20% DC, but when I comment out DC1 =20; I should get a 90%
> > DC (as specified before) but then I get a constant high output!!
> > How can I get the global to work?
> > 
> > (P.S. I also posted this question on the gnuarm group because I
> > suspect this may not be a typical LPC problem but maybe a gnu-issue)
> >  
> > > That's the point. I have it already running hard coded! I have a
> > > simular setup in a PWM_Init () function and I get great 5% DC on my
> > > output-pin  when I have the following:
> > > 
> > > PWM_MR4 = (PWM_MR0 * 5) / 100; 
> > > 
> > > Also tried (DC1 defined in the function):
> > > int DC1 = 5;
> > > PWM_MR4 = (PWM_MR0 * DC1) / 100; 
> > > 
> > > and that works, but what I want and does not work is defining
DC1 as a
> > > global (outside the function) so I can change it with other
functions.
Show quoted textHide quoted text
> > > How can I solve this problem 
> > > 
> > > (we have evolved to a problem that has nothing to do with floats
> > > anymore ;-} )

Re: [lpc2000] Re: float in interrupt function?

2005-04-09 by capiman@t-online.de

The "volatile" is the thing, which makes it worth trying out...

Regards,

         Martin

----- Original Message ----- 
Show quoted textHide quoted text
From: "ed_hage" <ed_hage@...>
To: <lpc2000@yahoogroups.com>
Sent: Saturday, April 09, 2005 1:24 PM
Subject: [lpc2000] Re: float in interrupt function?


>
>
> I don't want to define DC1 = 20 inside the IRQfunction. That works
> already. I want to use the value of DC1 = 90 instead that is defined a
> a global,
>
> Already changed int to unsigned long because I also have defined some
> other variables that way which I can manipulate with another
> IRQfunction. But the results are the same.
>
> --- In lpc2000@yahoogroups.com, "charlesgrenz" <charles.grenz@s...> wrote:
>>
>> Hi guys, just a thought, try this instead
>>
>> volatile unsigned long DC1 = 90;
>>
>> void IRQfunction(void)
>> {
>>    DC1 = 20;
>>
>> }
>>
>> regards,
>> Charles
>>
>> --- In lpc2000@yahoogroups.com, "ed_hage" <ed_hage@y...> wrote:
>> >
>> > Latest update:
>> >
>> > When I reassign a value to DC1 in the function it works, example:
>> >
>> > int DC1 = 90;
>> >
>> > void IRQfunction (void)
>> > {
>> >   DC1 = 20;
>> >   PWM_MR4 = (PWM_MR0 * DC1) / 100;
>> >   ... etc
>> >
>> > Now I get a 20% DC, but when I comment out DC1 =20; I should get a 90%
>> > DC (as specified before) but then I get a constant high output!!
>> > How can I get the global to work?
>> >
>> > (P.S. I also posted this question on the gnuarm group because I
>> > suspect this may not be a typical LPC problem but maybe a gnu-issue)
>> >
>> > > That's the point. I have it already running hard coded! I have a
>> > > simular setup in a PWM_Init () function and I get great 5% DC on my
>> > > output-pin  when I have the following:
>> > >
>> > > PWM_MR4 = (PWM_MR0 * 5) / 100;
>> > >
>> > > Also tried (DC1 defined in the function):
>> > > int DC1 = 5;
>> > > PWM_MR4 = (PWM_MR0 * DC1) / 100;
>> > >
>> > > and that works, but what I want and does not work is defining
> DC1 as a
>> > > global (outside the function) so I can change it with other
> functions.
>> > > How can I solve this problem
>> > >
>> > > (we have evolved to a problem that has nothing to do with floats
>> > > anymore ;-} )
>
>
>
>
>
>
> Yahoo! Groups Links
>
>
>
>
>
>
>
>

Re: float in interrupt function?

2005-04-09 by charlesgrenz

When ever you use a global variable, you have to specify it as a
volatile to tell the compiler not to opitmize the variable out of the
equation when working with any ANSI C compiler.

Also by type casting the variable the same as the register you want to
use makes sure that the compiler is not going to do something funky
when optimization is performed no matter what level.

regards,
Charles

--- In lpc2000@yahoogroups.com, capiman@t... wrote:
> The "volatile" is the thing, which makes it worth trying out...
> 
> Regards,
> 
>          Martin
> 
> ----- Original Message ----- 
> From: "ed_hage" <ed_hage@y...>
> To: <lpc2000@yahoogroups.com>
> Sent: Saturday, April 09, 2005 1:24 PM
> Subject: [lpc2000] Re: float in interrupt function?
> 
> 
> >
> >
> > I don't want to define DC1 = 20 inside the IRQfunction. That works
> > already. I want to use the value of DC1 = 90 instead that is defined a
> > a global,
> >
> > Already changed int to unsigned long because I also have defined some
> > other variables that way which I can manipulate with another
> > IRQfunction. But the results are the same.
> >
> > --- In lpc2000@yahoogroups.com, "charlesgrenz"
<charles.grenz@s...> wrote:
> >>
> >> Hi guys, just a thought, try this instead
> >>
> >> volatile unsigned long DC1 = 90;
> >>
> >> void IRQfunction(void)
> >> {
> >>    DC1 = 20;
> >>
> >> }
> >>
> >> regards,
> >> Charles
> >>
> >> --- In lpc2000@yahoogroups.com, "ed_hage" <ed_hage@y...> wrote:
> >> >
> >> > Latest update:
> >> >
> >> > When I reassign a value to DC1 in the function it works, example:
> >> >
> >> > int DC1 = 90;
> >> >
> >> > void IRQfunction (void)
> >> > {
> >> >   DC1 = 20;
> >> >   PWM_MR4 = (PWM_MR0 * DC1) / 100;
> >> >   ... etc
> >> >
> >> > Now I get a 20% DC, but when I comment out DC1 =20; I should
get a 90%
> >> > DC (as specified before) but then I get a constant high output!!
> >> > How can I get the global to work?
> >> >
> >> > (P.S. I also posted this question on the gnuarm group because I
> >> > suspect this may not be a typical LPC problem but maybe a
gnu-issue)
> >> >
> >> > > That's the point. I have it already running hard coded! I have a
> >> > > simular setup in a PWM_Init () function and I get great 5% DC
on my
Show quoted textHide quoted text
> >> > > output-pin  when I have the following:
> >> > >
> >> > > PWM_MR4 = (PWM_MR0 * 5) / 100;
> >> > >
> >> > > Also tried (DC1 defined in the function):
> >> > > int DC1 = 5;
> >> > > PWM_MR4 = (PWM_MR0 * DC1) / 100;
> >> > >
> >> > > and that works, but what I want and does not work is defining
> > DC1 as a
> >> > > global (outside the function) so I can change it with other
> > functions.
> >> > > How can I solve this problem
> >> > >
> >> > > (we have evolved to a problem that has nothing to do with floats
> >> > > anymore ;-} )
> >
> >
> >
> >
> >
> >
> > Yahoo! Groups Links
> >
> >
> >
> >
> >
> >
> >
> >

Re: float in interrupt function?

2005-04-09 by ed_hage

Thanks for the explanation.

I defined it as volatile and really it still does not work.
--------------------------------------------------
volatile unsigned long	DC0 = 10;

void IRQMotorOut (void)
{
  PWM_MR4 = (PWM_MR0 * DC0) / 100; 
  PWM_MR6 = (PWM_MR0 * 80)  / 100; 
  PWM_IR = PWM_RESET_MR0; //clear flag
  PWM_TCR = (1<<1);
  PWM_TCR = (1<<0); 
  VICVectAddr = 0;
}
-------------------------------------------------
MR6 works great, MR4 not. MR4 will work if I put DC0 =20 inside the
function, but like this its hopeless.I run out of ideas of what it
could be solved.
Show quoted textHide quoted text
> 
> When ever you use a global variable, you have to specify it as a
> volatile to tell the compiler not to opitmize the variable out of the
> equation when working with any ANSI C compiler.
> 
> Also by type casting the variable the same as the register you want to
> use makes sure that the compiler is not going to do something funky
> when optimization is performed no matter what level.
> 
> regards,
> Charles
> 
> --- In lpc2000@yahoogroups.com, capiman@t... wrote:
> > The "volatile" is the thing, which makes it worth trying out...
> >

Re: float in interrupt function?

2005-04-09 by charlesgrenz

What's the assembly look like?

Charles

--- In lpc2000@yahoogroups.com, "ed_hage" <ed_hage@y...> wrote:
Show quoted textHide quoted text
> 
> Thanks for the explanation.
> 
> I defined it as volatile and really it still does not work.
> --------------------------------------------------
> volatile unsigned long	DC0 = 10;
> 
> void IRQMotorOut (void)
> {
>   PWM_MR4 = (PWM_MR0 * DC0) / 100; 
>   PWM_MR6 = (PWM_MR0 * 80)  / 100; 
>   PWM_IR = PWM_RESET_MR0; //clear flag
>   PWM_TCR = (1<<1);
>   PWM_TCR = (1<<0); 
>   VICVectAddr = 0;
> }
> -------------------------------------------------
> MR6 works great, MR4 not. MR4 will work if I put DC0 =20 inside the
> function, but like this its hopeless.I run out of ideas of what it
> could be solved.
> 
> > 
> > When ever you use a global variable, you have to specify it as a
> > volatile to tell the compiler not to opitmize the variable out of the
> > equation when working with any ANSI C compiler.
> > 
> > Also by type casting the variable the same as the register you want to
> > use makes sure that the compiler is not going to do something funky
> > when optimization is performed no matter what level.
> > 
> > regards,
> > Charles
> > 
> > --- In lpc2000@yahoogroups.com, capiman@t... wrote:
> > > The "volatile" is the thing, which makes it worth trying out...
> > >

Re: float in interrupt function?

2005-04-09 by ed_hage

I also posted the question on the gnuarm group and there I got a good
tip. Apparently my startup code was not good; the globally defined
variables were defined but not properly initialised. So I initialised
it in main and then it worked!!

I try to get some info on startup-files, if anyone can point me in the
good direction your ore than welcome (web-links, books etc.)  

Greetings, Edward

--- In lpc2000@yahoogroups.com, "charlesgrenz" <charles.grenz@s...> wrote:
> 
> What's the assembly look like?
> 
> Charles
> 
> --- In lpc2000@yahoogroups.com, "ed_hage" <ed_hage@y...> wrote:
> > 
> > Thanks for the explanation.
> > 
> > I defined it as volatile and really it still does not work.
> > --------------------------------------------------
> > volatile unsigned long	DC0 = 10;
> > 
> > void IRQMotorOut (void)
> > {
> >   PWM_MR4 = (PWM_MR0 * DC0) / 100; 
> >   PWM_MR6 = (PWM_MR0 * 80)  / 100; 
> >   PWM_IR = PWM_RESET_MR0; //clear flag
> >   PWM_TCR = (1<<1);
> >   PWM_TCR = (1<<0); 
> >   VICVectAddr = 0;
> > }
> > -------------------------------------------------
> > MR6 works great, MR4 not. MR4 will work if I put DC0 =20 inside the
> > function, but like this its hopeless.I run out of ideas of what it
> > could be solved.
> > 
> > > 
> > > When ever you use a global variable, you have to specify it as a
> > > volatile to tell the compiler not to opitmize the variable out
of the
> > > equation when working with any ANSI C compiler.
> > > 
> > > Also by type casting the variable the same as the register you
want to
Show quoted textHide quoted text
> > > use makes sure that the compiler is not going to do something funky
> > > when optimization is performed no matter what level.
> > > 
> > > regards,
> > > Charles
> > > 
> > > --- In lpc2000@yahoogroups.com, capiman@t... wrote:
> > > > The "volatile" is the thing, which makes it worth trying out...
> > > >

Re: float in interrupt function?

2005-04-09 by charlesgrenz

Yes that makes sense. I always initialize all my global variables in
main as a standard procedure (or some initialization procedure for
each module). That also includes all global variables as volatile and
if I need to save memory, I type cast all equation values to guarantee
that they are properly used or that I get a warning that there is some
compatibility problem by the compiler. Like in your case since the DC1
will always be below or equal to 100, then making that a char and then
type cast it in the equation as a (unsigned long).

regards,
Charles


--- In lpc2000@yahoogroups.com, "ed_hage" <ed_hage@y...> wrote:
> 
> I also posted the question on the gnuarm group and there I got a good
> tip. Apparently my startup code was not good; the globally defined
> variables were defined but not properly initialised. So I initialised
> it in main and then it worked!!
> 
> I try to get some info on startup-files, if anyone can point me in the
> good direction your ore than welcome (web-links, books etc.)  
> 
> Greetings, Edward
> 
> --- In lpc2000@yahoogroups.com, "charlesgrenz" <charles.grenz@s...>
wrote:
> > 
> > What's the assembly look like?
> > 
> > Charles
> > 
> > --- In lpc2000@yahoogroups.com, "ed_hage" <ed_hage@y...> wrote:
> > > 
> > > Thanks for the explanation.
> > > 
> > > I defined it as volatile and really it still does not work.
> > > --------------------------------------------------
> > > volatile unsigned long	DC0 = 10;
> > > 
> > > void IRQMotorOut (void)
> > > {
> > >   PWM_MR4 = (PWM_MR0 * DC0) / 100; 
> > >   PWM_MR6 = (PWM_MR0 * 80)  / 100; 
> > >   PWM_IR = PWM_RESET_MR0; //clear flag
> > >   PWM_TCR = (1<<1);
> > >   PWM_TCR = (1<<0); 
> > >   VICVectAddr = 0;
> > > }
> > > -------------------------------------------------
> > > MR6 works great, MR4 not. MR4 will work if I put DC0 =20 inside the
> > > function, but like this its hopeless.I run out of ideas of what it
> > > could be solved.
> > > 
> > > > 
> > > > When ever you use a global variable, you have to specify it as a
> > > > volatile to tell the compiler not to opitmize the variable out
> of the
> > > > equation when working with any ANSI C compiler.
> > > > 
> > > > Also by type casting the variable the same as the register you
> want to
> > > > use makes sure that the compiler is not going to do something
funky
Show quoted textHide quoted text
> > > > when optimization is performed no matter what level.
> > > > 
> > > > regards,
> > > > Charles
> > > > 
> > > > --- In lpc2000@yahoogroups.com, capiman@t... wrote:
> > > > > The "volatile" is the thing, which makes it worth trying out...
> > > > >

Re: [lpc2000] Re: float in interrupt function?

2005-04-09 by Robert Adsett

At 12:02 PM 4/9/05 +0000, ed_hage wrote:
>I also posted the question on the gnuarm group and there I got a good
>tip. Apparently my startup code was not good; the globally defined
>variables were defined but not properly initialised. So I initialised
>it in main and then it worked!!

Hmm, you need a new startup, the startup should initialize all globals for 
you (either to zero if unspecified or whatever is assigned to them)

>I try to get some info on startup-files, if anyone can point me in the
>good direction your ore than welcome (web-links, books etc.)

There are examples in the files section and there is an example in the 
newlib-lpc collection at http://www.aeolusdevelopment.com  That one 
certainly initializes the globals.  BTW, that is required behaviour for 
ANSI compliant code.

Robert

" 'Freedom' has no meaning of itself.  There are always restrictions,   be 
they legal, genetic, or physical.  If you don't believe me, try to chew a 
radio signal. "  -- Kelvin Throop, III
http://www.aeolusdevelopment.com/

Re: [lpc2000] Re: float in interrupt function?

2005-04-09 by Robert Adsett

At 11:31 AM 4/9/05 +0000, charlesgrenz wrote:
>When ever you use a global variable, you have to specify it as a
>volatile to tell the compiler not to opitmize the variable out of the
>equation when working with any ANSI C compiler.

Um, no.  The C compiler MUST assume that any global variable can change 
across a function call if it can't trace the call (ie if it's in a separate 
module).  Once a call is made outside of the compiler 'sight' all globals 
have to be considered changed by the compiler.

Now once a routine has read a global it can assume it's unchanged until 
it's made a function call unless it's declared as volatile.  But in this 
case volatile will make no difference.

Robert

" 'Freedom' has no meaning of itself.  There are always restrictions,   be 
they legal, genetic, or physical.  If you don't believe me, try to chew a 
radio signal. "  -- Kelvin Throop, III
http://www.aeolusdevelopment.com/

Re: [lpc2000] Re: float in interrupt function?

2005-04-09 by Robert Adsett

At 11:24 AM 4/9/05 +0000, ed_hage wrote:
>Already changed int to unsigned long because I also have defined some
>other variables that way which I can manipulate with another
>IRQfunction. But the results are the same.

On an ARM the only difference between an int and an unsigned long is the 
sign bit.  If you are changing to prevent overflow that won't be any help 
you would need to use a long long intermediate.

Robert

" 'Freedom' has no meaning of itself.  There are always restrictions,   be 
they legal, genetic, or physical.  If you don't believe me, try to chew a 
radio signal. "  -- Kelvin Throop, III
http://www.aeolusdevelopment.com/

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.