Help with creating music on arduino with Assembly language

I want to make music come out of a Buzzer that is connected to an arduino but i want to make it with assembly.
This is just for fun, but it's making me go crazy i can't figure out how to output a frequency for at least a second. I can make a frequency using this code:


ldi r16, 0                           ; reset system status
out SREG, r16                   ; init stack pointer
ldi r16, low(RAMEND)
out SPL, r16
ldi r16, high(RAMEND)
out SPH, r16

sbi DDRB, 5       ;pinMode(13, OUTPUT);

   sbi PORTB, PORTB5    ;turn LED_1 on
   rcall _delay1
   cbi PORTB, PORTB5    ;turn LED_1 off
   rcall _delay1
   rjmp _loop

_delay1:				;380Hz
   ldi r24, 0x00   
   ldi r23, 0x00
   ldi r22, 0x10            ;change this to make different frequencys
   sbci r24, 0
   sbci r23, 1 
   sbci r22, 0
   brcc _d1

but i this just makes it with giving it power and stoping it realy fast. And other codes like this dont work for some reason:
rjmp timer1

ldi r16, 0b00100000		;toggle PB5(D13)			
ldi r17, 0b00000000		;		
sbi DDRB, 5				;set PB5 OUTPUT			
out PORTB, r17			;PB5 = 0						
l1: rcall delay_timer1		;			
eor r17, r16			;r17 = r17 xor r16 			
out PORTB, r17			;set PB5 OUTPUT				
ldi r18, 61				;re-set loop counter				
rjmp l1					;					
delay_timer1:				;		
.equ value = 49911		;"49911" = 1sec(				
ldi r20, hi8(value)		;					
sts TCHT1H, r20			;				
ldi r20, lo8(value)		;							
sts TCNT1L, r20			;initialize counter TCNT1 = vreme								
ldi r20, 0b00000000		;											
sts TCCR1A, R20			;										
ldi r20, 0b00000101		;											
sts TCCR1B, r20			;normal mode, prescaler = 1024										
l2: in r20, TIFR1			;get TIFR1 byte & check										
sbrs r20, TOV1			;if TOV1=1, skip next instruction 										
rjmp l2					;else,loop back								
ldi r20, 1<<TOV1		;											
out TIFR1, r20 			;clear TOV1 flag										
ldi r20, 0b00000000		;											
sts TCCR1B, r20 		;stop timer											

Can someone help please

Your post was MOVED to its current location as it is more suitable.

Could you also take a few moments to Learn How To Use The Forum.

Other general help and troubleshooting advice can be found here.

It will help you get the best out of the forum in the future.

Looks like you spelled TCNT1H wrong.

You load 61 into r18 but never use it for anything?

You could check out for inspiration or guidance.

This is not my code i used it just to try and see if it worked i have no idea why they use r18 for.
And the spelling error is fixed but the result is the same, when i build this code it shows and error "syntax error, unexpected '(' " in this line:

 .equ value = 49911
 ldi r20, hi8(value)    ; its this line that shows the error
 sts  TCNT1H, r20
 ldi r20, lo8(value)    ; probably the same error will ocure

I think it show 1 error per build so i probably have the same for the same line belowe.

I just dont understand how the timers work

Thanks for the site it was a good read, but i already seen this one.

i did something like this decades ago on a KIM-1 using a 256 byte sinewave table to drive a dac connected to a speaker.

a song (score) table identified tones using fractional increments through the table for fixed periods of time. bear in mind all this was entered using a hex keypad. i believe the code i wrote did handle a limited number of tones per period.

in today's world, a script on the PC can generate the "score" downloaded to the Arduino to play, once the program were written

Did you read the processor data sheet?

Of course i did but it didnt help me one bit (see what i did there).
I solved the problem with the timer, i wrote "hi8" for high bit and "lo8" for low bit but the processor didnt understand that so i changed them to "high" and "low" and the timer worked (so stupid).
Why are there so many different versions of code for the stupid assembly language.

New question. The first time i wanted to put a timer to turn on and off an led on portb5 (digital 13 pin) realy fast so it gives a frequency and i can play a note. But with this i can play A note and just one note, i cant play 2 or 3 note continuesly it just goes through the code in a second and doesent sound like anything, and i know that i need periods for each note and all that, and i tried and it is a looong and cofusing code. So the question is can i just call a frequency and set a timer on it to act like periods and control the duration of how long the frequency is going to last.
I tried to find this first but no one has an answer for pure assembly everyone just uses C++ digital write command, i cant use that in assembly. So is there a way to call a frequency in pure assembly.

Im useing the atmega328p by the way.

Another way to gain an understanding is to look at the source code for some Timer library. But it's bad sign that you don't understand the data sheet. Nowhere else has so much effort been expended in detailing their operation. It has to be that way, in order for manufacturers to sell and support their products.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.