mega48 Timer0 and pwm

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi
Made time over the holidays to do some tinkering on a mega48. Set up a adc with a simple 10Kpot and a small program( as found here ) and got it putting out values to a terminal program . Got values from 0 to 255 ,Great! Next ,used that value to update the OCR0A reg. to be able to vary my frequency out of the OC0A pin in CTC mode.Worked . Was able to vary the clock (OC0A pin) into my stepper driver with good results.

I decided to try PWM with the same program(not for steppers but for servos) . Started to change some of my settings when I noticed that I had accidently set the WGM02 bit in CTC mode. For a while could not get PWM to work #!#$%!? Finally Cleared the WGM02 bit and it worked. I have no interrupts running, just a simple loop that looks for keypress to do update the adc into the OCR0A reg.

It seems that the WGM02 bit is doing the opposite of what I thought it should be doing . Well I still have some time left ,so on to timer1 and more
headshaking. Hope this helps someone .

Pete

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ahh, you didn't say what your problem is...............

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry

I did'nt mean to sound like I was "preaching" . It's just that trying to get something to work when you read the data sheet over and over again gets a little frustratting. I was hoping for a little feedback from others who might have had similar problems but as I see my post could have had some more of a question to it along the lines of "HELP DATASHEET MADNESS!!"
Just making something "WORK" maybe should have a hall of fame.

Pete

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you set WGM02,WGM01,WGM00 = 1 0 0 you entered an undefined state, and it probably reverted right back to 0 0 0. CTC is 0 1 0.

Edit: I dont really think there should be a hall of fame for getting the peripherals to work. Most of them are really easy to set up, and reading the datasheet very carefully is actually the easiest way to go about it IMO. I have had much better luck coding from scratch just by what the datasheet says rather than trying to use other people's code. (Not a rant or an insult, just a random personal thought.)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Unless you can pay someone knowledgeable for AVR direct support, the data sheet is THE authoritative source for day to day use. You have to realize that you must learn how to work with the data sheet. This skill does not come naturally. You can learn to get better at learning how to read data sheets, if you try.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well I guess my original post got a little misconstrued . I never said I couldn't get it to work but that the WGM02 bit was doing the opposite of what the Data Sheet said it should do. If i set WGM2:0 to 1 1 0 I get CTC mode with OCRA as top. If i set the bits to 0 1 1 then I get
fast PWM with OCRA as top . If I set the bits to 111 then my fast PWM doesn't work. Yes ,data sheets are invaluble but when the results don't match the expected then it's time to do a litte fiddling around . What I was hoping for was that someone that had actual experience with TIMER0 in a mega48 would tell me if they had the same problem.

I know that TIMER0 is like a red-headed orphan but I was using it to figure out things before trying TIMER1 (start easy first then harder).I'm a bit of a skeptic when it comes down to believing in what is printed is the gospel truth . If I can't see for my own eyes what is going on then i'm not convinced .

Sorry for the hall of fame bit but when things do work it's just a great feeling.This is a wonderful site and I've learned a lot here .

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I haven't done PWM on Timer0 of Mega48/88, but I suspect that the chip operates as described in the datasheet. We have nearly a dozen Mega48/88 production designs and I've yet to find an outright error in I/O bit descriptions, etc.

Let's see a code fragment of the TCCR0x register setup, description of what you expexted, and a description of what you got. Only then can we try to reproduce your situation and make detailed comments, perhaps confirming your results of a datasheet and/or chip problem.

Note that a quick datasheet read seems to indicate that Timer0 PWM doesn't happen "by itself" for many combinations--it appears that the compare match and overflow need to be "caught" (typically by interrupts/ISR code) and the pin (which must be an output) toggled/cleared by code.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Lee
I'll try and post some code shortly but what you say about the TIMER0 needing to be caught does not seem to apply . Once the timer is set up it runs without "maintenence" in both CTC and fast PWM ,don't know about Phase correct . I was able to change the OCR0A to be able to watch how it effected the waveform on a tek2246.If I didn't have the scope to watch the signal then I would never have posted because it's hard to tell what's going on without one.

Pete
P.S. You should get a little more sun .

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well tried to clean up the code a little so bear with me.

.include  "m48def.inc"

.def	Temp	=r16
.def	Temp1	=r17
.def	Delay	=r18
.def	Delay2	=r19

.equ	xclk	=PD6			;OC0A pin
.org	$000
	rjmp	RESET

RESET:							;Setup Stack
	ldi		Temp,high(RAMEND)
	out		SPL,Temp
	ldi		Temp,low(RAMEND)
	out		SPL,Temp

REGINIT:
	ldi		Temp,0b01000000		;setup PD6 as out
	out		DDRD,Temp
ADCINIT:						;setup	ADC
	ldi		TEMP,0b00000000
	sts		ADMUX,Temp
	ldi		Temp,0b11101111
	sts		ADCSRA,Temp

START:
	rcall 	RS232INIT
	rcall 	MESSAGE
	rcall	CTCSET 				;start up with ctc
;	rcall	PWMSET				;uncomment for different
;	rcall	PCPWMSET			;startup	
LOOP:
	rcall	dly
	rcall	RS232in				;get keypress from terminal

	cpi		Temp,'m'			;if m then send message
	brne	LPBY1
	rcall 	MESSAGE
	rjmp	LOOP
LPBY1:							;if a then read adc
	cpi		Temp,'a'
	brne	LPBY2
	rcall	ADCREAD
	rjmp	LOOP
LPBY2:							;if i then increment OCR0A
	cpi		Temp,'i'
	brne	LPBY3
	rcall	INCR1
	rjmp	LOOP
LPBY3:							;if d then decrement OCR0A
	cpi		Temp,'d'
	brne	LPBY4
	rcall	DECR1
	rjmp	LOOP
LPBY4:							;if f then set fast PWM
	cpi		Temp,'f'
	brne	LPBY5
	rcall 	PWMSET
	rjmp	LOOP

LPBY5:
	cpi		Temp,'t'			;if t then set ctc mode
	brne	LPBY6
	rcall 	CTCSET
	rjmp	LOOP

LPBY6:
	cpi		Temp,'p' 			;if p then phase correct 
	brne	LPBY7
	rcall	PCPWMSET
	rjmp	LOOP

LPBY7:
	cpi		Temp,'s'			;if s then set WGM02 bit
	brne	LPBY8
	rcall 	SETWGM02
	rjmp	LOOP
	
LPBY8:
	cpi		Temp,'c'			;if c then clear WGM02 bit
	brne	LPBY9
	rcall	CLRWGM02
	rjmp	LOOP

LPBY9:
tby1:							;print back to terminal

	rcall 	RS232OUT

	rjmp 	LOOP


RS232INIT:				;setup for 9600 baud at 14.7456 MHz
	ldi		Temp1,0
	ldi		Temp,95
	sts		UBRR0H,Temp1
	sts 	UBRR0L,Temp
	ldi		Temp, (1<<RXEN0)| (1<<TXEN0)
	sts		UCSR0B,Temp
	ldi		Temp, (1<<USBS0) | (3<<UCSZ00)
	sts		UCSR0C,Temp
	ret
							;
RS232in:					;Must use Regs - No sbis
	lds	    Temp,UCSR0A     ;Check Flag
	sbrs	Temp,RXC0
	rjmp 	RS232in
	lds		Temp,UDR0	    ;Load Data
	ret

RS232OUT:					;Must use Regs - No sbis

	lds		TEMP1,UCSR0A 	;Check Flag
	sbrs	TEMP1,UDRE0
	rjmp 	RS232OUT
	sts		UDR0,Temp		;Send Data
	ret
INCR1:						;this increments OCR0A
	in		Temp,OCR0A
	dec 	Temp
	out		OCR0A,Temp
;	rcall 	RS232OUT		;display to terminal
	ret

DECR1:						;this decrements OCR0A
	in		Temp,OCR0A
	inc 	Temp
	out		OCR0A,Temp
;	rcall 	RS232OUT		;display to terminal
	ret


ADCREAD:						;this code from avrfreaks 
								;beginners area for reading 
								;adc and formatting to 8bits
	lds		Temp,ADCL
	lds		Temp1,ADCH
	lsr		Temp1
	ror		Temp
	lsr		Temp1
	ror		Temp
	out		OCR0A,Temp		;update OCR0A 
	rcall	RS232OUT		;send out to terminal
	ret

PWMSET:						;this sets up fast pwm on OC0A
							;clock /1024
							;clear OC0A on match
							;mode 3 top is 0xFF but
							;OCR0A seems to vary it
							;setting WGM02 bit turns on
							;mode 7- but no output is seen

	ldi		Temp,(1<<COM0A1)|(1<<WGM00)|(1<<WGM01)
	out		TCCR0A,Temp
	ldi		Temp,(1<<CS00)|(1<<CS02)
	out		TCCR0B,Temp
	ldi		Temp,156
	out		OCR0A,Temp
	ret


CTCSET:					;setup timer0 for CTC mode
						;clock/1024
						;toggle OC0A
						;WGM02 seems to have no difference

	ldi		Temp,(1<<COM0A0)|(1<<WGM01)
	out		TCCR0A,Temp
	ldi		Temp,(1<<CS00)|(1<<CS02)
	out		TCCR0B,Temp
	ldi		Temp,128		;set ocr0a at midpoint
	out		OCR0A,Temp
	ret

PCPWMSET:				;setup timer for phase correct pwm
						;clock/1024
						;clear	OC0A on match
						;mode 1 top should be 0xFF
						;but OCRA  seems to 
						;have an effect
						;setting WGM02 makes mode 5

	ldi		Temp,(1<<COM0A1)|(1<<WGM00)
	out 	TCCR0A,Temp
	ldi		Temp,(1<<CS00)|(1<<CS02)
	out		TCCR0B,Temp
	ldi		Temp,128
	out		OCR0A,Temp
	ret

SETWGM02:
	in		Temp,TCCR0B
	sbr		Temp,1<<WGM02
	out 	TCCR0B,Temp
	ret

CLRWGM02:
	in		Temp,TCCR0B
	cbr		Temp,1<<WGM02
	out 	TCCR0B,Temp
	ret

STEPTEST: 				;send out 200 clocks to stepper
	ldi		Temp,200
STPINDX:
	sbi		PORTB,xclk	;clock active high
	ldi		Temp1,200
STPBY1:
	dec		Temp1		;hold line high for awhile
	brne	STPBY1
	cbi		PORTB,xclk
	rcall 	dly1
	dec		Temp
	brne	STPINDX
	ret

DLY:						;just a delay 

	dec		Delay
	brne	DLY
	dec		Delay2
	brne	DLY
	ret
DLY1:
	ldi		Delay2,45
	
DLY1A:
	ldi		Delay,250
DLY1B:
	dec		Delay
	brne	DLY1B
	dec		Delay2
	brne	DLY1A
	ret

MESSAGE:
	ldi 	ZL,low(2*msg)
	ldi 	ZH,high(2*msg)
Strout:
	lpm		Temp,Z+
	tst		Temp
	breq 	sext
	rcall 	rs232out
	rjmp 	Strout
SEXT:
	ret

MSG:

	.db "Hello World here I am " ,10,13
	.db "This is just a test of ny typing  skills ",10,13,0

Edit : Had bit masks flipped
Pete

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Edit : Had bit masks flipped

So the code as posted is that which showed the undesireable symptoms, or the symptoms went away when you flipped the bit masks?

With the code you posted, what did you expect the output to be? What did you see? How did you "measure" it--'scope?

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

They were "remnants " when I was trying many different combinations . Program worked in both versions ( the bits were selecting clock divider so got different clock "speed" ). I guess I have to come out and say that with WGM02 set and being in fast PWM mode I see no output as a PWM . Toggling WGM02 off and on alllows me too see how it behaves. Maybe it's just me being a little experimental and seeing what different modes do made me mess around with Timer0 . Somebody asked what the problem was and I guess I should have answered that it was "NOT enough time to explore "

Pete

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't get it.

It appears that when you originally made a simple bit mask mistake (we've all been there at one time or another) the mega48 was misbehaving and appearing not to be following the data sheet description, hence the data sheet seemed wrong at that moment. I guess your misunderstanding caused you to complain about "HELP DATASHEET MADNESS!!".

Are you now saying mega48 timer0 fast PWM does not work as described in the data sheet? The only functional difference between WGM mode 3 fast PWM and WGM mode 7 fast PWM is; in mode 3 TOP is fixed at 0xFF and OCR0A can be used for a normal output compare, while in mode 7 TOP is assigned by the value in OCR0A and OCR0A cannot be used for normal output compare with one exception. In WGM mode 7 nothing comes out of the OC0A pin because OCR0A is being used to set TOP for the fast PWM instead. The note under table 13-3 in the data sheet explains that if COM0A1 is set and OCR0A equals TOP, then it will simply do the programmed set or clear at TOP (this will only possibly change the OC0A pin state one time and keep setting it to the exact same state on every single TOP compare, so OC0A does nothing). The WGM mode 7 exception is when you set COM0A0=1 and COM0A1=0 to make the OC0A pin toggle at TOP (this does not work in mode 3).

digitool wrote:
I guess I have to come out and say that with WGM02 set and being in fast PWM mode I see no output as a PWM.

I agree with you with respect to the OC0A pin (except for the special COM0A0/1 setting). However, the OC0B pin still functions. So, if you see nothing you must also not be using the OC0B pin or the special COM0A0/1 setting.

In its own arcane :) way all this timer0 behavior is clearly and consistently described in the data sheet. Blindly experimenting your way through each function on the AVR seems like a really inefficient way to learn a chip and given all the possible permutations you may never learn enough. However, if you take your experiment results and apply them to the data sheet until you understand the data sheet, then you will not need to do as much experimenting in the future because you will learn a lot directly from the data sheet.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks Mike for letting me see the Byte through the bits.In modes 5 and 7 the top is set at OCR0A so it acts like a variable frequency as in CTC mode .With COM0A0 set and WGM02 set the OC0A is toggled as in CTC mode (OCR0A is buffered in this mode).So with modes 5 and 7 , OC0B does the PWM but it's resolution is set by OCR0A which it can't be equal or greater to which limits these modes if OCR0A is set low .

Sorry if I have offended anyone

Pete