assemblytimeratmelatmega

Issues with timers in assembly language (ATmega8)


I've written a program for ATmega8 that outputs two different sounds, taken from two potentiometers.

The issue with that is, that a sound is generated by turning the beeper on and off with a delay in it, which is basically the value of the potentiometer.

But the higher the frequency is, the lower is the time the sound is played, and I want that the time the sound is played is unattached to its frequency.

So I decided to use a timer.

Planned is the following structure:

while(timer0counter > 0)
    while(timer2counter > 0)
        output on
    while(timer2counter > 0)
        output off

As you see, this should give a frequency over a specified time. The implementation so far looks as follows (PORTB is the beeper) (This is only for one sound):

mainloop:
    ldi r27,250;The value of one potentiometer, here a static value

    ldi r22,255
    mov r23,r27
    loop:

          ldi r16,4
          out PORTB,r16

          tst r23
          brne loop

          mov r23,r27

          inner:
                ldi r16,0
                out PORTB,r16

                tst r23
                brne inner

          tst r22
          brne loop

rjmp mainloop

While the timer overflow functions are:

tmr0overflow:
  tst r22
  breq skip0
  sub r22,1
  skip0:
reti

tmr2overflow:
      tst r23
      breq skip2
      sub r23,1
      skip2:
reti

Timer initialization:

ldi r16,5
out TCCR0,r16
ldi r16,2
out TCCR2,r16

ldi r16,(1<<TOIE0) | (1<<TOIE2)
out TIMSK,r16

I've also set the interrupt vectors for T2OVF, T0OVF and enabled interrupts in general.

But it doesn’t work. The output seems like random. what’s wrong with it?


Solution

  • Use:

    ;PORTC  0 = INPUT
    ;POT. 1[C0 / ADC0]
    cbi     DDRC,0
    cbi     DDRC,1
    ;PULLUP
    sbi     DDRC,0
    sbi     DDRC,1
    

    The pull-up resistor is not set via the DDR, but the PORT. The input is not determined when reading from an output.