CARRERA:
Ingenieria en Sistemas Computacionales V Semestre
MATERIA:
Arquitectura de Computadoras Unidad IV Microcontroladres
UNIDAD IV MICROCONTROLADORES
1.- QUE ES UN MICROCONTROLADOR? Es un circuito integrado programable, capaz de ejecutar las órdenes grabadas en su memoria. Está compuesto de varios v arios bloques funcionales, los cuales cumplen una tarea específica. Un microcontrolador incluye en su interior las tres unidades funcionales principales de una computadora: unidad central de procesamiento, memoria y periféricos de entrada y salida. EN ARQUITECTURA DE COMPUTADORAS: Básicamente existen dos arquitecturas de computadoras, y por supuesto, están presentes en el mundo de los l os microcontroladores: microcontroladores: Von Neumann y Harvard. Ambas se diferencian en la forma de conexión de la memoria al procesador y en l os buses que cada una necesita. La arquitectura Von Neumann es la que se utiliza en las computadoras personales, para ella existe una sola memoria, donde coexisten l as instrucciones instrucciones de programa y los datos, accedidos con un bus de dirección, uno de datos y uno de control. Debemos comprender que en una PC, cuando se carga c arga un programa en memoria, a éste se le l e asigna un espacio de direcciones de la l a memoria que se divide en segmentos, de los cuales cual es típicamente tenderemos los siguientes: código (programa), datos y pila. Es por ello que podemos hablar de la l a memoria como un todo, aunque existan distintos dispositivos físicos en el sistema (HDD, RAM, CD, FLASH). En el caso de los l os microcontroladores, microcontroladores, existen dos tipos de memoria bien definidas: memoria de datos (típicamente algún tipo de SRAM) y memoria de programas (ROM, PROM, EEPROM, flash u de otro tipo no volátil). En este caso la organización es distinta a las de las PC, porque hay circuitos distintos para cada memoria y normalmente no se utilizan los registros de segmentos, sino que la memoria está segregada y el acceso a cada tipo de memoria depende de las l as instrucciones del procesador. A pesar de que en los sistemas integrados con arquitectura Von Neumann la memoria esté segregada, y existan diferencias con respecto a la l a definición tradicional de esta arquitectura; los l os buses para acceder a ambos tipos de memoria son los mismos, del procesador solamente salen el bus de datos, el de direcciones, y el de control. Como conclusión, conclusión, la arquitectura no ha sido alterada, porque la forma en que se conecta la l a memoria al procesador sigue el mismo principio definido en la arquitectura básica. Esta arquitectura es la variante adecuada para las PC, porque permite ahorrar una buena cantidad de líneas lí neas de E/S, que son bastante costosas, sobre todo para aquellos sistemas como las PC, donde el procesador se monta en algún tipo
de zócalo alojado en una placa madre. También esta organización les ahorra a los diseñadores de motherboards una buena cantidad de problemas y reduce el costo de este tipo de sistemas. Algunas familias de microcontroladores como la INTEL-51 y l a Z80 implementan este tipo de arquitectura, fundamentalmente porque era la utilizada cuando aparecieron los primeros microcontroladores. La otra variante es la arquitectura Harvard, y por excelencia la utilizada en supercomputadoras, en los microcontroladores, y sistemas integrados en general. En este caso, además de la memoria, el procesador tiene los buses segregados, de modo que cada tipo de memoria tiene un bus de datos, uno de direcciones y uno de control. La ventaja fundamental de esta arquitectura es que permite adecuar el tamaño de los buses a las características de cada tipo de memoria; además, el procesador puede acceder a cada una de ellas de forma simultánea, lo que se traduce en un aumento significativo de la velocidad de procesamiento, típicamente los sistemas con esta arquitectura pueden ser dos veces más rápidos que sistemas similares con arquitectura Von Neumann. La desventaja está en que consume muchas líneas de E/S del procesador; por lo que en sistemas donde el procesador está ubicado en su propio encapsulado, solo se utiliza en supercomputadoras. Sin embargo, en los microcontroladores y otros sistemas integrados, donde usualmente la memoria de datos y programas comparten el mismo encapsulado que el procesador, este inconveniente deja de ser un problema serio y es por ello que encontramos la arquitectura Harvard en la mayoría de los microcontroladores. Por eso es importante recordar que un microcontrolador se puede configurar de diferentes maneras, siempre y cuando se respete el tamaño de memoria que este requiera para su correcto funcionamiento. 2.- DIFERENCIA ENTRE UN MICROCONTROLADOR Y UN MICROPROCESADOR: La configuración mínima básica de un Microprocesador esta constituida por un Micro de 40 Pines, Una memoria RAM de 28 Pines, una memoria ROM de 28 Pines y un decodificador de direcciones de 18 Pines. Microcontrolador incluye todo estos elementos del Microprocesador en un solo Circuito Integrado por lo que implica una gran ventaja en varios factores: En el circuito impreso por su amplia simplificación de circuitería. El costo para un sistema basado en Microcontrolador es mucho menor, mientras que para del Microprocesador, es muy alto en la actualidad. Los Microprocesadores tradicionales se basan en la arquitectura de Von Newmann, mientras que los microcontroladores trabajan con arquitectura de harvard. El tiempo de desarrollo de su proyecto electrónico es menor para los Microcontroladores.
Se puede observar en las gráficas # 2 y 6, que la principal diferencia entre ambos radica en la ubicación del registro de trabajo, que para los PIC·s se denomina W (Working Register), y para los tradicionales es el Acumulador (A). En los microcontroladores tradicionales todas las operaciones se realizan sobre el acumulador. La salida del acumulador esta conectada a una de l as entradas de la Unidad Aritmética y Lógica (ALU), y por lo tanto este es siempre uno de los dos operandos de cualquier instrucción, las instrucciones de simple operando (borrar, incrementar, decrementar, complementar), actúan sobre el acumulador. En los microcontroladores PIC, la salida de la ALU va al registro W y también a la memoria de datos, por lo tanto el resultado puede guardarse en cualquiera de los dos destinos. La gran ventaja de esta arquitectura(Microcontroladores ) es que permite un gran ahorro de instrucciones ya que el resultado de cualquier instrucción que opere con la memoria, ya sea de simple o doble operando, puede dejarse en la misma posición de memoria o en el registro W, según se seleccione con un bit de la misma instrucción . Las operaciones con constantes provenientes de la memoria de programa (literales) se realizan solo sobre el registro W. PROYECTOS DE APLICACIÓN EN MICROCONTROLADOR PIC Y MICROCONTROLADOR ATMEL ESQUEMA
El sensor más económico y que además no provoca falsas alarmas, es un simple interruptor magnético, el cual es un simple interruptor que es accionado por un imán. El más usual es el de superficie, en donde queda el dispositivo visible, delatando que disponemos de algún sistema de seguridad.
Para los que deseen mantener la alarma completamente camuflada pueden disponer el sensor de empotrar, el cual incluso resulta muy cómoda su colocación, ya que solo es necesario hacer un taladró para su instalación. Para controlar varios accesos solo es necesario conectar varios de estos interruptores magnéticos en serie, o incluso podemos realizar una protección mediante un fino hilo de cobre, el cual se rompa al forzar alguna puerta o ventana. También podemos utilizar como sonda un simple termostato, para avisarnos de exceso de temperatura, o bien para indicarnos que haya algún problema en una cámara de refrigeración. Interruptor magnetico de superficie
interruptor magnetico de empotar
Por si a alguien aun le queda alguna duda de la forma de conectar el circuito, en este diagrama se aprecia todo el conjunto.
Temporizador programable - interruptor cíclico con relé Este equipo produce una salida a rele ciclica y programable en 16 escalones mediante la actuacion de 4 microinterruptores. Las aplicaciones de este tipo de circuitos puede ser muy amplia: disparador automatico para realizar fotografias, actuador de electrovalvuilas de agua para el control de la humedad o refrescar el ambiente, control de circuitos de ozono para desconectarlos periodicamente, accionar bombas de agua durante un instante para evitar que estas se queden agarrotadas y terminen estropeandose, etc, etc. El circuito incorpora un led,el cual esta parpadeando cuando la salida esta inactiva, y prende fijo cuando la salida esta activada. Bajo demanda se pueden cambiar los tiempos de funcionamiento para que el circuito se adapte a cualquier aplicacion. Este circuito esta basado en un microcontrolador pic de tan solo 8 pines y bajo coste, el cual dispone de oscilador interno de 4Mhz, con el que podemos obtener tiempos muy precisos, con tan solo un error del 1%. Como se puede apreciar en el esquema el diseño queda muy reducido.
Prestar atencion al esquema ya que el rele es de 9v, ya que corresponde con la tension del transformador de 9v. Perfectamente se pueden sustituir el rele y transformador por 12v.
Disposicion de los componentes sobre la placa de circuito impreso.
En esta posición estan todos en ON(cero)
En esta posición todos en OFF (quince)
Hay que prestar atencion ala hora de realizar el PCB, ya que esta imagen esta vista desde la parte de los componentes.
MICROCONTROLADORES ATMEL INTRODUCCION El AVR fue diseñado para la ejecución de programas escritos en código C compilado. Por lo tanto, algunas instrucciones no están; por ejemplo, no existe la instrucción 'suma inmediata' ('add immediate'), ya que la instrucción 'resta inmediata' ('substract immediate') con el complemento a dos puede ser usada como alternativa. La familia de microcontroladores AVR es bastante extensa y todas comparten el mismo núcleo AVR, pero tienen distintos periféricos y cantidades de RAM y ROM: desde el microcontrolador de la familia Tiny AVR ATtiny11 con 1kB de memoria flash y sin RAM (sólo los 32 registros), con un encapsulado de 8 pines, hasta el microcontrolador de la familia Mega AVRATmega2560 con 256kB de memoria flash, 8kB de memoria RAM, 4kB de memoria EEPROM, conversor análogo digital de 10 bits y 16 canales, temporizadores, comparador analógico, etc. Cada componente de la familia se ha diseñado para que guarde cierta compatibilidad con el resto. Los microcontroladores AVR permiten la ejecución de instrucciones mediante la metodología 'pipeline' con dos etapas (cargar y ejecutar), que les permite ejecutar la mayoría de las instrucciones en un ciclo de reloj, lo que los hace relativamente rápidos entre los microcontroladores de 8 bits. Como una primera síntesis, podemos decir que el set de instrucciones de los AVR es bastante ´regularµ, teniendo en cuenta las siguientes consideraciones: Los registros punteros X, Y y Z tienen capacidades de direccionamiento diferentes entre sí. Los registros 0 al 15 tienen diferentes capacidades de direccionamiento que los registros 16 al 31. Las registros de I/O 0 al 31 tienen distintas características que las posiciones 32 al 63. La instrucción CLR afecta los 'flag', mientras que la instrucción SER no lo hace, a pesar de que parecen ser instrucciones complementarias (dejar todos los bits en 1, y dejar todos los bits en 0 respectivamente). Los códigos de operación 0x95C8 y 0x9004 hacen exactamente lo mismo (LPM).
Los Microcontroladores AVR La empresa Atmel ha desarrollado una gran cantidad de microcontroladores en diferentes gamas, de forma similar a lo que ha hecho la empresa Microchip con nuestros viejos amigos: ´los PICsµ. Quizá, el más popular es el ATMEL AT90S1200, que es algo así como el 16F84 de Microchip (en cuanto a popularidad se refiere). A continuación se realiza algunos datos comparativos entre el AT90S1200 y el PIC16F84: Nº de instrucciones: AVR - 89, PIC - 35 Registros RAM: AVR - 32, PIC - 68 Velocidad: AVR - 12MHz, PIC: 20MHz Memoria de Programa: AVR - 1kByte FLASH (512 líneas de programa, 16bits por inst.), PIC:1kx14 (1024 líneas de programa de 14 bit cada una). Memoria EEPROM libre: AVR - 64Bytes, PIC - 64Bytes Salidas: AVR - 15, PIC - 13 TIMER: AVR - 1 de 8bit (con prescaler desde CK hasta CK/1024), PIC - 1 de 8 bit (con prescaler desde 1:2 hasta 1:256) Comparador Analógico (NO ADC): AVR - 1 PIC - NO POSEE Watchdog: Ambos poseen Oscilador interno: Ambos poseen, en el AVR sólo habilitable con programación paralela Niveles de pila (STACK): AVR - 3, PIC - 8 Interrupciones: AVR - reset, interna, externa, timer y por comparador analógico, PIC 5 interrupciones Básicamente, los AVR tienen 3 registros para cada puerto de salida a saber: DDRB - Sirve para decir qué patas son de entrada o salida, ´0µ es entrada, ´1µ es salida (es inverso a los PIC). PINB - Registro que sirve para entradas solamente. PORTB - Registro que sirve para salidas solamente. Esto significa que para leer una entrada se debe usar el registro PINB mientras que para escribir datos en una salida se debe emplear el registro PORTB (obviamente si hacemos referencia a las patas del puerto B). En el ATMEL AT90S1200 el PortB tiene 8 bits de datos, a diferencia del PORTD que tiene sólo 7. El bit 7 del PORTD no se emplea; PORTD también consta de 3 registros: DDRD, PORTD y PIND. CARACTERISTICAS: Alto desempeño, baja potencia. Arquitectura RISC avanzada: -120 instrucciones poderosas, la mayoría con ejecución de un solo ciclo de reloj. -32x8 registros de trabajo de propósito general. -operación totalmente estática.
Programa y Memoria de Datos no volátiles: -2/4/8 kbytes de Memoria Flash Programable en el sistema, con duración: 10000 ciclos de escritura/borrado. -128/256/512 bytes de EEPROM programable en el sistema, con duración: 100000 ciclos de escritura/borrado. -128/256/512 bytes de SRAM interna. -Cerrojo de programación para autoprogramar la Memoria Flash y Seguridad de Datos de EEPROM.
CARACTERISTICAS PERIFERICAS -Contador/Temporizador de 8 bits con Prescaler y dos canales PWM. -Contador/Temporizador de Alta Velocidad de 8 bits con Prescaler separado: Dos Salidas PWM de Alta Frecuencia con Registros de Comparación de Salida separados. Generador Programable de Tiempo Muerto. -Interfaz Serie Universal con Detector de Condición de Comienzo. -ADC de 10 bits: Cuatro Canales de Una Sola Salida. Dos Pares de Canales ADC Diferenciales con Ganancia Programable (1x, 20x). -Temporizador Programable de Vigilancia con Oscilador separado dentro del integrado. -Comparador Analógico dentro del integrado. CARACTERISTICAS ESPECIALES DEL MICROCONTROLADOR -Sistema de Depuración debugWIRE dentro del integrado. -Programable dentro del Sistema a través del Puerto SPI. -Fuentes de Interrupción Externas e Internas. -Modos de Descanso en Baja Potencia, de Reducción de Ruido de ADC, y de Reducción de Potencia. -Circuito Mejorado de Reinicialización de Encendido. -Circuito Programable de Detección de Brown-out (estado en que la tensión es entre un 8 y un 12% inferior al valor típico) . -Oscilador Calibrado interno.
PROGRAMADOR DE E2PROM AT28C64B El programador de memoria EEPROM At28c64B es un simple programador, basado en un diseño conocido, utiliza un microcontrolador At89c51 puede ser también el AT89C52 es indiferente, el Cristal debe ser si o realizar la comunicación serial con la computadora.
DIAGRAMA DEL CIRCUITO El circuito que se ve a continuación puede ser modificado para otras memorias Atmel como se la at28c16, at28c128, etc. Todas estas memorias tienen el mismo tipo de programación pero distinta cantidad de memoria por lo que se debe solamente cambiar el bus de direcciones conectadndo 1 pin mas o retirando el mismo.
CODIGO FUENTE DEL PROGRAMA ;----------------------------------------------------------ban_rx BIT 0 RX EQU r3 tx EQU 22h ; aux EQU 23h n EQU 32h CE equ P3.7 OE equ P3.6 WE equ P3.5 datos equ P0 ;----------------------------------------------------------; V E C T OR E S D E I NT E R R U PC IO N ;----------------------------------------------------------ORG 0000H ; encendido o reset jmp reset ORG 0003H ; external interrupt 0 reti ; ORG 000BH ; timer 0 overflow vector reti ; ORG 0013H ; external interrupt 1 vector reti ; ORG 001BH ; timer 1 overflow vector reti ; ORG 0023H ; serial I/O interrupt vector jb TI,no_chksum mov RX,SBUF setb ban_rx ; se ha resibido clr RI no_chksum: reti ; ;----------------------------------------------------------; PROGRAMA PRINCIPAL ;----------------------------------------------------------ORG 050h reset: call serial_9600 ;9600 baudios mov clr
rx,#'n' ban_rx
call call call
conectar write read
; no hay RX 'n' ; no RX
case:
jmp case ;----------------------------------------------------------------; configurar el puerto serial ;----------------------------------------------------------------serial_9600: ; inicia el puerto serie ; parauso con un oscilador de 11.0592Mhz ; para 9600 baudios
MOV SCON,#050H ;RX habilitada SETB ES ;interrupcion serial SETB EA ;interrupcion global SETB PS ;prioridad puerto serie alta MOV TMOD,#20H ;TIMER 1 MODO AUTORECARGA MOV TH1,#0fDH ;CARGA PARA 9600 BAUDIOS SETB TR1 ;INICIO DEL TIMER 1 clr ri clr ti ret ;----------------------------------------------------------------; Conectar a la pc configurara tiempo de tx ;----------------------------------------------------------------conectar: cjne Rx,#'c',fin_conectar mov tx,#'c' call tx_ mov rx,#'n' fin_conectar: ret ;----------------------------------------------------------------; Gravar en la memoria EEPROM ;----------------------------------------------------------------write: cjne RX,#'w',fin_write call iniciar falta_write: call sidale mov a,rx call write_at28c64b ; B,C <-- write(A) inc r0 inc dptr mov a,r0 cjne a,n,falta_write mov tx,rx call tx_ mov rx,#'n' fin_write: ret ;----------------------------------------------------------------; iniciar las direcciones ;----------------------------------------------------------------iniciar: call sidale ; n <-- sidale(rx) mov n,rx call sidale mov dph,r call sidale mov dpl,rx call sidale mov a,rx mov r0,a ret ;----------------------------------------------------------------; Read = lectura de la memoria EEPROM ;-----------------------------------------------------------------
read: cjne RX,#'r',fin_read call iniciar mov tx,rx call tx_ falta_read: call rx_ mov a,rx acall read_at28c64b mov tx,a acall tx inc r0 inc dptr mov a,r0 cjne a,n,falta_read fin_read: ret ;----------------------------------------------------------------; <-- sidale(rx= #'s') ; se responde a la computadora que ella puede enviar otro dato ;----------------------------------------------------------------sidale: mov tx,rx call tx_rx ret ;----------------------------------------------------------------; TX_rx programa que transmite el dato de TX ; espera un tiempo "delay" para recibir en RX seteando la bandera de recepcion ;----------------------------------------------------------------tx_rx: acall tx_ ; lo transmito acall rx_ ; espero recibir el mismo ret ;---------------------------------------------------------TX_: clr ri clr ti mov sbuf,tx falta_tx: jnb TI,falta_tx clr TI ret ;---------------------------------------------------------RX_: clr ban_rx clr ri no_rx: nop jnb ban_rx,no_rx clr ban_rx ; espero otro dato ret ;---------------------------------------------------read_at28c64b: ; clr We ; setb Ce ; setb Oe
mov p1,dpl mov p2,dph mov P0,#0ffh clr Ce nop clr Oe nop setb We nop ; 1 us mov a,p0 ret ;---------------------------------------------------write_at28c64b: mov p0,a mov p1,dpl mov p2,dph setb Oe clr Ce setb We nop clr We nop setb We nop ; clr Oe ; nop ret end
PLACAS DEL CIRCUITO Circuito completo
Parte debajo de la placa (lado de la soldadura)
Parte de arriba de la placa(lado de los componentes y los puentes)
TERMOMETRO DIGITAL DS1620 CON ATMEL AT89Cxx Diagrama del circuito Este sensor de temperatura se lee serialmente a través de su bus I2C.
Código fuente del programa ; esta es la conexión de pines entre el ds1620 y el at89c52 displays equ p0 dq equ p3.2 clk equ p3.3 rst equ p3.4 t equ 3ah auxa equ 3bh n_hex equ 3ch nh equ 3dh signo equ 3eh ; - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - -- - - - ; reset ; vector de interrupcion del reset org 000h ; localidad de interrupcion reset ajmp start ; saltar a inicio ;---------------------------------------; interrupciones (no usadas) ; - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - -- - - - -
org 03h ; interrupcion externa 0 reti org 0bh ; interrupcion del timer 0 reti org 13h ; interupcion externa 1 reti org 1bh ; interrupcion del timer 1 reti org 23h ; interrupcion del puerto serial reti org 25h ; localidad donde se inicia el resto del programa ;---------------------------------------; inicio del programa principal ;---------------------------------------org 30h start: setb clk ; pone a 1 el ck del ds1620 acall configure ; configura el ds1620 acall delay ; esperar 10 ms para configuracion de escritura loop: acall start_convert ; inicia el comando de convercion de temperatura acall delay ; esperar 1 segundo acall read_temperature ; inicia la lectura de temperatura mov a,r1 ; primer byte leydo call a_dec ; convercion a decimal call mostrar_display ; mostrando en el display ajmp loop ;---------------------------------------; ESCRITURA EN EL DS1620 ; esta rutina escribe datos en el DS1620 ;---------------------------------------write1620: mov r0, #08h ; contador de bits nextbitwrite: clr clk rrc a mov dq, c setb clk djnz r0, nextbitwrite ret ;---------------------------------------; LECTURA DEL DS1620 ;---------------------------------------read1620: mov r0, #09h ; contador de lectura de datos del DS1620 setb dq nextbitread: clr clk mov c, dq setb clk rrc a djnz r0, nextbitread clr dq ret ;----------------------------------------
; CONFIGURACION DEL DS1620 ;---------------------------------------configure: setb rst mov a, #0ch acall write1620 mov a, #00001010b ; cpu = 1, 1shot = 0, thf = 0, tlf = 0 acall write1620 clr rst ret ;---------------------------------------; inicio de conversión ;---------------------------------------start_convert: setb rst mov a, #0eeh acall write1620 clr rst ret ;---------------------------------------; LECTURA DE TEMPERATURA ;---------------------------------------read_temperature: setb rst mov a, #0aah ; transmitir comando lectura acall write1620 acall read1620 ; leer primer byte mov r1, a ; guarda primer byte acall read1620 ; leer segundo byte mov r2, a ; guardar el segundo byte clr rst ; final de la transferencia ret ;--------------------------------------; convercion de hexadecimal a decimal ; ----------------------------------; la convercion es de un numero hexadecimal de 1 byte en el acumulador a ; a un numero de datos decimales de 2 bytes en el mismo a = low y b = high ;--------------------------------------a_dec: mov signo,#0 jnb acc.7,es_posi es_nega: mov signo,#0ffh mov auxa,a ; guardo el negativo setb c clr a subb a,auxa addc a,#0 ; ahora a es positivo es_posi: mov n_hex,a mov a,#99h mov auxa,a mov b,#0ffh mov nh,#0ffh ; nl es el resultado high lazo:
mov a,auxa add a,#1 da a jnc salto inc nh
; incrementando el nhigh
salto: inc b mov auxa,a mov a,b cjne a,n_hex,lazo mov b,nh ; detectando el signo mov a,signo cjne a,#0ffh,sin_signo con_signo: mov a,b ; agregando el signo negativo orl a,#040h mov b,a sin_signo: mov a,auxa ret ;---------------------------------------; mostrar el display ;---------------------------------------mostrar_display: mov auxa,a anl a,#0fh call buscar_numero ; encuentra el numero del display en aca mov displays,a clr p2.3 acall delay setb p2.3 mov a,auxa swap a anl a,#0fh call buscar_numero ; encuentra el numero del display en aca mov displays,a clr p2.2 acall delay setb p2.2 mov a,b ; la parte alta del decimal mov auxa,a anl a,#0fh call buscar_numero ; encuentra el numero del display en ac a mov displays,a clr p2.1 acall delay setb p2.1 mov a,b ; en la parte alta de b esta el signo anl a,#0f0h mov displays,a clr p2.0 acall delay setb p2.0 ret ;------------------------------------------
; busca numero (retardo) ;-----------------------------------------buscar_numero: mov dptr,#tabla_display movc a,@a+dptr ret ;-----------------------------------------; d e l a y (retardo) ;-----------------------------------------delay: mov t,#0ffh buc: nop djnz t,buc ret ;-----------------------------------------; tabla del display ; ; esta es la secuencia de datos que genera los ; numeros para catodo comun ;-----------------------------------------tabla_display: ; 0 1 2 3 4 5 6 7 8 9 db 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh end