From: Scott Dattalo
;------------------------------------------------------------
;pwm_multiple
;
; The purpose of this routine is to generate 8 pulse width
;modulated waveforms. The algorithm consists of 9 counters
;that change the state of the pwm bits whenever they roll over.
;One of the counters, rising_edge, will drive the pwm bits
;high when it rolls over. The other 8 counters pwm0-pwm7 will
;drive their corresponding bits low when they roll over.
;
;
;RAM:
; pwm0-pwm7 - pwm counters [ed: initialized with 0..255, but not greater
; then PWM_PERIOD (0..255). 0 corresponds to 256 cycles period]
; rising_edge - rising edge counter [ed.: initialized with PWM_PERIOD]
; pwm_state - current state of the pwm outputs.
;ROM
; 23 instructions
;Execution time
; 23 cycles
pwm_multiple
CLR W ;Build the bit mask for turning
;off the PWM outputs. Assume that
;all of the outputs will be turned
;off.
;
DECSZ pwm0 ;If the first counter has not reached 0
OR W, #%00000001 ;then we don't want to turn it off.
;
DECSZ pwm1 ;Same for the second one
OR W, #%00000010 ;
;
DECSZ pwm2 ;and so on...
OR W, #%00000100 ;
;
DECSZ pwm3 ;
OR W, #%00001000 ;
;
DECSZ pwm4 ;
OR W, #%00010000 ;
;
DECSZ pwm5 ;
OR W, #%00100000 ;
;
DECSZ pwm6 ;
OR W, #%01000000 ;
;
DECSZ pwm7 ;
OR W, #%10000000 ;
;
;
AND W, pwm_state ; Clear all of those pwm outputs
;that have reached zero.
;
XOR W, #%11111111 ;Toggle the current state.
DECSZ rising_edge ;If the rising edge counter has not
XOR W, #%11111111 ;rolled over then toggle them again.
;Double toggle == no effect. However,
;if the rising edge counter does roll
;over then a single toggle will turn
;the pwm bits on, unless of course the
;pwm counter has just rolled over too.
;
MOV pwm_state, W ;Save the state
MOV PWM_PORT, W ;update the outputs
;[ed. by Nikolai Golovchenko
;Update pwm counters with new values when rising_edge reaches zero.
;If update is not necessary and PWM period is 256 cycles, then this portion
;of code may be skipped because rising_edge counter has 256 cycles period
;and all initial values of pwm counters are restored in the end of each period.
;
;Additional 22 instructions.
TEST rising_edge
SB Z ;update if zero
RET
pwm_init
MOV W, PWM_PERIOD ;init period
MOV rising_edge, W
MOV W, pwm0_init ;init pwm0
MOV pwm0, W
MOV W, pwm1_init ;init pwm1
MOV pwm1, W
etc.
MOV W, pwm7_init ;init pwm7
MOV pwm7, W
RET
;end of ed.]
Now this routine has been optimized for speed. It would be difficult (but
not impossible) to modify it to: 1) change the duty cycle on the fly and
2) have different frequencies for each pwm.
One technique is to maintain two counters for each pwm. Call them say,
rising_edge_counter and falling_edge_counter. Make the counters the same
size and do something like this:
if(--rising_edge_counter == 0) {
turn_PWM_on();
rising_edge_counter = PWM_PERIOD;
}
if(--falling_edge_counter == 0) {
turn_PWM_off();
falling_edge_counter = PWM_PERIOD;
}
In other words, every time the rising edge counter rolls over, you make
the PWM output high and when the falling edge counter rolls over you make
it low.
Now, to get duty cycle, you simply adjust the phase between the counters:
set_duty_cycle(int new_duty_cyle)
{
falling_edge_counter = rising_edge_counter + new_duty_cyle;
if(falling_edge_counter > PWM_PERIOD)
falling_edge_counter -= PWM_PERIOD;
}
Now this routine assumes that the new_duty_cycle is less than the
PWM_PERIOD.
Scott
Also:
See also:
| file: /Techref/scenix/lib/io/osi1/pwm/PWM_sx.HTM, 5KB, , updated: 2004/6/10 14:40, local time: 2025/10/24 11:12,
216.73.216.20,10-1-5-169:LOG IN
|
| ©2025 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://ecomorder.com/Techref/scenix/lib/io/osi1/pwm/PWM_sx.HTM"> PIC Microcontroller IO Routine Pulse Width Modulation from Scott Dattalo</A> |
| Did you find what you needed? |
Welcome to ecomorder.com! |
|
Ashley Roll has put together a really nice little unit here. Leave off the MAX232 and keep these handy for the few times you need true RS232! |
.