6 Replies - 1180 Views - Last Post: 13 May 2018 - 01:10 AM

#1 rhhh12   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 18
  • Joined: 02-April 18

AVR Assembly Traffic Lights - help

Posted 11 May 2018 - 09:32 AM

Hi, i am new to C and Assembly and have been set the task of completing the delay subroutine such that it accurately provides a 1-second delay and then to modify the blink functionality to implement a single four phase traffic light. The blink code should run in 2000ms + timing overheads, which are approx. 17ms.
I am extremely new to assembly and have read the instruction manual however and still confused, if there is anyone who can help me get started i would be grateful.

This is the first part of the code i need to edit:

//-----------------------------------------------------------------------
    // Task 1 - complete delay_ms subroutine below until displayed error < 1%
    //-----------------------------------------------------------------------
    
    /* Input variable - millisecond count in register pair r30:r31
  
    registers used:
     r31 - millisecond count (lo byte)
     r30 - millisecond count (hi byte)
     r17 - 100 microsecond count
     r16 - 1 microsecond count
    
     Overall delay (ms) = r30:r31 * r17 * r16
    ---------------------------------------------------------------------*/
    "delay_ms%=:    nop                 ; replace nop with your code  \n"
    "delay_100us%=: nop                 ; replace nop with your code  \n"
    "delay_1us%=:   nop                 ; replace nop with your code  \n"
    "               sbiw r30,1          ; decrement ms count (r31:r30)\n"
    "               brne delay_ms%=     ; loop to delay_ms while > 0  \n"
    "               ret                 ; return from subroutine      \n"


This is the second part of the code for the traffic lights:

//-----------------------------------------------------------------------
    // Task 2 - modify blink code below to implement four phase traffic light
    //-----------------------------------------------------------------------
  
    " blink%=:                               ; start of blink code    \n"
    //
    // turn onboard LED on
    //   
    "               ldi  r18,0x20            ; bit 5 (pin 13) = high  \n"
    "               out  5,r18               ; output to port B       \n"
    //
    // delay by value in millisecs variable
    //
    "               lds  r30,millisecs      ; r30 = hi byte           \n"
    "               lds  r31,millisecs + 1  ; r31 = lo byte           \n"
    "               call delay_ms%=         ; call millisec delay sub \n"
    //
    // turn onboard LED off
    // 
    "               ldi  r18,0x00           ; value for all LEDs off  \n"
    "               out  5,r18              ; output to port B        \n"
    //
    // delay by value in millisecs variable
    //
    "               lds  r30,millisecs      ; r30 = hi byte           \n"
    "               lds  r31,millisecs + 1  ; r31 = lo byte           \n"
    "               call delay_ms%=         ; call millisec delay sub \n"

    ::: "r16", "r17", "r18", "r30", "r31");    // clobbered registers


Is This A Good Question/Topic? 0
  • +

Replies To: AVR Assembly Traffic Lights - help

#2 turboscrew   User is offline

  • D.I.C Lover
  • member icon

Reputation: 171
  • View blog
  • Posts: 1,107
  • Joined: 03-April 12

Re: AVR Assembly Traffic Lights - help

Posted 11 May 2018 - 12:55 PM

These are a strong suggestion:

Quote

registers used:
r31 - millisecond count (lo byte)
r30 - millisecond count (hi byte)
r17 - 100 microsecond count
r16 - 1 microsecond count

Overall delay (ms) = r30:r31 * r17 * r16


microseconds delay uses the delay_1us-subroutine the given number of times (or a couple of times less depending on the call overhead).
It should be able to delay at least 100 us, so the 100 us delay can use it.
The millisecond delay then uses the 100us delay and so on.
It probably wouldn't hurt if the routines could delay longer than the required minimum.

The "Overall delay" is something I'm a bit confused - that can't be right?
Then again, it "kind of suggests" the same hierarchy of calls that I mentioned.
It would have made better sense if there was a 1us_delay, us_delay using register pair r16:r17 and
a millisecond delay using register pair r30:r31.

There is other strange things too, like:
"delay_1us%=:   nop                 ; replace nop with your code  \n"
"               sbiw r30,1          ; decrement ms count (r31:r30)\n"
"               brne delay_ms%=     ; loop to delay_ms while > 0  \n"
"               ret                 ; return from subroutine      \n"


It said earlier that r31:r30 were used for millisecond count, and then they seem to be used as us count.
In the traffic lights (led blinking) code the register pair is again used as millisecond count.

What's a "four phase traffic light"?

The code seems to be inline assembly within C (gcc?) telling by the "::: "r16", "r17", "r18", "r30", "r31"); // clobbered registers".

I don't think I can be of any more specific help, because I don't know the chip nor the clock frequency, and I don't have the instruction table available to me now either (to know how many cycles each instruction takes).

This post has been edited by turboscrew: 11 May 2018 - 01:17 PM

Was This Post Helpful? 0
  • +
  • -

#3 turboscrew   User is offline

  • D.I.C Lover
  • member icon

Reputation: 171
  • View blog
  • Posts: 1,107
  • Joined: 03-April 12

Re: AVR Assembly Traffic Lights - help

Posted 11 May 2018 - 01:28 PM

Aha, there you can see the cycles required by instructions: https://people.ece.c...VRinstr2002.PDF .
Was This Post Helpful? 0
  • +
  • -

#4 turboscrew   User is offline

  • D.I.C Lover
  • member icon

Reputation: 171
  • View blog
  • Posts: 1,107
  • Joined: 03-April 12

Re: AVR Assembly Traffic Lights - help

Posted 11 May 2018 - 01:34 PM

Note also, the more accurate you can make the shortest delays, the smaller the overall timing error.
Was This Post Helpful? 0
  • +
  • -

#5 turboscrew   User is offline

  • D.I.C Lover
  • member icon

Reputation: 171
  • View blog
  • Posts: 1,107
  • Joined: 03-April 12

Re: AVR Assembly Traffic Lights - help

Posted 11 May 2018 - 01:43 PM

Ah, only r26:r27, r28:r29 and r30:r31 can be used as register pairs in instructions.
(You can still use R16 and r17 as a register pair "manually".)
Was This Post Helpful? 0
  • +
  • -

#6 rhhh12   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 18
  • Joined: 02-April 18

Re: AVR Assembly Traffic Lights - help

Posted 12 May 2018 - 04:48 AM

Still quite confused by this all, what is it actually asking me to do?? What are the different registers doing
Was This Post Helpful? 0
  • +
  • -

#7 turboscrew   User is offline

  • D.I.C Lover
  • member icon

Reputation: 171
  • View blog
  • Posts: 1,107
  • Joined: 03-April 12

Re: AVR Assembly Traffic Lights - help

Posted 13 May 2018 - 01:10 AM

The registers aren't doing anything. The descriptions are trying to tell what you should use them for. ;-)

I'd go with the "registers used" description.

I made a little googling and came up with an explanation of the 4 phase traffic lights:
phase 1: red
phase 2: red & yellow
phase 3: green
phase 4: yellow
phase 1: red

That means: in one call (I think) it should:
- set LED1 ON and LED2 OFF
- delay for phase1
- set LED2 ON too
- delay for phase 2
- set LEDs 1 and 2 OFF and set LED3 ON
- delay for phase 3
- set LED2 ON and LED3 OFF
- delay for phase 4

It could also mean that it does one phase with each adjacent call, but I doubt it.
Given the timing restrictions, it may also be that one call is expected to loop forever.

For the timing you need to know how long is the processor cycle and how wide is the address (because devices with different address widths take different amount of cycles to execute some instructions).
That is: to calculate the timings you need to know the device and the clock frequency.

The idea (I think) with the timing is that you write 4 subroutines:
delay number of milliseconds (number given in register pair r30:r31) (here 1us error is 0.1%)
delay 100 us number of times (number given in r17). (here 1us error is 1%)
delay number of us (number given in r16) (accurate - maybe 98 calls to 1us delay + "adjustment" NOPs)
delay 1 us (as accurate as you can)

such that us delay calls 1us delay (about) the given number of times
100us delay calls the delay us routine 100 (about) times in a loop executed given times
ms delay calls the 100us delay 10 times in a loop that's executed given number of times

This post has been edited by turboscrew: 13 May 2018 - 01:35 AM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1