Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
02/18/10 12:14
Read: times


 
#173244 - Faster PWM
Responding to: ???'s previous message
I haven't tested the code I show here, it's just doodles, meant to be run as a timer ISRs, but I'm pretty sure it'll work. Maybe somone feels compelled... Timing estimates based on a bog standard 12-clocker '51 at 12 MHZ.

You say you get 30 Hz output. Is that right? That's pretty disappointing. You say you want to drive LEDs with that, I'd perceive a flicker at that frequency.
The first example shows a straightforward approach with an orderly loop and a small IRAM footprint. Written for ease of maintainance and expandability, this example, I estimate, can do about 40 Hz, 8 channels, each at 8 bit resolution. A slight improvement.


NumChannels	equ	8	
			
PWMCounter:	ds	1		;Continuous counter
PWMOutput:	ds	1		;Staging register for the output port
			
PWMArray:		ds	8		;the 8 PWM settings you want
			
timerisr:		push	acc		;Save registers about to be thrashed
		push	psw	
		push	r0	
		push	r2	
			
		inc	PWMCounter	;Bump the counter
		mov	a,PWMCounter	;Read it for later use
		mov	r0,#PWMArray	;First PWM setting
		mov	r2,#NumChannels	;8 channels
			
PWMLoop:		cjne	a,@r0,dummy	;See if setting is bigger than counter
dummy:		xch	a,PWMOutput	;Avoid pushing as that costs cycles
		rlc	a		;Rotate in the result
		xch	a,PWMOutput	;Restore accu and store result
		inc	r0		;Next setting
		djnz	r2,PWMLoop	;Do all channels
			
		mov	p1,PWMOutput	;Output to port
			
		pop	r2		;Restore registers
		pop	r0	
		pop	psw	
		pop	acc	
		reti			;Done

 


The second example does away with the loop overhead, avoids touching registers (as much as possible), and has separate sections for setting and resetting the port pins. The main improvement however is the introduction of a resolution limiting feature. This allows you to practically double the speed with each bit of resolution you drop! At the cost of a slightly bigger memory footprint, this code is all about speed, to heck with ease of maintainance and expandability. I estimate this code can easily achieve 4kHz at 8 channels at 3 bit resolution per channel. Plenty of room for plenty more channels, and no flicker.


Resolution	equ	8				;Desired resolution (in steps - not bits!)
			
PWMMaster:	ds	1				;Continuous master counter
			
PWMArray:	ds	8					;Settings
PWMCounters:	ds	8				;Channel counters
			
timerisr:		djnz	PWMMaster,noreset			;Bump master counter, don't jump if zero
			
		mov	PWMMaster,#Resolution		;Reset master counter
		mov	PWMCounters + 0,PWMArray + 0	;Copy settings to channel counters
		mov	PWMCounters + 1,PWMArray + 1	
		mov	PWMCounters + 2,PWMArray + 2	
		mov	PWMCounters + 3,PWMArray + 3	
		mov	PWMCounters + 4,PWMArray + 4	
		mov	PWMCounters + 5,PWMArray + 5	
		mov	PWMCounters + 6,PWMArray + 6	
		mov	PWMCounters + 7,PWMArray + 7	
		mov	p1,#0ffh				;All port pins high
			
		reti		;Done
			
noreset:		djnz	PWMCounters + 0,$+2		;Bump channel 0 counter
		clr	p1.0				;Reset port pin when it crosses zero
			
		dec	PWMCounters + 1,$+2	
		clr	p1.1	
			
		dec	PWMCounters + 2,$+2	
		clr	p1.2	
			
		dec	PWMCounters + 3,$+2	
		clr	p1.3	
			
		dec	PWMCounters + 4,$+2	
		clr	p1.4	
			
		dec	PWMCounters + 5,$+2	
		clr	p1.5	
			
		dec	PWMCounters + 6,$+2	
		clr	p1.6	
			
		dec	PWMCounters + 7,$+2	
		clr	p1.7	
			
		reti		


 


You see: as much as the amount of channels and the algorithm used play a role in the time needed to generate the signals, so does the resolution you want the stuff to work at. At 3 bit resolution, as in this example, you have 8 possible pulsewidths, and a theoretical speed gain of 2^8-3 = 32 times compared to a 256 pulsewidths resolution setting. So don't take 256 step resolution for granted! Think of the implications! Take only what you need! 3 bits red, 3 bits green and 3 bits blue will give you 512 possible colors. I bet that's enough for any average application.

Please try to remember: You should have a good look at your requirements before you start coding. Play with ideas and different approaches. Do rough calculations regarding the timing. How many intensity levels do you need? What's more important to you: Plenty of intensity levels, or flicker free operation? Do you need a faster processor? Do you need external chips or specialized hardware? It pays of to think about stuff like that and form a pretty good idea about what you are about to do before touching your computer keyboard or soldering iron once.


List of 23 messages in thread
TopicAuthorDate
89S52 and multiple PWM            01/01/70 00:00      
   Speed            01/01/70 00:00      
   is 2 times 5 less than 8?            01/01/70 00:00      
      processor sugestion + PWM IC            01/01/70 00:00      
         you need to describe EXACTLY            01/01/70 00:00      
            what I want            01/01/70 00:00      
               clarify?            01/01/70 00:00      
                  1st DMX 2nd auto            01/01/70 00:00      
               ???            01/01/70 00:00      
                  Agreed            01/01/70 00:00      
                     RGB and PWM            01/01/70 00:00      
                        ???            01/01/70 00:00      
                           GIVING UP!            01/01/70 00:00      
                        What is the point of it?            01/01/70 00:00      
                           misunderstood            01/01/70 00:00      
                              ideas and giving up            01/01/70 00:00      
   look at some servo code (recently published on this forum)            01/01/70 00:00      
   Faster PWM            01/01/70 00:00      
      PWM            01/01/70 00:00      
         check this            01/01/70 00:00      
   randomly bumped on TM1803            01/01/70 00:00      
   PCA9685            01/01/70 00:00      
      tlc5947            01/01/70 00:00      

Back to Subject List