New to Assembly (ATMega32)

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

I have a project for ATMega32 with a button  and a LED; when i press the button the LED turns ON and if I press the button the second time the LED turns OFF.

So I have a few questions I didn't find the answers to,  what does the underlined bold lines mean, what are their purpose?

.include"m32def.inc"

.cseg

.org 0

Init:

LDI R10, 0b00000000

OUT DDRC, R10

LDI R10, 0b11111111

OUT PORTC, R10

LDI R10, 0b00000000

OUT DDRD, R10

LDI R10, 0b11111111

OUT PORTD, R10

LDI R10, 0b00000000

OUT DDRA, R10

LDI R10, 0b11111111

OUT PORTA, R10

LDI R10, 0b01000000

OUT DDRB, R10

LDI R10, 0b10111111

OUT PORTB, R10

MainLoop:

SBIS PINA,1

RJMP delay

NOP

RJMP MainLoop

ValidPress:

SBIS PINB, 6

RJMP LedOn

RJMP LedOff

LedOn:

SBI PORTB,6

RJMP ButtonOff

LedOff:

CBI PORTB,6

RJMP ButtonOff

ButtonOff:

SBIS PINA,1

RJMP ButtonOff

RJMP MainLoop

delay:

SBIC PINA,1

LDI R17, 0b11111111

DEC R17

CPI R17, 0b00000000

BREQ ValidPress

RJMP delay

This topic has a solution.
Last Edited: Thu. Jan 2, 2020 - 01:25 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Where do you find this code ?

It's not legal AVR code 

You Can't LDI on R10 !

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


rimreaper wrote:
questions I didn't find the answers to

Where did you look?

 

Go to the ATmega32 Product Page:

 

https://www.microchip.com/wwwproducts/en/ATmega32

 

Click 'View Datasheets', or just go to the 'Documents' tab

 

You will see the AVR Instruction Set manual at the bottom of the page:

 

http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-0856-AVR-Instruction-Set-Manual.pdf

 

It documents the instructions & their formats; eg,

 

 

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

from my university guide. From what i understood, you load the immediate "x" (constant) into the R10 register, but I did not understand what that long constant means. Why you say this is wrong? What would be the right way and what it means anyway? Thanks!

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

I specifically mentioned in my post what I did not find, you either read one more time or just ignore this post.

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

rimreaper wrote:
I specifically mentioned in my post what I did not find

I know - that's not what I asked you!

 

I asked where you had looked.

 

As I said, the AVR Instruction Set manual is the document which answers your question - as shown in the image posted.

 

So which part is unclear ?

 

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

As awneil pointed out, this is not valid AVR code as he explained. 

 

In terms of your question:

0b00000000 is a binary value of 8 bits. 

 

DEC R17 subtracts 1 from register 17.

 

Awneil gave you a reference to the AVR instruction set

 

rimreaper wrote:
I specifically mentioned in my post what I did not find, you either read one more time or just ignore this post.

 

That comment doesn't come across well.  You're not in a position to dictate.

 

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

read here & look at every link they show:   http://www.avr-asm-tutorial.net/avr_en/beginner/index.html

be sure to give your registers names, or you will rapidly  become confused & have all kinds of bugs.

this example does not much useful, just something to take a look at:

.def dog = r20
.def cat = r21
.def frog = r22

start:  ldi dog, 23
        ldi cat, 0xA7
        inc dog
        dec cat
        mov frog, dog
        add frog, cat
        cpi frog, 100
        brsh winner
        rjmp loser  ;note: could be rearranged to get rid of rjmp

winner: clr frog
        rjmp start

loser:  clr cat
        rjmp start
        

 

 

 

 

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

Last Edited: Wed. Jan 1, 2020 - 04:09 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I specifically mentioned in my post what I did not find, you either read one more time or just ignore this post.

But it explain/show why your code as I told you in #2 is illegal AVR code. (LDI only works on the high registers) 

 

So please answer where you got this code from !

 

for the rest :

0xnnnn  indicate a number in hex format (base 16)

0bnnnnnnnn indicate a binary number (base2)

 

and the DEC instruction  is the same as counter-- in C.  

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

I only changed R10 to R16, then I added comments

.include"m32def.inc"

.cseg
.org 0

Init:
; set all pins of C port as input
LDI R16, 0b00000000
OUT DDRC, R16
; enable pull-up resistors of C port pins
LDI R16, 0b11111111
OUT PORTC, R16

; set all pins of D port as input
LDI R16, 0b00000000
OUT DDRD, R16
; enable pull-up resistors of D port pins
LDI R16, 0b11111111
OUT PORTD, R16

; set all pins of A port as input
LDI R16, 0b00000000
OUT DDRA, R16
; enable pull-up resistors of A port pins
LDI R16, 0b11111111
OUT PORTA, R16

; set all pins of B port as input, except pin 6
LDI R16, 0b01000000
OUT DDRB, R16
; enable pull-up resistors of A port input pins
; and let output pin 6 be low
LDI R16, 0b10111111
OUT PORTB, R16

MainLoop:
; if pin 1 of A port is high (button open), do nothing (do MainLoop loop)
; otherwise, goto delay
SBIS PINA,1
RJMP delay 

NOP
RJMP MainLoop

;===

ValidPress:
; if pin 6 of B port is low (LED is off), goto LedOn
; otherwise, goto LedOff
SBIS PINB, 6
RJMP LedOn

RJMP LedOff

;===

LedOn:
; set pin 6 of port B (LED turns on)
SBI PORTB,6
RJMP ButtonOff

LedOff:
; clear pin 6 of port B (LED turns off)
CBI PORTB,6
RJMP ButtonOff

;===

ButtonOff:
; if pin 1 of A port is low (button not released), do ButtonOff loop
; otherwise ( button released), goto MainLoop
SBIS PINA,1
RJMP ButtonOff

RJMP MainLoop

;===

delay:
; if pin 1 of A port is low (shorted to ground), do delay loop
; otherwise, reset delay counter and do delay loop
SBIC PINA,1
LDI R17, 0b11111111

; decrement delay counter, if 0, goto ValidPress
; otherwise, do delay loop
DEC R17
CPI R17, 0b00000000
BREQ ValidPress

RJMP delay

 

hope it helps.

 

Kerim

 

Last Edited: Thu. Jan 2, 2020 - 02:40 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

KerimF wrote:

I only changed R10 to R16, then I added comments

.include"m32def.inc"

.cseg
.org 0

Init:
; set all pins of C port as input
LDI R16, 0b00000000
OUT DDRC, R16
; enable pull-up resistors of C port pins
LDI R16, 0b11111111
OUT PORTC, R16

; set all pins of D port as input
LDI R16, 0b00000000
OUT DDRD, R16
; enable pull-up resistors of D port pins
LDI R16, 0b11111111
OUT PORTD, R16

; set all pins of A port as input
LDI R16, 0b00000000
OUT DDRA, R16
; enable pull-up resistors of A port pins
LDI R16, 0b11111111
OUT PORTA, R16

; set all pins of B port as input, except pin 6
LDI R16, 0b01000000
OUT DDRB, R16
; enable pull-up resistors of A port input pins
; and let output pin 6 be low
LDI R16, 0b10111111
OUT PORTB, R16

MainLoop:
; if pin 1 of A port is high (button open), do nothing (do MainLoop loop)
; otherwise, goto delay
SBIS PINA,1
RJMP delay 

NOP
RJMP MainLoop

;===

ValidPress:
; if pin 6 of B port is low (LED is off), goto LedOn
; otherwise, goto LedOff
SBIS PINB, 6
RJMP LedOn

RJMP LedOff

;===

LedOn:
; set pin 6 of port B (LED turns on)
SBI PORTB,6
RJMP ButtonOff

LedOff:
; clear pin 6 of port B (LED turns off)
CBI PORTB,6
RJMP ButtonOff

;===

ButtonOff:
; if pin 1 of A port is low (button not released), do ButtonOff loop
; otherwise ( button released), goto MainLoop
SBIS PINA,1
RJMP ButtonOff

RJMP MainLoop

;===

delay:
; if pin 1 of A port is low (shorted to ground), do delay loop
; otherwise, reset delay counter and do delay loop
SBIC PINA,1
LDI R17, 0b11111111

; decrement delay counter, if 0, goto ValidPress
; otherwise, do delay loop
DEC R17
CPI R17, 0b00000000
BREQ ValidPress

RJMP delay

 

hope it helps.

 

Kerim

 

Doing the OPs homework does not help.
WTHE, Cuts down on the posts....

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

Last Edited: Thu. Jan 2, 2020 - 02:46 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sorry Jim... he has a lot to do afterwards...

If he doesn't read the datasheet after reading my comments (on HIS work) and compare them with what he will read on it... I am afraid he is not interested to learn in the first place.

I personally hated every teacher :) who kept telling me to find answers while he gave me anything to start with.

I mean giving just the answers doesn't mean giving the way how to find them... very big difference. At early age, learning means knowing how to get the given right answer.

Only later... it will be time to design and solve problems that no one has their answers yet :)

 

Kerim

 

 

 

Last Edited: Thu. Jan 2, 2020 - 03:08 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Fair enough Kerim smiley

 

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

You could be a good teacher Jim smiley

And as you said, it seems I exaggerated in adding comments to almost all his code lines.

 

Kerim

 

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

KerimF wrote:
learning means knowing how to get the given right answer.

Absolutely - which is why just spoon-feeding answers doesn't help much.

 

OP needs to learn how to use resources -  the Assembler manual is the key one here - to find answers ...

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

You have a good reasoning too, Awneil,

 

But in my case, most of my teachers in literature (Arabic, French and English), I had at school, thought as you do smiley I hardly passed their exams (besides getting sometimes a big zero as a grade) because I had no idea, most of the time, what each of them had in HIS mind as good answers to find and quote crying 

 

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

Thank you very much for the solution, it answered my questions. I don't think you exaggerated in adding comments to almost all code lines, even though it could've been enough to just explain the highlighted lines,but will be useful to future generations who will read this post;  I noticed you added port C and D which were originally in the source code and I omitted them because i thought they were useless, but I guess they're not and i have to research the datasheet about it.

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

The great thing about learning AVR at a university is that you not only study what to do right, but you also get to study everything that can possibly go wrong.  Which is what you get when someone gives you the "solution" to the homework project that you are assigned.  What appears to have happened here is that this assignment appears to have been used for years at the university.   But it was for a different microprocessor/microcontroller.   Probably the 8051-based family.  And somebody in the past took the code that worked for the 8051 and "adapted" it to the AVR, and gave you this "solution".   So now you have to do twice as much work: you have to debug the "solution" and you end up having to write your own AVR code after coming to realize that the "solution" can't possibly work correctly on the AVR.  The "solution" assumes that the opcodes worked the same between the 8051 and the AVR even though they had slightly different mnemonics.   A Load_Register is a Load_Register for every CPU, right?  

   Well, not exactly.  The 8051 was designed to be flexible, while the AVR was designed to be really fast; with every opcode/instruction be the same size and executing in the same amount of time, to the extent that it is possible.   The AVR instruction set has lots of exceptions and weird special cases not found in other CPUs that makes it go fast, compared to an 8051 from the 1980s.

   The first eight or so instructions set all the pins but one to be inputs, and then turns on the internal pull-up resistors.   Then comes the really dumb part:  the main loop does nothing but a delay (or jumps over that delay) and goes back to the start of the main code.   Do nothing, delay, then jump back and do nothing again.  Repeat forever.  It's the kind of thing that stands out once you actually read the code instead of simply loading it into the AVR and wondering why nothing seems to happening.  But, hey, it's at a university.

 

  The push-switch-LED assignment is pretty standard in all beginning microprocessors classes.  The solution is straightforward:

     - make a delay that is about 50 milliseconds long.  This means that it happens 20 times a second.  This is slightly faster than anyone can press a push-switch. After each delay, read the switch.

     - make a variable that holds the state of the push-switch from the last time that you read it.

     - If the new switch reading is the same as the previous switch reading, save the new reading in the variable, and leave

     - If the new reading is different,  save the new reading in the variable.  Then turn the LED off or on according to the new reading.

     Repeat forever

 

  Good luck in your engineering career.