aboutsummaryrefslogtreecommitdiffstats
path: root/web/avr-asm.html
diff options
context:
space:
mode:
Diffstat (limited to 'web/avr-asm.html')
-rw-r--r--web/avr-asm.html340
1 files changed, 340 insertions, 0 deletions
diff --git a/web/avr-asm.html b/web/avr-asm.html
new file mode 100644
index 0000000..04ca746
--- /dev/null
+++ b/web/avr-asm.html
@@ -0,0 +1,340 @@
+<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
+<html xmlns='http://www.w3.org/1999/xhtml' lang='es-MX,en'>
+<head>
+<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
+<meta content='initial-scale=1.0, maximum-scale=1.0, user-scalable=yes' name='viewport'/>
+<link rel='stylesheet' href='./static/estilo.css'>
+<title>🥭 &mdash; avr-asm</title>
+</head>
+<body>
+<header>
+<p><a href='./index.html'>{🥭}</a></p>
+<h1>avr-asm</h1>
+</header>
+<nav><ul><li><a href='#attiny85'>attiny85</a></li>
+<li><a href='#programas'>programas</a></li>
+
+</ul></nav>
+<main><section><p>
+explorando programación de microcontroladores avr a través de asm, en attiny85. <a href='./s-camino.html'>{s-camino}</a>
+</p>
+</section><section>
+<h1 id='attiny85'>attiny85</h1>
+<h2 id='diagrama de pines'>diagrama de pines</h2>
+<pre>
+ ┌──────┐
+PB5 │1 8│ VCC
+PB3 │2 7│ PB2
+PB4 │3 6│ PB1
+GND │4 5│ PB0
+ └──────┘
+</pre>
+<p>
+además, cada pin es:
+</p>
+<ul>
+<li>1: PB5 / PCINT5 / ~RESET / ADC0 / dW</li>
+<li>2: PB3 / PCINT3 / XTAL1 / CLKI / ~OC1B / ADC3</li>
+<li>3: PB4 / PCINT4 / XTAL2 / CLKO / OC1B / ADC2</li>
+<li>5: PB0 / MOSI / DI / SDA / AIN0 / OC0A / ~OC1A / AREF / PCINT0</li>
+<li>6: PB1 / MISO / DO / AIN1 / OC0B / OC1A / PCINT1</li>
+<li>7: PB2 / SCK / USCK / SCL / ADC1 / T0 / INT0 / PCINT2</li>
+</ul>
+<p>
+para flashear nos interesan los pines desde el punto de vista de SPI:
+</p>
+<pre>
+ ┌──────┐
+~RESET │1 8│ VCC
+ │2 7│ SCK
+ │3 6│ MISO
+GND │4 5│ MOSI
+ └──────┘
+</pre>
+<h2 id='programador'>programador</h2>
+<p><a href='https://www.fischl.de/usbasp/' rel=external target=_blank>USBasp - USB programmer for Atmel AVR controllers (web)</a></p>
+<h2 id='makefile'>makefile</h2>
+<p>
+para ensamblar y flashear
+</p>
+<pre>
+# Makefile
+# nombre del programa sin .S :
+PROG = test
+# config hardware
+BOARD = attiny85
+PROGRAMMER = usbasp
+
+# ensambla programa a .hex
+hex:
+ avr-gcc -Os -DF_CPU=8000000 -mmcu=$(BOARD) -c $(PROG).S
+ avr-ld -o $(PROG).elf $(PROG).o
+ avr-objcopy $(PROG).elf -O ihex $(PROG).hex
+ rm $(PROG).o $(PROG).elf
+
+# flashea
+flash:
+ avrdude -c $(PROGRAMMER) -p $(BOARD) -U flash:w:$(PROG).hex:i
+
+# lee la memoria flash a read.hex
+read:
+ avrdude -c $(PROGRAMMER) -p $(BOARD) -U flash:r:read.hex:i
+
+# prueba conexión con programador y micro
+test:
+ avrdude -c $(PROGRAMMER) -p $(BOARD)
+</pre>
+</section><section>
+<h1 id='programas'>programas</h1>
+<p>
+software experimental, compartido como referencia y sin garantía de ningún tipo :)
+</p>
+<h2 id='test.S'>test.S</h2>
+<p>
+enciende un el pin PB0 — conecta un led
+</p>
+<pre>
+; test.S
+; enciende un pin
+#include &lt;avr/io.h&gt;
+.org 0x0000
+
+ ldi r17, (1&lt;&lt;DDB0) ; configura al PB0 como salida
+ sts DDRB, r17
+
+ ldi r16, (1&lt;&lt;PB0) ; enciende el bit correspondiente al PB0
+ sts PORTB, r16 ; actualiza el puerto
+
+ sleep ; duerme por siempre (?)
+</pre>
+<h2 id='blink.S'>blink.S</h2>
+<p>
+parpadea el pin PB0 usando el timer/counter0 — conecta un led
+</p>
+<pre>
+; blink.S
+; parpadea el pin PB0 (OC0A)!
+; r16 y r17 se usan como registros auxiliares
+
+; el programa usa el timer/counter 0 con:
+; * waveform generation mode (WGM0): 2, que es CTC (clear timer on compare match)
+; * compare match output A mode (COM0A): 1, que es toggle en compare match
+; * clock select (CS0): 5, que utiliza el reloj i/o dividido entre 1024
+
+; notas sobre el reloj:
+; por default el attiny85 va a 8MHz, y el reloj i/o va a 1MHz
+; 1MHz/1024 ~= 967 Hz
+
+#include &lt;avr/io.h&gt;
+; ***********************
+; vectores de interrupts:
+; ***********************
+; Reset
+.org 0x0000
+ rjmp main
+
+; ***********************
+; Main
+; ***********************
+.org 0x0010
+main:
+ ; pin PB0 (OC0A) como pin de salida
+ ldi r16, (1&lt;&lt;DDB0) ; pin de salida
+ sts DDRB, r16
+
+ ; togglea OC0A en Compare match (1 en COM0A[1:0])
+ ; y usa modo Clear Timer on Compare Match (2 en WGM0[2:0])
+ ldi r16, (0&lt;&lt;COM0A1) | (1&lt;&lt;COM0A0) | (1&lt;&lt;WGM01) | (0&lt;&lt;WGM00)
+ sts TCCR0A, r16
+
+ ; completa el modo WGM (waveform generaton mode, bit 2)
+ ; establece el tipo de reloj: 0b101 en CS0 es clk/1024
+ ldi r16, (0&lt;&lt;WGM02) | (1&lt;&lt;CS02) | (0&lt;&lt;CS01) | (1&lt;&lt;CS00)
+ sts TCCR0B, r16
+
+ ; el TOP es el valor en OCR0A
+ ldi r16, 0x80
+ sts OCR0A, r16
+
+loop:
+ sleep
+ rjmp loop
+</pre>
+<h2 id='buzz.S'>buzz.S</h2>
+<p>
+zumba el pin PB0 — conecta un buzzer
+</p>
+<pre>
+; buzz.S
+; haz zumbar el pin PB0 (OC0A)!
+; el código es igual a blink.S, pero con diferentes frecuencias
+; r16 y r17 se usan como registros auxiliares
+
+; el programa usa el timer/counter 0 con:
+; * waveform generation mode (WGM0): 2, que es CTC (clear timer on compare match)
+; * compare match output A mode (COM0A): 1, que es toggle en compare match
+; * clock select (CS0): 4, que utiliza el reloj i/o dividido entre 256
+
+; notas sobre el reloj:
+; por default el attiny85 va a 8MHz, y el reloj i/o va a 1MHz
+; 1MHz/256 ~= 3906 Hz (/2 para el periodo completo ~=1953Hz)
+
+#include &lt;avr/io.h&gt;
+; ***********************
+; vectores de interrupts:
+; ***********************
+; Reset
+.org 0x0000
+ rjmp main
+
+; ***********************
+; Main
+; ***********************
+.org 0x0010
+main:
+ ; pin PB0 (OC0A) como pin de salida
+ ldi r16, (1&lt;&lt;DDB0) ; pin de salida
+ sts DDRB, r16
+
+ ; togglea OC0A en Compare match (1 en COM0A[1:0])
+ ; y usa modo Clear Timer on Compare Match (2 en WGM0[2:0])
+ ldi r16, (0&lt;&lt;COM0A1) | (1&lt;&lt;COM0A0) | (1&lt;&lt;WGM01) | (0&lt;&lt;WGM00)
+ sts TCCR0A, r16
+
+ ; completa el modo WGM (waveform generaton mode, bit 2)
+ ; establece el tipo de reloj: 0b100 en CS0 es clk/256
+ ldi r16, (0&lt;&lt;WGM02) | (1&lt;&lt;CS02) | (0&lt;&lt;CS01) | (0&lt;&lt;CS00)
+ sts TCCR0B, r16
+
+ ; el TOP es el valor en OCR0A
+ ldi r16, 0x02
+ sts OCR0A, r16
+
+loop:
+ sleep
+ rjmp loop
+</pre>
+<h2 id='alarm.S'>alarm.S</h2>
+<p>
+zumbido intermitente en el pin PB0 — conecta un buzzer
+</p>
+<pre>
+; alarm.S
+; zumbido intermitente en el pin PB0 (OC0A)!
+; r16 y r17 se usan como registros auxiliares
+; r20 tiene el valor de TCCR0A para apagar sonido
+; r21 tiene el valor de TCCR0A para encenderlo
+
+; el programa usa el timer/counter 0 con:
+; * waveform generation mode (WGM0): 2, que es CTC (clear timer on compare match)
+; * compare match output A mode (COM0A): 1, que es toggle en compare match
+; * clock select (CS0): 3, que utiliza el reloj i/o dividido entre 64
+
+; y el timer/counter 1 con:
+; * clock select (CS1): 0b1010, que es clk/512
+; * interrupciones de overflow y de compare match A:
+; - en compare match A el zumbido se apaga
+; - en overflow el zumbido inicia
+
+; notas sobre el reloj:
+; por default el attiny85 va a 8MHz, y el reloj i/o va a 1MHz
+; 1MHz/256 ~= 3906 Hz (/2 para el periodo completo ~=1953Hz)
+
+#include &lt;avr/io.h&gt;
+; ***********************
+; vectores de interrupts:
+; ***********************
+; Reset
+.org 0x0000
+ rjmp main
+
+; dirección 0x0003 * 2
+.org 0x0006
+ rjmp timer1compareA_isr
+
+; dirección 0x0004 * 2
+.org 0x0008
+ rjmp timer1overflow_isr
+
+; ***********************
+; Main
+; ***********************
+.org 0x001E
+main:
+ ;----------------------------------
+ ; configuración general
+ ;----------------------------------
+
+ ; habilita interrupciones
+ sei
+
+ ; pin PB0 (OC0A) como pin de salida
+ ldi r16, (1&lt;&lt;DDB0) ; pin de salida
+ sts DDRB, r16
+
+ ; valores de TCCR0A para encender o apagar sonido
+ ldi r20, (0&lt;&lt;COM0A1) | (0&lt;&lt;COM0A0) | (1&lt;&lt;WGM01) | (0&lt;&lt;WGM00)
+ ldi r21, (0&lt;&lt;COM0A1) | (1&lt;&lt;COM0A0) | (1&lt;&lt;WGM01) | (0&lt;&lt;WGM00)
+
+ ;----------------------------------
+ ; configuración TIMER0 para buzzer
+ ;----------------------------------
+ ; togglea OC0A en Compare match (1 en COM0A[1:0])
+ ; y usa modo Clear Timer on Compare Match (2 en WGM0[2:0])
+ sts TCCR0A, r21
+
+ ; completa el modo WGM (waveform generaton mode, bit 2)
+ ; establece el tipo de reloj: 0b011 en CS0 es clk/64
+ ldi r16, (0&lt;&lt;WGM02) | (0&lt;&lt;CS02) | (1&lt;&lt;CS01) | (1&lt;&lt;CS00)
+ sts TCCR0B, r16
+
+ ; el TOP es el valor en OCR0A
+ ; más pequeño es más agudo
+ ldi r16, 0x06
+ sts OCR0A, r16
+
+ ;----------------------------------
+ ; configuración TIMER1 para alternar entre sonido on/off
+ ;----------------------------------
+ ; CS1 en 0b1010 es CK/512
+ ldi r16, (1&lt;&lt;CS13) | (0&lt;&lt;CS12) | (1&lt;&lt;CS11) | (0&lt;&lt;CS10)
+ sts TCCR1, r16
+
+ ; establece el valor A al que cuenta el timer1 antes de apagar sonido
+ ; menor valor, menor tiempo de sonido (duty cycle)
+ ldi r16, 0x30
+ sts OCR1A, r16
+
+ ; set Timer overflow interrupt enable 1
+ ; y timer output compare A interrupt enable 1
+ ldi r16, (1&lt;&lt;TOIE1) | (1&lt;&lt;OCIE1A)
+ sts TIMSK, r16
+
+loop:
+ sleep
+ rjmp loop
+
+timer1compareA_isr:
+ ; apaga la salida
+ sts TCCR0A, r20
+ reti
+
+timer1overflow_isr:
+ ; enciende la salida
+ sts TCCR0A, r21
+ ; regresa de la interrupción
+ reti
+</pre>
+
+</section>
+</main>
+<footer>
+<p><a href='./index.html'>{🥭}</a></p>
+<p>página actualizada en:
+<time datetime='2021-05-20'>sejmana-1660, día 1</time>
+ (12021-05-20)
+</p>
+<a href='https://endefensadelsl.org/ppl_es.html' rel=external target=_blank>ppl: licencia de producción de pares</a></p>
+</footer>
+</body>
+</html>
Un proyecto texto-plano.xyz