Hola gente en este post les voy a enseñar a programar microcontroladores pic, los de la marca microchip. (de una forma básica)
Para programar vamos a necesitar básicamente 3 programas:
-Picsim (el que compila el código y nos sirve para simularpaso a paso)
-Proteus (es un programa para diseño y simulación decircuitos que nos permite importar un archibo de assembler y probarlo)
-El software del grabador (este viene con tu grabador quecompres o fabriques)
NOTA: se puede escribir el programa en texto plano en dondequeramos, pero se necsita transformarlo en un archivo .hex
Además se recomienda un mínimo conocimiento de electrónica ylenguaje digital, para este último pueden pasarse por mi post sobre lógica yoperadores binarios que subiré en breve.
Estos microcontroladores son muy útiles en muchos tipos de aplicaciones, son baratos, fáciles de programar, y tienen un muy gran potencial.
Hay una enorme variedad de microcontroladores y cada uno tiene sus respectivas hojas de datos o datasheet con sus instrucciones especiales y características, yo me voy a centrar en los más fáciles los de la línea 16f84, son extremadamente básicos, cuentas con dos puertos de “8bit” pero en realidad su puerto “A” tiene menos (5bit) ya que los otros se utilizan para cristal de resonancia y masterclear o reset a esto le sumamos las dos patas de alimentación y tenemos un pequeño integrado de 18patitas.
Primero y principal tendremos que aprender a “decirle” EXACTAMENTE que es lo que tienen que hacer para que cumpla la función que queremos, esto suena simple pero es lo mas difícil ya que muchas cosas las damos por sentadas y nop, no es asi.
Imaginemos que tratamos con alguien increíblemente idiota que solamente puede seguir al pie de la letra lo que decimos, sin razonar nada, solo haciéndolo, si queremos pedirle que abra una ventana no le podemos decir abrí la ventana, tendíamos que decirle:
Camina 3 pasos a la derecha
Gira a la izquierda
Camina hasta la pared
Fíjate como esta la ventana
Estaba abierta?; entonces no hagas nada volvete y quédate ahí hasta que te diga
Estaba cerrada?; entonces pone la mano en la traba
Destraba la ventana
Abri la ventana
ahora volvete y quédate ahí hasta que te diga
Ven que no es tan fácil?, eso es exactamente lo que tenemos que hacer para decirle “que hacer” a cualquier computadora o microcontrolador (es como una compu chiquita)
Para empezar a pensar como computadora tenemos que aprender a hacer un diagrama de flujo.
Para empezar a pensar como computadora tenemos que aprender a hacer un diagrama de flujo.
Diagramas de flujo:
Un diagrama de flujo es una serie de como paradas en las que pensamos ¿qué es lo que queremos hacer?, uno para un microcontrolador es bastante simple ya que sus funciones son muy básicas, para el ejemplo anterior seria:
Como verán, tiene una serie de “símbolos” que son los que se suelen usar para simbolizar gráficamente un tipo de acción, diferenciando decisión de procesos de acciones (estos últimos dos no es necesario diferenciarlos)
Como verán, tiene una serie de “símbolos” que son los que se suelen usar para simbolizar gráficamente un tipo de acción, diferenciando decisión de procesos de acciones (estos últimos dos no es necesario diferenciarlos)
Un poco de conocimientos técnicos básicos:
Tiempos:
Tiempos:
Estos microcontroladores funcionan por ciclos de clock, esto es que tenemos un cristal resonando y con cada ciclo se efectua una acción dentro del microcontrolador; la mayoría de las acciones requieren uno o dos cilcos de controlador, pero a su vez un ciclo de microcontrolador son 4 ciclos de clock por la forma de procesamiento de datos que tiene adentro.
Asi que tendremos:
Siendo u el tiempo de ejecución de una acción, mas fácil, si nuestro cristal es de 4MHz, cada acción consumiría 1useg (microsegundo)
También tenemos que la frecuencia de procesamiento es aproximadamente un cuarto de la frecuencia de clock.
IMPORTANTE recordar que las acciones que demanden “saltos de línea” consumen 2 cilcos de procesamiento.
Asi que tendremos:
Siendo u el tiempo de ejecución de una acción, mas fácil, si nuestro cristal es de 4MHz, cada acción consumiría 1useg (microsegundo)
También tenemos que la frecuencia de procesamiento es aproximadamente un cuarto de la frecuencia de clock.
IMPORTANTE recordar que las acciones que demanden “saltos de línea” consumen 2 cilcos de procesamiento.
Corrientes y tensiones:
-No hay mucho que decir de corrientes, la corriente de entrada es casi nula y la de salida minima, por eso siempre es conveniente controlar de forma indirecta con el micro (por medio de una etapa de potencia)
-El microcontrolador es muy muy muy quisquilloso con la tension de alimentación, trabaja con 5V +-0.3V NI MAS NI MENOS, si le ponemos mas se quema, si le ponemos menos no anda,
por eso se alimenta convenientemente con un regulador de tension y algunas etapas de filtrado (se suele usar el regulador 7805 con su ciruito de aplicación típico) por esta misma razón también conviene censar de manera indirecta mediante una etapa de entrada que baje y regule las tenciones y en la medida de lo posible que minimice los ruidos eléctricos a la entrada.
-El microcontrolador es muy muy muy quisquilloso con la tension de alimentación, trabaja con 5V +-0.3V NI MAS NI MENOS, si le ponemos mas se quema, si le ponemos menos no anda,
por eso se alimenta convenientemente con un regulador de tension y algunas etapas de filtrado (se suele usar el regulador 7805 con su ciruito de aplicación típico) por esta misma razón también conviene censar de manera indirecta mediante una etapa de entrada que baje y regule las tenciones y en la medida de lo posible que minimice los ruidos eléctricos a la entrada.
Flags y STATUS:
El pic se maneja por direcciones de memoria en exadecimal, pero algunas muy importantes tienen nombres llamados etiquetas, la mas importante es el byte STATUS, en este byte tenemos toda la información importante sobre el microcontrolador
Siendo sus bits mas importantes:
STATUS,Z : este bit nos indica si el rejistro W esta en 0 00000000 (zero)
status,5 : cuando este bit este en “alto” (1) estaremos trabajando en la configuración del
microcontrolador y cuando este en “bajo” (0) estaremos trabajando de forma normal
Cuando estemos programando el puerto que pongamos en alto será una entrada y el que pongamos en bajo una salida (imput, output) (si, todas las instrucciones estan en ingles)
Portb: es el puerto B
Porta: es el puerto A
W : es el rejistro w, es como la ram del micro, aca le ponemos la información a la ALU (unidad argmetico lógica) y aca nos tira la información (este no es un byte partido en varios bit, este es todo el byte + un bit de carry out)
INTCON: es el rejistro de configuración para las interrupciones
Existen otros, pero es mas avanzado, capas los dejo para una segunda parte
status,5 : cuando este bit este en “alto” (1) estaremos trabajando en la configuración del
microcontrolador y cuando este en “bajo” (0) estaremos trabajando de forma normal
Cuando estemos programando el puerto que pongamos en alto será una entrada y el que pongamos en bajo una salida (imput, output) (si, todas las instrucciones estan en ingles)
Portb: es el puerto B
Porta: es el puerto A
W : es el rejistro w, es como la ram del micro, aca le ponemos la información a la ALU (unidad argmetico lógica) y aca nos tira la información (este no es un byte partido en varios bit, este es todo el byte + un bit de carry out)
INTCON: es el rejistro de configuración para las interrupciones
Existen otros, pero es mas avanzado, capas los dejo para una segunda parte
COMO CARAJO PROGRAMAR?
Bueno, nosotros programando con pic solamente vamos a poder:
Sumar números binarios
Saber si un bit, y que quede claro BIT esta en uno o en 0
Eso es todo.
Bueno, capas fui muy pesimista, pero eso es lo único que hace un microcontrolador
Se puede sumar, rebalastar un numero (contar mas de lo que se pueda contar), “restar números” (es sumarlos rebalsando) y cotejar y forzar bits y bytes de una forma medio molesta, también podremos desplazar posiciones, pero todos son casos particulares de las otras dos acciones.
Para poder pensar de esta forma tenemos que aprender una nueva matemática WIIIII
Na, mentira, es la misma pero en otra base, el problema es que las propiedades son diferentes, este tipo de algebra binario se basa en el algebra de Boole.
(Podran ver más de lenguaje y operaciones binarias en mi post sobre lenguaje y operaciones)
Trabajaremos con una base binaria, osea todo o nada 1 o 0
Y se suma o resta en binario; para que se entienda aca pongo una tabla de conversión de los números binarios del 0 al 15 (esto no es lineal)
Nbits ( 43 2 1 0)
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
10 1010
11 1011
12 1100
13 1101
14 1110
15 1111
(notse que voy sumando de a una unidad en los dos)
El numero en decimal ENTERO que representa un numero binario ENTERO se puede conseguir elevando 2(la base) a la potencia que sea su peso ósea que
1010
Tiene
2^3+2^1=10, osea ( 8 + 2)
Para sumar se suma usando la casita como en la primaria, pero recordando que ahora llegamos hasta 1 y ese es nuesto máximo (como el 9 en decimal)
En la electrónica un bit es cada uno de los lugarcitos y un byte es un paquete con 8 lugares para 8 bits numerados según su peso.
Y se suma o resta en binario; para que se entienda aca pongo una tabla de conversión de los números binarios del 0 al 15 (esto no es lineal)
Nbits ( 43 2 1 0)
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
10 1010
11 1011
12 1100
13 1101
14 1110
15 1111
(notse que voy sumando de a una unidad en los dos)
El numero en decimal ENTERO que representa un numero binario ENTERO se puede conseguir elevando 2(la base) a la potencia que sea su peso ósea que
1010
Tiene
2^3+2^1=10, osea ( 8 + 2)
Para sumar se suma usando la casita como en la primaria, pero recordando que ahora llegamos hasta 1 y ese es nuesto máximo (como el 9 en decimal)
En la electrónica un bit es cada uno de los lugarcitos y un byte es un paquete con 8 lugares para 8 bits numerados según su peso.
UN POCO DE INFORMACION SOBRE LAS FUNCIONES:
El listado básico de funciones es el siguiente:
(enrealidad son todas las funciones)
Sin mas vueltas vamos a programar:
(un comentario es un renglón que tienen un ; (cuando ve eso el compilador le deja de dar pelota a esa línea)
Vamos a prender una patita:
El diagrama de flujo seria el siguiente:
Y se escribe de la siguiente manera:
org 0 ;inicio del programa
bsf status,5 ;entro en el modo de configuracion
clrf portb ;”limpio” (pongo en 0) el puerto B ENTERO
clrf porta
bcf status,5 ;salgo del modo de configuración
inicio ;esto es un nombre que nos sirve para decirle a donde “saltar”
bsf portb,0 ;pongo en 1 el bit 0 del puerto b
goto inicio ;”salto” a inicio
end ;termina el programa
org 0 ;inicio del programa
bsf status,5 ;entro en el modo de configuracion
clrf portb ;”limpio” (pongo en 0) el puerto B ENTERO
clrf porta
bsf portb,0 ;configuro el bit 0 del puerto b como salida
bcf status,5 ;salgo del modo de configuración
inicio
btfss portb,1 ;pregunto por el estado del bit 1 del puerto b (salto si ES 1)
goto inicio
bsf portb,0
encender
btfss portb,2 ;pregunto por el estado de bit 2
goto encender
bcf portb,0 ;apago la luz
goto inicio
end
DEMORAS:
Vamos a prender una patita:
El diagrama de flujo seria el siguiente:
Y se escribe de la siguiente manera:
org 0 ;inicio del programa
bsf status,5 ;entro en el modo de configuracion
clrf portb ;”limpio” (pongo en 0) el puerto B ENTERO
clrf porta
bcf status,5 ;salgo del modo de configuración
inicio ;esto es un nombre que nos sirve para decirle a donde “saltar”
bsf portb,0 ;pongo en 1 el bit 0 del puerto b
goto inicio ;”salto” a inicio
end ;termina el programa
si corremos este programa en el picsim veremos como en el sexto ciclo se enciende la patita 0 del puerto b y permanece asi (lo mismo en el proteus, pero seria instantáneo)
bueno, este programa de mucho no sirvió, para eso la conecto y ya… AAAA pero si te digo que ahora vas a poder hacer que se prenda cuando apretes un botón y que se apague cuando se apreté otro? Mas jugoso no?
Tendríamos que plantear algo de la siguiente forma:
bueno, este programa de mucho no sirvió, para eso la conecto y ya… AAAA pero si te digo que ahora vas a poder hacer que se prenda cuando apretes un botón y que se apague cuando se apreté otro? Mas jugoso no?
Tendríamos que plantear algo de la siguiente forma:
org 0 ;inicio del programa
bsf status,5 ;entro en el modo de configuracion
clrf portb ;”limpio” (pongo en 0) el puerto B ENTERO
clrf porta
bsf portb,0 ;configuro el bit 0 del puerto b como salida
bcf status,5 ;salgo del modo de configuración
inicio
btfss portb,1 ;pregunto por el estado del bit 1 del puerto b (salto si ES 1)
goto inicio
bsf portb,0
encender
btfss portb,2 ;pregunto por el estado de bit 2
goto encender
bcf portb,0 ;apago la luz
goto inicio
end
y ahora muajajajaj puedo prender y apagar a gusto y piachere una luz, soy re malote
y ahí me vas a decir que eso no te impreciona? No? Bueno, vamos a hacer que la prenda después de 0,2 segundos de apretado el botón, cosa que paresca re down
pero como verga hago para esperar 0,2 segundos si me dijiste que va a las chapas esto?
Bueno, con maña, esto se llama demora
y ahí me vas a decir que eso no te impreciona? No? Bueno, vamos a hacer que la prenda después de 0,2 segundos de apretado el botón, cosa que paresca re down
pero como verga hago para esperar 0,2 segundos si me dijiste que va a las chapas esto?
Bueno, con maña, esto se llama demora
DEMORAS:
Una demora es en escencia hacer que el micro pierda tiempo haciendo cosas inutieles
Esto se puede lograr poniendo 200000 nop en el código para que pierda 200000 us y asi demore 0,2seg o de la forma en la que se hace (no es posible escribir tantas líneas de comando, llenas la memoria)
Se gace haciendo que el micro repita 200000 la misma operación con un progama mas complejo
Para esto vamos a precisar byts para contar, cuantos? Depende de cuanta demora queres
La estructura básica de demora es la siguiente:
Esto se puede lograr poniendo 200000 nop en el código para que pierda 200000 us y asi demore 0,2seg o de la forma en la que se hace (no es posible escribir tantas líneas de comando, llenas la memoria)
Se gace haciendo que el micro repita 200000 la misma operación con un progama mas complejo
Para esto vamos a precisar byts para contar, cuantos? Depende de cuanta demora queres
La estructura básica de demora es la siguiente:
movlw b’11111111’
movwf h’1e’ ;pongo en 255 la dirección 1e en exadecimal
cont
nop ;1us
decfsz h’1e’,f ;1us
goto cont ;2us
goto prog
prog (el programa)
que lo que hace eso?, eso repite ese nop 255 veces que es la cantidad de vueltas que va a pegar para llevar hasta 0 el byte
osea uqe la demora total seria 255x(1us+1us+2us)+2us, osea 1022us que aun no son los que yo quería mmmmm como hago entonces? Lo multiplico
osea uqe la demora total seria 255x(1us+1us+2us)+2us, osea 1022us que aun no son los que yo quería mmmmm como hago entonces? Lo multiplico
movlw b’11111111’
movwf h’1f’
mult
movlw b’11111111’;1us
movwf h’1e’;pongo en 255 la dirección 1e en exadecimal (1us)
cont
nop;1us
decfsz h’1e’,f;1us (resto 1 y salto cuando llego a cero)
goto cont;2us
decfsz h’1f’,f;1us
goto mult;2us
goto prog
prog (el programa)
ahora nuestra demora seria de:
255x(255x(1us+1us+2us)+1us+1us+2us)+2us = 261122 us, masomenos 0,26 segundos, y asi se puede ir refinando la demora para lograr mejores aproccimaciones (yo no tengo ganas) pero se puede partir de otro numero para contar, en ves de contar 255 veces, se puede contar 2 o 3 o 174 veces y asi vamos “multiplicando” el tiempo, este algoritmo también aplica para miltiplicar
Y como lo que uso esto?
Bueno, el programa quedaría asi:
255x(255x(1us+1us+2us)+1us+1us+2us)+2us = 261122 us, masomenos 0,26 segundos, y asi se puede ir refinando la demora para lograr mejores aproccimaciones (yo no tengo ganas) pero se puede partir de otro numero para contar, en ves de contar 255 veces, se puede contar 2 o 3 o 174 veces y asi vamos “multiplicando” el tiempo, este algoritmo también aplica para miltiplicar
Y como lo que uso esto?
Bueno, el programa quedaría asi:
org 0;inicio del programa
bsf status,5 ;entro en el modo de configuracion
clrf portb;”limpio” (pongo en 0) el puerto B ENTERO
clrf porta
bsf portb,0;configuro el bit 0 del puerto b como salida
bcf status,5;salgo del modo de configuración
inicio
btfss portb,1 ;pregunto por el estado del bit 1 del puerto b (salto si ES 1)
goto inicio
;--------------------------------------------------- aca puse la demora
movlw b’11111111’
movwf h’1f’
mult
movlw b’11111111’;1us
movwf h’1e’;pongo en 255 la dirección 1e en exadecimal (1us)
cont
nop;1us
decfsz h’1e’,f;1us (resto 1 y salto cuando llego a cero)
goto cont;2us
decfsz h’1f’,f;1us
goto mult;2us
;---------------------------------------------------
bsf portb,0
encender
btfss portb,2;pregunto por el estado de bit 2
goto encender
bcf portb,0;apago la luz
goto inicio
end
(nota, no recomiendo probar con el picsim un programa con la demora completa porque el picsim anda mas lento que el micro, asi que lo que nosotros hagamos para que el micro tarde 1/4seg al programa le tomaría como 10 minutos, por eso conviene poner “menos demora” cuando probemos el programa en la compu)
Ahora tu micro parece retrasado, pero solamente se puede prender y apagar una luz?
Mmmmmmm si queres podemos hacer que camine como la viborita del snake, te va?
Ahora tu micro parece retrasado, pero solamente se puede prender y apagar una luz?
Mmmmmmm si queres podemos hacer que camine como la viborita del snake, te va?
Para eso podemos usar dos métodos:
Método de tablas:
El método de tablas consiste en generar como una “tabla” dentro del programa, esto se hace escribiendo las líneas de comando de una forma mas entrecruzada y teniendo en cuenta los REGISTROS especiales del micro, (por esto amo assembler, con alto nivel esto no lo podes hacer), el micro guarda el renglón del programa en el que esta en un registro llamado PCL, entonces que hacemos? Haremos lo siguiente:
Cargamos en w o de preferencia en una dirección el renglón de nuestra tabla al que queramos ir.
Le sumamos con addwf ese renlon al PCL y lo guardamos en el pcl (addwf PCL,f) y esto funcionara como un “goto largo” que harqa que nuestro programa “salte” a la línea que queremos,
así la tabla seria
Cargamos en w o de preferencia en una dirección el renglón de nuestra tabla al que queramos ir.
Le sumamos con addwf ese renlon al PCL y lo guardamos en el pcl (addwf PCL,f) y esto funcionara como un “goto largo” que harqa que nuestro programa “salte” a la línea que queremos,
así la tabla seria
Tabla
Movfw h’2b’
Addwf PCL,f
Goto instruccion1
Goto instruccion2
Goto instruccion3
… etc
Instruccion1
Lo que queremos que haga
Goto prog
Instruccion2
Lo que queremos que haga
Goto prog
Movfw h’2b’
Addwf PCL,f
Goto instruccion1
Goto instruccion2
Goto instruccion3
… etc
Instruccion1
Lo que queremos que haga
Goto prog
Instruccion2
Lo que queremos que haga
Goto prog
(Obviamente este método es más útil para casos en los que hay que hacer algo más importante que rotar un led y se suele usar en combinación con el método de las subrutinas que explicare más adelante)
Método de rotación:
Método de rotación:
Este es el método usado para rotar posiciones de bits dentro de los bytes y nadamas se necesita usar la función rrf o rlf (rotar a la derecha o la izquierda una fila)
Solamente tendremos que aplicar la función de la librería siendo nuestro programa muy muy simple asi que solamente hare el diagrama de flujo:
Que lindo, ya se hacer muchas cosas inútiles. Pero mi programa es una cosa horriblemente larga y enquilombada, no se puede optimizar mas el espacio y los algoritmos?
Si, si se puede, se puede usar algo llamado subrutinas
SUBRUTINAS:
Una subrutina es como un “programa dentro del programa”, esto nos permite no solo programar de una manera mas prolija y compacta, sino usar esquemas recursivos o implementar algoritmos que serian demasiado complejos sin esta herramienta
Trabaja “saltando” de la linia en la que la llamamos a la parte donde esta escrita la subrutina, pero guardando en un rejstro especial la línea del progama en donde se encrontraba cuando fue llamada, la instrucción para su invocación es call nombre y la instrucción para volver es return, re fáciles no?
Esto tiene una limitación, si bien se pueden llamar subrutinas anidadas el espacio para almacenar la dirección a la cual volver es limitado (no me acuerdo si 6 u 8 llamados) asi que si “anidamos” mas de esa cantidad limite de llamados explota todo a la goma.
Una de sus aplicaciones mas útiles es en combinación con las tablas, y asi podremos tomar los datos de la tabla “llamándola”
Nuestro anterior ejemplo quedaría de la siguiente manera:
Trabaja “saltando” de la linia en la que la llamamos a la parte donde esta escrita la subrutina, pero guardando en un rejstro especial la línea del progama en donde se encrontraba cuando fue llamada, la instrucción para su invocación es call nombre y la instrucción para volver es return, re fáciles no?
Esto tiene una limitación, si bien se pueden llamar subrutinas anidadas el espacio para almacenar la dirección a la cual volver es limitado (no me acuerdo si 6 u 8 llamados) asi que si “anidamos” mas de esa cantidad limite de llamados explota todo a la goma.
Una de sus aplicaciones mas útiles es en combinación con las tablas, y asi podremos tomar los datos de la tabla “llamándola”
Nuestro anterior ejemplo quedaría de la siguiente manera:
org 0
bsf status,5
clrf portb
clrf porta
bcf status,5
inicio
bsf portb,0 ;inicio prendiendo este led
rotacion
call demora;llamo a la demora
rrf portb,f;roto el puerto (mievo el led)
goto rotacion;repito
end
;----------------------- aca escrivo la demora como sub rutina
demora
movlw d'98';cargo 98 para que me de una demora de 0,1seg
movwf h'1c'
mult
movlw d'255'
movwf h'1d'
cont
nop;1us
decfsz h'1d',f;1us (resto 1 y salto cuando llego a cero)
goto cont;2us
decfsz h'1c',f;1us
goto mult;2us
return;cuando termino la subrutina regreso
bsf status,5
clrf portb
clrf porta
bcf status,5
inicio
bsf portb,0 ;inicio prendiendo este led
rotacion
call demora;llamo a la demora
rrf portb,f;roto el puerto (mievo el led)
goto rotacion;repito
end
;----------------------- aca escrivo la demora como sub rutina
demora
movlw d'98';cargo 98 para que me de una demora de 0,1seg
movwf h'1c'
mult
movlw d'255'
movwf h'1d'
cont
nop;1us
decfsz h'1d',f;1us (resto 1 y salto cuando llego a cero)
goto cont;2us
decfsz h'1c',f;1us
goto mult;2us
return;cuando termino la subrutina regreso
(notese que si se compila habría un momento en que el bit pasa por el carri, el cual no es una de las patitas del puerto b, entonces no lo veremos)
Todo muy lindo, ya tenemos una luz que gira como idiota sola, ahora hagamos que rota cada vez que yo presiono el botón, esto se haría preguntando por el boton cada vez que queramos mover la luz, de la siguiente manera:
Todo muy lindo, ya tenemos una luz que gira como idiota sola, ahora hagamos que rota cada vez que yo presiono el botón, esto se haría preguntando por el boton cada vez que queramos mover la luz, de la siguiente manera:
inicio
bsf portb,0 ;inicio prendiendo este led
rotacion
btfss porta,0;esta prendido?
goto rotacion;si no pregunto de vuelta
rrf portb,f;si si roto el puerto (mievo el led)
goto rotacion;repito
bsf portb,0 ;inicio prendiendo este led
rotacion
btfss porta,0;esta prendido?
goto rotacion;si no pregunto de vuelta
rrf portb,f;si si roto el puerto (mievo el led)
goto rotacion;repito
nosotros copilamos esto, lo ponemos en el simulador y anda re piola, lo ponemos en e isis y se prenden todas la luces a la ves -_- por que? Porque estamos preguntando “sin retención”
RETENCIONES:
La retención nos sirve para evitar que nuestro programa repita acciones porque somos muy lentos para levantar el garfio antes de que de un ciclo el programa, esto se arregla muy simple: preguntando si ya lo soltamos, quedaría asi:
inicio
bsf portb,0 ;inicio prendiendo este led
rotacion
btfss porta,0;esta prendido?
goto rotacion;si no pregunto de vuelta
rrf portb,f;si si roto el puerto (mievo el led)
no
btfsc porta,0;ya se apago? (btfsc: salta cuando este limpio)
goto no
goto rotacion;repito
bsf portb,0 ;inicio prendiendo este led
rotacion
btfss porta,0;esta prendido?
goto rotacion;si no pregunto de vuelta
rrf portb,f;si si roto el puerto (mievo el led)
no
btfsc porta,0;ya se apago? (btfsc: salta cuando este limpio)
goto no
goto rotacion;repito
PERFECTO!!!! Ahora hace lo que quiero!!!! WIIIIII
Voy a hacerlo en la vida real para presumirle a todos que puedo mover un led
Momento, en la vida real no anda!!!!, sip lo que verían es que al igual que cuando no tenia la retención se prenden todos los leds (al menos por un tiempo), esto se debe a los ruidos, los cuales si pueden aparecer y desaparecer en u segundos
Yyyyyyy como zafo esto????
Primero, en la placa se colocan filtros (capacitores de .1nf en paralelo a las entradas) y además de esto se colocan protecciones contra rebotes
Voy a hacerlo en la vida real para presumirle a todos que puedo mover un led
Momento, en la vida real no anda!!!!, sip lo que verían es que al igual que cuando no tenia la retención se prenden todos los leds (al menos por un tiempo), esto se debe a los ruidos, los cuales si pueden aparecer y desaparecer en u segundos
Yyyyyyy como zafo esto????
Primero, en la placa se colocan filtros (capacitores de .1nf en paralelo a las entradas) y además de esto se colocan protecciones contra rebotes
PROTECCION CONTRA REBOTES:
La protección contra reboes es estar seguro de que apretaron el boton, las formas mas comunes son:
1-Preguntar muchas veces durante un tiempo (y que den igual) (unos 25ms)
2-Preguntar un par de veces cada cierto tiempo (y que den igual) (también el total son unos 25ms)
3-Preguntar hasta que x cantidad de veces sean afirmativo
A mi me gusta preguntar unas cuantas veces durante unos 10ms (masomenos una ves cada 2ms) y después volver a preguntar
La forma mas fácil y que funciona es la siguiente:
espera
Btfss porta,0 ;o el que queramos
Goto espera
Call demora
Btfss porta,0;pregunto otra ves
Goto espera
Call demora
Btfss porta,0;pregunto una tercera ves
Goto espera
Sigo con lo mio
Notese que este es el método 2, funciona muy bien si se utiliza en conjunto con capacitores de filtro y con demoras de unos 8 o 9 ms.
1-Preguntar muchas veces durante un tiempo (y que den igual) (unos 25ms)
2-Preguntar un par de veces cada cierto tiempo (y que den igual) (también el total son unos 25ms)
3-Preguntar hasta que x cantidad de veces sean afirmativo
A mi me gusta preguntar unas cuantas veces durante unos 10ms (masomenos una ves cada 2ms) y después volver a preguntar
La forma mas fácil y que funciona es la siguiente:
espera
Btfss porta,0 ;o el que queramos
Goto espera
Call demora
Btfss porta,0;pregunto otra ves
Goto espera
Call demora
Btfss porta,0;pregunto una tercera ves
Goto espera
Sigo con lo mio
Notese que este es el método 2, funciona muy bien si se utiliza en conjunto con capacitores de filtro y con demoras de unos 8 o 9 ms.
Ahora si ya pueden hacer proyectos simples con pic y como estoy de buen humor les voy a enseñar a hacer una bomba de tiempo de esas de las películas con la cuenta regresiva de 9 hasta 0 BOOOOOOOM!
Este seria su programa
Este seria su programa
org 0
bsf status,5
clrf portb
clrf porta
bsf porta,0
bcf status,5
clrf porta;limpio los puertos porsi (siempre conviene al empesar)
clrf portb
goto inicio;salto directo al inicio
;--------------------------- hago la tabla
tabla
movfw h'1f';cargo el numero por el que voy
addwf PCL,f;se lo sumo al rejistro de paso
goto num0
goto num1
goto num2
goto num3
goto num4
goto num5
goto num6
goto num7
goto num8
goto num9
num0
movlw b'01111110'
movwf portb
return
num1
movlw b'00110000'
movwf portb
return
num2
movlw b'01101101'
movwf portb
return
num3
movlw b'01111001'
movwf portb
return
num4
movlw b'00110011'
movwf portb
return
num5
movlw b'01011011'
movwf portb
return
num6
movlw b'01011111'
movwf portb
return
num7
movlw b'01110000'
movwf portb
return
num8
movlw b'01111111'
movwf portb
return
num9
movlw b'01110011'
movwf portb
return
;notese que la tabla esta codificada para encender los segmentos de un display led 7seg
;-----------------------------cierro la tabla
inicio
movlw d'5'
movwf h'1e' ;seteo el multiplicador en 5 para la demora de 8ms
espera
Btfss porta,0 ;o el que queramos
Goto espera
Call demora
Btfss porta,0;pregunto otra ves
Goto espera
Call demora
Btfss porta,0;pregunto una tercera ves
Goto espera
movlw d'9'
movwf h'1f';guardo la cantidad de veces que voy a preguntar, y tambien el numero en el que estoy
movlw d'98'
movwf h'1e';guardo el multiplicador para la demora de 0,1s
resto
call tabla;empiezo a mostrar los numeros
call demora
decfsz h'1f',f;resto uno a la cuenta
goto resto
call tabla;muestro el 0
call demora
bsf porta,1;explota todo a la goma
goto inicio; mera prolijidad porque aca ya exploto todo
end
;----------------------- aca escrivo la demora como sub rutina
demora
; ahora directamente voy a cargar el multiplicador desde el programa, demostrando la utilidad de las subrutinas
movfw h'1e';cargo lo que esta en esta direccion
movwf h'1c'
mult
movlw d'255'
movwf h'1d'
cont
nop;1us
decfsz h'1d',f;1us (resto 1 y salto cuando llego a cero)
goto cont;2us
decfsz h'1c',f;1us
goto mult;2us
return;cuando termino la subrutina regreso
bsf status,5
clrf portb
clrf porta
bsf porta,0
bcf status,5
clrf porta;limpio los puertos porsi (siempre conviene al empesar)
clrf portb
goto inicio;salto directo al inicio
;--------------------------- hago la tabla
tabla
movfw h'1f';cargo el numero por el que voy
addwf PCL,f;se lo sumo al rejistro de paso
goto num0
goto num1
goto num2
goto num3
goto num4
goto num5
goto num6
goto num7
goto num8
goto num9
num0
movlw b'01111110'
movwf portb
return
num1
movlw b'00110000'
movwf portb
return
num2
movlw b'01101101'
movwf portb
return
num3
movlw b'01111001'
movwf portb
return
num4
movlw b'00110011'
movwf portb
return
num5
movlw b'01011011'
movwf portb
return
num6
movlw b'01011111'
movwf portb
return
num7
movlw b'01110000'
movwf portb
return
num8
movlw b'01111111'
movwf portb
return
num9
movlw b'01110011'
movwf portb
return
;notese que la tabla esta codificada para encender los segmentos de un display led 7seg
;-----------------------------cierro la tabla
inicio
movlw d'5'
movwf h'1e' ;seteo el multiplicador en 5 para la demora de 8ms
espera
Btfss porta,0 ;o el que queramos
Goto espera
Call demora
Btfss porta,0;pregunto otra ves
Goto espera
Call demora
Btfss porta,0;pregunto una tercera ves
Goto espera
movlw d'9'
movwf h'1f';guardo la cantidad de veces que voy a preguntar, y tambien el numero en el que estoy
movlw d'98'
movwf h'1e';guardo el multiplicador para la demora de 0,1s
resto
call tabla;empiezo a mostrar los numeros
call demora
decfsz h'1f',f;resto uno a la cuenta
goto resto
call tabla;muestro el 0
call demora
bsf porta,1;explota todo a la goma
goto inicio; mera prolijidad porque aca ya exploto todo
end
;----------------------- aca escrivo la demora como sub rutina
demora
; ahora directamente voy a cargar el multiplicador desde el programa, demostrando la utilidad de las subrutinas
movfw h'1e';cargo lo que esta en esta direccion
movwf h'1c'
mult
movlw d'255'
movwf h'1d'
cont
nop;1us
decfsz h'1d',f;1us (resto 1 y salto cuando llego a cero)
goto cont;2us
decfsz h'1c',f;1us
goto mult;2us
return;cuando termino la subrutina regreso
aca pueden ver algunos screens del circuito y programa andando
y un screen del assembler y la simulación en picsim, noten que la simulación nos dice por que instrucción vamos, cual sigue y el valor de todos los registros en cada momento
si quieren mas información sobre como usar estos programas y sobre electrónica y lógica digital voy a estar haciendo un post sobre eso
además si quieren hago otro con las técnicas e instrucciones que quedaron afuera de este post como interrupciones y TMR0 o EEPROM
muchas gracias por pasar, espero los haya iluminado
y un screen del assembler y la simulación en picsim, noten que la simulación nos dice por que instrucción vamos, cual sigue y el valor de todos los registros en cada momento
si quieren mas información sobre como usar estos programas y sobre electrónica y lógica digital voy a estar haciendo un post sobre eso
además si quieren hago otro con las técnicas e instrucciones que quedaron afuera de este post como interrupciones y TMR0 o EEPROM
muchas gracias por pasar, espero los haya iluminado
ME ACABO DE DAR CUENTA DE QUE ESTA BOSTA NO TOMA LAS IDENTACIONES
(todas las instrucciones se escriben asi
tab instruccion espacio la cosa
y las etiquetas se escriben contra el margen)
(todas las instrucciones se escriben asi
tab instruccion espacio la cosa
y las etiquetas se escriben contra el margen)
(asi se veria identado)
[/size]