Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PWM without using Ouput Compare pins

Status
Not open for further replies.

apakhira

New Member
Hi
I'm using an Atmel ATMega32 for a robotics project. Is ther a way to use PWM using other pins besides the OC0, OC1A OC1B and OC2 pins?

Thanx
 
You could use a timer interrupt scheme.

Say if you had a servo that needed updating every 20ms, and you wanted six bit or 64 step speed control. Preload a timer register to rollover approximately every 300us (or just use the lower register value for faster updates). Within the on interrupt service routine, compare a duty cycle variable against your max 64 steps, and which I/O pins to turn off/on. Decrement a counter to keep track the I/O on/off. Use the top two bits of the duty cyle variable to tell which direction and which motor. Compare if new duty cycle variable is different from last, and reset counter if true.

Good luck:).
 
I didn't get the part about the duty cycle variable. Could you explain a bit more? In fact, an example would be great.

Thanx
 
Make that duty cycle scheme to send two variables, one for each motor. Don't have a direct working example, but hope the idea is expressed better in the following incomplete "pseudo" code.

Code:
;initialize timer interrupt rollover counter at 64 steps
step64 = 63	
R_DutyNew = 0
R_Duty = 0
R_Dir = 0

;Main program code
;send out R_Motor forward signal
R_DutyNew = b'10100000'	;dir-fwd, 50% duty cycle		

;interrupt service routine
sub PWMduty

	If step64 = 63 And R_Duty = 0 Then	;start new interrupt period
		R_Duty = R_DutyNew AND b'00111111'	;fetch new duty update register
		R_Dir = R_DutyNew AND b'10000000'          ;check motor dir bit
		...
		...
	end if

;Call this R_Motor forward
	If R_duty > 0 AND R_Dir = 1 Then
		sbi PortB.0
	else
		cbi PortB.0
	end if
...
...
...
	step64 = step64 - 1		;decrement interrupt rollover counter
	If step64 = 0 Then		;start new period counter
		step64 = 63
	end if
	R_Duty = R_Duty - 1	;decrement duty cycle on time
	
end sub
 
Hey thanx. I finally did it in a dfferent way. I had to control motors using an L293D. I used one PWM channel(TIMER0) and used 4 AND gates to signal the motors.
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top