pwm question

Started by aaajbell September 30, 2007
Hello,
I want to implement a PWM on an ARM2103 from Futurelec.com which can
perform a leap tick algorithm for more precise control of frequency
around 42800Hz. (Longer term, I'll want to vary the frequency in small
increments of about 1/10Hz around 42800Hz and also vary the duty cycle)

The leap tick algorithm I want to use approximates a frequency much
like we use days to measure the yearly cycle of the earth around the
sun. If I remember correctly, the yearly cycle frequency is 365.2426
days per year. Our calendar approximates the 365.2426 frequency with
365 days for 3 years and then with 366 days then next.
To approximate 365.2426 days per year:
year 1 - 365 days with accumulated error .2426 days
year 2 - 365 days with accumulated error .4852 days
year 3 - 365 days with accumulated error .7278 days
year 4 - 365 days with accumulated error .9704 days
year 5 - 366 days with accumulated error .2130 days
year 6 - 365 days with accumulated error .4556 days
year 7 - 365 days with accumulated error .6982 days
year 8 - 365 days with accumulated error .9408 days
year 9 - 366 days with accumulated error .1834 days
year 10 - 365 days with accumulated error 4260 days
and so on.

To approximate 42800Hz with a clock ticking at a 58.9824Mz rate I need
1378.0934 ticks per cycle as follows
cycle 1 - 1378 ticks with .0934 ticks accumulated error
cycle 2 - 1378 ticks with .1869 ticks accumulated error
cycle 3 - 1378 ticks with .2803 ticks accumulated error
cycle 4 - 1378 ticks with .3738 ticks accumulated error
cycle 5 - 1378 ticks with .4672 ticks accumulated error
cycle 6 - 1378 ticks with .5607 ticks accumulated error
cycle 7 - 1378 ticks with .6542 ticks accumulated error
cycle 8 - 1378 ticks with .7476 ticks accumulated error
cycle 9 - 1378 ticks with .8411 ticks accumulated error
cycle 10 - 1378 ticks with .9345 ticks accumulated error
cycle 11 - 1379 ticks with .0280 ticks accumulated error
cycle 12 - 1378 ticks with .1214 ticks accumulated error
and so on.

Basically, I want to set the number of ticks for the cycle in a PWM
interrupt routine, and also keep track of the accumulated error which
increments by .0934 ticks each cycle. I would use scaled integer
arithmetic with 16 bits for the number of ticks and 16 bits for the
accumulated error fraction.

So I have 3 questions.

First, can the PWM operate at 58.9824Mz? I'm new to ARMs and a bit
confused by the LPC2103 board's documentation with regards to which
clock is used where.

Second, can the LPC2103 generate an interrupt at the start or end of
each PWM cycle so I could implement a leap tick algorithm in an
interrupt routine?

Third; if it can generate an interrupt at each PWM cycle, does anyone
have some example code for a setting up PWM interrupts and a PWM
interrupt routine?

Thank you in advance,
aaajbell

An Engineer's Guide to the LPC2100 Series

>Basically, I want to set the number of ticks for the cycle in a PWM
>interrupt routine, and also keep track of the accumulated error which
>increments by .0934 ticks each cycle. I would use scaled integer
>arithmetic with 16 bits for the number of ticks and 16 bits for the
>accumulated error fraction.
>
>So I have 3 questions.
>
>First, can the PWM operate at 58.9824Mz? I'm new to ARMs and a bit
>confused by the LPC2103 board's documentation with regards to which
>clock is used where.

Yes - you need to choose a crystal and PLL setting to get the system clock to be 58.9824MHz
If you set the IO divider to 1, the timers will clock at the same frequency.

>Second, can the LPC2103 generate an interrupt at the start or end of
>each PWM cycle so I could implement a leap tick algorithm in an
>interrupt routine?

Yes- just set the appropriate interrupt on match enable bit

Something else you may want to consider is instead of using PWM mode, use normal match mode, as this
will let you control the length of both the high and low times to within a single clock cyle, giving
better control of duty cycle. To do this, just set it up to toggle the MAT pin, and interrupt on
match - this gives you an interrupt on each edge, and on each interrupt, you increment the match
register by the amount corresponding to the required length of the next half-cycle.
>Third; if it can generate an interrupt at each PWM cycle, does anyone
>have some example code for a setting up PWM interrupts and a PWM
>interrupt routine?
Another thought - as you're new to ARM, you might want to keep things simple and start off by not
using interrupts at all, so you can get your head round how the timer hardware works, and make sure
it will actually do what you want before having to deal with the interrupt side of things.

Just sit in a loop polling the timer interrupt flag. As the external waveform is generated by
hardware, this would not cause any jitter as long as the cycle time is longer than the time to poll
and update, which in your case it will easily be.

Once you've got that working you can then set it up to generate interrupts and move your polled
update code to the interrupt routine.
Thanks Mike.
The ARM2103 I purchased has a 19.66MHz crystal on it already but
system clock is supposed to run 3 times faster at 58.9824Mz. So I
should be a to set the PLL to run 3 times faster, and then if I set
the IO divider to 1, the PWM will operate with a tick rate of 58.9824?

Is that the fastest tick rate I can set for the PWM with the 19.66Mz
crystal?

Thanks again,
aaajbell
--- In l..., Mike Harrison wrote:
> >Basically, I want to set the number of ticks for the cycle in a PWM
> >interrupt routine, and also keep track of the accumulated error which
> >increments by .0934 ticks each cycle. I would use scaled integer
> >arithmetic with 16 bits for the number of ticks and 16 bits for the
> >accumulated error fraction.
> >
> >So I have 3 questions.
> >
> >First, can the PWM operate at 58.9824Mz? I'm new to ARMs and a bit
> >confused by the LPC2103 board's documentation with regards to which
> >clock is used where.
>
> Yes - you need to choose a crystal and PLL setting to get the system
clock to be 58.9824MHz
> If you set the IO divider to 1, the timers will clock at the same
frequency.
>
> >Second, can the LPC2103 generate an interrupt at the start or end of
> >each PWM cycle so I could implement a leap tick algorithm in an
> >interrupt routine?
>
> Yes- just set the appropriate interrupt on match enable bit
>
> Something else you may want to consider is instead of using PWM
mode, use normal match mode, as this
> will let you control the length of both the high and low times to
within a single clock cyle, giving
> better control of duty cycle. To do this, just set it up to toggle
the MAT pin, and interrupt on
> match - this gives you an interrupt on each edge, and on each
interrupt, you increment the match
> register by the amount corresponding to the required length of the
next half-cycle.
>
I have GNUARM installed which seems to work well with vi and make from
a Cygwin window. The example makefiles I have found use jtag_flash to
copy hex files to the lpc2103. Is there a similar command line program
I can use in a makefile to copy over rs232?

Thanks in advance,
aaajbell

--- In l..., "aaajbell" wrote:
>
> Thanks Mike.
> The ARM2103 I purchased has a 19.66MHz crystal on it already but
> system clock is supposed to run 3 times faster at 58.9824Mz. So I
> should be a to set the PLL to run 3 times faster, and then if I set
> the IO divider to 1, the PWM will operate with a tick rate of 58.9824?
>
> Is that the fastest tick rate I can set for the PWM with the 19.66Mz
> crystal?
>
> Thanks again,
> aaajbell
> --- In l..., Mike Harrison wrote:
> >
> >
> > >Basically, I want to set the number of ticks for the cycle in a PWM
> > >interrupt routine, and also keep track of the accumulated error which
> > >increments by .0934 ticks each cycle. I would use scaled integer
> > >arithmetic with 16 bits for the number of ticks and 16 bits for the
> > >accumulated error fraction.
> > >
> > >So I have 3 questions.
> > >
> > >First, can the PWM operate at 58.9824Mz? I'm new to ARMs and a bit
> > >confused by the LPC2103 board's documentation with regards to which
> > >clock is used where.
> >
> > Yes - you need to choose a crystal and PLL setting to get the system
> clock to be 58.9824MHz
> > If you set the IO divider to 1, the timers will clock at the same
> frequency.
> >
> > >Second, can the LPC2103 generate an interrupt at the start or end of
> > >each PWM cycle so I could implement a leap tick algorithm in an
> > >interrupt routine?
> >
> > Yes- just set the appropriate interrupt on match enable bit
> >
> > Something else you may want to consider is instead of using PWM
> mode, use normal match mode, as this
> > will let you control the length of both the high and low times to
> within a single clock cyle, giving
> > better control of duty cycle. To do this, just set it up to toggle
> the MAT pin, and interrupt on
> > match - this gives you an interrupt on each edge, and on each
> interrupt, you increment the match
> > register by the amount corresponding to the required length of the
> next half-cycle.
>
--- In l..., "aaajbell" wrote:
>
> I have GNUARM installed which seems to work well with vi and make from
> a Cygwin window. The example makefiles I have found use jtag_flash to
> copy hex files to the lpc2103. Is there a similar command line program
> I can use in a makefile to copy over rs232?
>
> Thanks in advance,
> aaajbell

WinARM includes lpc21isp for device programming using ISP
(in-system-programming).

There is an lpc21isp group here on Yahoo but I doubt you will need it.
I have been using it regularly on Linux without problems.

In my Makefile I have the target:

program : ${TARGET}.hex
lpc21isp ${TARGET}.hex /dev/ttyS0 38400 12000

Entering a command:

C:>lpc21isp

will give a list of the required parameters.

Richard
Could you not simply embed a call to the philips flash utility?
eg:
C:\Program Files\Philips Flash Utility\LPC210x_ISP.exe
x:\software_directory\example.hex 12000 LPC2129 COM1: 9600 1

Obviously your paths / filenames will no doubt be different but you get the
idea...

Andy

-----Original Message-----
From: l... [mailto:l...]On Behalf Of
aaajbell
Sent: 04 October 2007 10:50
To: l...
Subject: [lpc2000] Re: pwm question
I have GNUARM installed which seems to work well with vi and make from
a Cygwin window. The example makefiles I have found use jtag_flash to
copy hex files to the lpc2103. Is there a similar command line program
I can use in a makefile to copy over rs232?

Thanks in advance,
aaajbell

--- In l..., "aaajbell" wrote:
>
> Thanks Mike.
> The ARM2103 I purchased has a 19.66MHz crystal on it already but
> system clock is supposed to run 3 times faster at 58.9824Mz. So I
> should be a to set the PLL to run 3 times faster, and then if I set
> the IO divider to 1, the PWM will operate with a tick rate of 58.9824?
>
> Is that the fastest tick rate I can set for the PWM with the 19.66Mz
> crystal?
>
> Thanks again,
> aaajbell
>
>
> --- In l..., Mike Harrison wrote:
> >
> >
> > >Basically, I want to set the number of ticks for the cycle in a PWM
> > >interrupt routine, and also keep track of the accumulated error which
> > >increments by .0934 ticks each cycle. I would use scaled integer
> > >arithmetic with 16 bits for the number of ticks and 16 bits for the
> > >accumulated error fraction.
> > >
> > >So I have 3 questions.
> > >
> > >First, can the PWM operate at 58.9824Mz? I'm new to ARMs and a bit
> > >confused by the LPC2103 board's documentation with regards to which
> > >clock is used where.
> >
> > Yes - you need to choose a crystal and PLL setting to get the system
> clock to be 58.9824MHz
> > If you set the IO divider to 1, the timers will clock at the same
> frequency.
> >
> > >Second, can the LPC2103 generate an interrupt at the start or end of
> > >each PWM cycle so I could implement a leap tick algorithm in an
> > >interrupt routine?
> >
> > Yes- just set the appropriate interrupt on match enable bit
> >
> > Something else you may want to consider is instead of using PWM
> mode, use normal match mode, as this
> > will let you control the length of both the high and low times to
> within a single clock cyle, giving
> > better control of duty cycle. To do this, just set it up to toggle
> the MAT pin, and interrupt on
> > match - this gives you an interrupt on each edge, and on each
> interrupt, you increment the match
> > register by the amount corresponding to the required length of the
> next half-cycle.
> >
>