Este blog lo voy a dedicar a subir algunos códigos básicos de programación en distintos lenguajes. Creo que a veces es bueno tener una idea de como iniciar algo, a mi me sucedía, y me hubiera gustado encontrar algún código que me ayudara a ordenar mis ideas... Yo buscaba mucho algunos códigos y no los encontraba, casos como verilog, vhdl y codigos en ensamblador para micros de freescale en especifico los de la familia flexis. Así que aquí voy a ir dejando algunos codigos, espero ayudar a alguien a entender estos codigos. (Dejé de adentrarme en la programación de los microcontroladores, pero eso no implica que me hayan dejado de gustar. Voy a tratar de dejar entradas del avance que van teniendo y con ellos los gadgets que podremos ver.)

viernes, 25 de julio de 2014

14 nm y la Ley de Moore

Es impresionante como la tecnología avanza. Me gusta mucho los avances tecnológicos y lo que se puede lograr con ese tipo de avances, ahora que Intel anuncia su nueva hazaña de llegar a los 14 nanómetros en tecnología de fabricación de semiconductores, no cabe duda que ellos mismos han dejado atrás la Ley de Moore.

Pero ¿Que es todo eso de los 14nm y la ley de Moore?
 Empecemos por lo básico, las computadoras se basan esencialmente en transistores, un transistor colocado adecuadamente y haciendo equipo con otros transistores pueden lograr compuertas lógicas que van dando forma a un microcontrolador. Antes las computadoras necesitaban espacios grandes ya que los transistores eran grandes, con el tiempo ese espacio se ha ido reduciendo hasta poder llegar a tener una computadora en la palma de tu mano. Gordon Moore cofundador de Intel dijo en su momento que el espacio que necesitaban los transistores dentro de un chip se reduciría a la mitad cada 24 meses, fue algo disparatado en el momento que lo publicó, y si lo fue, se quedó corto, ya que la tecnología a avanzado mucho mas rápido.

Intel nos muestra su tecnología de 14nm es decir que ahora los transistores dentro de un chip son de ese tamaño !14 nanómetros! Un nanómetro es la milmillonésima parte de un metro, si nos ponemos a comparar podemos ver que la bacteria del cólera mide aproximadamente 1.5 micrómetros, es decir que los transistores que lanza Intel ahora son mil veces mas pequeños que esa bacteria.

A parte de lo sorprendente en tamaño, el rendimiento de los microcontroladores incrementa, son mas veloces, se calientan menos, consumen menos electricidad, baja el costo de producción, etc.
esto gracias a que los transistores pueden estar mas cerca el uno del otro y necesitan menos energía eléctrica para comunicarse.

Estoy en espera de ver que dispositivos usaran esta tecnología, supongo que Apple será de los primeros, cuando salgan escribiré mas a cerca de esto.

sábado, 15 de marzo de 2014

Arquitectura ARM

Hace mucho que dejé de estar involucrado con micro-controladores, desde la escuela no lo hacía, pero me sigue interesando mucho el código ensamblador de algunos micros. En esta entrada voy a dejar un código de un core ARM específicamente un cortex M0 de 32 bits, estos procesadores son de bajo consumo y es interesante como está estructurado su set de instrucciones. También voy a adjuntar el set de instrucciones y el manual de referencia por si a alguien le interesa.

Este código es muy sencillo, solo para mostrar como se activan los puertos y los módulos de este micro,
en este codigo se conecta un trimpot a un puerto del micro y con el ADC cambiamos el valor que se guarda en un registro especifico, valores desde 0000 a FFFF ya que el ADC es de 16 bits.

Nota: El compilador que usé fue CodeWarrior y no se puede debuggear a menos que esté conectado el micro.


/* This assembly file uses GNU syntax */
.text
.section .rodata
.align 2

.data 


.LC0:

.text
.align 2
.global main
.type main function

/*Etiquetas     */
 /*Con estas etiquetas ponemos las direcciones de memoria donde se encuentran los módulos requeridos */    /*En este caso tenemos que activar clocks del ADC y del puerto que vamos a conectar con el trimpot*/
 .set SIM_SCGC6, 0X4004803C
 .set SIM_SCGC5, 0x40048038
 .set ADC0_CFG1, 0x4003B008 
 .set ADC0_SC1A, 0x4003B000
 .set ADC0_RA, 0X4003B010

 .set SIM_SCG6_ENABLE, (1<<27)
 .set SIM_SCG5_ENABLE, (1<<13)
 .set ADC0_CFG1_MODE_16BITS, 0x0C
 .set ADCO_SC1A_ENABLE_A, 0X17 





main:
push {r3, lr} 
add r3, sp, #4

/*En esta sección activamos los clocks de los puertos y el ADC de acuerdo a los valores requeridos y que se encuentran marcados en el manual de referencia del micro. Pag 191 cap. 12*/

ldr r0,=SIM_SCGC6
ldr r1,=SIM_SCG6_ENABLE
str r1,[r0]

ldr r0,=SIM_SCGC5
ldr r1,=SIM_SCG5_ENABLE
str r1,[r0]

ldr r0,=ADC0_CFG1
ldr r1,=ADC0_CFG1_MODE_16BITS
str r1,[r0]

/*Iniciamos el loop infinito*/

Loop:
ldr r0,=ADC0_SC1A
ldr r1,=ADCO_SC1A_ENABLE_A
str r1,[r0]

/*Aquí hacemos que el ADC comience a leer los datos y esperamos la bandera de que ya leyó dato para mostrarlo en un registro especifico. Estos valores los podemos ver en la pag 457 cap. 28 del manual de referencia. */
ldr r0,=ADC0_SC1A
Wait:
ldr r2,[r0]
ldr r3,=(1<<7)
and r2,r3
cmp r2,#0
beq Wait 

ldr r0,=ADC0_RA
ldr r3,[r0]
b Loop    /*Aqui brincamos al loop infinito y hacemos lo mismo todo el tiempo*/

mov r3, #0
mov r0, r3
pop {r3, pc}

.align 2
.L3:
.word .LC0
.end

Aqui dejo el enlace para que puedan ver el Manual de referencia del micro
https://drive.google.com/file/d/0B8nrTf9p3apyczFxVS1udEZxQVk/edit?usp=sharing

miércoles, 21 de marzo de 2012

Escritura en lcd de 16x2 programa en ensamblador

/* Aquí dejo el código en ensamblador para el micro de freescale de la serie MM 256 **/
/**Prueben con distintos códigos de inicialización para la lcd, yo tuve ese problema, tuve que cambiar mas de tres ocasiones el código de inicializacion porque para cada lcd es diferente. Observen que estoy utilizando muchos registros para los datos, si pueden utilizar menos esta perfecto. Este código lo hice muy rápido y no me senté a optimizarlo, solo espere que prendiera la pantalla y entregue la practica. Observe que utilicé solamente cuatro bits del puerto en el micro para mandar los datos a la lcd, esto es importante por eso prendo y apago mas seguido el enable, si quieren para 8 bits es un poco mas sencillo, después subo el código para 8 bits.

He tardado en subir los códigos porque quiero subir todos los códigos comentados para que sepan a que se refiere cada linea, me parece importante eso para que puedan comprender el código a fondo.
     .extern   ___SP_INIT  
     .global _main
     .global _asm_startup
     .include "derivative.inc"
/*****************************************************************************/
/*  Variables Declaration */
/*****************************************************************************/
     .bss
   
/*****************************************************************************/
/*  Constants declaration */
/*****************************************************************************/
 .text
      config: .byte $36, $36, $36, $06, $06, $01
       msg1: .byte "hola"

     .align 4
/*****************************************************************************/
/*****************************************************************************/
/*  Start Up Code */
_asm_startup:
     /* disable interrupts */
     move.w  #$2700,SR
     /* setup the stack pointer */
     lea     ___SP_INIT,A7
     /* WDT Disable */
     move.b  #$23,d1
     move.b  d1,SOPT1
   
/*****************************************************************************/
/*****************************************************************************/
/*  Main Function */
/*****************************************************************************/
/*****************************************************************************/
_main:
      move.b #%11000000,d0
      move.b d0,PTCDD      //activando como salida pin 6 y 7 para enable y Rs respectivamente del puerto D
      move.b #%11110000,d1
      move.b d1, PTHDD     //activando como salida de los datos los primeros cuatro pines del puerto H
      move.b #0, d4


              /********************Aqui inicializamos la lcd**********************/


comando:
      move.b #$00,d0
      move.b d0,PTCD          // ponemos rs en 0 para comando
      move #config, A0        // A0 apunta a lo que esta en config
      move #6,d2              //ponemos 6 en d2 para utilizarlo como referencia del comando que hay en el main          
      bsr escribe_lcd         //  vamos a escribir el comando en la lcd

escribe_lcd:
   
      move.b (A0)+,d0         // lo que esta en A0 se mueve a d0
      move.b d0, PTHD         // despues al puerto de los pines de salida que van a mandar dato, los primeros cuatro bits

      move.b #%01000000,d1    //pasamos a registro lo que activa enable
      move.b d1,PTCD          // ACTIVAMOS ENABLE

   move.b #0, d4  
   bsr delay_20               // VAMOS AL DELAY DE 20ms
   
      move.b #000000,d3
      move.b d3,PTCD          // ponemos enable en 0
      lsl.l #4,d0             //rotamos para que llegue la segunda parte, pues usamos 4 bits
      move.b d0,PTHD          // mandamos los otros cuatro bits
      move.b d1, PTCD         // volvemos a activar enable

   move.b #0, d4
   bsr delay_20                //vamos a delay de 20ms

      move.b d3,PTCD           //ponemos enable  en 0          
      subi.l #1,d2             // le restamos uno a d2 para contar que ya ingresamos el primer comando
      cmpi.l #0,d2             // comparamos cero con d2 para ver si ya termino
      bne escribe_lcd          // si aun faltan comandos regresar a escribe_lcd

              /**************si es igual 0 con d2 brincamos a escribir datos, lo que queremos ver en la lcd ***/

dato:

      movea #msg1, A0          // A0 apunta a lo que esta en msg1 que es la palabra hola
      move.b #4,d2             // ponemos un 4 en d2

                               // pasamos a escribe_lcd1

escribe_lcd1:              
      move.b #%10000000,d0    
      move.b d0, PTCD          // ponemos rs en 1 porque estamos escribiendo datos y enable se mantiene en 0
      move.b (A0)+, d1         //movemos lo que esta en A0 a D1
      move.b d1, PTHD          // pasamos a los puertos la primer parte de la letra
      move.b #%11000000,d4
      move.b d4, PTCD          // activamos enable

   move.b #0, d4
   bsr delay_20                // vamos a dalay de 20ms

      move.b d0,PTCD           // dejamos rs en 1 y enable lo mandamos a 0
      lsl.l #4,d1              // rotamos pra poner la segunda parte de la letra
      move.b d1,PTHD           //mandamos la segunda parte de la letra al puerto de salida
      move.b d4, PTCD          // ponemos enable en 1
   
   move.b #0, d4
   bsr delay_20                // brincamos al delay de 20ms

      move.b d0,PTCD           //pasamos enable a 0 y rs se mantiene en 1
      subi.l #1,d2             // le restamos 1 a d2 para saber que ya pasamos la letra
      cmpi.l #0,d2             //comparamos 0 con d2 para ver si ya termino y si no termino regresamos a escribe_lcd1
      bne escribe_lcd1
  bra _main

          /********************************** Aqui va el delay *********************************/
      /***este delay es de 20 milisegundos, esta hecho para la lcd que yo necesite, dependiendo del delay que ustedes necesitan ajustan el numero de lineas de codigo, este micro hace una instruccion en un microsegundo es por eso que comparo el 6667 para que en tres lineas sean aprox 20 milisegundos**/                        
delay_20:
      addi.l #1,d4
      cmpi.l #6667,d4
       bne delay_20
   

rts

lunes, 20 de febrero de 2012

Codigo ensamblador para convertir de binario a bcd

/**** Aquí dejo esta parte de código, espero poder subir todo lo que haga  de ensamblador de freescale, me parecen buenas aportaciones porque no he encontrado mucho de esta arquitectura, espero les sirva******/
/*****************************************************************************/
     .extern   ___SP_INIT  
     .global _main
     .global _asm_startup
     .include "derivative.inc"
/*****************************************************************************/
/*  Declaracion de variables  */
/*****************************************************************************/
     .bss
   
Dato: .space 2
dm:   .space 1
m:   .space 1
c:   .space 1
d:   .space 1
u:   .space 1
/*****************************************************************************/
/*  Declaracion de constantes */
/*****************************************************************************/
 .text
     .align 4
/*****************************************************************************/
/*****************************************************************************/
/*  Start Up Code */
_asm_startup:
     /* disable interrupts */
     move.w  #$2700,SR
     /* setup the stack pointer */
     lea     ___SP_INIT,A7
     /* WDT Disable */
     move.b  #$23,d1
     move.b  d1,SOPT1
   
/*****************************************************************************/
/*****************************************************************************/
/*  Main Function */
/*****************************************************************************/
/*****************************************************************************/
_main:
     move.l    #65535,d0    // movemos el numero al registro d0
     move.w    d0,Dato      //movemos lo que hay en d0 a la variable Dato
   
     BSR       BinToBCD     //declaramos la subrutina bintobcd
   
     BRA       _main  
   
   
BinToBCD:                   //creamos la etiqueta BinToBcd
     move.l    #0,d0    //limpiamos el registro d0
     move.b    d0,dm        //movemos lo que hay en d0 a las demas variables para limpiarlas
     move.b    d0,m
     move.b    d0,c
     move.b    d0,d
     move.b    d0,u
   
     move.w    Dato,d0      // movemos lo que hay en Dato a d0 que es el 65535
     move.b    dm,d1        //movemos lo que hay en dm a d1 en este caso 0 para limpiar
DecMilLoop:                 //creamos la etiqueta DecMilLoop
     cmpi.l    #10000,d0    //comparamos si lo que hay en d0 es menor a 10000
     blo       Millar      // brincamos a millar si d0 ya es menor que 10000, si no, va a la siguiente linea
     subi.l    #10000,d0    // si no es menor le restamos 10000 a d0 es decir 65535-1000
     addi.l    #1,d1        // le sumamos 1 a d1, d1 se va a estar incrementando como un contador
     bra       DecMilLoop   //regresamos a la etiqueta DecMilLoop siempre que lleguemos hasta aqui.
   
Millar:    //creamos la etiqueta Millar
     move.b    d1,dm        // movemos lo que quedo en d1 a dm que eria en este caso 6
     move.b    m,d1    // ahora movemos lo que hay en m a d1 que es un 0 para limpiar
MilLoop:                    // Creamos la etiqueta MilLoop
     cmpi.l    #1000,d0     // Comparamos 1000 con lo que quedo en d0
     blo       Centena      // brincamos a Centena si d0 es menor que 1000
     subi.l    #1000,d0     // le restamos 1000 a d0 es decir 5535-1000
     addi.l    #1,d1        // aumentamos 1 a d1
     bra       MilLoop      // regresamos a la etiqueta MilLoop
   
Centena:                    // creamos la etiqueta Centena
     move.b    d1,m         // movemos lo que quedo en d1 a m en este caso es 5
     move.b    c,d1         // movemos el cero de c a d1 para limpiar
CenLoop:                    // creamos la etiqueta CenLoop
     cmpi.l    #100,d0      // comparamos 100 con lo que hay en d0 que es 535
     blo       Decena       // si d0 es menor que 100 brincamos a Decena
     subi.l    #100,d0      // le restamos a d0 100 es decir 535-100
     addi.l    #1,d1        // aumentamos 1 a d1
     bra       CenLoop      // regresamos a la etiqueta CenLoop
   
Decena:                     // Creamos la etiqueta Decena
     move.b    d1,c         // movemos lo que hay en d1 a c que seria en este caso 5
     move.b    d,d1         // movemos el 0 que hay en d a d1 para limpiar
DecLoop:                    // creamos la etiqueta DecLoop
     cmpi.l    #10,d0       // comparamos 10 con lo que hay en d0
     blo       Unidad       // si d0 es menor que 10 brincamos a unidad
     subi.l    #10,d0       // le restamos 10 a d0 es decir 35-10
     addi.l    #1,d1        // agregamos 1 a d1
     bra       DecLoop      // regresamos a la etiqueta DecLoop
   
Unidad:                     // Creamos la etiqueta Unidad
     move.b    d1,d         // movemos lo que hay en d1 a d que en este caso es 3
     move.b    d0,u         // finalmente lo que quedo en d0 que es un 5 se mueve a u
     RTS                    // retornamos a la subrutina