Seven segment + Assembly issue Arduino Uno

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

Hi all,

The project is to make a seven segment display count from 9 to 0 repeatedly. I've got the counter going down, but I cannot get it to reset.

 

My idea to reset is to "jmp loop" when y is pointing to 0x00 and z is pointing to 0xFC. When I try to enter this in, the counter won't even count down anymore (if I wait a few seconds, the count down happens, but initially we start at some arbitrary value). Any hints in the right direction would be greatly appreciated!

 

delay0:
            nop
            dec r20
            brne delay0
            nop
            dec r19
            brne delay1
            dec r18
            brne delay2
            cpi r16, 0x00 ; compare r17 to 0x00
            brne next ; go to next if it is anything else
            cpi r17, 0xFC ; check if r17 is 0xFC
            brne next ; go to next if it is anything else. Worth mentioning 0xFC appears twice, but the first time it appears, r16 is 0x01.
            jmp loop ; if we get here, r16 is 0x00 and r17 is 0xFC. We need to reset

 

Here is my code that works for 1 count down:

#include "avr/io.h"

.data
digitB: .byte 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00
digitD: .byte 0x9C, 0xFC, 0x1C, 0xF4, 0xB6, 0x98, 0x3C, 0x6C, 0x18, 0xFC
;; Only allowed to use PINS 2-13 on the Arduino Uno board. Using PORTB/PORTD
.text
.global setup
.global loop

setup: ldi r16, 0b11111100 ; Set DDRB output as needed (all but PIN 0 and 1)
       out 0x0A, r16
       ldi r16, 0b00000011 ; Set DDRD output as needed (Only PIN 1 and 0)
       out 0x04, r16
       ret

loop:  ldi r28, lo8(digitB) ; point ot the first item in the array for PORTB
       ldi r29, hi8(digitB)
       ldi r30, lo8(digitD) ; point to the first item in the array for PORTD
       ldi r31, hi8(digitD)
next:  ld r16, y+ ; load PORTB item into reg and increment the pointer
       ld r17, z+ ; load PORTD item into reg and icnrement the pointer
       out 0x05, r16 ; set PORTB bits
       out 0x0B, r17 ; set PORTD bits
       jmp delay_sec ; wait a sec
nZero: jmp next ; go to next label nZero isn't used at the moment

delay_sec: 
            ldi r18, 100
delay2:
            ldi r19, 200
delay1: 
            ldi r20, 200
delay0:
            nop
            dec r20
            brne delay0
            nop
            dec r19
            brne delay1
            dec r18
            brne delay2
            jmp next

 

This topic has a solution.

;pls help

Last Edited: Wed. Mar 14, 2018 - 05:02 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why not simply run it in a simulator and watch what's happening ... ?

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Arduino ide doesn't have a simulation? Which would you suggest?

;pls help

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

Atmel Studio

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Edit: It appears it isn't the same kind of assembly? Not too sure, but it gave me a compilation error when I used ".byte".

;pls help

Last Edited: Wed. Mar 14, 2018 - 01:26 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You want the gcc assembler not avrasm.

I’d suggest you use another register as a loop counter. You can either load it with a value, decrement then test for 0 or load it with 0, increment it and compare with the end value.

You’ve included io.h , so you should be able to use the labels PORTB rather than the actual address.

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

Thanks for the reply! Ill try the other assembler

I added the counter using dec, but now my array starts at like digitB[-4] and digitD[-4]..Then counts to 5 and restarts lol
 

 

 

#include "avr/io.h"

.data
digitB: .byte 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00
digitD: .byte 0x9C, 0xFC, 0x1C, 0xF4, 0xB6, 0x98, 0x3C, 0x6C, 0x18, 0xFC
.text
.global setup
.global loop

setup: ldi r16, 0b11111100
       out 0x0A, r16
       ldi r16, 0b00000011
       out 0x04, r16
       ret

loop:
go:    ldi r28, lo8(digitB)
       ldi r29, hi8(digitB)
       ldi r30, lo8(digitD)
       ldi r31, hi8(digitD)
       ldi r21, 9

next:  ld r22, Y+
       ld r23, Z+
       out 0x05, r22
       out 0x0B, r23
       call delay_sec
       dec r21
       breq go
       jmp next

delay_sec: 
            ldi r18, 100
delay2:
            ldi r19, 200
delay1: 
            ldi r20, 200
delay0:
            nop
            dec r20
            brne delay0
            nop
            dec r19
            brne delay1
            dec r18
            brne delay2
            ret

 

;pls help

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

Your data table is in flash but you read from ram. Either copy your data table to ram or use lpm to read from flash. The AVR is Harvard achitecture so the code memory space is separate from the data memory space. Flash is code memory space, so you need to use lpm (load program memory) to read the flash.

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

Ahh I see. Thanks! This really helps. I think I'll have it done in a bit. I'll be back to mark this solved!

;pls help