uControl
Febrero 24, 2017, 05:19:17 *
Bienvenido(a), Visitante. Por favor, ingresa o regístrate.
¿Perdiste tu email de activación?

Ingresar con nombre de usuario, contraseña y duración de la sesión
 
   Inicio   Ayuda Buscar Ingresar Registrarse  
Páginas: [1]   Ir Abajo
  Imprimir  
Autor Tema: solicito tu ayuda con adc  (Leído 1994 veces)
0 Usuarios y 1 Visitante están viendo este tema.
mazter
PIC10F
*
Desconectado Desconectado

Sexo: Masculino
Mensajes: 8


« : Abril 03, 2015, 01:00:16 »

Hola, soy nuevo en este foro, y quisiera pedir tu ayuda, mi situacion es la siguiente: deceo crear un programa en asm para un pic 16f877a con cristal de 4 Mhz, estoy usando mplab ide v 8.88 y la simulacion en proteus, para mostrar en un lcd de 16x2 conectado  en 8 bits al puerto b, rs y enable por cercania los conecte al 6 y 7 del puerto d,mis referencias son vdd y vss, necesito que muestre un valor de voltaje comprendido entre 185v y 260v , ya me puse a estudiar como funciona el adc y me atore donde despues de convertir las entradas del an0.... an7 y tener dresh y dresl ahora como le hago para que en el lcd se visualice el voltaje correspondiente, opte por justificar a la izquierda y solo usar los bits de dresh ya que no ocupo tanta resolucion y con los 256 bits que me daria son mas que suficiente, ya que el rango que existe entre 260 y 185 son 75v dividido entre los 256 bits de resolucion tendria una variacion de 0.29 volts entre bit y bit y dado que solo quiero mostrar volts enteros (si se pudieran dos o almenos una decimal seria excelente) pues tengo tres veces mas resolucion de la necesarea, he leido algunos post pero como soy demaciado nuevo, no los entiendo bien, unos dicen que debo sumar 48 pero para que me de un caracter de ascii, mi pregunta es: como hacer para obtener: 185,186...225,226,227....259,260 apartir de dresh?? y asi poder mostrarlos en el lcd,entiendo que al enviarlos al lcd se enviarian 2 luego 2 y al final 3 para obtener 223; necesito usar 6 canales analogicos, pero segun lei basta con antes de iniciar una convercion le digo al pic cual canal debe leer, de manera que en primer lugar leo el an0, realizo todo el proceso y muestro en el lcd digamos 223, acto seguido leo an1 y asi sucesivamente, no es asi?, usare 6 por que con los primeros 3 mostrare el voltaje de cada fase de un regulador trifasico y con los otros 3 quiero mostrar el flujo de amperaje con un valor comprendido entre 0 y 15 amperes en un regulador trifasico, tomando en cuenta que la capacidad maxima son 15 amperes pensaba si sera posible tambien mostrar el porcentaje de  trabajo, es decir si el consimo son 7.5 amperes que tambien muestre que esa fase esta trtabajando al 50%, y si alguna o mas de una de las 3 fases pasa de 15 amperes que apage un canal de salida, digamos el 6 del puerto d para que este desactive un contactor y asi cortal el flujo de la corriente por exceso de consumo,  el consumo de amperaje lo leere de un dispositivo que apenas estoy creando y que generara un voltaje apartir del campo magnetico que crea la corriente al fluir por un conductor, pero me gustaria si no es mucho pedir un programa de como hacer la conversion en an0 y si me lo pudieran explicar, para asi comprenderlo y yo hacer el programa para los otros 5 canales analogos, de antemano gracias por leer y ojala alguien me pueda orientar
Gracias Sonamos Sonamos Sonamos
En línea

Si algo puede salir mal, saldrá mal, si dos cosas distintas pueden fallar, fallaran y al mismo tiempo, E. Murphy; ahora que ya lo sabes no lo des por hecho, has algo para evitarlo; mazter!
Leon Pic
Moderator
dsPIC
***
Desconectado Desconectado

Sexo: Masculino
Mensajes: 5693


Cumulonimbus


WWW
« Respuesta #1 : Abril 03, 2015, 02:30:16 »

Hola mazter.
Bienvenido al foro de ucontrol.

Antes de empezar mi explicación, te quiero pedir que seas más claro. Que separes los párrafos y armes bien las oraciones. Tuve que volver atrás varias veces pare entenderte.

No estás equivocado con tu razonamiento, pero al parecer aún no lo comprendes bien.
Los registros no son DRESL y DRESH, se llaman ADRESL y ADRESH. Es importante que lo escribas bien en el ASM sino te dará error.

Entiendo que sabes como son los pasos para iniciar una conversión ¿verdad? Por ahora empezaré del principio para no obviar algo:

El pic tiene un registro en el cual, te da la conversión obtenida, para eso hay que fijarce en el datasheet. También es necesario ajustar los voltages de referencias, que son +Vref y -Vref. Esto es, para +Vref, es la máxima tensión que puede tener un valor analógico y -Vfre, es la mínima tensión que tendrá el valor analógico.

Por ejemplo, tenemos una señal analógica que varía entre 5V y 0V. Cuando el AD del pic, detecta 5V en la entrada AD, en el registro escribe 11111111, y cuando detecta 0V, en el registro escribe 0000000. Luego para las tensiones intermedias, colocará la codificación en binario correspondiente.

Obviamente, para estos cálculos, dependerá de la resolución del PIC, el cual está detallado en el datasheet.

Veamos un ejemplo de como hace la conversiónel PIC:

Datos a saber:

+Vref= 5V
-Vref= 0V
Resolución del Pic 256 (2^8)

La fórmula es la siguiente:

5V / 256 = 0.01953125 redondeando 0.019V

Esto quiere decir que, por cada 0.019V, el pic aumentaráen 1 al registro. O sea

0V         0000000
0.019     0000001
0.038     0000010
0.057     0000011

Para saber la resolución correspondiente a cada volt, corresponde la fórmula siguiente

Resolución = Voltage (+Vref - -Vref) / 2^n

Si se ingresa a +Vref y -Vref en mV, la resolución será en mV, si en cambio, se ingresa en V, la resolución será en V

Veamos un ejemplo:  que voltaje le corresponde al código 11011010 (218)

Despejamos la fórmula anterior:


Resolución * 2^n = Voltaje

0.019 * 218 = 4.142 V

Cuando el pic detecte 4.142 V, en el registro pondrá 11011010



Partamos ahora del valor leído en el registro ADRESH (que es el con el que quieres trabajar).
Tienes que multiplicarlo por la resolución para obtener el valor del voltaje. O sea, ADRESH * 0,019 = Voltios. El problema acá, es que estamos trabajando con decimales; y el pic que usas no soporta decimales. Hay dos opciones para solucionar esto, pero antes quiero que veas tres operaciones matemáticas:

0,019 * 218 = 4,142V
19 * 218 = 4142V
19 * 218000 = 4142000V

Como verás, la segunda opción es la más adecuada. Lo malo es que necesitas dos memorias RAM para realizar dicha operación. Lo bueno, es que 19 (en nuestro caso) es una constante, por lo que directamente cargas el multiplicador 19 directamente en el código de programa. O sea, no es necesario que hagas 0,019 * 1000 para obtener dicho valor a multiplicar. ¿Se entiende?

Una vez que obtenemos el valor de la tensión, tienes que dividirlo para poder separar los números.
En el programa debes hacer:

4142 / 1000 = 4,142 (omitimos después de los valores después de la coma); pero no hay que borrarlo. De esta manera obtienes el 4.
El 142 que te quedó de la coma, lo dividis por 100 y te queda 1,42. Recuperas el 1. El 42 lo dividis por 10 y obtienes el 4 y te queda el 2.

Para entender como se hace, visita Medidor de temperatura Descarga el archivo adjunto y verás el código ASM que realicé. Está comentado así que no creo que tengas problemas.

Antes de terminar, el ejemplo que te di aquí, es con una variación de 0 a 5V. Tu tienes que realizar un circuito divisor de tensión para que le lleguen al PIC 5V y no 260V; Por lo que estimo un divisor de 52. El divisor es necesario porque sino, despídete del PIC.

Ahora bien. Cuando le lleguen 5V al pic, el ADC se cargará con 255 (b'11111111). Si hacemos 255 * 1.02 = 260.1V. La constante de 1.02 resulta de dividir 260V / 255 = 1,019607843137255 (redondee 1.02)
En línea

Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.
mazter
PIC10F
*
Desconectado Desconectado

Sexo: Masculino
Mensajes: 8


« Respuesta #2 : Abril 05, 2015, 03:32:34 »

Hola Leon Pic!!!
Gracias por contestarme.

Pues si tienes razon esta todo muy apilado, pero como dice el chavo: se me chispotio je je y ademas el celular me cambio la palabra pic por pico en fin...
Espero me disculpen

Respecto de iniciar el adc, pues he leido en datasheet y algunos tutoriales ademas de leer algunos programas en asm y espero que no me de conflictos iniciar el adc, ya hice una prueba en mplab y no muestra errores.

Copie este pedaso de un ejemplo que posteo suky y modifique lo que crei necesario:
   bsf    STATUS,RP0   ; Banco 1
   MOVLW B'111111'    ;carga el acumulador con seleccion
   MOVWF TRISA   
   MOVLW B'00000000'    ;carga el acumulador con seleccion
   MOVWF TRISB   
   MOVLW B'00000000'    ;carga el acumulador con seleccion
   MOVWF TRISD   
   movlw   B'10000000'      ; Justificado a la izquierda, Fosc/8, los 8 analógos, VDD, VSS.referencias
   movwf   ADCON1
   bcf    STATUS,RP0   ; Banco 0
   CLRF PORTA           ;Inicializa el puerto a
   CLRF PORTB           ;Inicializa el puerto b
   CLRF PORTD           ;Inicializa el puerto c
   movlw   B'01000001'      ; Fosc/8, Canal 0, módulo habilitado.-
CICLO   movwf   ADCON0
   call   Demora_20us   ; Demora de adquision.-
   bsf      ADCON0,GO
Espera
   btfsc   ADCON0,GO   ; Espera a que termine conversion.-
   goto   Espera   
   movf   ADRESH,W   ; Movemos resultado de la conversion.-
   movwf   ByteAlto
   bsf    STATUS,RP0   ; Banco 1
   movf   ADRESL,W
   movwf   ByteBajo
   bcf    STATUS,RP0   ; Banco 0.-
   bsf      ADCON0,ADON   ; Apago modulo de conversion.-

En relacion al tema del medidor de temperatura lo estoy estudiando, solo que no puedo ver la imagen donde aparece el diagrama, ya descarge el asm y el hex, ojala me pudieras mostrar la imagen del del diagrama.

De lo que he leido del asm me surgen algunas preguntas:

1ra:  duda   Debido a que la constante es 19 (que fue multiplicada por 1000) para no perder la relacion o la escala de la equivalencia tambien es necesareo multiplicar el contenido de adresh por mil, y al resultado se le divide por 100 para obtener las centenas, el sobrante de la divicion (se que tiene un nombre especifico pero ahun no estoy tan documentado como para decirte cual es, espero me entiendas) lo vuelvo a dividir entre 10 para las centenas y el sobrante de esta nueva divicion seran mis unidades?

2da: duda   Si entendi bien y lo que dije es correcto, el numero obtenido solo sera entre 0 y 255 (por ser de 8 bits) escritos en binario y solo restaria convertirlos a decimal; o no se si al enviarlos escritos en binario el lcd me interprete el numero en decimal

3ra: duda   Al multiplicar 255 por el factor de 1.02 si funciona, pero al miltiplicar por ejemplo 1 por 1.02 ya no funciona por que necesito mostrar un minimo de 185, es decir b'00000000' =185 y b'11111111' =260, ahora te explico el por que de los 185 y 260 para ver que formula ó formulas se pueden aplicar:

El equipo donde montare el pic es un regulador trifasico de 220 vac conectado internamente en estrella. Que seria L1, L2 L3 Y Neutro
Esto nos da como resultado interno: tres fases simetricas conectadas a una fase y al neutro cada una y cada una ahora trabaja con 127vac, esto por la relacion que guarda la conexion estrella-delta de 1.73

220/1.73=127

Una vez obtenidos los 127 vac se aplicaran a un transformador con salida de 12 vac, estos a su vez seran filtrados y rectificados obtendremos 16.8vdc esto despues de multiplicarlos por el factor de 1.4

Este transformador entrega 0.0944 voltios de salida por cada uno de entrada

Una vez obtenidos los 16.8 que se originan solo cuando todos los voltages descritos son los descritos es decir desde los 220 vac tendremos como resultado 16.8 vdc se harán pasar por un zener de 9v y una de 5.2, dejando solo 2.6vdc.

16.8-9=7.8
7.8-5.2=2.6
estos 2.6 se ajustaran a 2.5 con un divisor variable, mejor conocido como potenciometro, 2.5vdc = d'01111111' =127 en decimal

Al tener 185vac de entrada se tienen:
185/1.73=106.9 redondeado a 107
El transformador toma los 107 y entrega:
107*0.0944=10.1
Estos 10.1 ya filtrados y rectificados nos dan:
10.1*1.4=14.14
Si los 14.14 los hacemos pasar por los zener que entotal suman 14.2 (9+5.2) tenemos como resultado 0vdc = d'00000000' cero en decimal

Por el contrario si nenemos 260vac de entradase tienen:
260/1.73=150vac
El transformador toma los 150 y entrega:
150*0.0944=14.16
Estos 14.16 filtrados y rectificados nos dan:
14.16*1.4=19.82
Si los 19.82 los hacemos pasar por los zener que en total suman 14.2 tenemos como resultado:5.62,  =d'11111111' = 255
El .62 excedente se eliminara con el divisor variable ademas de agregar un zener de proteccion a la entrada de cada puerto analogico

A grandes rasgos ese es el porque de los parametros que debe mostrar el lcd quiza sea necesario algunos ajustes de ultima hora pero primero necesito saber como hacer el programa en asm para despues (una vez que comprenda el proceso) afinar detalles


De cualquier forma seguire estudiando le asm del medidor de temperatura

Gracias por prestarme atencion!!!

 Ola
En línea

Si algo puede salir mal, saldrá mal, si dos cosas distintas pueden fallar, fallaran y al mismo tiempo, E. Murphy; ahora que ya lo sabes no lo des por hecho, has algo para evitarlo; mazter!
Leon Pic
Moderator
dsPIC
***
Desconectado Desconectado

Sexo: Masculino
Mensajes: 5693


Cumulonimbus


WWW
« Respuesta #3 : Abril 05, 2015, 06:37:08 »

Lo mío, fue a modo de ejemplo y sin saber bien que es lo que necesitabas hacer. Tu deberás modificarlo para tu proyecto.

Sobre la tercera duda.
En mi ejemplo que te di, trabajaras con un valor de entre 65535 y 0.
La idea de dividirlo, es para aislar los números y luego codificarlo en código ASCII. En mi programa que te pasé, la codificación a ASCII lo hago por medio de tablas.

NOTA: El compilador, chequea que no haya errores de sintaxis; o errores de escritura (escribir mal un registro, por ejemplo). Que no te de errores, no quiere decir que hiciste los pasos correctos.
En línea

Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.
mazter
PIC10F
*
Desconectado Desconectado

Sexo: Masculino
Mensajes: 8


« Respuesta #4 : Mayo 18, 2015, 01:26:56 »

             Hola compañeros!!! aqui sigo con esta cuestion, he avanzado un poco y ahora estoy detenido por que ya descubri la formula que debo aplicar a adresh solo que no se como aplicarla en asm; dicha formula es X=(a * 0.29) +185 donde a es el resultado del convertidor adc que sera como maximo 255 y X es el resultado que despues enviare al bdc

   Ejemplo: con el adc al 50% me debe mostrar 220, si aplico la formula me dara asi: 127*0.29=36.83 + 185=221.83 osea mas menos 220!

             Pues bien, segun lei no se puede aplicar 0.29 en asm por lo tanto debo multiplicar por 100 para obtener 29, pero ahora debo multiplicar adresh por 100 y despues dividir el resultado entre 10000 para al final sumarle 185

  Ejemplo: 127x100=12700x29=368300/10000=36.83+185=221.83 osea mas menos 220!

 Al multiplicar adresh por 100 me da hasta 15 bit ........ osea 8 bit de adresh por 8 bit del numero 100 = 16 bit

    Despues de esto, al multiplicar por 29 me da hasta 20 bit ........ osea 16 bit por 8 bit del numero 29 =24 bit

        En seguida debo dividir entre 10000 que son 14 bit ..............osea 24 entre 16 bit = 8 bit

Ahora solo falta sumarle los 185 lo cual cabe en 8 bit ............ a lo maximo tendre 9 bit 258=9 bit

                Como no se dividir ni multiplicar en asm, ahi es donde esta el detalle.

          Nota: las decimales no me importan, y el adc en 0 me debe mostrar 185 en el lcd y
                      el adc en 255 me debe mostrar 258 en el ldc

     Espero que alguien me pueda ayudar a realizar esta serie de operaciones matematicas

De cualquier manera Gracias por su atencion!!!
En línea

Si algo puede salir mal, saldrá mal, si dos cosas distintas pueden fallar, fallaran y al mismo tiempo, E. Murphy; ahora que ya lo sabes no lo des por hecho, has algo para evitarlo; mazter!
mazter
PIC10F
*
Desconectado Desconectado

Sexo: Masculino
Mensajes: 8


« Respuesta #5 : Mayo 18, 2015, 01:31:12 »

   O sera mejor solo multiplicar 127 por 29 y dividir entre 100???
 en vez de 12700 por 29 y entre 10000....
En línea

Si algo puede salir mal, saldrá mal, si dos cosas distintas pueden fallar, fallaran y al mismo tiempo, E. Murphy; ahora que ya lo sabes no lo des por hecho, has algo para evitarlo; mazter!
pastbytes
PIC12F
**
Desconectado Desconectado

Mensajes: 170


« Respuesta #6 : Mayo 18, 2015, 08:27:30 »

Cuanto mas ajustados sean los valores, mejor, hay que tener en cuenta los valores maximos y minimos que vas a obtener y usar rutinas con la resolucion suficiente pero sin exagerar, ya que cuanto mas grandes sean los numeros mas se tarda en multiplicar y dividir. Hay montones de rutinas para eso en la red, incluso Microchip tiene notas de aplicacion para los PIC16, yo las tengo en un libro bastante grande que venia con los programadores de Microchip en los 90s, de cuando lo moderno era un 16C84 o un 17C44 y no se solia usar mas de 4MHz, asi que en un 16F877A a 20MHz esas rutinas tienen que andar muy bien.
Me parece que te estas complicando con las cuentas, lo que tenes que hacer es multiplicar el numero, en el ejemplo 127, por 0,29, que es lo mismo que hacer 127 x (29/100) asi que multiplicas por 29 y luego dividis todo por 100. Con una rutina de multiplicacion de 8x8 bits tendria que alcanzar, y luego una de division de 16x8 bits. Tene en cuenta que despues tambien vas a tener que dividir sucesivamente por 10 para mostrar el numero en decimal en el LCD, para ir obteniendo cada digito a imprimir.
Si vas a multiplicar por un numero fijo, en este caso 29, te conviene hacer una rutina especifica para eso, ya que las genericas tardan mas porque toman en cuenta todos los casos.
Para multiplicar N por 29 se puede hacer:  Nx16 + Nx8 + Nx4 + Nx1
Esto se resuelve desplazando N 4 veces a la izquierda (x16), 3 veces a la izquierda (x8), 2 veces (x4), y sumando esos 3 resultados mas el propio N.
En el caso de 127, esto quedaria asi:
127 (01111111) << 4 = 11111110000 = 2032
127 (01111111) << 3 = 1111111000 = 1016
127 (01111111) << 2 = 111111100 = 508
127 (01111111) << 0 = 01111111 = 127

2032 + 1016 + 508 + 127 = 3683

La rutina tendria que sumar N al resultado final, luego desplazar N dos veces y sumarlo, luego una vez mas y sumarlo, y luego una ultima vez y tambien sumarlo.
Por ultimo te quedaria aplicar la division, de la que no te salvas, y la suma:

(3683 / 100) + 185 = 36,83 + 185 = 221,83
« Última modificación: Mayo 18, 2015, 08:58:20 por pastbytes » En línea
mazter
PIC10F
*
Desconectado Desconectado

Sexo: Masculino
Mensajes: 8


« Respuesta #7 : Mayo 19, 2015, 10:00:06 »

   Hola pastbytes! Muchísimas gracias por responderme!

         Pues si imaginaba algo como que tendría que usar las funciones de recorrer Hacia la izquierda,
     solo me quedan un par de grandes dudas, ojala me puedas  ayudar
         Si inicio con 8 bit y desplazo a la izquierda para multiplicar
           Los bits que se recoran como le hago para ponerlos en otro lugar,
         digamos si tengo n al desplazar como le hago para ponerlos en digamos n alto?
           Y eso me lleva a la segunda duda: una vez que tenga n y n alto quisiera pensar que al recorrer a la derecha se divide y como le hago para recorrer digamos los últimos 4 bits de n alto a los primeros 4 bits de n?

    Ahhh una pregunta mas: en una resta donde tengo digamos 85 en binario, si le digo al pic que reste 100 en binario, que pasa? Me da como resultado 15??? Entiendo que estatus c se pondrá en ser pero que le pasan a mis 85? O me deja cero? O simplemente no le resta nada y me deja los 85 y me setea estatus c??

Disculpa si mi pregunta resulta muy sin sentido, pero no conozco mucho de pics
   


  Nota: lo escribí en el celular, es posible que en la computadora se vea muy apilado, una disculpa de antemano!
En línea

Si algo puede salir mal, saldrá mal, si dos cosas distintas pueden fallar, fallaran y al mismo tiempo, E. Murphy; ahora que ya lo sabes no lo des por hecho, has algo para evitarlo; mazter!
pastbytes
PIC12F
**
Desconectado Desconectado

Mensajes: 170


« Respuesta #8 : Mayo 20, 2015, 12:49:26 »

        Si inicio con 8 bit y desplazo a la izquierda para multiplicar
           Los bits que se recoran como le hago para ponerlos en otro lugar,
         digamos si tengo n al desplazar como le hago para ponerlos en digamos n alto?

Necesitas 2 registros, por ejemplo un RESULTL y un RESULTH, lo primero seria poner a 0 o cargar con el valor a multiplicar los registros que correspondan, en el caso anterior donde multiplicabamos por 29, se podria obviar lo de poner a 0 RESULTL porque directamente habria que sumarle N, entonces es mas facil cargarle N directamente, pero eso es una optimizacion.
Cuando se desplaza un registro con rlf o rrf se hace a traves de CARRY, es decir del bit STATUS, C
Si hacemos rlf sobre un registro, lo que ocurre es que se desplazan los bits hacia la izquierda un lugar (hacia el mas significativo), lo cual implica multiplicar por 2 el numero. Pero hay un detalle, el desplazamiento no es circular, es decir el bit 7 que es el que se saldria del registro, no entra por el bit 0, lo que ocurre es que la bandera CARRY se copia al bit 0, y el bit 7 en lugar de perderse, se copia a CARRY. Si queres hacer un desplazamiento circular, luego de cada rrf vas a tener que chequear el valor de STATUS, C y colocar ese valor en el bit 0.
En procesadores mas complejos suele haber mas variaciones del desplazamiento, pero esta es la mas util en operaciones matematicas, tambien es practica para por ejemplo ir enviando en serie un byte, ya que en lugar de andar chequeando cada bit particular, basta con desplazar y luego chequear CARRY para ver el valor del siguiente bit, lo mismo para recibir, se coloca el bit recibido en CARRY y luego se desplaza para ingresarlo al registro.
Pero volviendo a la multiplicacion, conociendo ahora como funciona rlf, lo primero que tenes que tener en cuenta es el contenido de CARRY antes de hacer un desplazamiento. Si queremos multiplicar un numero de 16 bits por 2, lo primero es asegurarse de que CARRY es 0, para esto hacemos bcf STATUS, C antes de hacer rlf RESULTL, f
Lo que ocurre luego del rlf es que el bit 7 de RESULTL se pierde del registro pero pasa a CARRY, entonces inmediatamente hacemos rlf RESULTH, f y magicamente el contenido de CARRY va a parar al bit 0 de RESULTH, ademas de desplazar los otros bits del registro. Si tenemos un tercer registro, tambien podemos salvar ese bit 7 (bit 15 juntando L y H) desplazando a la izquierda otro registro, y asi con todos los que hagan falta segun la cantidad de bits que usemos.
Es importante mirar en la tabla de instrucciones cuales afectan el bit CARRY porque a veces necesitamos ejecutar alguna instruccion intermedia sin perder ese valor, tambien hay que tenerlo en cuenta porque alguna puede poner CARRY a 1 y olvidarnos de esto antes de hacer un desplazamiento.

          Y eso me lleva a la segunda duda: una vez que tenga n y n alto quisiera pensar que al recorrer a la derecha se divide y como le hago para recorrer digamos los últimos 4 bits de n alto a los primeros 4 bits de n?

Efectivamente desplazando hacia la derecha se divide por 2, el desplazamiento es muy practico pero solo sirve para multiplicar y dividir por potencias de 2, por ejemplo por 2, 4, 8, 16, 32, etc.
Supongo que te referis a desplazar el conjunto de 2 registros (16 bits) 4 bits hacia la derecha, lo que dividiria el numero por 16 (N/2/2/2/2 = N/16), para esto se haria algo asi, teniendo ya cargado el valor de 16 bits en RESULTL y RESULTH:

bcf STATUS, C
rrf RESULTH, f
rrf RESULTL, f

Esto poner a 0 el bit CARRY, desplaza a la derecha el byte alto RESULTH, quedando el bit 0 en CARRY y el bit 7 en 0 (porque se puso a 0 CARRY previamente), luego se desplaza el byte bajo RESULTL, lo cual rescata el ex bit 0 de RESULTH desde CARRY y lo coloca en el bit 7 de RESULTL, y pierde el bit 0 de RESULTL para colocarlo en CARRY, este bit ya no importa mas.
Para desplazar los otros 3 bits restantes simplemente se repite ese codigo 3 veces mas:

bcf STATUS, C
rrf RESULTH, f
rrf RESULTL, f
bcf STATUS, C
rrf RESULTH, f
rrf RESULTL, f
bcf STATUS, C
rrf RESULTH, f
rrf RESULTL, f

Hay que tener en cuenta el orden en que se hacen los desplazamientos, si va hacia la derecha, primero debe desplazarse el registro mas alto, porque el que se pierde es el bit 0, que entrara al bit 7 del siguiente, no podemos desplazar primero el byte bajo si no tenemos el valor todavia del bit 0 del byte alto. Si se desplaza hacia la izquierda, se haria primero con el byte bajo y se sigue con el alto, es mas practico de esa forma.

   Ahhh una pregunta mas: en una resta donde tengo digamos 85 en binario, si le digo al pic que reste 100 en binario, que pasa? Me da como resultado 15??? Entiendo que estatus c se pondrá en ser pero que le pasan a mis 85? O me deja cero? O simplemente no le resta nada y me deja los 85 y me setea estatus c??

Tendrias que leer como se representan los numeros en complemento a 2, pero digamos que un byte se puede usar para contener numeros con o sin signo, sin signo representa valores de 0 a 255, pero si se toma con signo representa numeros entre -128 y 127, los numeros positivos quedan tal cual con o sin signo, los numeros negativos se representan como los numeros mayores a 127. El valor 128 equivale en binario a 10000000, es el primero que tiene en 1 el bit 7, por lo que si vemos que el bit 7 es 1, sabemos que es un numero negativo.
Para simplificarlo un poco, si haces por ejemplo 2-3, es como si decrementaras el 2 tres veces, quedaria en 1, luego en 0, y luego empezaria de nuevo por 255, si se continuara restando decrementaria mas. Es decir que 2-3 = -1 y esto se representa como 255 en un byte con signo, 255 seria un -1 representado en complemento a 2, que tiene la particularidad de que si se suma normalmente funciona como corresponde.
Si queremos hacer por ejemplo 4-1, podemos hacer 4+(-1), como sabemos que -1 se representa como 255, basta con hacer 4+255 = 259, esto en binario es 100000011 (9 bits), el bit 9 se pierde, quedando 00000011 = 3.
En el ejemplo de 85-100, lo que quedaria como resultado es -15, que se representa como 11110001 = 241, y como tiene el bit 7 a 1 sabemos que es un numero negativo. Para verificarlo, podemos hacer 100-15 y nos tiene que dar 85. 100+(-15) = 100+241 = 341 = 101010101, eliminando el bit 9 queda 01010101 = 85.
Si queres calcular rapido como se representa un numero negativo, haces 256-N, por ejemplo para -15 seria 256-15 = 241. Por ejemplo -1 es 255, -2 es 254, y asi, hasta -128 que es 128.
Yo la verdad no opero con numeros negativos porque puede ser confuso, pero a veces no se pueden evitar, si los uso cuando quiero restar un numero fijo, calculo el complemento a 2 y simplemente se lo sumo al numero que quiero decrementar, pero hay que hacerlo teniendo en cuenta el rango de valores que se va a usar, para no exceder los limites.
En línea
mazter
PIC10F
*
Desconectado Desconectado

Sexo: Masculino
Mensajes: 8


« Respuesta #9 : Mayo 25, 2015, 12:11:34 »

        Caramba pastbytes!!! me explicaste muy bien, muchisimas gracias! quedo todo clarisisisimo

No habia contestado antes por que estaba tratando de dividir entre 100 con solo recorrer a la derecha, solo que no supe como, lo mas que pude fue dividir entre 64, en fin supongo que tendre que hacer restas sucesivas, a no ser que tengas un consejo mas que me puedas regalar!!

     Independientemente de todo ahora ya estoy en la programacion y estoy corrijiendo los errores tipicos de usar una o varias funciones por primera vez, solo me queda decirte muchisimas gracias!!!!
En línea

Si algo puede salir mal, saldrá mal, si dos cosas distintas pueden fallar, fallaran y al mismo tiempo, E. Murphy; ahora que ya lo sabes no lo des por hecho, has algo para evitarlo; mazter!
Páginas: [1]   Ir Arriba
  Imprimir  
 
Ir a:  

Impulsado por MySQL Impulsado por PHP Powered by SMF 1.1.21 | SMF © 2011, Simple Machines
SMFAds for Free Forums
XHTML 1.0 válido! CSS válido!
Página creada en 0.085 segundos con 25 consultas. (Pretty URLs adds 0.007s, 2q)
loggkey