Anda di halaman 1dari 8

Gua de prctica

Que queremos hacer?


Vamos a hacer el Hello World del mundo de la electrnica que no es ms que prender y apagar un LED a intervalos regulares. PROYECTO LAPEGE

1 = Prende 0 = Apaga

Dispositivo

Como lo vamos a hacer?


Vamos a utilizar un microcontrolador como dispositivo y desarrollaremos un programa en assembler que cumpla con la lgica esperada. Debemos seleccionar: 1. Que microcontrolador vamos a usar 2. Que frecuencia de CPU va a tener 3. En que pata o pn estar conectado el Led 4. La frecuencia de encendido del led Utilizaremos el microcontrolador de ATMEL ATMega 328 por ser uno de los ms utilizados hoy en da. La frecuencia ser de 8 MHz elegiremos la salida en la pata 14 que corresponde al PUERTO B, particularmente el bit 0 (PB0) La frecuencia ser de 1Hz y debe estar 500ms encendido y 500ms Apagado

1. 2. 3. 4.

Y ahora?
Bueno lo primero que hay que hacer indefectiblemente es estudiar la arquitectura del dispositivo, a diferencia de la programacin clsica en PCs (comnmente arquitectura i386 o AMD64 FIJA) en la programacin de uC lo que cambia es justamente la arquitectura en funcin del dispositivo elegido, y el desarrollo del software tiene que machear perfectamente con ella. En este caso el dispositivo elegido es el ATMega328

Idealmente uno debe ir al datasheet http://www.atmel.com/devices/atmega328.aspx ah es donde estn todas las especificaciones del dispositivo, en mi experiencia personal eh perdido horas y horas buscando en internet como se configura tal o cual perifrico por miedo a leer el tenebroso datasheet , pero cuando lo lees te das cuenta que todo esta ah de la forma ms clara y sinttica que puede ser explicado. Aunque son 555 hojas para este dispositivo no hay que leerlo todo, sino solo lo que se necesita. Datasheet

A desarrollar!
Entorno de desarrollo de software: AVRStudio Project->New Project y seleccionar AVR ASEMBLER, poner el nombre de proyecto lape y en initial file poner main, luego en Location elegir la carpeta donde se crear el proyecto. NEXT-> Seleccionar AVR Simulator 2 en el lado izquierdo y ATmega328 en el derecho, en este punto estamos seleccionando el microcontrolador que vamos a utilizar (en este caso a simular). FINISH-> y listo ya tenemos nuestro proyecto creado. Que es lo primero que tenemos que incluir? (no vale mirar abajo) Si, el archivo que hace la redefinicin de nombre de los registros, podramos programar esto sbi 0x25, 2 Que funcionaria bien, pero claramente es mejor escribir la sentencia de la siguiente manera sbi PORTB,2 // set bit 2 in register 0x25 (que para el ATmega328 es el puerto B ) Esto permita que el cdigo sea mucho ms portable que el primer ejemplo. Por lo tanto incluyamos el archivo de definiciones. .include <m328def.inc> loop_for_ever: rjmp loop_for_ever

Una vez que agregamos esto vamos a ensamblar el cdigo

todo ok?

En este punto tenemos un programa que se puede bajar al micro (aunque como se ve no hace nada) si vamos a Project Patht/lape se puede ver los archivos generados. Abrir el .hex con el block de notas Continuemos ahora asignando algunos nombres a registros, que utilizaremos como variables, pero tiene que quedar bien en claro que no son variables sino registros de hardware, o sea que no estn en memoria RAM. Debajo de la asignacin de nombres agregamos el vector de interrupciones. Analizar la estructura y la secuencia de ejecucin.

.include <m328def.inc> .def Temp1 = r17 .def Temp2 = r18 .def Temp3 = r19 .def data .def byte = r20 = r21 = 0x00 ; = 0xFF ;

.equ INPUT .equ OUTPUT

.org 0x0000 rjmp RESET rjmp EXT_INT0 rjmp EXT_INT1 rjmp PC_INT0 rjmp PC_INT1 rjmp PC_INT2 rjmp WDT rjmp TIM2_COMPA rjmp TIM2_COMPB rjmp TIM2_OVF rjmp TIM1_CAPT rjmp TIM1_COMPA rjmp TIM1_COMPB rjmp TIM1_OVF rjmp TIM0_COMPA rjmp TIM0_COMPB rjmp TIM0_OVF rjmp SPI_STC rjmp USART_RXC rjmp USART_UDRE rjmp USART_TXC rjmp ADC_RDY rjmp EE_RDY rjmp ANA_COMP rjmp TWI rjmp SPM_RDY EXT_INT0: EXT_INT1: PC_INT0: PC_INT1: PC_INT2: WDT: TIM2_COMPA: TIM2_COMPB: TIM2_OVF:

; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;

Reset Handler IRQ0 Handler IRQ1 Handler PCINT0 Handler PCINT1 Handler PCINT2 Handler Watchdog Timer Handler Timer2 Compare A Handler Timer2 Compare B Handler Timer2 Overflow Handler Timer1 Capture Handler Timer1 Compare A Handler Timer1 Compare B Handler Timer1 Overflow Handler Timer0 Compare A Handler Timer0 Compare B Handler Timer0 Overflow Handler SPI Transfer Complete Handler USART, RX Complete Handler USART, UDR Empty Handler USART, TX Complete Handler ADC Conversion Complete Handler EEPROM Ready Handler Analog Comparator Handler 2-wire Serial Interface Handler Store Program Memory Ready Handler

TIM1_CAPT: TIM1_COMPA: TIM1_COMPB: TIM1_OVF: TIM0_COMPA: TIM0_COMPB: TIM0_OVF: SPI_STC: USART_RXC: USART_UDRE: USART_TXC: ADC_RDY: EE_RDY: ANA_COMP: TWI: SPM_RDY: reti loop_for_ever: rjmp loop_for_ever

Que falta?
Ahora agreguemos el siguiente fragmento de cdigo RESET: ldi out ldi out sei

r16, high(RAMEND); Main program start SPH,r16 ; Set Stack Pointer to top of RAM r16, low(RAMEND) SPL,r16 ; Enable interrupts

En este punto se setea donde comienza la pila de programa (STACK), y se habilitan las interrupciones. Hasta el momento tenemos lo que llamaramos un template de programa, ahora hay que escribir la lgica. Comenzaremos escribiendo las rutinas de retardo, como no estamos utilizando interrupciones ni timers la nica forma de crear un retardo es a travs de espera ocupada (Busy Wait) del CPU. Para esto hay que saber principalmente 2 cosas 1) Frecuencia de CPU 2) Tiempo que tardan en ejecutarse cada instruccin del set. La frecuencia la escogemos nosotros, por ejemplo 4MHz, y para los tiempos de instruccin podemos ir al datasheet ( Instruction Set Summary) y ver cuanto tarda cada instruccin involucrada en la rutina. Un ejemplo a continuacin.

Comenzaremos realizando un retardo de 5 ms ;-------------------------------------------------------------;Rutinas de Retardo de 5ms ;-------------------------------------------------------------; hacer un llamado tarda 5 ciclos delay5ms: ldi Temp1, 66 ;para 8mhz ; 1 ciclo LOOP0: ldi temp2, 200 ; 1 ciclo LOOP1: dec temp2 ; 1 ciclo brne LOOP1 ; 1 si es falso 2 si es verdadero dec Temp1 ; 1 brne LOOP0 ; 2 ret ;-------------------------------------------------------------Llamada 5 Ldi 1 1 LDI 2 1 dec 1 1 brne 1 2 dec 2 1 brne 2 2 ret 4 * * * * * * * * 1 1 66 200 200 66 66 1

Tiempo= (5+1+66+(200+400)*66+66+132+4)/8000000= 0,00498seg ~= 5ms De la misma manera procedemos para hacer un retardo de 0,5 seg utilizando la rutina anterior ;-------------------------------------------------------------;Rutinas de Retardo de 500ms ;-------------------------------------------------------------delay500ms: ldi temp3,100 ;para 8mhz LOOP500ms: call delay5ms dec temp3 brne LOOP500ms ret ;-------------------------------------------------------------Tambin podan utilizar la aplicacin AVRdelayloop.exe que les hace estos clculos automticamente ;) . Ahora hay que inicializar el puerto escogido como salida. y por ltimo PRENDER y APAGAR el LED

RESET: ldi out ldi out ldi out sei

Temp1, low(RAMEND) SPL, Temp1 Temp1, high(RAMEND) SPH, Temp1 temp1,0xFF DDRB,temp1

;******************************************** ; Bucle Principal ;******************************************** final: call delay500ms sbi PORTB,0 call delay500ms cbi PORTB,0 rjmp final

NOTA: Leer Newbies guide to AVR development.pdf

Como ltimo paso hay que debuggear, as que podemos hacerlo apretando movemos por el cdigo. si queremos algo ms pro Proteus!!!

con F11 nos

Anda mungkin juga menyukai