LPC812 BASIC - PWM Error

Questions about the BASICtools and MakeItC
Post Reply
FIREWALL
Posts: 15
Joined: Thu Nov 08, 2012 6:31 pm

LPC812 BASIC - PWM Error

Post by FIREWALL »

I am having trouble getting the software PWM to work on the LPC812 BASICchip. Using the code below, no matter what value I pass in for 'milliseconds' the period of the PWM out is 176 microseconds (see attached logic analyzer output). Changing the duty work fines but the period seems to be always 'locked' to 176 microseconds. Any ideas?

Code: Select all

#include <PULSE.bas> 
WHILE 1
	PWM (15, 128, 20) 
LOOP
PWMerror.png
PWMerror.png (31.93 KiB) Viewed 24912 times



basicchip
Posts: 1090
Joined: Fri Oct 19, 2012 2:39 am
Location: Weeki Watchee, FL
Contact:

Re: LPC812 BASIC - PWM Error

Post by basicchip »

I took a look and we have not written a version of PWM for the LPC812 yet.

And the timer module of the LPC812 is quite different than earlier parts. So it may be some time before we get to it. I'm actually surprised that the current one does anything, as we will be adding an #error statement into the library routine for now flagging that the version is not yet supported.

FIREWALL
Posts: 15
Joined: Thu Nov 08, 2012 6:31 pm

Re: LPC812 BASIC - PWM Error

Post by FIREWALL »

Odd... I have I2C working on the LPC812 using I2C.bas and that appears to use the same TIMER as PWM. Would you expect I2C communications to work with the LPC812?

I2C Snippet

Code: Select all

SUB I2Cwait
	dim start as integer
	start = TIMER
	while (TIMER - start) < I2CwaitTime
	loop
END SUB
PWM Snippet

Code: Select all

while ((TIMER - start) < timeperiod) 
			i = duty
			while (i)
				i = i - 1
			loop
			OUT(pin) = 0
			i = 256-duty
			while (i)
				i = i - 1
			loop
			OUT(pin) = 1
		loop

basicchip
Posts: 1090
Joined: Fri Oct 19, 2012 2:39 am
Location: Weeki Watchee, FL
Contact:

Re: LPC812 BASIC - PWM Error

Post by basicchip »

Yes because the TIMER construct is built into the BASIC, as well as the IN, OUT, DIR constructs. I2C.bas is actually bit banged.

TIMER in BASIC is distinct from the 4 timers of most of most other parts, or the SCT timers (2) in the LPC812. In most of the earlier parts TIMER uses timer0 that increments at microsecond intervals. In the 812 and all Cortex parts going forward we are using the Systick timer which is part of the CPU, that are set to count up to 65.536 milliseconds. We combine the 16 bits of that timer and the 16 bits of time kept by Systick interrupts to generate a 32 bit TIMER.

The switch to SysTick is because all Cortex parts have the same hardware for this, and that was not being used. So it also frees up whatever timer hardware the parts have for the user BASIC program.

FIREWALL
Posts: 15
Joined: Thu Nov 08, 2012 6:31 pm

Re: LPC812 BASIC - PWM Error

Post by FIREWALL »

I thought that the PWM in PULSE.bas was bitbanged as well?
Why is it that the TIMER seems to function fine in I2C.bas but not in PULSE.bas?


PWM Sub from PULSE.bas

Code: Select all

' on pin for time (msec) do bit-banged PWM of duty cycle (0-255) 

SUB PWM (pin, duty, timeperiod)
	DIM i as INTEGER
	DIM start AS INTEGER

	OUTPUT (pin)
	duty = duty & 0xFF
	
	if(duty) then OUT(pin) = 1 else OUT(pin) = 0

	INTERRUPT(0)
	
	timeperiod = timeperiod * 1000
	start = TIMER		
			
	if (duty=0 OR duty=255) then		' check always high or low
		while ((TIMER - start) < timeperiod) 
		loop
	else
		while ((TIMER - start) < timeperiod) 
			i = duty
			while (i)
				i = i - 1
			loop
			OUT(pin) = 0
			i = 256-duty
			while (i)
				i = i - 1
			loop
			OUT(pin) = 1
		loop
	endif
	
	INTERRUPT(1)
	
	INPUT (pin)		' allow pin to float
END SUB

basicchip
Posts: 1090
Joined: Fri Oct 19, 2012 2:39 am
Location: Weeki Watchee, FL
Contact:

Re: LPC812 BASIC - PWM Error

Post by basicchip »

You're racking up some credits here.

I'll have to enable interrupts at least for SysTick for those routines, as without them TIMER never counts beyond 65 milliseconds.

FIREWALL
Posts: 15
Joined: Thu Nov 08, 2012 6:31 pm

Re: LPC812 BASIC - PWM Error

Post by FIREWALL »

So, After looking at the PWM code (instead of just assuming I knew what the code was doing). I realized that I was trying to use PWM wrong.
I wanted to hook up a Servo and I saw the PWM function and thought "Perfect, I don't even have to write any code!"

I thought that the milliseconds parameter was used to set the period of the pulse not duration of the pulse.

MY FAILED BRAIN:
I thought if I called PWM(15,128,20) that I would get a pulse train on pin 15 that was "high" for 10 milliseconds and low for 10 milliseconds.

REALITY:
In fact PWM(15,128,20) will output a 50% duty pulse train on pin 15 with some predetermined period X (which i measures as 170 us) for a duration of 20 milliseconds

The PWM function makes sense I just had my "Servo Blinders" on for the past 2 days.

-Dan

P.S. I was never actually hitting the 65 millisecond bug in any of my code. The "bug" I was running into was that I made a bad assumption that PWM worked how I wanted it to work at the moment. The PWM function as it "imagined" it would not be very useful dimming leds etc :)

basicchip
Posts: 1090
Joined: Fri Oct 19, 2012 2:39 am
Location: Weeki Watchee, FL
Contact:

Re: LPC812 BASIC - PWM Error

Post by basicchip »

The bit-banged PWM (pretty obsolete now, but was written in the PBASIC compatibility days), runs as fast as the CPU can in a tight loop, so the period is a function of the CPU speed.

But as you found the duty cycle varies.

basicchip
Posts: 1090
Joined: Fri Oct 19, 2012 2:39 am
Location: Weeki Watchee, FL
Contact:

Re: LPC812 BASIC - PWM Error

Post by basicchip »

This version of PULSE has been modified for the LPC812 and future Cortex firmware releases.

I no longer turns off interrupts
PULSE.bas
(3.9 KiB) Downloaded 1606 times

Post Reply