diff options
author | sejo <sejo@texto-plano.xyz> | 2021-05-20 17:58:00 -0500 |
---|---|---|
committer | sejo <sejo@texto-plano.xyz> | 2021-05-20 17:58:00 -0500 |
commit | e2003fcc93d8cc25a85e55f12ef1044ca3a3bd1d (patch) | |
tree | 9ec6ec8f8626935e0667f389862687deddb948f6 /src/avr-asm.gmo | |
parent | 5ee0826789dfc0beb432b29104a16b0480884b99 (diff) | |
download | sitio-e2003fcc93d8cc25a85e55f12ef1044ca3a3bd1d.tar.gz |
acomodando sitio
Diffstat (limited to 'src/avr-asm.gmo')
-rw-r--r-- | src/avr-asm.gmo | 319 |
1 files changed, 319 insertions, 0 deletions
diff --git a/src/avr-asm.gmo b/src/avr-asm.gmo new file mode 100644 index 0000000..dbe5869 --- /dev/null +++ b/src/avr-asm.gmo @@ -0,0 +1,319 @@ +# avr-asm + +explorando programación de microcontroladores avr a través de asm, en attiny85. {s-camino} + +# attiny85 + +## diagrama de pines + +```diagrama de pines + ┌──────┐ +PB5 │1 8│ VCC +PB3 │2 7│ PB2 +PB4 │3 6│ PB1 +GND │4 5│ PB0 + └──────┘ +``` + +además, cada pin es: + +* 1: PB5 / PCINT5 / ~RESET / ADC0 / dW +* 2: PB3 / PCINT3 / XTAL1 / CLKI / ~OC1B / ADC3 +* 3: PB4 / PCINT4 / XTAL2 / CLKO / OC1B / ADC2 +* 5: PB0 / MOSI / DI / SDA / AIN0 / OC0A / ~OC1A / AREF / PCINT0 +* 6: PB1 / MISO / DO / AIN1 / OC0B / OC1A / PCINT1 +* 7: PB2 / SCK / USCK / SCL / ADC1 / T0 / INT0 / PCINT2 + +para flashear nos interesan los pines desde el punto de vista de SPI: + +```pines spi + ┌──────┐ +~RESET │1 8│ VCC + │2 7│ SCK + │3 6│ MISO +GND │4 5│ MOSI + └──────┘ +``` + +## programador + +=> https://www.fischl.de/usbasp/ USBasp - USB programmer for Atmel AVR controllers (web) + +## makefile + +para ensamblar y flashear + +```makefile +# 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) +``` + + + +# programas + +software experimental, compartido como referencia y sin garantía de ningún tipo :) + + +## test.S + +enciende un el pin PB0 — conecta un led + +``` +; test.S +; enciende un pin +#include <avr/io.h> +.org 0x0000 + + ldi r17, (1<<DDB0) ; configura al PB0 como salida + sts DDRB, r17 + + ldi r16, (1<<PB0) ; enciende el bit correspondiente al PB0 + sts PORTB, r16 ; actualiza el puerto + + sleep ; duerme por siempre (?) +``` + +## blink.S + +parpadea el pin PB0 usando el timer/counter0 — conecta un led + +``` +; 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 <avr/io.h> +; *********************** +; vectores de interrupts: +; *********************** +; Reset +.org 0x0000 + rjmp main + +; *********************** +; Main +; *********************** +.org 0x0010 +main: + ; pin PB0 (OC0A) como pin de salida + ldi r16, (1<<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<<COM0A1) | (1<<COM0A0) | (1<<WGM01) | (0<<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<<WGM02) | (1<<CS02) | (0<<CS01) | (1<<CS00) + sts TCCR0B, r16 + + ; el TOP es el valor en OCR0A + ldi r16, 0x80 + sts OCR0A, r16 + +loop: + sleep + rjmp loop +``` + +## buzz.S + +zumba el pin PB0 — conecta un buzzer + +``` +; 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 <avr/io.h> +; *********************** +; vectores de interrupts: +; *********************** +; Reset +.org 0x0000 + rjmp main + +; *********************** +; Main +; *********************** +.org 0x0010 +main: + ; pin PB0 (OC0A) como pin de salida + ldi r16, (1<<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<<COM0A1) | (1<<COM0A0) | (1<<WGM01) | (0<<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<<WGM02) | (1<<CS02) | (0<<CS01) | (0<<CS00) + sts TCCR0B, r16 + + ; el TOP es el valor en OCR0A + ldi r16, 0x02 + sts OCR0A, r16 + +loop: + sleep + rjmp loop +``` + +## alarm.S + +zumbido intermitente en el pin PB0 — conecta un buzzer + +``` +; 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 <avr/io.h> +; *********************** +; 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<<DDB0) ; pin de salida + sts DDRB, r16 + + ; valores de TCCR0A para encender o apagar sonido + ldi r20, (0<<COM0A1) | (0<<COM0A0) | (1<<WGM01) | (0<<WGM00) + ldi r21, (0<<COM0A1) | (1<<COM0A0) | (1<<WGM01) | (0<<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<<WGM02) | (0<<CS02) | (1<<CS01) | (1<<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<<CS13) | (0<<CS12) | (1<<CS11) | (0<<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<<TOIE1) | (1<<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 +``` |