ATtiny26 PWM & timer adjustment maddness

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

Hello:

I am writing my fiorst AVR program for the STK500. It kind of works. What I'm trying to do is generate two PWM outputs(along with the inverted outputs---that is, using all four PB0-PB3 outputs.)
I do not want to use any interrupts--are any needed?
I want to use the high freq PLL clock to generate a 20khz pwm with a 7 bit approx duty cycle adjustment resolution. This should give about 0.5% adjustment per step
The chip is programming properly (I added the two extra jumper wires for the tiny 26)!!! I have left all of the STK500 jumpers in place (default).

The program SEEMS to work, but not quite. It reads the switches & does adj the freq & duty cycle. BUT the duty cyle jumps in about 5% steps & is very course. this is strange. If I HARD code the inital duty cycle value as $69 I get 52.5% duty, $6A give 53%, $6B gives 53.5% etc, which is just fine (note the small duty % steps).

I'm assuming my switch reading is inc/dec the duty value by one count...but doing it this way is giving 5-10% duty steps. Is there a trick to updating the duty cycle (timer) registers? This code just dumps the lastest duty value into OCR1A & OCR1B. Does something intermediate, like shutting off timers, need done? Like polling or setting an interrupt? At this point I really don't want to use any interrrupts (unless I must).

I am almost positive the switches are reading properly, and this is not a switch bounce problem.

Also, my coding skill is rather new. Please look at where I am reading the PLL lock bit. Why can't I use an SBIS instruction here???!!. My code methods seems a bit kludgy. Can't the bit be read/tested in one instruction?
Also in setting all these register I load a value into temp, then do an "OUT Reg, temp"
Is there a more direct way to set these?

Is anything special needed to update the time PWM values? Also, I seem to get the same duty cycle jumping no matter what clock option I burn in on the STK500 programming menu (pll or internal RC).

;**** tiny 26 simple PWM test

.include "tn26def.inc"
.def temp=r16 ;set up some registers
.def delay=r17
.def delay2=r18
.def duty=r25
.def freq=r20
clr temp
out ddra, temp ;set port a to inputs
ser Temp ;set all to ones
out ddrb,temp ;set port b to outputs
ldi duty, $69 ; set intial duty
ldi freq, $c7 ;set initial freq
ldi temp, $53
out tccr1a, temp ;set tccr1a ---IS there a more direct way to set these?
ldi temp, $85 ; set ctc1 & set tp to pck/16
out tccr1b, temp
ldi temp,$02
out pllcsr, temp ;enable pcke bit
waitpll: in temp, pllcsr ;this seems a kludgy way to check the bit---any ideas?
sbrs temp,$00 ;can the bit be checked with one instruction?
rjmp waitpll ;wait for plllock
ldi temp,$06
out pllcsr, temp ; enable async mode

Main:

sbis pina,$07 ;change freq & duty based on switches
inc freq ;COUNT THEM UP/DOWN
sbis pina,$06
dec freq
sbis pina,$05
inc duty
sbis pina, $04
dec duty

delay: dec delay ;PUT IN A LONG WAIT
brne delay
dec delay2
brne delay
;update PWM REGISTERS
pwm:

out ocr1a, duty ;change the pwm timer settings
out ocr1b, duty
out ocr1c, freq

rjmp main ;GO BACK & REREAD SWITCHES

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

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

Hi,

I may be way off here but perhaps your 'delay' routine finishes before you can release the switch and therefore you are seeing several switch closings. Just a off the cuff thought after quickly looking over your code.

BTW, it turns out nicer if you use the Code button (in the list of items under the Subject input box). Just click on Code, paste in your code and click on Code again.

Regards,
Steve

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

I think the delay timer should be ok..it is the same routine used in the AVR examples....They use it to blink & count through the leds when you hold the switches down...maybe I'll try to make it even slower!!

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

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

thanks for the tip....after MUCH messing around it does appear that the timer was running too fast & that i was incrementing the duty values by several counts with each switch press....now its working well

I was still wondering about my coding methods....why can't you use sbis on the pllcsr bit monitoring...do you always have to use "in" and "out to work with these registers?

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

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

thanks for the tip....after MUCH messing around it does appear that the timer was running too fast & that i was incrementing the duty values by several counts with each switch press....now its working well

I was still wondering about my coding methods....why can't you use sbis on the pllcsr bit monitoring...do you always have to use "in" and "out to work with these registers?

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

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

Hi,

The SBI/CBI/SBIC/SBIS instructions only work on addresses to 0x1F. There is an AVR Assembler User Guide available on the Atmel site. This explains this little gotcha. I am sorry but I don't have the web address handy. I will get it to you tomorrow if you need it. It is quitting time now.

Regards,
Steve

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

Hi again,

Here is the document I mentioned:

http://www.atmel.com/dyn/resourc...

Saying that document that gotcha may be stretching it a bit. It does say this:

Quote:
This instruction operates on the lower 32 I/O Registers – addresses 0-31.

Regards,
Steve