[solved] problem using timer interrupt in assembly

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

hellow, im new with asm in the field of AVR

 

but it should be a simple project to only make LED flashing using timers

 

chip is Atmega8a-pu

 

here is the code :

.nolist
.include "m8Adef.inc"
.list

.def temp = r16
.def overflows = r17
.def milliseconds = r18

.macro delay
   clr overflows
   ldi milliseconds,@0
  sec_count:
   cpse overflows, milliseconds
  rjmp sec_count
.endmacro

.org 0x000
rjmp reset

.org 0x003
rjmp overflow_handler

reset:
	;- setup timer
	ldi temp,0b00001111
	out TCCR2,temp
	ldi temp,240
	out OCR2,temp
	ldi temp,0b00000000
	out TCNT2,temp
	ldi temp,0b10000000
	out TIMSK,temp

	sei
	;- setup pin
	ldi temp,0b00000010
	out DDRB,temp
main:
	sbi PORTB,1
	delay 4
	cbi PORTB,1
	delay 4
	rjmp main

overflow_handler:
   inc overflows
reti

after running via simulator, overflows(R17) does not incremented,  seems compare match interrupt never called.

in actual test, led not blinking.

 

i tested above without use of macro, using overflow interrupt instead with no success, what is wrong?

code always paused at  first delay 4

 

This topic has a solution.

I'm new, please help me.

Last Edited: Fri. Dec 7, 2018 - 12:56 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In your delay macro your are not incrementing/decrementing your counter so it will just sit there looping forever.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

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

thank you so much for replying :)

 

i did it inside interrupt sub routine,

overflow_handler:

which is attached @

 

.org 0x003
rjmp overflow_handler

I'm new, please help me.

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

Can we trust that the register called "milliseconds" really is a count of milliseconds? (how have you calibrated that?)

 

Anwyay assuming it is exactly what were you expecting to see with:

main:
	sbi PORTB,1
	delay 4
	cbi PORTB,1
	delay 4
	rjmp main

Assuming "delay 4" really does deliver a 4 millisecond delay the LED is on for 4ms and off for 4ms. So it has an 8ms flashing period. In 1 second there are 1000ms. So it will flash 125 times per second.

 

Do you really think the human eye/brain is fast and smart enough to be able to detect 125 flashes per second? I'm afraid it isn't. The best it can cope with is about 10 to 15 flashes per second, above that the on/off periods tend to merge into one another. In fact this is how movies (24 frames per second) and TV (25..30 fps) work. They change so quickly the human brain cannot see the flickering.

 

That's the problem you have. Your LED (assuming it really is as slow as 4ms) will not be able to tell on from off and the LED will simply look like it's on (at reduced brightness) all the time. In fact if you have ever seen anything (like Christmas tree lights) where LEDs appear to increase/decrease in brightness all that is really happening is that the LEDs are being swicthed on/off so fast you cannot see it then the controller is varying the ratio of the on/off time. If it's more on than off the LED if bright, if it is more off than on the LED is dim. This is known as Pulse Width Modulation (PWM) and is probably the next thing you'll want to explore with your AVR/LED.

 

But for not try making your delays MUCH longer like:

main:
	sbi PORTB,1
	delay 400
	cbi PORTB,1
	delay 400
	rjmp main

and see what transpires. (Depending on whether "delay 4" really is 4 ms it may need to be a figure much larger even than 400!)

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

Are you sure! you use a big divider for the timer (1024), does the timer run? what happens when it reach the match value? etc 

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

dear clawson thank you for reply

excuse me for providing an confusing code

i noticed my mistake by keep the wrong name for register R18,

it is named millisecond but actually its not because code updated but equivalent to R18 stays millisecond.

 

what i did and what datasheet said for Atmega8A,

  • i used 8bit timer/counter 2 and set following registers
  •  TCCR2  [ FOC2 | WGM20 | COM21COM20 |  WGM21 | CS22 | CS21 | CS20 ]
    where 0b00001111 means:

    • 1024 prescaler
    • CTC mode
  •  OCR2  = 240, means we just count to 240 then interrupt will be called?
  • finaly i set  TIMSK  (in atmega8A this register is shared for whole timers) to 0b10000000
    which means OCIE2, timer/counter2 Output Compare Math interrupt Enable

the final result is 1000000(1MHZ cpu speed)/1024/240 = 4

its the reason that i used delay 4, to count 4 overflows for simulating 1 second

 

but LED stills bright

I'm new, please help me.

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

@Sparrow2, thanks alot for spending time here,

nothing happend seems attached ISR not invoked!!

timer is running and TCNT2 is counting

 

i used both of AVR simulator and Atmega8a for actual test

I'm new, please help me.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

In Post#1, I don't see where you have initialized the Stack Pointer.

 

From the ATmega8A datasheet (12 - Interrupts):

 

$013 RESET:  ldi r16,high(RAMEND)    ; Main program start
$014             out SPH,r16                   ; Set Stack Pointer to top of RAM
$015             ldi r16,low(RAMEND)
$016             out SPL,r16
$017             sei                                 ; Enable interrupts

 

Last Edited: Fri. Dec 7, 2018 - 10:54 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

just to break it down to find the error

 

does the timer clear at 240 ? (just to check correct mode)

 

does  OCF2 ever gets set ?

 

add

perhaps clear OCF2 (by writing a 1 to it) in case it get set before interrupt is enabled (else it will clear it)

 

 

add

OK I see it's solved I forgot about the stack problem on old chips

Last Edited: Fri. Dec 7, 2018 - 11:09 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@ chuck99, special thanks, i tried it before posting with no success because i missed setting SPH
it just solved my problem with a huge shame on me

 

but the same code runs truly on atmegax8 chips and atties without stack pointer, is it auto assigned in newer chips?

I'm new, please help me.

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

Chuck99 wrote:

In Post#1, I don't see where you have initialized the Stack Pointer.

 

Nice catch, the mega8 is one of those that doesn't initialise SP to RAMEND but clears it to zero on reset.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

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

payam_sbr wrote:

but the same code runs truly on atmegax8 chips and atties without stack pointer, is it auto assigned in newer chips?

 

Yes, see my post just above.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

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

@Sparrow2, its a good practice for similar problems, tnx

I'm new, please help me.

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

payam_sbr wrote:
but the same code runs truly on atmegax8 chips and atties without stack pointer, is it auto assigned in newer chips?

Sheesh, what do the datashets say?!?

 

What is an "x8" chip?  Which model are you referring to?  What does the datasheet for THAT MODEL say?

 

[side note:  Another current/recent thread from an ASM programmer asked about how to do interrupts in C.  Now we have a C programmer asking about doing interrupts in ASM.]

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.