Author Topic: Assembly Code not Working  (Read 9443 times)

eduardocl

  • Newbie
  • *
  • Posts: 5
Assembly Code not Working
« on: August 19, 2019, 11:10:37 am »
Hello,

I'm trying to learn the AVR assembly. I success with some code using the ATmega328p (arduino nano), but I tried out the code bellow and its not working:

.nolist
.include "tn85def.inc"
.list

rjmp main

main:
    ldi R16, 0b00000001  ; Pin 0 as output
    out DDRB, R16
    out PORTB, R16          ; write 1 on Pin 0
    rjmp loop

loop:
   rjmp loop


I don't what's wrong since the similar code in C works well blinking the LED on Pin 0. Can one help me?

Thanks,

granzeier

  • Jr. Member
  • **
  • Posts: 73
Re: Assembly Code not Working
« Reply #1 on: August 20, 2019, 03:06:31 am »
Hello,

I'm trying to learn the AVR assembly. I success with some code using the ATmega328p (arduino nano), but I tried out the code bellow and its not working:

.nolist
.include "tn85def.inc"
.list

rjmp main

main:
    ldi R16, 0b00000001  ; Pin 0 as output
    out DDRB, R16
    out PORTB, R16          ; write 1 on Pin 0
    rjmp loop

loop:
   rjmp loop


I don't what's wrong since the similar code in C works well blinking the LED on Pin 0. Can one help me?

Thanks,
1) Your initial rjmp is redundant (it is not needed) since the normal flow of the program will go to main: anyway.
2) You set up port B for output, and then write a 01H to port B to turn the LED on, but never write any thing to turn the LED off.
3) Immediately after turning the LED on, you jump to the end (at loop:,) where you have the program do an infinite loop doing nothing.
4) If you take care of #2), your LED will blink, but it will blink so fast that your eye cannot see it (the microcontroller works in microseconds (millionths of a second,) but your eye can only see tenths of seconds. (The human eye cannot see something happening faster than about 1/30th of a second.) So, you will need to put two delay loops inside the blinking loop - one after turning the LED on, and another after turning the LED off.
Code: [Select]
1 - Initialize the system
2 - Turn the LED on
3 - Delay for 1000 milliseconds (or whatever time you want)
4 - Turn the LED off
5 - Delay for 1000 milliseconds (or whatever time you want) again
6 - Loop back to #2
With the loop in #6 above, you will not need the stop loop as in your example, since the program will loop, flashing the LED, forever.

eduardocl

  • Newbie
  • *
  • Posts: 5
Re: Assembly Code not Working
« Reply #2 on: August 20, 2019, 04:22:28 am »

1 - Initialize the system
2 - Turn the LED on
3 - Delay for 1000 milliseconds (or whatever time you want)
4 - Turn the LED off
5 - Delay for 1000 milliseconds (or whatever time you want) again
6 - Loop back to #2



Thanks for the explanation,

I was porting the following code, running on ATmega, to attiny:

Code: [Select]
;hello.asm
;  turns on an LED which is connected to PB5 (digital out 13)

.include "m328Pdef.inc"

ldi r16,0b00100000
out DDRB,r16
out PortB,r16
Start:
rjmp Start

The delay mentioned is really necessary?  Can I just turn the LED on forever like the code above?



Thanks,
Eduardo.


granzeier

  • Jr. Member
  • **
  • Posts: 73
Re: Assembly Code not Working
« Reply #3 on: August 21, 2019, 04:37:24 am »
...
The delay mentioned is really necessary?  Can I just turn the LED on forever like the code above?
Yes, sorry, in your original post, you said (at the bottom):
Hello,

I'm trying to learn the AVR assembly. I success with some code using the ATmega328p (arduino nano), but I tried out the code bellow and its not working:
...
I don't what's wrong since the similar code in C works well blinking the LED on Pin 0. Can one help me?

Thanks,
As English is not your first language, you may not know that blinking means to turn the LED on, then off, then on and then off, repeating. For blinking, technically, you do not need to have timing routines, but then (as I mentioned earlier) your eye would not be able to tell that the LED was blinking. You would be able to "watch" the LED blinking with an oscilloscope, or some other test equipment, but not your eyes.
To just turn the LED on, and then leave it on, I did not see anything wrong with your original code. Both of your first two rjmp (relative jump) commands are unnecessary, since without a jump, the normal flow of the program will go to those referenced labels. The only jump that is needed is the final one, which changes the normal flow of the program to go back "up" to the loop: label. What is the LED doing, or not doing, that makes you say it is not working?
You said that the C program worked, but on a Nano... what happens when you compile and run the sample program on a Tiny85? Does that work in the smaller controller?
« Last Edit: August 21, 2019, 04:43:09 am by granzeier »

eduardocl

  • Newbie
  • *
  • Posts: 5
Re: Assembly Code not Working
« Reply #4 on: August 21, 2019, 06:14:20 am »
Hello,

yes, English is not my mother tongue, and I think few people here speak Portuguese :-)  Sorry for the confusion.

I read the datasheet, and I compared with some code for ATTiny13, very similar to ATTiny85. Indeed, I see nothing wrong with the code. Maybe the compilation and flashing the code could be the problem. I compile with avra:

avra ledon.asm

and upload the code with (I'm using the Digispark board):

~/.arduino15/packages/digistump/tools/micronucleus/2.0a4/launcher -cdigispark --timeout 60 -Uflash:w:ledon.hex:


In order run on nano, I just change the directive .include "tn85def.inc" to .include "m328def.inc" and do the same two commands above. The led is turn on as expected. The C code do the same in both platforms. So, I still not figure out what's going on.

 
Thanks for your help.

granzeier

  • Jr. Member
  • **
  • Posts: 73
Re: Assembly Code not Working
« Reply #5 on: August 21, 2019, 06:52:23 pm »
Hello,

yes, English is not my mother tongue, and I think few people here speak Portuguese :-)  Sorry for the confusion.
Yes, however your English is much better than my Portuguese. I suspect that if I tried to speak to you in Portuguese, you might wonder what in the world was wrong (mentally) with me. ;D I would need to study that language quite a bit before I could make sense. 

I read the datasheet, and I compared with some code for ATTiny13, very similar to ATTiny85. Indeed, I see nothing wrong with the code. Maybe the compilation and flashing the code could be the problem. I compile with avra:

avra ledon.asm

and upload the code with (I'm using the Digispark board):

~/.arduino15/packages/digistump/tools/micronucleus/2.0a4/launcher -cdigispark --timeout 60 -Uflash:w:ledon.hex:


In order run on nano, I just change the directive .include "tn85def.inc" to .include "m328def.inc" and do the same two commands above. The led is turn on as expected. The C code do the same in both platforms. So, I still not figure out what's going on.

 
Thanks for your help.
Ok, I installed the avra package for my distro (Linux Mint) and was able to compile your 328P example (by the way, thanks for the idea of using avra. I really enjoyed assembler as a kid, and it is fun to get back into it now.) I then changed the include to the tn85 definition. I also changed what was stored in R16 to 0B00000011 so that I could cover both types of Digispark (with the LED on P1 and the other with the LED on pin 0.) I was able to get the new hello-85.asm to compile. When I tried to download, I noticed that the Digispark does not use the standard AVRDude, but the modified Launcher (as you are showing in your posts.) I copied the .hex file to the Launcher directory because I was not able to get launcher to see the file when it was in my Engineering/projects/AVR Assembly folder but then was able to download it to my Digispark (which I verified by using the blink example from within the Arduino IDE.) The download completed successfully, because it overwrote the blink example, and the on-board LED quit blinking. So now I have a working toolchain for Digispark assembly (thanks again.)

The issue that I had was that the LED did not light, even though the assembler reported that assembly went well, and the downloader worked right. So, looking at the code, I changed it so that I loaded 0XFF into the DDR and Port - this should have turned on every bit of Port B. This still did not work.

Next I tried looking at the TN85 definitions - PortB is supposed to be at address: 0X18. The ATtiny85 datasheet confirms this, but I still could not get the LED to light. Since the datasheet shows that bit 6 and 7 of PortB are not used, I wrote 0x3F to both the DDR and Port registers, still no LED light up. I even tried writing 0X00 to the Port register, just in case I misread the schematic and/or the diode was turned backwards. Finally, since the example program in the datasheet showed using the C format of setting bits (1<<PB0) I used that to set bits 0 and 1; still no lit LED.

At this point, I went back to the Arduino IDE and loaded up the Digispark blink program and verified that my LED is connected to PB1. This verified, again, that my Digispark is working. So... back to troubleshooting.

Well, I'm not sure what is going on here. I guess that the next step is to follow the bits. There is a guy from Russia, who did an article on flashing an ATtiny with just pushbuttons and an LED. I will look into that tomorrow, and see if I can find out where the trouble is by following the bit-by-bit programming.

eduardocl

  • Newbie
  • *
  • Posts: 5
Re: Assembly Code not Working
« Reply #6 on: August 22, 2019, 04:30:39 am »
A good start for learning AVR assembly can be found here: https://www.instructables.com/id/Command-Line-AVR-Tutorials/

eduardocl

  • Newbie
  • *
  • Posts: 5
Re: Assembly Code not Working
« Reply #7 on: August 22, 2019, 07:34:38 am »
Well, I'm not sure what is going on here. I guess that the next step is to follow the bits. There is a guy from Russia, who did an article on flashing an ATtiny with just pushbuttons and an LED. I will look into that tomorrow, and see if I can find out where the trouble is by following the bit-by-bit programming.

Friend,

try that:


.nolist
.include "tn85def.inc"
.list


vectors:
    rjmp main  ;; reset vector
    rjmp main     ;; unused interrupt vectors
    rjmp main     ;;   perhaps needed by tiny85 bootloaders
    rjmp main
    rjmp main
    rjmp main
    rjmp main
    rjmp main
    rjmp main
    rjmp main
    rjmp main
    rjmp main
    rjmp main
    rjmp main
    rjmp main
    rjmp main
   
   
main:
    ldi     r16, 1 << PB0
    out     DDRB, r16
    out     PORTB, r16
loop:
    rjmp    loop
]

It worked for me.