TODOPIC

Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: Pinolillo16 en 29 de Octubre de 2015, 17:51:23

Título: PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 29 de Octubre de 2015, 17:51:23
 :) Que tal amigos hace unos días me compre unos pics por una buena oferta y llego la hora de probarlos, me llamo la atención las capacidades que tiene es de los últimos 16F que saco microchip y esta rondando por los 1.4usd cada uno, lo consulte en digikey. Bueno en la imagen anexa tenemos sus principales características. Abro este hilo para poder ir colgando códigos ejemplo que nos puedan servir a la comunidad y también para que me ayuden a corregir si es que tengo errores. Así mismo si alguien tiene ya ejemplos con este micro no dude en compartirlos.

Saludos
Título: PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 29 de Octubre de 2015, 18:05:53
Algo de lo que mas me gusto son los 8 canales touch que tiene y que corre a 8MPIS  :) para ser un 16F lo considero muy bueno, dentro del data sheet encontré que tiene 8 bancos de memoria, lo cual para mi era completamente nuevo ya que siempre he trabajado con micros que tienen máximo 4, cabe mencionar que regularmente trabajo en versiones del MPLAB 8.xx porque me agradan mas, para poder manejar este micro es necesario el MPLABX donde encontré esta instrucción:

MOVLB La cual según lo entendí, mueve una literal al BSR que es el registro de selección de banco. Para poder configurarlo.

Otro registro que considere importante es el OSCCON donde configure el Oscilador interno. De acuerdo al la hoja de datos tenemos:

- Oscilador interno de precisión de hasta 16Mhz con un PLL de 4x entonces la lógica dice que podemos llevarlo a 64Mhz?

Esa es mi duda, yo lo deje así. En cuanto pueda haré la prueba en un osciloscopio para conocer la frecuencia real. Bien el primer código es:
Código: ASM
  1. #INCLUDE "P16F1707.INC"
  2.  
  3. ; CONFIG1
  4. ; __config 0xF9A4
  5.  __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOREN_OFF & _CLKOUTEN_OFF
  6. ; CONFIG2
  7. ; __config 0xDF7F
  8.  __CONFIG _CONFIG2, _WRT_OFF & _PPS1WAY_ON & _ZCDDIS_OFF & _PLLEN_ON & _STVREN_ON & _BORV_LO & _LPBOR_OFF & _LVP_OFF
  9.  
  10.  
  11.     CBLOCK  0X020
  12.     RET
  13.     RET2
  14.     ENDC
  15.  
  16.  
  17.     ORG     0X00
  18.     GOTO    CONFIGURA_PIC
  19.     ORG     0X04
  20.     RETFIE
  21.  CONFIGURA_PIC
  22.     MOVLB   0X01; MOVEMOS UN VALOR AL BSR PARA SABER EN QUE BANCO ESTAMOS
  23.     MOVLW   B'11111011'
  24.     MOVWF   OSCCON
  25.     MOVLB   0X00
  26.     CLRF    PORTA
  27.     CLRF    PORTB
  28.     CLRF    PORTC
  29.     MOVLB   0X02
  30.     CLRF    LATA
  31.     CLRF    LATB
  32.     CLRF    LATC
  33.     MOVLB   0X03
  34.     CLRF    ANSELA
  35.     CLRF    ANSELB
  36.     CLRF    ANSELC
  37.     MOVLB   0X01
  38.     CLRF    TRISA
  39.     CLRF    TRISB
  40.     CLRF    TRISC
  41.     MOVLB   0X00
  42.    
  43.  PRINCIPAL
  44.     MOVLW   0XFF
  45.     MOVWF   PORTB
  46.     CALL    RETARDO
  47.     CLRF    PORTB
  48.     CALL    RETARDO
  49.     GOTO    PRINCIPAL
  50.    
  51.    
  52. RETARDO
  53.     MOVLW   0XFF
  54.     MOVWF   RET
  55.     MOVWF   RET2
  56. ESP
  57.     DECFSZ  RET,F
  58.     GOTO    ESP
  59.     MOVLW   0XFF
  60.     MOVWF   RET
  61.     DECFSZ  RET2,F
  62.     GOTO    ESP
  63.     RETURN
  64.     END
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: KILLERJC en 29 de Octubre de 2015, 19:37:17
Tenes mal puesto el titulo, es PIC16F1707 , te olvidaste un 1.
Asi que si podes cambialo, asi de esa forma es correcto, el PIC16F707 es otro pic y tiene muy poco.
Sino cualquier cosa me avisas y lo cambio.

Citar
- Oscilador interno de precisión de hasta 16Mhz con un PLL de 4x entonces la lógica dice que podemos llevarlo a 64Mhz?

No, la entrada al PLL es de 4 a 8Mhz, lo cual llegaria maximo 32Mhz

Citar
MOVLB La cual según lo entendí, mueve una literal al BSR que es el registro de selección de banco. Para poder configurarlo.

Exacto, como ya son mas bancos, imagino que debe ser feo estar cambiando 5 bits y encima buscar el banco con el registro, entonces tenes una instruccion para eso. Los PIC18 ya lo traian a esto, por que tenian 16 bancos facilmente los primeros.
En realidad traen varias mas instrucciones como ya habras visto.

Citar
dentro del data sheet encontré que tiene 8 bancos de memoria
Tiene 32 xD

Y el OSCCON lo tocas para modificar la frecuencia del oscilador interno o activar el PLL si no lo activaste con los fuses, o cambiar el reloj de externo a interno, o al reves.
Tambien en los puertos tenes Open-Drain, Slew-Rate e Input-Level como algo "nuevo"

Tambien hay otras cosas buenas que vas a encontrar :P
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 05 de Noviembre de 2015, 03:34:08
Gracias KILLERJC por tus observaciones ya modifique algunas,  :D no he actualizado debido a que he tenido un poco de trabajo. Estaba montandolo en proto todo el circuito ya que no tenia donde simular, me actualice la version de Proteus a la 8.3 y me sorprendio mucho ya que actualizaron los Micros y ya esta este PIC incluido en las librerias para simulación así mismo me di cuenta de que ya hay mas sensores para simular. Hace algunos meses trabaje con la LCD Nokia 5110, despues de unos dias pude hecharla a andar con ensamblador y un SPI por software, para aprender mas y aprovechando que tambien la LCD ya esta en proteus voy a realizar un ejemplo de como utilizarla pero con el SPI que incluye el micro por hardware. De cualquier modo esta abierto este tema por si alguien desea contribuir  ;-) 

Saludos
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: KILLERJC en 05 de Noviembre de 2015, 03:50:03
Te dejo a vos que lo llenes con ejemplos :P

En especial sobre aquellos que cambia sobre la arquitectura de los pics 16F viejos
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 05 de Noviembre de 2015, 04:01:07
Jeje gracias KillerJC por ser tan atento  :lol: bueno pues creo que siempre es bueno poder aprender mas. Aqui anexo mi diagrama, leyendo la hoja de datos me encontre con algo completamente nuevo.Un Módulo PPS....  :shock: aun no se que es pero lo poco que lei es para asignar los pines de ciertos perifericos a donde tu desees. Crei que para configurar el SPI seria como los otros  :? pines ya definidos para SDO y SDI. La sorpresa es que el unico al parecer fijo es SCK.

Pero bueno vamos leyendo un poco mas sobre este PPS y veamos como trabajar con el.  :o
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 05 de Noviembre de 2015, 04:06:12
Espero ir entendiéndolo bien, anexo una foto del bloque simplificado de estos PPS. Por lo que entendí y si es que comprendo mal les pido me orienten, tenemos PPS de entrada y PPS de salida. Los cuales pueden permitir entrar información o salir segun sean configurados... eso creo  :?
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: KILLERJC en 05 de Noviembre de 2015, 11:21:41
El PPS es una de las cosas buenas que me gustan de Microchip, Como su nombre lo dice Peripherical Pin Selection permitela seleccion del pin a un modulo, Esto termina con eso de que ciertos pines eran para un modulo, y con esos pines no podias usar el USB por ejemplo. Vi otras empresa pero a lo sumo suelen tener pines fijos o maximo 2 opciones, tal ves por la frencuencia en la cual se manejan y lo complejo que seria hacerlo para 100 pines xD.

El PPS no acepta todos los modulos. sino que acepta algunos nomas
Como entrada creo que acepta todos, Pero solo permite al puerto A y C (bit0 a bit6 de ambos puertos) para servir de entradas.

Como salida solo es posible seleccionar a los siguientes modulos

• EUSART (synchronous operation)
• MSSP (I2C,SPI)
• COG (auto-shutdown)

Por lo tanto vas a tener registros para cada salida de unos de esos modulos

10010 = Rxy source is SDO
10001 = Rxy source is SDA(1)
10000 = Rxy source is SCK/SCL(1)

En el banco 28 tenes para configurar cada pin como entrada, y en el banco 29 tenes los pines para usar como salida.
Algunos requieren estar configurados como entrada Y salida al mismo tiempo, tal cual seria el SDA del I2C , o en la UART si es sincrono, un pin funciona como ambos, entrada y salida.

PD: Seguis teniendo mas cosas, nomas que estas mirando los modulos nomas xD
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 07 de Noviembre de 2015, 03:44:11
KillerJc vaya que si tiene bastantes cosas nuevas para mi  :o de las cuales estoy sorprendido. Estuve leyendo un rato el datasheet y bueno pues me encontré efectivamente lo que tu dices, hay que configurar los registros Rxy de acuerdo a lo que necesitemos. Pero antes de eso si no me equivoco, microchip recomienda desbloquear los PPS configurarlos y después volver a bloquearlos para asegurar que no haya cambios inoportunos. Bueno acá el ejemplo de como desbloquear y bloquear sacado del datasheet.

Código: ASM
  1. ; suspend interrupts
  2. bcf INTCON,GIE
  3. ; BANKSEL PPSLOCK ; set bank
  4. ; required sequence, next 5 instructions
  5. movlw 0x55
  6. movwf PPSLOCK
  7. movlw 0xAA
  8. movwf PPSLOCK
  9. ; Set PPSLOCKED bit to disable writes or
  10. ; Clear PPSLOCKED bit to enable writes
  11. bsf PPSLOCK,PPSLOCKED
  12. ; restore interrupts
  13. bsf INTCON,GIE

Bueno pues esa es la recomendación.

Aun no terminaba de comprender Rxy a que se refería y como era que se iban a configurar los PPS. Busque mas información sobre ellos y ahora creo que funciona de la siguiente manera si me equivoco corrijanme por favor.

Rxy

Donde R se refiere al registro.
x al puerto y
y al pin

Para ser mas objetivos si deseo asignar una salida SDO por ejemplo al pin RC0. Como menciono KillerJC anteriormente, hay que mover un valor= B'00010010'

Obtenido de la data en la pagina 140 donde nos indica que al cargar este valor su fuente sera SDO.

Mirar la imagen anexa.


Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 07 de Noviembre de 2015, 04:34:37
 :) Después de jugar un rato con las instrucciones ya logré enviar datos tal cual lo configure. Sin interrupciones solo con la bandera. Es un ejemplo sencillo donde envío un dato vía SPI. Bajo la siguiente configuración.

Código: ASM
  1. ; NOS POSICIONAMOS EN BANCO DE PPSLOCK
  2. ; PARA DELBLOQUEARLO
  3.     BANKSEL PPSLOCK
  4.     MOVLW   0X55
  5.     MOVWF   PPSLOCK
  6.     MOVLW   0XAA
  7.     MOVWF   PPSLOCK
  8.     BCF     PPSLOCK,PPSLOCKED
  9.     BANKSEL RC0PPS
  10.     MOVLW   B'00010010'
  11.     MOVWF   RC0PPS
  12.     MOVLW   B'00010000'
  13.     MOVWF   RC1PPS
  14. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  15.     BANKSEL PPSLOCK
  16.     MOVLW   0X55
  17.     MOVWF   PPSLOCK
  18.     MOVLW   0XAA
  19.     MOVWF   PPSLOCK
  20.     BSF     PPSLOCK,PPSLOCKED
  21. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  22.     BANKSEL SSP1CON1
  23.     MOVLW   B'00110000'
  24.     MOVWF   SSP1CON1
  25.     BANKSEL PORTB

Con esto configure el RC0 como SDO y el RC1 como SCK.

Obtuve una transmisión correcta con el siguiente código.

Código: ASM
  1. MOVLW   0XFF
  2.     CALL    DATO_SPI
  3.      CALL    RETARDO
  4.     ;;;;;;;;;;;;;;;;;;;;;
  5.     MOVLW   0X03
  6.     CALL    DATO_SPI
  7.      CALL    RETARDO
  8.     GOTO    PRINCIPAL
  9. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;    
  10. DATO_SPI
  11.     BSF     DC_NOKIA
  12.     BCF     LCD_NOKIA
  13.     BANKSEL SSP1BUF
  14.     MOVWF   SSP1BUF
  15.     BANKSEL PIR1
  16.     BCF     PIR1,SSP1IF
  17. WSPI
  18.     BTFSS   PIR1,SSP1IF
  19.     GOTO    WSPI
  20.     BCF     PIR1,SSP1IF
  21.     BANKSEL PORTA
  22.     BSF     LCD_NOKIA
  23.     RETURN


Parece que todo OK. si ven algún error me ayudan....
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 07 de Noviembre de 2015, 04:49:37
Bueno como ya solucionamos la parte del SPI que al parecer trabaja bien, ahora veamos que hay con respecto a la LCD Nokia 5110.

Como sabemos es una LCD gráfica con comunicación SPI.

(http://shop.boxtec.ch/images/45040_a.jpg)

Esta es la imagen que encontré adecuada.

Donde tenemos la siguiente información:

- Pin1 Vcc=2.7 a 3.3V
- Pin2 GND
- Pin3 Chip Select
- Pin4 Reset
- Pin5 D/C  Selección de Dato o comando
- Pin6 Din  Entrada de datos
- Pin7 SCK Señal de Reloj
- Pin 8 LED

Como vemos esta imagen tiene los pines de la misma manera y numeración que en el modelo de proteus.
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 07 de Noviembre de 2015, 04:52:29
Sacado de la hoja de datos de la LCD anexo una imagen donde vemos el modo de transmisión de datos de 1 Byte que ha quedado compatible con nuestra configuración.
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 07 de Noviembre de 2015, 04:59:57
También sacado del data sheet anexo el set de instrucciones de la LCD. Seguido de el set tenemos la parte de inicializacion de la LCD la cual consta de los siguientes pasos.

- 1. Reset por Software
- 2. Function Set
- 3. Display Control
- 4. Set y Address of RAM
- 5. Set x Address of RAM
- 6. Control de temperatura
- 7. Bias Value

Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: KILLERJC en 07 de Noviembre de 2015, 11:50:06
Excelente.. Como te vas ya a la aplicacion te voy a dejar unas lineas para que las veas y las apliques si es necesario.

- Grabado automatico del contexto al entrar a la interrupcion. Al contexto me refiero a: W,STATUS,FSR0,FSR1,PCLATCH y BSR
- Acceso indirecto: Aca tenes 2.

1- Como ves el acceso a bancos es complejo. Crear un buffer grande lo es ya que deberias estar vigilando constantemente si superaste la direccion para saltar al otro punto de registros del proximo banco, el acceso indirecto te permite hacer esto automaticamente, Entonces si tu acceso indirecto esta en 0x6F en ves de pasar a 0x70 (que se una posicion de memoria comun a todos los bancos, pasa a 0xA0 del otro banco, es decir se saltea todos los SFR tambien
2- Con el acceso indirecto podes acceder a la memoria de programa, como si esta estuviera mapeada de forma lineal, Antes unicamente podias hacerlo con las tablas, ahora con el acceso indirecto tambien. Esto es interesante, ya que te olvidas de estar pensando en que los CALL tendrias qeu cambiar la pagina O ubicar la tabla si o si al comienzo de una pagina de la flash. Sino que el acceso indirecto posee todos los bits y podrias simplemente tomar uno detras de otro.
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 07 de Noviembre de 2015, 18:21:33
KillerJC siempre con buenos consejos, mira aun no manejo las interrupciones y me quedo un poco claro lo que me has explicado. Sabes  :( siempre he batallado con el direccionamiento indirecto honestamente no lo se usar, me caería bien empezar a hacer algo con los SFRs en este PIC. Que consejo me das como un buen método de aplicación y aprendizaje del uso de el direccionamiento indirecto?

Mientras tanto cuelgo el código realizado para trabajar con esta LCD. Adjunto la imagen de la simulación.

Código: ASM
  1. #INCLUDE "P16F1707.INC"
  2.  __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOREN_OFF & _CLKOUTEN_OFF
  3.  __CONFIG _CONFIG2, _WRT_OFF & _PPS1WAY_ON & _ZCDDIS_OFF & _PLLEN_ON & _STVREN_ON & _BORV_LO & _LPBOR_OFF & _LVP_OFF
  4.  
  5.     CBLOCK  0X020
  6.     RET
  7.     RET2
  8.     ENDC
  9.  
  10.     ORG     0X00
  11.     GOTO    CONFIGURA_PIC
  12.     ORG     0X04
  13.     RETFIE
  14.  CONFIGURA_PIC
  15.     BANKSEL OSCCON
  16.     MOVLW   B'11111011'
  17.     MOVWF   OSCCON
  18.     MOVLW   B'00011111'
  19.     MOVWF   OSCTUNE
  20.     BANKSEL PORTA
  21.     CLRF    PORTA
  22.     CLRF    PORTB
  23.     CLRF    PORTC
  24.     BANKSEL LATA
  25.     CLRF    LATA
  26.     CLRF    LATB
  27.     CLRF    LATC
  28.     BANKSEL ANSELA
  29.     CLRF    ANSELA
  30.     CLRF    ANSELB
  31.     CLRF    ANSELC
  32.     BANKSEL TRISA
  33.     CLRF    TRISA
  34.     CLRF    TRISB
  35.     CLRF    TRISC
  36. ; NOS POSICIONAMOS EN BANCO DE PPSLOCK
  37. ; PARA DELBLOQUEARLO
  38.     BANKSEL PPSLOCK
  39.     MOVLW   0X55
  40.     MOVWF   PPSLOCK
  41.     MOVLW   0XAA
  42.     MOVWF   PPSLOCK
  43.     BCF     PPSLOCK,PPSLOCKED
  44.     BANKSEL RC0PPS
  45.     MOVLW   B'00010010'
  46.     MOVWF   RC0PPS
  47.     MOVLW   B'00010000'
  48.     MOVWF   RC1PPS
  49. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  50.     BANKSEL PPSLOCK
  51.     MOVLW   0X55
  52.     MOVWF   PPSLOCK
  53.     MOVLW   0XAA
  54.     MOVWF   PPSLOCK
  55.     BSF     PPSLOCK,PPSLOCKED
  56. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  57.     BANKSEL SSP1CON1
  58.     MOVLW   B'00110000'
  59.     MOVWF   SSP1CON1
  60.     BANKSEL PORTB
  61.    
  62.     #DEFINE LCD_NOKIA   PORTC,2
  63.     #DEFINE RST_NOKIA   PORTC,3
  64.     #DEFINE DC_NOKIA    PORTC,4
  65.  
  66.     BSF     RST_NOKIA
  67.     BSF     LCD_NOKIA
  68.     CALL    INI_LCD_NOKIA
  69.  PRINCIPAL
  70.  ;H
  71.     MOVLW   0X00
  72.     CALL    DATO_SPI
  73.     MOVLW   B'11111110'
  74.     CALL    DATO_SPI
  75.     MOVLW   B'00010000'
  76.     CALL    DATO_SPI
  77.     MOVLW   B'00010000'
  78.     CALL    DATO_SPI
  79.     MOVLW   B'11111110'
  80.     CALL    DATO_SPI
  81.     MOVLW   0X00
  82.     CALL    DATO_SPI
  83. ; O
  84.     MOVLW   B'01111100'
  85.     CALL    DATO_SPI
  86.     MOVLW   B'10000010'
  87.     CALL    DATO_SPI
  88.     MOVLW   B'10000010'
  89.     CALL    DATO_SPI
  90.     MOVLW   B'01111100'
  91.     CALL    DATO_SPI
  92.     MOVLW   0X00
  93.     CALL    DATO_SPI    
  94. ;L
  95.     MOVLW   B'11111110'
  96.     CALL    DATO_SPI
  97.     MOVLW   B'10000000'
  98.     CALL    DATO_SPI
  99.     MOVLW   B'10000000'
  100.     CALL    DATO_SPI
  101.     MOVLW   B'10000000'
  102.     CALL    DATO_SPI
  103.     MOVLW   0X00
  104.     CALL    DATO_SPI    
  105. ;A
  106.     MOVLW   B'11111100'
  107.     CALL    DATO_SPI
  108.     MOVLW   B'00010010'
  109.     CALL    DATO_SPI
  110.     MOVLW   B'00010010'
  111.     CALL    DATO_SPI
  112.     MOVLW   B'11111100'
  113.     CALL    DATO_SPI
  114.     MOVLW   0X00
  115.     CALL    DATO_SPI
  116.  
  117.         MOVLW   0X00
  118.     CALL    DATO_SPI
  119.    
  120.    
  121.     CALL    RETARDO
  122.     GOTO    PRINCIPAL
  123. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  124. INI_LCD_NOKIA
  125.     BCF     RST_NOKIA
  126.     NOP
  127.     BSF     RST_NOKIA
  128.     ;CREAMOS UN RESET POR SOFTWARE DE LA LCD
  129.     MOVLW   B'00100001'; SELECCIONAMOS MODO SET INSTRUCTION
  130.     CALL    COMANDO_SPI
  131.     MOVLW   B'11001111'; DEFINIMOS CONTRASTE
  132.     CALL    COMANDO_SPI
  133.     MOVLW   B'00100000';SLECCIONAMOS MODO NORMAL DE INSTRUCCION
  134.     CALL    COMANDO_SPI
  135.     MOVLW   B'00001100';DEFINIMOS MODO NORMAL DE DISPLAY
  136.     CALL    COMANDO_SPI
  137.     ;;;;;;;;;;;;;;;;;;;;;;;;; ACABAMOS LA INICIALIZACION DE LA LCD
  138.     RETURN
  139. DATO_SPI
  140.     BSF     DC_NOKIA
  141.     BCF     LCD_NOKIA
  142.     BANKSEL SSP1BUF
  143.     MOVWF   SSP1BUF
  144.     BANKSEL PIR1
  145.     BCF     PIR1,SSP1IF
  146. WSPI
  147.     BTFSS   PIR1,SSP1IF
  148.     GOTO    WSPI
  149.     BCF     PIR1,SSP1IF
  150.     BANKSEL PORTA
  151.     BSF     LCD_NOKIA
  152.     RETURN
  153. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  154. COMANDO_SPI
  155.     BCF     DC_NOKIA
  156.     BCF     LCD_NOKIA
  157.     BANKSEL SSP1BUF
  158.     MOVWF   SSP1BUF
  159.     BANKSEL PIR1
  160.     BCF     PIR1,SSP1IF
  161. WSPIC
  162.     BTFSS   PIR1,SSP1IF
  163.     GOTO    WSPIC
  164.     BCF     PIR1,SSP1IF
  165.     BANKSEL PORTA
  166.     BSF     LCD_NOKIA
  167.     RETURN
  168. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  169.    
  170.    
  171. RETARDO
  172.     MOVLW   0XFF
  173.     MOVWF   RET
  174.     MOVWF   RET2
  175. ESP
  176.     DECFSZ  RET,F
  177.     GOTO    ESP
  178.     MOVLW   0XFF
  179.     MOVWF   RET
  180.     DECFSZ  RET2,F
  181.     GOTO    ESP
  182.     RETURN
  183.     END


Saludos
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: KILLERJC en 07 de Noviembre de 2015, 19:38:25
Te puedo dar ejemplos de aplicacion que seria mejor con un acceso indirecto que uno directo. El mas clasico es un buffer. Comencemos por un buffer de 4 lugares. En el que recibis datos por la UART o SPI y vas guardando los valores, finalmente tenes que hacer un checksum de esos valores. Como harias con direccionamiento directo el guardar estos 4 lugares ?

Código: ASM
  1. Guardado
  2.         MOVF    Indice, W       ;El indice de mi dato
  3.         ADDWF   PCL, F          ; Utilizo una tabla para ir al programa donde debo guardarlo
  4.         GOTO    Dato0
  5.         GOTO    Dato1
  6.         GOTO    Dato2
  7.  
  8.         MOVF    DatoUART, W
  9.         MOVWF   Buffer3
  10.         CLRF    Indice          ; Comienzo de nuevo
  11.         RETURN
  12.  
  13. Dato0
  14.         MOVF    DatoUART, W     ; Tomo dato y guardo
  15.         MOVWF   Buffer0
  16.         RETURN
  17. Dato1
  18.         MOVF    DatoUART, W
  19.         MOVWF   Buffer1
  20.         RETURN
  21. Dato2
  22.         MOVF    DatoUART, W
  23.         MOVWF   Buffer2
  24.         RETURN


Y eso es solo para guardarlo. Ahora debo sumarlos

Código: ASM
  1. MOVF    Buffer0, W
  2.         ADDWF   Buffer1, W
  3.         ADDWF   Buffer2, W
  4.         ADDWF   Buffer3, W

Bien, solo 4 instrucciones, bastante simple, o podria sumarlos apenas van llegando eso me ahorraria instrucciones. Ahora veamos usando acceso indirecto

Antes de comenzar cargo en el FSR los el valor de buffer0, es decir su direccion.

Código: ASM
  1. MOVLW   low(Buffer0)
  2.         MOVWF   FSR0L
  3.         MOVLW   high(Buffer0)
  4.         MOVWF   FSR0H

Lo que hago con eso es decir que cuando yo acceda a INDF0 , es lo mismo que acceder a la direccion de memoria que esta cargada en FSR0, en mi caso de acceder a INDF0 accederia a Buffer0. En los PIC16 normales harias eso, aca tenes una instruccion que lo hace por si solo, solo tenes que indicarle que FSR estas tratando y que hace depues
Ahora a guardar el dato:

Código: ASM
  1. Guardado
  2.         MOVLW   d'4'
  3.         MOVWF   Contador
  4. Loop
  5.         MOVF    DatoUART, W
  6.         MOVWI   FSR0++
  7.         DECFSZ  Contador, F
  8.         RETURN
  9.  
  10. Recargar_FSR
  11.  
  12.         MOVLW   low(Buffer0)
  13.         MOVWF   FSR0L
  14.         MOVLW   high(Buffer0)
  15.         MOVWF   FSR0H
  16.         RETURN
La instruccion MOVWI, lo que hace es guardar el dato de W en la direccion que tiene FSR0 (Buffer0 ) Luego a esa direccion la incrementa por 1 apuntando ahora a Buffer1 (Al incrementar por 1 tiene en cuenta ambos registros FSR0 L y H). Entonces la proxima ves que entre va a guardar W en Buffer1 y va a apuntar a Buffer2 y asi hasta que guarde en Buffer3 y apunte a lo que sigue, ahi en ese momento me va a dar una igualdad el codigo y va a reponer el valor de FSR

Para sumar seria algo parecido

Código: ASM
  1. Guardado
  2.         MOVLW   d'4'
  3.         MOVWF   Contador
  4.         CLRF    Suma_Total
  5.         CALL    Recargar_FSR    ;Nos aseguramos que empezamos del comienzo
  6. Loop:
  7.         MOVIW   FSR0++
  8.         ADDWF   Suma_Total, F
  9.         DECFSZ  Contador, F
  10.         GOTO    Loop                    ; Todavia quedan para sumar asi que vuelve al loop
  11.         RETURN                          ; No queda mas nada

Nuevamente veo a que llegue al final y de ser asi salgo. Esta ves la instruccion es inversa (MOVIW ), tomo desde donde apunta el FSR0 y lo guardo en W. Y luego aumento FSR0.

Perfecto, pero para que complicarse la vida por 4 valores? Ahora supone que tenes un buffer de 32 lugares. No es nada lindo hacerlo con acceso directo, Y con acceso indirecto solo deberia cambiar esto (en ambos lugares ):

Código: ASM
  1. MOVLW   d'4'

por un

Código: ASM
  1. MOVLW   d'32'

Y listo funcionando :P.

Solo hay incrementos ? No. Esa instruccion permite pre y post incremento y decremento

Código: ASM
  1. MOVWI FSR0++      ; Guarda y luego aumenta
  2. MOVWI  ++FSR0     ; Aumenta y luego guarda
  3. MOVWI  FRS0--       ; Guarda y luego decrementa
  4. MOVWI  --FRS0       ; Decrementa y luego guarda.
  5. MOVWI  k[FSR0]     ; Guarda solamente, no incrementa ni decrementa., igual que hacer MOVWF INDF0

--------------------------------------------------------------------------------------------------------------

Ahora veamos un poco mas tu ejemplo.
viste el codigo que te llevo hacer un Hola no ?

Entonces hagamos algo simple para comenzar.

Vamos a crear una tabla ( no recuerdo si esta correctamente definida asi, no tuve tiempo de mirar el manual del MPASM )

Tabla:
.dt 0x00, 0xFE, 0x10, 0x10, 0xFE, 0xFC, 0x82, 0x82, 0x7C
.dt 0x00, 0xFE, 0x80, 0x80, 0x80, 0x00, 0xFC, 0x12, 0x12
.dt 0xFC, 0x00

Es un total de ... 20 datos que envias. En ves de binario los puse como hexadecimal

Código: ASM
  1. Tabla:
  2. .dt 0x00, 0xFE, 0x10, 0x10, 0xFE, 0xFC, 0x82, 0x82, 0x7C
  3. .dt 0x00, 0xFE, 0x80, 0x80, 0x80, 0x00, 0xFC, 0x12, 0x12
  4. .dt 0xFC, 0x00
  5.  
  6.  
  7.         MOVLW   low(Tabla)              ;Cargo Valor inicial de la tabla
  8.         MOVWF   FSR0L
  9.         MOVLW   high(Tabla) | 0x80
  10.         MOVWF   FSR0H
  11.  
  12.         MOVLW   d'20'                   ;Pongo la cantidad de datos a enviar
  13.         MOVWF   Contador
  14.  
  15. Loop
  16.         MOVIW   FSR0++                  ; Leo la tabla guardo en W y apunto al siguiente dato
  17.         CALL    DATO_SPI                ; LLamo a la funcion de enviar
  18.         DEFSZ   Contador, F             ; Decremetno el contador y si llego a 0 salgo, sino envio el siguiente
  19.         GOTO    Loop
  20.         ;Fin

Y listo. con acceso indirecto accediste a la memoria de programa, tomaste todos los datos que necesitaste y listo. Pero esto seguro que lo hiciste antes.. antes hacias:

Código: ASM
  1. ADDWF   PCL, F
  2.         RETLW   0x00
  3.         RETLW   0xFE
  4.         RETLW   0x10
  5.         RETLW   0x10
  6.         RETLW   0xFE
  7.         ....
  8.         RETLW   0x00

O podias usar la misma tabla que antes.. Pero esto se complicaba si la tabla estaba entre 2 paginas.
Recorda que PCL es un registros de 8 bits y por lo tanto solo puede direccionar 256 lugares. Si querias uno mas ya se ponia mas complejo por que tenias que modificar PCLATH a la entrada y a la salida de la funcion.

Esto con el acceso indirecto que permite leer la memoria de programa no hace falta. Ya que FSR0 ( Ly H ) son 16 bits y permiten direccionar toda la memoria, si hay un incremento de 1 no es complicacion para el mismo.

EDIT: Estos codigos ninguno esta probado, asi que tal ves tengan errores, pero es para que te des una idea de como usarlos, seguro que no deben de estar MUY errados. pero si puden tener algunos errores.
Corregido el tema de usar un contador
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: KILLERJC en 07 de Noviembre de 2015, 20:32:49
Otro ejemplo bastante simple y "tonto" seria el de tener que estar cambiando de bancos a cada rato. Aunque el PIC agrupa todo en un solo banco, a veces tenes que cambiar.
Supongamos que estas continuamente cambiando el valor de LATB, y ademas queres leer el PORTB. Uno esta en el banco 2 y otro en el banco 0.

Formas mas comun:

Código: ASM
  1. MOVLB   0
  2.         ;Leo PORTB
  3.         MOVF    PORTB, W
  4.  
  5.         MOVLB   2
  6.         ;Escribo LATB
  7.         MOVLW   0x10
  8.         MOVWF   LATB


Ahora con acceso indirecto, al comienzo le cargo el valor de direccion del LATB

Código: ASM
  1. MOVLW   low(LATB)
  2.         MOVWF   FSR0L
  3.         MOVLW   high(LATB)
  4.         MOVWF   FSR0H


Luego lo unico que hago es:

Código: ASM
  1. MOVLB   0       ; Estoy en el banco 0, me aseguro
  2.         ;Leo PORTB
  3.         MOVF    PORTB, W
  4.  
  5.         ;Escribo LATB
  6.         MOVLW   0x10
  7.         MOVWF   INDF0

Como el acceso indirecto tiene 16 bits para direccionar no le hace falta tener que cambiar de "bancos". En cambio las instrucciones comunes que usan acceso directo ( es decir el dato esta en su opcode) solo usan 8 bits, por lo tanto es necesario cambiar de "banco". Para el acceso indirecto no existen los bancos, es lo mejor que podes tener ya que podes direccionar toda la memoria. Utiles en casos como grandes lugares de datos a rellenar. o incluso pedir datos.

Si quisiera leer los datos del PORTA, PORTB y PORTC como estan todos seguidos podria hacerlo tanto como un acceso directo como indirecto.
Como ves es medio complejo cargar la direccion en los registros, pero si va a un PIC18 te encontras que tenes una instruccion que te permite cargar la direccion.

Entonces en ves de hacer lo que hicismos arriba solo haria un

Código: [Seleccionar]
   LFSR 0, LATB
Y cargaria toda la direccion ( por mas que sean mas de 8 bits ) al FSR0. Esto en los PIC18, este no lo posee.
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 08 de Noviembre de 2015, 05:32:35
KillerJc muchas gracias por esos ejemplos. Vamos por partes para que termine de entender:

Cuando hablamos de FSRL y FSRH entiendo que estamos refiriéndonos a la dirección únicamente?
y cuando hablamos de INDF es el dato o valor contenido dentro de esa dirección o el que vamos a mover a esa direccion?

La instrucción MOWI es nueva para mi y me quedo clara. Un pequeño ejemplo si no me equivoco si yo tengo un DatoX alojado en una dirección 0x34 por decir un ejemplo. Puedo cargar un valor a DatoX poniendo las direcciones en FSRl y FSRH. Y la literal cargarla a INDF?

La instrucción MOVIW es inversa tal cual lo dijiste del INDF movemos a W y aumenta en 1 FSR. Entendido.

Muy claros todos los ejemplos ahora, una pregunta algo tonta las direcciones de los registros que utilizo como variables siempre las he utilizado con un CBLOCK 0x020 entonces la primera enseguida corresponde a 0x020 y así sucesivamente? Si es así hasta que dirección me limita?

Y respecto al último ejemplo, anexo una imagen de los SFRs sacada del Data donde encierro la dirección del registro LATA, aquí dos preguntas. La dirección que yo debería cargar es FSRH=0x01  y FSRL=0x0C ?

Y la otra es, si yo no le indico al FSR que incremente o decremente guarda la última dirección? Por ejemplo si siempre quisiera mostrar datos por LATB puedo dejar la dirección y solo mandarlos al INDF?

Perdón se me olvidaba, en los PIC18F esa última instrucción que mencionas es para cargar la dirección del registro que indicas?

LFSR 0, LATB

De tu ejemplo,  LFSR 0,LATB   quiero entender que LSFR es algo como cargar al FSR  con dirección de R(LatB). El cero a que se refiere?


Gracias KillerJC y disculpa tantas preguntas. Me interesa aprender a manejarlos.
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: KILLERJC en 08 de Noviembre de 2015, 10:08:17
Empecemos por que no hay preguntas tontas.

Citar
Cuando hablamos de FSRL y FSRH entiendo que estamos refiriéndonos a la dirección únicamente?
y cuando hablamos de INDF es el dato o valor contenido dentro de esa dirección o el que vamos a mover a esa direccion?

Exacto, tenes varios FSR, en ese pic hay 2 FSR0 y FSR1, cada uno con su propio INDF. en los FSR la direccion y el INDF como decis accedes a la direccion que apunta el FSR

Citar
La instrucción MOWI es nueva para mi y me quedo clara. Un pequeño ejemplo si no me equivoco si yo tengo un DatoX alojado en una dirección 0x34 por decir un ejemplo. Puedo cargar un valor a DatoX poniendo las direcciones en FSRl y FSRH. Y la literal cargarla a INDF?

Correcto. La instruccion es nueva para mi tambien. Pero la MOVWI te permite hacerlo sin tener que especificar que lo moves a INDF. Por eso puse que podias hacerlo de 2 formas

MOVWI  k[FSR0]
MOVWF INDF0

Ambos son equivalentes. Utilizas distintas instrucciones,, pero el objetivo es el mismo, es guardar lo de W a donde apunta el FSR0, y no incrementar ni nada.

Citar
Muy claros todos los ejemplos ahora, una pregunta algo tonta las direcciones de los registros que utilizo como variables siempre las he utilizado con un CBLOCK 0x020 entonces la primera enseguida corresponde a 0x020 y así sucesivamente? Si es así hasta que dirección me limita?
Tenes que entender que hace CBLOCK, Con CBLOCK vos lo unico que haces es darle un valor constante a una palabra. Esto hace que tu codigo sea absoluto, es decir vos controlas exactamente donde va a estar cada variable

CBLOCK 0x20
Var1
Var2
ENDC

Var1 es una constante 0x20, y Var2 es una constante 0x21
Esto al ser una constante permite que uno pueda hacer:

MOVLW Var1
MOVLW Var2

Y es correcto, por que justamente Var1 es una constante. Hay otras formas para definir una variable, yo en un post de PIC18 creo que se trato el tema.
http://www.todopic.com.ar/foros/index.php?topic=45254.msg376570#msg376570

El usarlo asi o no hace de tu codigo por ahi mas dependiente del PIC y mas dificil de portar a otro PIC, ya que no solo te preocuparias sobre las instrucciones que son distintas sino que ademas tendrias que ver la memoria exacta. De la forma que digo yo el compilador se encarga solo de acomodar las variables donde hay lugar. Y puede evitar algunos problemas

Ahora respondiendo tu pregunta, No estas limitado en direccion. Personalmente si yo hubiera necesitado de variables muy usadas las hubiera posicionado de 0x70 a 0x7F que es compartido por todos los bancos, sino podes usar cualquier direccion que este como General Purpose Register, es decir:
0x20 a 0x6F - Banco 0
0xA0 a 0xEF - Banco 1
0x120 a 0x16F - Banco 2

Esos serian los unicos limites a respetar.

Citar
Y respecto al último ejemplo, anexo una imagen de los SFRs sacada del Data donde encierro la dirección del registro LATA, aquí dos preguntas. La dirección que yo debería cargar es FSRH=0x01  y FSRL=0x0C ?
Si asi es. Pero supongamos que cambias de micro y LATB ahora se encuentra en 0x0212 , si pones solo constantes vas a tener que cambiar eso tambien. con low(LATB) te da 0x0C y con high(LATB) te da 0x01, si por alguna razon existiera 3 bytes por que la memoria es MUY grande (24 bits), podrias usar upper(xx) esto daria el byte mas importante. Pero lo que queria recalcar es que usando high y low te olvidas de luego cambiar lo demas. si te fijas en tu .inc LATB esta definido como

LATB EQU 0x10C

Citar
Y la otra es, si yo no le indico al FSR que incremente o decremente guarda la última dirección? Por ejemplo si siempre quisiera mostrar datos por LATB puedo dejar la dirección y solo mandarlos al INDF?
El FSR no se modifica jamas por si solo, vos cargas la direccion, y a no ser que vos expresamente pidas con una instruccion que incremente o decremente, no lo va a hacer y va a mantener la misma direccion. Con lo cual tenes las dos opciones que nombre antes tanto con el MOVWI /IW como MOVWF para "acceder" a INDFx

Citar
Perdón se me olvidaba, en los PIC18F esa última instrucción que mencionas es para cargar la dirección del registro que indicas?

LFSR 0, LATB

De tu ejemplo,  LFSR 0,LATB   quiero entender que LSFR es algo como cargar al FSR  con dirección de R(LatB). El cero a que se refiere?

La instruccion que puse no recuerdo si es correcta o no. Pero no debe estar muy lejos. Esa instruccion ocupa 2 lugares de memoria, pero en su opcode pueden tener hasta 12bits ( y no 8 como la mayoria ) entonces lo que hace es cargar los 12 bits de direccion de LATB a FSR0 , el 0 indica a que FSR lo envio.

Cualquier otra pregunta que se te ocurra, podes hacerla sin problemas
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 08 de Noviembre de 2015, 11:09:52
Creo que explicas demasiado bien KillerJC  ((:-)) muchisimas gracias, bueno pues como me dejas la puerta abierta a otras preguntas. Los otros FSRs, funcionan igual? Y acaso sirven para poder manejar direccionamiento indirecto con 2 registros diferentes sin que se alteren el uno al otro?

Saludos y de nuevo muchas gracias.

Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: KILLERJC en 08 de Noviembre de 2015, 23:29:39
En ese PIC tenes 2 FSR, independientes uno de otro. Y si funcionan igual.

En otros PICs a veces algun FSR tiene unas propiedas mas. Por ejemplo en el PIC18 el FSR2 se usa en el modo extendido de instrucciones, los demas FSR ( 0 y 1 ) no se pueden usar para el acceso a memoria + offset. En fin esto es un caso especial, y activar el set de instrucciones extendido es un caso MUY raro de ver si alguno programa en ASM.

Respecto a un programa que use 2 FSR podria ser el de copiar un buffer a otro lado.

FSR0 = Buffer0
FSR1 = Buffer1

Y luego haces un

MOVIW FSR0++
MOVWI FSR1++

Repetis eso varias veces y estarias copiando los valores a otro buffer.  Por mas que sean 64 valores solo necesitas repetir esas 2 instrucciones 64 veces. El FSR0 seria el origen y el FSR1 el destino, podria haber cargado la ultima posicion de memoria y haber invertido el buffer
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 09 de Noviembre de 2015, 00:57:16
Excelente información KillerJC  :-/ deberiamos tener en el foro puntos por consejos dados y tu estarias repleto de puntos. Bueno sigo trabajando en ejemplos y los colgaré espero no equivocarme. Solo una pregunta más, las tablas las he manejado muy poco solo con el PCL y a lo mucho unos 20 saltos no más. Como ingreso la dirección de la tabla? Es decir como se donde le puedo asignar un origen? Si ocupo varias tablas para generar distintos caracteres que direccion le puedo dar a cada una?


Saludos
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: KILLERJC en 09 de Noviembre de 2015, 01:23:35
De la misma forma que te di el ejemplo antes.. Supongamos que tenes una tabla

Código: ASM
  1. Tabla:
  2. .dt 0x00, 0xFE, 0x10, 0x10, 0xFE, 0xFC, 0x82, 0x82, 0x7C
  3. .dt 0x00, 0xFE, 0x80, 0x80, 0x80, 0x00, 0xFC, 0x12, 0x12
  4. .dt 0xFC, 0x00
  5.  
  6.  
  7.         MOVLW   low(Tabla)              ;Cargo Valor inicial de la tabla
  8.         MOVWF   FSR0L
  9.         MOVLW   high(Tabla) | 0x80
  10.         MOVWF   FSR0H

El .dt hace que los datos que pones se transformen en instrucciones RETLW

.dt 0xFC, 0x00, 0x75

El compilador lo transforma en

RETLW 0xFC
RETLW 0x00
RETLW 0x75

Y Tabla ( es decir la etiqueta ) es la direccion del primer elemento de todos esos RETLW

Citar
Si ocupo varias tablas para generar distintos caracteres que direccion le puedo dar a cada una?
No entiendo por que necesitas tantos caracteres, si las letras estan en la ROM

Si vos decis que queres tener varios mensajes a mostrar en el LCD podrias tener algo asi:

Código: ASM
  1. Mensaje1: .dt "Hola Hola Hola",0x00
  2. Mensaje2: .dt "Aca otro mensaje",0x00
  3. Mensaje3: .dt "Nuevo mensaje",0x00

Entonces luego cargas en el FSR la direccion de Mensaje1 2 o 3 segun quieras mostrar y envias al LCD hasta que encuentre un 0x00 el cual le va a indicar que termine el string ese

Código: ASM
  1. Enviar_mensajes
  2.  
  3.         MOVLW   low(Mensaje1)           ;Cargo Valor inicial de la tabla
  4.         MOVWF   FSR0L
  5.         MOVLW   high(Mensaje1) | 0x80
  6.         MOVWF   FSR0H
  7.         CALL Enviar                     ;Envio Mensaje1
  8.  
  9.         MOVLW   low(Mensaje2)           ;Cargo Valor inicial de la tabla
  10.         MOVWF   FSR0L
  11.         MOVLW   high(Mensaje2) | 0x80
  12.         MOVWF   FSR0H
  13.         CALL Enviar                     ;Envio Mensaje2
  14.  
  15.         MOVLW   low(Mensaje3)           ;Cargo Valor inicial de la tabla
  16.         MOVWF   FSR0L
  17.         MOVLW   high(Mensaje3) | 0x80
  18.         MOVWF   FSR0H
  19.         CALL Enviar                     ;Envio Mensaje3
  20.  
  21.         RETURN
  22.  
  23. Enviar
  24.         MOVIW   FSR0++          ; W = [FSR0] , luego FSR0 = FSR0 + 1
  25.         CALL    Enviar_a_LCD    ; Llamo a la rutina para que envie el valor de W
  26.         MOVIW   k[FSR0]         ; Pregunto si el valor que esta ahora es 0, W = [FSR0], la instruccion actualiza Z
  27.         BTFSS   STATUS,Z       
  28.         GOTO    Enviar          ; No es 0 entonces la palabra sigue
  29.         RETURN                  ; Es 0 entonces salgo

Observa que en los comentarios puse [FSR0] como para indicar el contenido de lo que apunta el FSR0.

Si tenes mas dudas te las repsondo, si seguis con los ejemplos veo si es posible indicarte algo para que quede mas compacto por ejemplo.

------------------

EDIT: No se si el valor que se carga es correcto y perteneciente a la etiqueta, tal ves para acceder correctamente a la memoria de probramaa se necesite ponerle un 1 en el bit 7
Tal cual puse en el caso del Mensaje 3.
Esto por que se necesita ese bit en 1 para acceder a la memoria de programa. Hay que probar , ya que es nuevo para mi tambien.
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: RALF2 en 09 de Noviembre de 2015, 12:05:11
Hola amigos.
Killerjc, que hace esta instruccion:  MOVLW   low(Tabla), low(tabla) es una etiqueta?no entiendo como haces el llamado a la tabla y la toma de datos de la misma  :? me lo podrias aclarar  :mrgreen:

Gracias
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: KILLERJC en 09 de Noviembre de 2015, 12:34:11
Tabla es una etiqueta. La etiqueta no es mas que una direccion. Ejemplo cuando haces:

Código: ASM
  1. Loop:
  2.    GOTO  Loop


Eso es un loop infinito, "Loop" representa la direccion. "Loop" no es una instruccion y no ocupa espacio de memoria. Entonces el compilador luego reemplaza eso. Suponete que ese GOTO ocupa la posicion de memoria 0x350 , entonces Loop vale/representa 0x350, el compilador luego cuando lo pasa a codigo maquina o opcode pasa eso a

Código: ASM
  1. GOTO 0x350

Recorda que el GOTO recibe un literal de hasta 11 bits ( no como la mayoria que solo acepta 8 bits )

Ahora con eso en mente, en el que el Label ( Etiqueta ) es simplemente la direccion. Cuando uno hace esto:

Código: ASM
  1. low(Loop)

el resultado es un numero igual a 0x50 y si hago el high() el numero es un 0x03, como eso es un numero, muevo ese numero a W y luego lo pongo en el registro FSR, asi indicando el comienzo.

Solo decirte que este PIC es "especial" y permite que el acceso indirecto pueda acceder a la memoria de programa, ya que para el acceso directo esta mapeado como una memoria lineal
Un error mio es poner los valores asi nomas

Código: ASM
  1. MOVLW   low(Tabla)              ;Cargo Valor inicial de la tabla
  2.         MOVWF   FSR0L
  3.         MOVLW   high(Tabla)
  4.         MOVWF   FSR0H

Eso es incorrecto. La direccion de memoria es correcta, pero la memoria mapeada comienza en 0x8000 para la flash.
Es decir En el acceso indirecto (FSR) la direccion 0x8000 corresponde al 0x0000 de la flash

Por eso mi edit diciendo que me habia equivocado. Y lo correcto seria

Código: ASM
  1. MOVLW   low(Tabla)           ;Cargo Valor inicial de la tabla
  2.         MOVWF   FSR0L
  3.         MOVLW   high(Tabla) | 0x80       ; Aca ademas de tomar la direccion alta de memoria le pongo un 1 al bit 7 asi acceder a la flash
  4.         MOVWF   FSR0H

Espero que esto resuelva tu pregunta y ademas aclare a Pinolillo el error que estuve cometiendo todo este tiempo en los anteriores post. Tal ves sea mejor editarlos a todos asi nadie termina confundido la primera ves que lo lee e intenta probarlos
EDITADO y corregido lo anterior
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: RALF2 en 09 de Noviembre de 2015, 13:21:39
A ok, ahora si entiendo, no habia visto esas instruccion en asm de low(table) o high(tabla) de alli mi duda  :mrgreen:
Y bien claro lo del acceso a la memoria flash por medio de los FSR  :mrgreen:

Gracias

Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: KILLERJC en 09 de Noviembre de 2015, 13:29:45
Lo que ahora me hiciste dudar es si es low(Tabla) y high(Tabla)

Y puede ser

Código: ASM
  1. MOVLW   LOW Tabla              ;Cargo Valor inicial de la tabla
  2.         MOVWF   FSR0L
  3.         MOVLW   HIGH (Tabla | 0x8000)
  4.         MOVWF   FSR0H

Esto me pasa por que se me mezclan todos los assemblers entre pic16/18/dsPIC
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 09 de Noviembre de 2015, 21:06:03
Que tal KillerJC ya quede un poco confundido con lo de la memoria,  :shock: no me terminaba de quedar clara la dirección que me genera cada etiqueta, y en los ejemplos que me diste en MOVLW LOW(TABLA) no sabia si era literalmente hablando escribirlo. Y sí si fue así  :) es nuevo para mi todo esto pero es bastante interesante saber que puedes optimizar mucho código. Bueno la primera que modificación que hice fue esta:

Código: ASM
  1. INIT_NOKIA
  2.     MOVIW   FSR0++
  3.     CALL    COMANDO_SPI
  4.     ;MOVIW   k[FSR0]
  5.     ;BTFSS   STATUS,Z
  6.     ;GOTO    INIT_NOKIA
  7.      MOVIW   FSR0++
  8.      CALL    COMANDO_SPI
  9.      MOVIW   FSR0++
  10.      CALL    COMANDO_SPI
  11.      MOVIW   FSR0++
  12.      CALL    COMANDO_SPI
  13.      MOVIW   FSR0++
  14.     CALL    COMANDO_SPI
  15.     RETURN

Esto lo hice así porque al principio no me funcionaba bien esta instrucción:

Código: ASM
  1. MOVIW   k[FSR0]

Primero me genero un error, despues busque información sobre esa instrucción y lei que K es una constante que se suma a FSR0 cuando se mueve a W entonces al estar asignando cualquier numero no me funcionaba porque nunca se activaba mi bit Zero.

Finalmente el código de inicialización me quedo así y funciono perfectamente.
Código: ASM
  1. INIT_NOKIA
  2.     MOVIW   FSR0++
  3.     CALL    COMANDO_SPI
  4.     MOVIW   [FSR0]
  5.     BTFSS   STATUS,Z
  6.     GOTO    INIT_NOKIA
  7.     RETURN
  8.    
  9.    
  10.     INICIA_NOKIA: dt 0X21,0XCF,0X20,0X0C,0X00

Sustituyendolo por los MOVLW de configuración que tenia en un principio.
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 09 de Noviembre de 2015, 21:14:37
Perdón y mis direcciones quedaron de la siguiente manera:
Código: ASM
  1. MOVLW   LOW(INICIA_NOKIA)
  2.     MOVWF   FSR0L
  3.     MOVLW   HIGH(INICIA_NOKIA)
  4.     MOVWF   FSR0H

Entonces con lo último que me dices, está bien mi codigo? Refiriendonos a la parte de las direcciones de la tabla?. Las instrucciones de las direcciones en tabla como lo acabamos de hacer si se han asignado de manera correcta se puede hacer esto con cualquier PIC? y por último no se si he encontrado el correcto data pero no encuentro las direcciones donde tengo los caracteres de esta LCD, no la he manejado mucho solo he realizado pequeños dibujitos en ella pero nunca mire que ya tenia los caracteres, no sera mucha molestia si me dices en que parte puedo encontrarlos?

Saludos y de nuevo muchas gracias.
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 09 de Noviembre de 2015, 21:48:14
Bueno aca otra modificación del mismo programa ahora usando los FSRs para enviar los mensajes, en definitiva mucho mejor.  :-/
Código: ASM
  1. #INCLUDE "P16F1707.INC"
  2.  __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOREN_OFF & _CLKOUTEN_OFF
  3.  __CONFIG _CONFIG2, _WRT_OFF & _PPS1WAY_ON & _ZCDDIS_OFF & _PLLEN_ON & _STVREN_ON & _BORV_LO & _LPBOR_OFF & _LVP_OFF
  4.  
  5.     CBLOCK  0X020
  6.     RET
  7.     RET2
  8.     CONTADOR_BYTES
  9.     ENDC
  10.  
  11.     ORG     0X00
  12.     GOTO    CONFIGURA_PIC
  13.     ORG     0X04
  14.     RETFIE
  15.  CONFIGURA_PIC
  16.     BANKSEL OSCCON
  17.     MOVLW   B'11111011'
  18.     MOVWF   OSCCON
  19.     MOVLW   B'00011111'
  20.     MOVWF   OSCTUNE
  21.     BANKSEL PORTA
  22.     CLRF    PORTA
  23.     CLRF    PORTB
  24.     CLRF    PORTC
  25.     BANKSEL LATA
  26.     CLRF    LATA
  27.     CLRF    LATB
  28.     CLRF    LATC
  29.     BANKSEL ANSELA
  30.     CLRF    ANSELA
  31.     CLRF    ANSELB
  32.     CLRF    ANSELC
  33.     BANKSEL TRISA
  34.     CLRF    TRISA
  35.     CLRF    TRISB
  36.     CLRF    TRISC
  37. ; NOS POSICIONAMOS EN BANCO DE PPSLOCK
  38. ; PARA DELBLOQUEARLO
  39.     BANKSEL PPSLOCK
  40.     MOVLW   0X55
  41.     MOVWF   PPSLOCK
  42.     MOVLW   0XAA
  43.     MOVWF   PPSLOCK
  44.     BCF     PPSLOCK,PPSLOCKED
  45.     BANKSEL RC0PPS
  46.     MOVLW   B'00010010'
  47.     MOVWF   RC0PPS
  48.     MOVLW   B'00010000'
  49.     MOVWF   RC1PPS
  50. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  51.     BANKSEL PPSLOCK
  52.     MOVLW   0X55
  53.     MOVWF   PPSLOCK
  54.     MOVLW   0XAA
  55.     MOVWF   PPSLOCK
  56.     BSF     PPSLOCK,PPSLOCKED
  57. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  58.     BANKSEL SSP1CON1
  59.     MOVLW   B'00110000'
  60.     MOVWF   SSP1CON1
  61.     BANKSEL PORTB
  62.    
  63.     #DEFINE LCD_NOKIA   PORTC,2
  64.     #DEFINE RST_NOKIA   PORTC,3
  65.     #DEFINE DC_NOKIA    PORTC,4
  66.  
  67.     BSF     RST_NOKIA
  68.     BSF     LCD_NOKIA
  69.     CALL    INI_LCD_NOKIA
  70.  
  71.  PRINCIPAL
  72.     MOVLW   LOW(HOLA_MENSAJE)
  73.     MOVWF   FSR0L
  74.     MOVLW   HIGH(HOLA_MENSAJE)
  75.     MOVWF   FSR0H
  76.     MOVLW   .20
  77.     CALL    MENSAJE_X_BYTES
  78.     GOTO    PRINCIPAL
  79. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  80. MENSAJE_X_BYTES
  81.     MOVWF   CONTADOR_BYTES
  82. WRITING_LCD    
  83.     MOVIW   FSR0++
  84.     CALL    DATO_SPI
  85.     DECFSZ  CONTADOR_BYTES,F
  86.     GOTO    WRITING_LCD
  87.     RETURN
  88.    
  89.    
  90.    
  91. INI_LCD_NOKIA
  92.     BCF     RST_NOKIA
  93.     NOP
  94.     BSF     RST_NOKIA
  95.     ;CREAMOS UN RESET POR SOFTWARE DE LA LCD
  96.     MOVLW   LOW(INICIA_NOKIA)
  97.     MOVWF   FSR0L
  98.     MOVLW   HIGH(INICIA_NOKIA)
  99.     MOVWF   FSR0H
  100. INIT_NOKIA
  101.     MOVIW   FSR0++
  102.     CALL    COMANDO_SPI
  103.     MOVIW   [FSR0]
  104.     BTFSS   STATUS,Z
  105.     GOTO    INIT_NOKIA
  106.     RETURN
  107. SET_Y
  108.     ADDLW   B'01000000'
  109.     CALL    COMANDO_SPI
  110.     RETURN
  111. SET_X
  112.     ADDLW   B'10000000'
  113.     CALL    COMANDO_SPI
  114.     RETURN
  115.    
  116.    
  117.     INICIA_NOKIA: dt 0X21,0XCF,0X20,0X0C,0X00
  118.    
  119.     HOLA_MENSAJE: dt 0XFE,0X10,0X10,0XFE,0X00,0X7C,0X82,0X82,0X7C,0X00,0XFE,0X80,0X80,0X80,0X00,0XFC,0X12,0X12,0XFC,0X00;A
  120.  
  121.  
  122.  
  123. DATO_SPI
  124.     BSF     DC_NOKIA
  125.     BCF     LCD_NOKIA
  126.     BANKSEL SSP1BUF
  127.     MOVWF   SSP1BUF
  128.     BANKSEL PIR1
  129.     BCF     PIR1,SSP1IF
  130. WSPI
  131.     BTFSS   PIR1,SSP1IF
  132.     GOTO    WSPI
  133.     BCF     PIR1,SSP1IF
  134.     BANKSEL PORTA
  135.     BSF     LCD_NOKIA
  136.     RETURN
  137. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  138. COMANDO_SPI
  139.     BCF     DC_NOKIA
  140.     BCF     LCD_NOKIA
  141.     BANKSEL SSP1BUF
  142.     MOVWF   SSP1BUF
  143.     BANKSEL PIR1
  144.     BCF     PIR1,SSP1IF
  145. WSPIC
  146.     BTFSS   PIR1,SSP1IF
  147.     GOTO    WSPIC
  148.     BCF     PIR1,SSP1IF
  149.     BANKSEL PORTA
  150.     BSF     LCD_NOKIA
  151.     RETURN
  152. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  153.  
  154.    
  155. RETARDO
  156.     MOVLW   0XFF
  157.     MOVWF   RET
  158.     MOVWF   RET2
  159. ESP
  160.     DECFSZ  RET,F
  161.     GOTO    ESP
  162.     MOVLW   0XFF
  163.     MOVWF   RET
  164.     DECFSZ  RET2,F
  165.     GOTO    ESP
  166.     RETURN
  167.     END
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 09 de Noviembre de 2015, 22:09:23
Jugando un poco mas logramos un saludo para la comunidad.  :) 

Código: ASM
  1. #INCLUDE "P16F1707.INC"
  2.  __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOREN_OFF & _CLKOUTEN_OFF
  3.  __CONFIG _CONFIG2, _WRT_OFF & _PPS1WAY_ON & _ZCDDIS_OFF & _PLLEN_ON & _STVREN_ON & _BORV_LO & _LPBOR_OFF & _LVP_OFF
  4.  
  5.     CBLOCK  0X020
  6.     RET
  7.     RET2
  8.     CONTADOR_BYTES
  9.     ENDC
  10.  
  11.     ORG     0X00
  12.     GOTO    CONFIGURA_PIC
  13.     ORG     0X04
  14.     RETFIE
  15.  CONFIGURA_PIC
  16.     BANKSEL OSCCON
  17.     MOVLW   B'11111011'
  18.     MOVWF   OSCCON
  19.     MOVLW   B'00011111'
  20.     MOVWF   OSCTUNE
  21.     BANKSEL PORTA
  22.     CLRF    PORTA
  23.     CLRF    PORTB
  24.     CLRF    PORTC
  25.     BANKSEL LATA
  26.     CLRF    LATA
  27.     CLRF    LATB
  28.     CLRF    LATC
  29.     BANKSEL ANSELA
  30.     CLRF    ANSELA
  31.     CLRF    ANSELB
  32.     CLRF    ANSELC
  33.     BANKSEL TRISA
  34.     CLRF    TRISA
  35.     CLRF    TRISB
  36.     CLRF    TRISC
  37. ; NOS POSICIONAMOS EN BANCO DE PPSLOCK
  38. ; PARA DELBLOQUEARLO
  39.     BANKSEL PPSLOCK
  40.     MOVLW   0X55
  41.     MOVWF   PPSLOCK
  42.     MOVLW   0XAA
  43.     MOVWF   PPSLOCK
  44.     BCF     PPSLOCK,PPSLOCKED
  45.     BANKSEL RC0PPS
  46.     MOVLW   B'00010010'
  47.     MOVWF   RC0PPS
  48.     MOVLW   B'00010000'
  49.     MOVWF   RC1PPS
  50. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  51.     BANKSEL PPSLOCK
  52.     MOVLW   0X55
  53.     MOVWF   PPSLOCK
  54.     MOVLW   0XAA
  55.     MOVWF   PPSLOCK
  56.     BSF     PPSLOCK,PPSLOCKED
  57. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  58.     BANKSEL SSP1CON1
  59.     MOVLW   B'00110000'
  60.     MOVWF   SSP1CON1
  61.     BANKSEL PORTB
  62.    
  63.     #DEFINE LCD_NOKIA   PORTC,2
  64.     #DEFINE RST_NOKIA   PORTC,3
  65.     #DEFINE DC_NOKIA    PORTC,4
  66.  
  67.     BSF     RST_NOKIA
  68.     BSF     LCD_NOKIA
  69.     CALL    INI_LCD_NOKIA
  70.  
  71.  PRINCIPAL
  72.     MOVLW   .1
  73.     CALL    SET_Y
  74.     MOVLW   .30
  75.     CALL    SET_X
  76.     MOVLW   LOW(HOLA_MENSAJE)
  77.     MOVWF   FSR0L
  78.     MOVLW   HIGH(HOLA_MENSAJE)
  79.     MOVWF   FSR0H
  80.     MOVLW   .20
  81.     CALL    MENSAJE_X_BYTES
  82.     MOVLW   .3
  83.     CALL    SET_Y
  84.     MOVLW   .23
  85.     CALL    SET_X
  86.     MOVLW   LOW(TODO_MENSAJE)
  87.     MOVWF   FSR0L
  88.     MOVLW   HIGH(TODO_MENSAJE)
  89.     MOVWF   FSR0H
  90.     MOVLW   .21
  91.     CALL    MENSAJE_X_BYTES
  92. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  93.     MOVLW   LOW(PIC_MENSAJE)
  94.     MOVWF   FSR0L
  95.     MOVLW   HIGH(PIC_MENSAJE)
  96.     MOVWF   FSR0H
  97.     MOVLW   .14
  98.     CALL    MENSAJE_X_BYTES
  99.    
  100. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  101.     CALL    RETARDO
  102.     GOTO    PRINCIPAL
  103. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  104. MENSAJE_X_BYTES
  105.     MOVWF   CONTADOR_BYTES
  106. WRITING_LCD    
  107.     MOVIW   FSR0++
  108.     CALL    DATO_SPI
  109.     DECFSZ  CONTADOR_BYTES,F
  110.     GOTO    WRITING_LCD
  111.     RETURN
  112.    
  113.    
  114.    
  115. INI_LCD_NOKIA
  116.     BCF     RST_NOKIA
  117.     NOP
  118.     BSF     RST_NOKIA
  119.     ;CREAMOS UN RESET POR SOFTWARE DE LA LCD
  120.     MOVLW   LOW(INICIA_NOKIA)
  121.     MOVWF   FSR0L
  122.     MOVLW   HIGH(INICIA_NOKIA)
  123.     MOVWF   FSR0H
  124. INIT_NOKIA
  125.     MOVIW   FSR0++
  126.     CALL    COMANDO_SPI
  127.     MOVIW   [FSR0]
  128.     BTFSS   STATUS,Z
  129.     GOTO    INIT_NOKIA
  130.     RETURN
  131. SET_Y
  132.     ADDLW   B'01000000'
  133.     CALL    COMANDO_SPI
  134.     RETURN
  135. SET_X
  136.     ADDLW   B'10000000'
  137.     CALL    COMANDO_SPI
  138.     RETURN
  139.    
  140.    
  141.     INICIA_NOKIA: dt 0X21,0XCF,0X20,0X0C,0X00
  142.    
  143.     HOLA_MENSAJE: dt 0XFE,0X10,0X10,0XFE,0X00,0X7C,0X82,0X82,0X7C,0X00,0XFE,0X80,0X80,0X80,0X00,0XFC,0X12,0X12,0XFC,0X00;A
  144.     TODO_MENSAJE: dt 0X02,0X02,0XFE,0X02,0X02,0X00,0X7C,0X82,0X82,0X7C,0X00,0XFE,0X82,0X82,0X7C,0X00,0X7C,0X82,0X82,0X7C,0X00
  145.     PIC_MENSAJE:  dt 0X00,0X00,0XFE,0X12,0X12,0X0C,0X00,0XFE,0X00,0X7C,0X82,0X82,0X44,0X00
  146.  
  147.  
  148.  
  149.  DATO_SPI
  150.     BSF     DC_NOKIA
  151.     BCF     LCD_NOKIA
  152.     BANKSEL SSP1BUF
  153.     MOVWF   SSP1BUF
  154.     BANKSEL PIR1
  155.     BCF     PIR1,SSP1IF
  156. WSPI
  157.     BTFSS   PIR1,SSP1IF
  158.     GOTO    WSPI
  159.     BCF     PIR1,SSP1IF
  160.     BANKSEL PORTA
  161.     BSF     LCD_NOKIA
  162.     RETURN
  163. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  164. COMANDO_SPI
  165.     BCF     DC_NOKIA
  166.     BCF     LCD_NOKIA
  167.     BANKSEL SSP1BUF
  168.     MOVWF   SSP1BUF
  169.     BANKSEL PIR1
  170.     BCF     PIR1,SSP1IF
  171. WSPIC
  172.     BTFSS   PIR1,SSP1IF
  173.     GOTO    WSPIC
  174.     BCF     PIR1,SSP1IF
  175.     BANKSEL PORTA
  176.     BSF     LCD_NOKIA
  177.     RETURN
  178. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  179.  
  180.    
  181. RETARDO
  182.     MOVLW   0XFF
  183.     MOVWF   RET
  184.     MOVWF   RET2
  185. ESP
  186.     DECFSZ  RET,F
  187.     GOTO    ESP
  188.     MOVLW   0XFF
  189.     MOVWF   RET
  190.     DECFSZ  RET2,F
  191.     GOTO    ESP
  192.     RETURN
  193.     END
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: KILLERJC en 09 de Noviembre de 2015, 22:52:45
Bueno parece que ultimamente le estoy errando a todo..

Citar
por último no se si he encontrado el correcto data pero no encuentro las direcciones donde tengo los caracteres de esta LCD, no la he manejado mucho solo he realizado pequeños dibujitos en ella pero nunca mire que ya tenia los caracteres, no sera mucha molestia si me dices en que parte puedo encontrarlos?

Es correcto, nomas que yo me equivoque con un LCD 2x16, Ese es un LCD grafico asi que no posee una ROM con caracteres

Citar
Esto lo hice así porque al principio no me funcionaba bien esta instrucción:
MOVIW   k[FSR0]

Para mi es nueva la instruccion tambien, y solo tome lo del datasheet, me parecia raro esa k, pero como estba escrito asi en el datasheet procedi a copiarlo de esa forma. Como te decia, es nueva para mi y nunca la use, solo sabia para que se usaba.

Citar
Entonces con lo último que me dices, está bien mi codigo? Refiriendonos a la parte de las direcciones de la tabla?. Las instrucciones de las direcciones en tabla como lo acabamos de hacer si se han asignado de manera correcta se puede hacer esto con cualquier PIC?

Tal ves el compilador ya le agrega el 1 a la direccion de la etiqueta, eso no va a modificar el programa ya que los CALL/GOTO solo usan 11 bits.
Como es nuevo para mi tambien, me asegure con ponerle el bit a 1. Por si las dudas el compilador no lo tomaba. Pero si en algun momento queres leer la memoria flash recorda que tenes ese 1.
Nuevamente se el funcionamiento pero me faltaba probarlo para decirte exactametne si funciona asi o no.
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 10 de Noviembre de 2015, 14:12:17
Bueno parece que si esta bien el código ahora la idea es empezar a trabajar con el módulo ADC para poder hacer algo más con este micro.

Acá el bloque de la configuración del ADC vamos viendo como realizar la correcta configuración.

Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 10 de Noviembre de 2015, 14:29:36
De la hoja de datos, tiene el siguiente procedimiento:

1. Configure Port:
• Disable pin output driver (Refer to the TRIS
register)
• Configure pin as analog (Refer to the ANSEL
register)
2. Configure the ADC module:
• Select ADC conversion clock
• Configure voltage reference
• Select ADC input channel
• Turn on ADC module
3. Configure ADC interrupt (optional):
• Clear ADC interrupt flag
• Enable ADC interrupt
• Enable peripheral interrupt
• Enable global interrupt(1)
4. Wait the required acquisition time(2).
5. Start conversion by setting the GO/DONE bit.
6. Wait for ADC conversion to complete by one of
the following:
• Polling the GO/DONE bit
• Waiting for the ADC interrupt (interrupts
enabled)
7. Read ADC Result.
8. Clear the ADC interrupt flag (required if interrupt
is enabled).

Con el código:

Código: ASM
  1. ;This code block configures the ADC
  2. ;for polling, Vdd and Vss references, FRC
  3. ;oscillator and AN0 input.
  4. ;
  5. ;Conversion start & polling for completion
  6. ; are included.
  7. ;
  8. BANKSEL ADCON1 ;
  9. MOVLW B’11110000;Right justify, FRC
  10. ;oscillator
  11. MOVWF ADCON1 ;Vdd and Vss Vref
  12. BANKSEL TRISA ;
  13. BSF TRISA,0 ;Set RA0 to input
  14. BANKSEL ANSEL ;
  15. BSF ANSEL,0 ;Set RA0 to analog
  16. BANKSEL ADCON0 ;
  17. MOVLW B’00000001;Select channel AN0
  18. MOVWF ADCON0 ;Turn ADC On
  19. CALL SampleTime ;Acquisiton delay
  20. BSF ADCON0,ADGO ;Start conversion
  21. BTFSC ADCON0,ADGO ;Is conversion done?
  22. GOTO $-1 ;No, test again
  23. BANKSEL ADRESH ;
  24. MOVF ADRESH,W ;Read upper 2 bits
  25. MOVWF RESULTHI ;store in GPR space
  26. BANKSEL ADRESL ;
  27. MOVF ADRESL,W ;Read lower 8 bits
  28. MOVWF RESULTLO ;Store in GPR space
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 11 de Noviembre de 2015, 04:26:36
Bueno después de pelear un rato con los bancos de memoria nuevamente... Aquí esta el código ejemplo para un ADC con el PIC16F1707. Es el primero e iremos haciendo modificaciones.

Código: ASM
  1. #INCLUDE "P16F1707.INC"
  2.  __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOREN_OFF & _CLKOUTEN_OFF
  3.  __CONFIG _CONFIG2, _WRT_OFF & _PPS1WAY_ON & _ZCDDIS_OFF & _PLLEN_ON & _STVREN_ON & _BORV_LO & _LPBOR_OFF & _LVP_OFF
  4.  
  5.     CBLOCK  0X020
  6.     RET
  7.     RET2
  8.     CONTADOR_BYTES
  9.     RESULTHI
  10.     RESULTLO
  11.     ENDC
  12.  
  13.     ORG     0X00
  14.     GOTO    CONFIGURA_PIC
  15.     ORG     0X04
  16.     RETFIE
  17.  CONFIGURA_PIC
  18.     BANKSEL OSCCON
  19.     MOVLW   B'11111011'
  20.     MOVWF   OSCCON
  21.     MOVLW   B'00011111'
  22.     MOVWF   OSCTUNE
  23.     BANKSEL PORTA
  24.     CLRF    PORTA
  25.     CLRF    PORTB
  26.     CLRF    PORTC
  27.     BANKSEL LATA
  28.     CLRF    LATA
  29.     CLRF    LATB
  30.     CLRF    LATC
  31.     BANKSEL ANSELA
  32.     CLRF    ANSELA
  33.     CLRF    ANSELB
  34.     CLRF    ANSELC
  35.     BANKSEL TRISA
  36.     CLRF    TRISA
  37.     CLRF    TRISB
  38.     CLRF    TRISC
  39. ; NOS POSICIONAMOS EN BANCO DE PPSLOCK
  40. ; PARA DELBLOQUEARLO
  41. ;    BANKSEL PPSLOCK
  42. ;    MOVLW   0X55
  43. ;    MOVWF   PPSLOCK
  44. ;    MOVLW   0XAA
  45. ;    MOVWF   PPSLOCK
  46. ;    BCF            PPSLOCK,PPSLOCKED
  47. ;    BANKSEL RC0PPS
  48. ;    MOVLW   B'00010010'
  49. ;    MOVWF   RC0PPS
  50. ;    MOVLW   B'00010000'
  51. ;    MOVWF   RC1PPS
  52. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  53. ;    BANKSEL PPSLOCK
  54. ;    MOVLW   0X55
  55. ;    MOVWF   PPSLOCK
  56. ;    MOVLW   0XAA
  57. ;    MOVWF   PPSLOCK
  58. ;    BSF            PPSLOCK,PPSLOCKED
  59. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  60. ;    BANKSEL SSP1CON1
  61. ;    MOVLW   B'00110000'
  62. ;    MOVWF   SSP1CON1
  63. ;;;; VAMOS A CONFIGURAR EL ADC
  64.     BANKSEL ADCON1 ;
  65.     MOVLW   B'01100000'
  66.     MOVWF   ADCON1
  67.     BANKSEL TRISA
  68.     BSF     TRISA,0    
  69.     BANKSEL ANSELA ;
  70.     BSF     ANSELA,0
  71.     BANKSEL PORTB
  72.     CLRF    PORTA
  73.     CLRF    PORTB
  74.     CLRF    PORTC
  75.  
  76.  
  77. PRINCIPAL
  78.     CALL    CONV_ADC
  79.     MOVF    RESULTHI,W
  80.     BANKSEL LATC
  81.     MOVWF   LATC
  82.     BANKSEL PORTC
  83.     CALL    RETARDO
  84.     GOTO    PRINCIPAL
  85.  
  86. CONV_ADC
  87.     BANKSEL ADCON0 ;
  88.     MOVLW   B'00000001' ;Select channel AN0
  89.     MOVWF   ADCON0 ;Turn ADC On  
  90.     BSF     ADCON0,ADGO ;Start conversion
  91.     BTFSC   ADCON0,ADGO ;Is conversion done?
  92.     GOTO    $-1 ;No, test again
  93.     BANKSEL ADRESH ;
  94.     MOVF    ADRESH,W ;Read upper 2 bits
  95.     MOVWF   RESULTHI ;store in GPR space
  96.     BANKSEL ADRESL ;
  97.     MOVF    ADRESL,W ;Read lower 8 bits
  98.     MOVWF   RESULTLO ;Store in GPR space
  99.     RETURN
  100. RETARDO
  101.     MOVLW   0X0F
  102.     MOVWF   RET
  103.     MOVWF   RET2
  104. ESP
  105.     DECFSZ  RET,F
  106.     GOTO    ESP
  107.     MOVLW   0XFF
  108.     MOVWF   RET
  109.     DECFSZ  RET2,F
  110.     GOTO    ESP
  111.     RETURN
  112.  
  113.     END

Anexa la imagen de la simulación en proteus.

Bueno pues les platico que tuve problemas al mandar los datos, ya que en principio quería sacarlos por el PORTC. Pero recordé que es por el LATC así que tuve que moverme a ese banco para poder actualizar los datos del ADC correctamente.
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: KILLERJC en 11 de Noviembre de 2015, 10:35:27
Si solo tenes esos "registros" Usa:

Código: ASM
  1. CBLOCK  0X70
  2.     RET
  3.     RET2
  4.     CONTADOR_BYTES
  5.     RESULTHI
  6.     RESULTLO
  7.     ENDC

Eso te va a ahorrar un par de errores que tenes. Como este:

Código: ASM
  1. BANKSEL ADRESL ;
  2.     MOVF    ADRESL,W ;Read lower 8 bits
  3.     MOVWF   RESULTLO ;Store in GPR space

RESULTLO lo definiste como si fuera del banco 0, pero ahi estarias cambiando la direccion 0xA4 y no 0x24. Si pones todos tus regisrtos desde el 0x70 ( solo 15 puede haber ubicados ahi )
Podes acceder desde cualquier banco al banco 0. es decir si vos accedes a 0xF0 o 0x170 estarias accediendo a 0x70, es asi en esa porcion de memoria para evitar estar cambiando mucho de bancos.

La parte de configuracion del canal del ADC si no vas a cambiar el canal no hace falta que lo pongas dentro de la rutina, y pasalo a la configuracion.

Tenes repetido la limpieza de PORTx, que es innecesaria, ya que si tenes LATx simplemente limpias eso y listo.

Cambie el RETFIE por un RETURN, de esa forma si entra a una interrupcion por error, simplemente sale, con RETFIE se vuelven a activar las interrupciones, por lo cual existiria la posibilidad de que vuelta a entrar.

Código: ASM
  1. #INCLUDE "P16F1707.INC"
  2.  __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOREN_OFF & _CLKOUTEN_OFF
  3.  __CONFIG _CONFIG2, _WRT_OFF & _PPS1WAY_ON & _ZCDDIS_OFF & _PLLEN_ON & _STVREN_ON & _BORV_LO & _LPBOR_OFF & _LVP_OFF
  4.  
  5.     CBLOCK  0X70
  6.     RET
  7.     RET2
  8.     CONTADOR_BYTES
  9.     RESULTHI
  10.     RESULTLO
  11.     ENDC
  12.  
  13.     ORG     0X00
  14.     GOTO    CONFIGURA_PIC
  15.     ORG     0X04
  16.     RETURN
  17. CONFIGURA_PIC
  18.         BANKSEL OSCCON
  19.         MOVLW   B'11111011'
  20.         MOVWF   OSCCON
  21.         MOVLW   B'00011111'
  22.         MOVWF   OSCTUNE
  23.  
  24.         BANKSEL LATA
  25.         CLRF    LATA
  26.         CLRF    LATB
  27.         CLRF    LATC
  28.         BANKSEL ANSELA
  29.         CLRF    ANSELA
  30.         CLRF    ANSELB
  31.         CLRF    ANSELC
  32.         BANKSEL TRISA
  33.         CLRF    TRISA
  34.         CLRF    TRISB
  35.         CLRF    TRISC
  36.  
  37. ;;;; VAMOS A CONFIGURAR EL ADC
  38.         BANKSEL ADCON1          ; El mismo que el de TRISx
  39.         MOVLW   B'01100000'
  40.         MOVWF   ADCON1
  41.         MOVLW   B'00000001'     ;Select channel AN0
  42.         MOVWF   ADCON0          ;Turn ADC On  
  43.         BSF     TRISA,0    
  44.         BANKSEL ANSELA          ;
  45.         BSF     ANSELA,0
  46.  
  47.  
  48. PRINCIPAL
  49.         CALL    CONV_ADC
  50.         MOVF    RESULTHI,W
  51.         BANKSEL LATC
  52.         MOVWF   LATC
  53.         CALL    RETARDO
  54.         GOTO    PRINCIPAL
  55.  
  56. CONV_ADC
  57.         BANKSEL ADCON0          ;
  58.         BSF     ADCON0,ADGO     ;Start conversion
  59.         BTFSC   ADCON0,ADGO     ;Is conversion done?
  60.         GOTO    $-1             ;No, test again
  61.         MOVF    ADRESH,W        ;Read upper 2 bits
  62.         MOVWF   RESULTHI        ;store in GPR space
  63.         MOVF    ADRESL,W        ;Read lower 8 bits
  64.         MOVWF   RESULTLO        ;Store in GPR space
  65.         RETURN
  66. RETARDO
  67.         MOVLW   0X0F
  68.         MOVWF   RET
  69.         MOVWF   RET2
  70. ESP
  71.         DECFSZ  RET,F
  72.         GOTO    ESP
  73.         MOVLW   0XFF
  74.         MOVWF   RET
  75.         DECFSZ  RET2,F
  76.         GOTO    ESP
  77.         RETURN
  78.  
  79.     END
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 15 de Noviembre de 2015, 04:18:51
Muchisimas gracias KillerJC por las observaciones. Ya cambie el código y esta perfecto. Ahora trabajare en unir los dos últimos programas LCD+ADC con esto haber que aplicación le podemos dar.
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 15 de Noviembre de 2015, 04:38:33
Ya un poco entrados juntamos ambos programas esperando no cometer errores. Acá el código y anexo el circuito, es sencillo lo unico que hace es mostrar el byte alto del ADC en la LCD. Ojo no gráfica si no que mandamos directo el byte lo que nos puede simular un movimiento.

Código: ASM
  1. #INCLUDE "P16F1707.INC"
  2.  __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOREN_OFF & _CLKOUTEN_OFF
  3.  __CONFIG _CONFIG2, _WRT_OFF & _PPS1WAY_ON & _ZCDDIS_OFF & _PLLEN_ON & _STVREN_ON & _BORV_LO & _LPBOR_OFF & _LVP_OFF
  4.  
  5.     CBLOCK  0X020
  6.     RET
  7.     RET2
  8.     CONTADOR_BYTES
  9.     ADC_VALUE
  10.     ENDC
  11.  
  12.     ORG     0X00
  13.     GOTO    CONFIGURA_PIC
  14.     ORG     0X04
  15.     RETURN
  16.  CONFIGURA_PIC
  17.     BANKSEL OSCCON
  18.     MOVLW   B'11111011'
  19.     MOVWF   OSCCON
  20.     MOVLW   B'00011111'
  21.     MOVWF   OSCTUNE
  22.     BANKSEL PORTA
  23.     CLRF    PORTA
  24.     CLRF    PORTB
  25.     CLRF    PORTC
  26.     BANKSEL LATA
  27.     CLRF    LATA
  28.     CLRF    LATB
  29.     CLRF    LATC
  30.     BANKSEL ANSELA
  31.     CLRF    ANSELA
  32.     CLRF    ANSELB
  33.     CLRF    ANSELC
  34.     BANKSEL TRISA
  35.     CLRF    TRISA
  36.     CLRF    TRISB
  37.     CLRF    TRISC
  38. ;CONFIGURAMOS ADC
  39.     BANKSEL ADCON1          ; El mismo que el de TRISx
  40.     MOVLW   B'01100000'
  41.     MOVWF   ADCON1
  42.     MOVLW   B'00000001'     ;Select channel AN0
  43.     MOVWF   ADCON0          ;Turn ADC On  
  44.     BSF     TRISA,0    
  45.     BANKSEL ANSELA          ;
  46.     BSF     ANSELA,0
  47. ; NOS POSICIONAMOS EN BANCO DE PPSLOCK
  48. ; PARA DELBLOQUEARLO
  49.  
  50.     BANKSEL PPSLOCK
  51.     MOVLW   0X55
  52.     MOVWF   PPSLOCK
  53.     MOVLW   0XAA
  54.     MOVWF   PPSLOCK
  55.     BCF     PPSLOCK,PPSLOCKED
  56.     BANKSEL RC0PPS
  57.     MOVLW   B'00010010'
  58.     MOVWF   RC0PPS
  59.     MOVLW   B'00010000'
  60.     MOVWF   RC1PPS
  61. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  62.     BANKSEL PPSLOCK
  63.     MOVLW   0X55
  64.     MOVWF   PPSLOCK
  65.     MOVLW   0XAA
  66.     MOVWF   PPSLOCK
  67.     BSF     PPSLOCK,PPSLOCKED
  68. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  69.     BANKSEL SSP1CON1
  70.     MOVLW   B'00110000'
  71.     MOVWF   SSP1CON1
  72.     BANKSEL PORTB
  73.    
  74.     #DEFINE LCD_NOKIA   PORTC,2
  75.     #DEFINE RST_NOKIA   PORTC,3
  76.     #DEFINE DC_NOKIA    PORTC,4
  77.  
  78.     BSF     RST_NOKIA
  79.     BSF     LCD_NOKIA
  80.     CALL    INI_LCD_NOKIA
  81.  
  82.  PRINCIPAL
  83.     CALL    CONV_ADC
  84.     MOVF    ADC_VALUE,W
  85.     CALL    DATO_SPI
  86.     CALL    RETARDO
  87.     GOTO    PRINCIPAL
  88. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SUBRUTINA ADC
  89. CONV_ADC
  90.         BANKSEL ADCON0          ;
  91.         BSF     ADCON0,ADGO     ;Start conversion
  92.         BTFSC   ADCON0,ADGO     ;Is conversion done?
  93.         GOTO    $-1             ;No, test again
  94.         MOVF    ADRESH,W        ;Read upper 2 bits
  95.         BANKSEL ADC_VALUE
  96.         MOVWF   ADC_VALUE        ;store in GPR space
  97.         RETURN
  98.    
  99. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  100. MENSAJE_X_BYTES
  101.     MOVWF   CONTADOR_BYTES
  102. WRITING_LCD    
  103.     MOVIW   FSR0++
  104.     CALL    DATO_SPI
  105.     DECFSZ  CONTADOR_BYTES,F
  106.     GOTO    WRITING_LCD
  107.     RETURN
  108.    
  109.    
  110.    
  111. INI_LCD_NOKIA
  112.     BCF     RST_NOKIA
  113.     NOP
  114.     BSF     RST_NOKIA
  115.     ;CREAMOS UN RESET POR SOFTWARE DE LA LCD
  116.     MOVLW   LOW(INICIA_NOKIA)
  117.     MOVWF   FSR0L
  118.     MOVLW   HIGH(INICIA_NOKIA)
  119.     MOVWF   FSR0H
  120. INIT_NOKIA
  121.     MOVIW   FSR0++
  122.     CALL    COMANDO_SPI
  123.     MOVIW   [FSR0]
  124.     BTFSS   STATUS,Z
  125.     GOTO    INIT_NOKIA
  126.     RETURN
  127. SET_Y
  128.     ADDLW   B'01000000'
  129.     CALL    COMANDO_SPI
  130.     RETURN
  131. SET_X
  132.     ADDLW   B'10000000'
  133.     CALL    COMANDO_SPI
  134.     RETURN
  135.    
  136.    
  137.     INICIA_NOKIA: dt 0X21,0XCF,0X20,0X0C,0X00
  138.    
  139.     HOLA_MENSAJE: dt 0XFE,0X10,0X10,0XFE,0X00,0X7C,0X82,0X82,0X7C,0X00,0XFE,0X80,0X80,0X80,0X00,0XFC,0X12,0X12,0XFC,0X00;A
  140.     TODO_MENSAJE: dt 0X02,0X02,0XFE,0X02,0X02,0X00,0X7C,0X82,0X82,0X7C,0X00,0XFE,0X82,0X82,0X7C,0X00,0X7C,0X82,0X82,0X7C,0X00
  141.     PIC_MENSAJE:  dt 0X00,0X00,0XFE,0X12,0X12,0X0C,0X00,0XFE,0X00,0X7C,0X82,0X82,0X44,0X00
  142.  
  143.  
  144.  
  145.  DATO_SPI
  146.     BSF     DC_NOKIA
  147.     BCF     LCD_NOKIA
  148.     BANKSEL SSP1BUF
  149.     MOVWF   SSP1BUF
  150.     BANKSEL PIR1
  151.     BCF     PIR1,SSP1IF
  152. WSPI
  153.     BTFSS   PIR1,SSP1IF
  154.     GOTO    WSPI
  155.     BCF     PIR1,SSP1IF
  156.     BANKSEL PORTA
  157.     BSF     LCD_NOKIA
  158.     RETURN
  159. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  160. COMANDO_SPI
  161.     BCF     DC_NOKIA
  162.     BCF     LCD_NOKIA
  163.     BANKSEL SSP1BUF
  164.     MOVWF   SSP1BUF
  165.     BANKSEL PIR1
  166.     BCF     PIR1,SSP1IF
  167. WSPIC
  168.     BTFSS   PIR1,SSP1IF
  169.     GOTO    WSPIC
  170.     BCF     PIR1,SSP1IF
  171.     BANKSEL PORTA
  172.     BSF     LCD_NOKIA
  173.     RETURN
  174. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  175.  
  176.    
  177. RETARDO
  178.     MOVLW   0XFF
  179.     MOVWF   RET
  180.     MOVWF   RET2
  181. ESP
  182.     DECFSZ  RET,F
  183.     GOTO    ESP
  184.     MOVLW   0XFF
  185.     MOVWF   RET
  186.     DECFSZ  RET2,F
  187.     GOTO    ESP
  188.     RETURN
  189.     END
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 15 de Noviembre de 2015, 05:18:14
 ;-) Bueno pues ya es algo tarde por aca pero les dejo un codigo ejemplo que aun le falta pero me entretuvo un rato. Estoy pensando ahora como sera la manera mas fácil de obtener por la lectura del adc un tipo graficador como el que hice pero en lugar de utilizar 1 byte y utilice 2 para que se vea mejor. El procedimiento para lograr esto fue: Comparar el valor del ADC en 8 partes de 32 si era mayor le asignaba un valor fijo para que pareciera que la gráfica crece o disminuye. Espero que les sirva de algo.

Código: ASM
  1. #INCLUDE "P16F1707.INC"
  2.  __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOREN_OFF & _CLKOUTEN_OFF
  3.  __CONFIG _CONFIG2, _WRT_OFF & _PPS1WAY_ON & _ZCDDIS_OFF & _PLLEN_ON & _STVREN_ON & _BORV_LO & _LPBOR_OFF & _LVP_OFF
  4.  
  5.     CBLOCK  0X020
  6.     RET
  7.     RET2
  8.     CONTADOR_BYTES
  9.     ADC_VALUE
  10.     GH
  11.     GL
  12.     ENDC
  13.  
  14.     ORG     0X00
  15.     GOTO    CONFIGURA_PIC
  16.     ORG     0X04
  17.     RETURN
  18.  CONFIGURA_PIC
  19.     BANKSEL OSCCON
  20.     MOVLW   B'11111011'
  21.     MOVWF   OSCCON
  22.     MOVLW   B'00011111'
  23.     MOVWF   OSCTUNE
  24.     BANKSEL PORTA
  25.     CLRF    PORTA
  26.     CLRF    PORTB
  27.     CLRF    PORTC
  28.     BANKSEL LATA
  29.     CLRF    LATA
  30.     CLRF    LATB
  31.     CLRF    LATC
  32.     BANKSEL ANSELA
  33.     CLRF    ANSELA
  34.     CLRF    ANSELB
  35.     CLRF    ANSELC
  36.     BANKSEL TRISA
  37.     CLRF    TRISA
  38.     CLRF    TRISB
  39.     CLRF    TRISC
  40. ;CONFIGURAMOS ADC
  41.     BANKSEL ADCON1          ; El mismo que el de TRISx
  42.     MOVLW   B'01100000'
  43.     MOVWF   ADCON1
  44.     MOVLW   B'00000001'     ;Select channel AN0
  45.     MOVWF   ADCON0          ;Turn ADC On  
  46.     BSF     TRISA,0    
  47.     BANKSEL ANSELA          ;
  48.     BSF     ANSELA,0
  49. ; NOS POSICIONAMOS EN BANCO DE PPSLOCK
  50. ; PARA DELBLOQUEARLO
  51.  
  52.     BANKSEL PPSLOCK
  53.     MOVLW   0X55
  54.     MOVWF   PPSLOCK
  55.     MOVLW   0XAA
  56.     MOVWF   PPSLOCK
  57.     BCF     PPSLOCK,PPSLOCKED
  58.     BANKSEL RC0PPS
  59.     MOVLW   B'00010010'
  60.     MOVWF   RC0PPS
  61.     MOVLW   B'00010000'
  62.     MOVWF   RC1PPS
  63. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  64.     BANKSEL PPSLOCK
  65.     MOVLW   0X55
  66.     MOVWF   PPSLOCK
  67.     MOVLW   0XAA
  68.     MOVWF   PPSLOCK
  69.     BSF     PPSLOCK,PPSLOCKED
  70. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  71.     BANKSEL SSP1CON1
  72.     MOVLW   B'00110000'
  73.     MOVWF   SSP1CON1
  74.     BANKSEL PORTB
  75.    
  76.     #DEFINE LCD_NOKIA   PORTC,2
  77.     #DEFINE RST_NOKIA   PORTC,3
  78.     #DEFINE DC_NOKIA    PORTC,4
  79.  
  80.     BSF     RST_NOKIA
  81.     BSF     LCD_NOKIA
  82.     CALL    INI_LCD_NOKIA
  83.  
  84.  PRINCIPAL
  85.     MOVLW   .0
  86.     CALL    SET_Y
  87.     MOVLW   .0
  88.     CALL    SET_X
  89.     MOVLW   LOW(ADC_TEXT)
  90.     MOVWF   FSR0L
  91.     MOVLW   HIGH(ADC_TEXT)
  92.     MOVWF   FSR0H
  93.     MOVLW   .16
  94.     CALL    MENSAJE_X_BYTES
  95.     MOVLW   .2
  96.     CALL    SET_Y
  97.     MOVLW   .0
  98.     CALL    SET_X
  99. UPDATE_ADC  
  100.     CALL    CONV_ADC
  101.     MOVF    ADC_VALUE,W
  102.     CALL    CONVIERTE_ADC
  103. ;    MOVF    GH,W
  104.     CALL    DATO_SPI
  105.     CALL    RETARDO
  106.     GOTO    UPDATE_ADC
  107. ;;;; SUBRUTINA PARA CONVERTIR EL ADC EN VALOR 0-7
  108. CONVIERTE_ADC
  109.     SUBLW   .250
  110.     BTFSC   STATUS,C
  111.     GOTO    $+2
  112.     RETLW   .1
  113.     MOVF    ADC_VALUE,W
  114.     SUBLW   .223
  115.     BTFSC   STATUS,C
  116.     GOTO    $+2
  117.     RETLW   .2
  118.     MOVF    ADC_VALUE,W
  119.     SUBLW   .191
  120.     BTFSC   STATUS,C
  121.     GOTO    $+2
  122.     RETLW   .4
  123.     MOVF    ADC_VALUE,W
  124.     SUBLW   .159
  125.     BTFSC   STATUS,C
  126.     GOTO    $+2
  127.     RETLW   .8
  128.     MOVF    ADC_VALUE,W
  129.     SUBLW   .127
  130.     BTFSC   STATUS,C
  131.     GOTO    $+2
  132.     RETLW   .16
  133.     MOVF    ADC_VALUE,W
  134.     SUBLW   .95
  135.     BTFSC   STATUS,C
  136.     GOTO    $+2
  137.     RETLW   .32
  138.     MOVF    ADC_VALUE,W
  139.     SUBLW   .63
  140.     BTFSC   STATUS,C
  141.     GOTO    $+2
  142.     RETLW   .64
  143.     MOVF    ADC_VALUE,W
  144.     SUBLW   .31
  145.     BTFSC   STATUS,C
  146.     GOTO    $+2
  147.     RETLW   .128
  148.     RETLW   .128
  149.    
  150. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SUBRUTINA ADC
  151. CONV_ADC
  152.         BANKSEL ADCON0          ;
  153.         BSF     ADCON0,ADGO     ;Start conversion
  154.         BTFSC   ADCON0,ADGO     ;Is conversion done?
  155.         GOTO    $-1             ;No, test again
  156.         MOVF    ADRESH,W        ;Read upper 2 bits
  157.         BANKSEL ADC_VALUE
  158.         MOVWF   ADC_VALUE        ;store in GPR space
  159.         RETURN
  160.    
  161. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  162. MENSAJE_X_BYTES
  163.     MOVWF   CONTADOR_BYTES
  164. WRITING_LCD    
  165.     MOVIW   FSR0++
  166.     CALL    DATO_SPI
  167.     DECFSZ  CONTADOR_BYTES,F
  168.     GOTO    WRITING_LCD
  169.     RETURN
  170.    
  171.    
  172.    
  173. INI_LCD_NOKIA
  174.     BCF     RST_NOKIA
  175.     NOP
  176.     BSF     RST_NOKIA
  177.     ;CREAMOS UN RESET POR SOFTWARE DE LA LCD
  178.     MOVLW   LOW(INICIA_NOKIA)
  179.     MOVWF   FSR0L
  180.     MOVLW   HIGH(INICIA_NOKIA)
  181.     MOVWF   FSR0H
  182. INIT_NOKIA
  183.     MOVIW   FSR0++
  184.     CALL    COMANDO_SPI
  185.     MOVIW   [FSR0]
  186.     BTFSS   STATUS,Z
  187.     GOTO    INIT_NOKIA
  188.     RETURN
  189. SET_Y
  190.     ADDLW   B'01000000'
  191.     CALL    COMANDO_SPI
  192.     RETURN
  193. SET_X
  194.     ADDLW   B'10000000'
  195.     CALL    COMANDO_SPI
  196.     RETURN
  197.    
  198.    
  199.     INICIA_NOKIA: dt 0X21,0XCF,0X20,0X0C,0X00
  200.     ADC_TEXT:     dt 0XFC,0X12,0X12,0XFC,0X00,0XFE,0X82,0X82,0X7C,0X00,0X7C,0X82,0X82,0X44,0X00,0X44
  201.     HOLA_MENSAJE: dt 0XFE,0X10,0X10,0XFE,0X00,0X7C,0X82,0X82,0X7C,0X00,0XFE,0X80,0X80,0X80,0X00,0XFC,0X12,0X12,0XFC,0X00;A
  202.     TODO_MENSAJE: dt 0X02,0X02,0XFE,0X02,0X02,0X00,0X7C,0X82,0X82,0X7C,0X00,0XFE,0X82,0X82,0X7C,0X00,0X7C,0X82,0X82,0X7C,0X00
  203.     PIC_MENSAJE:  dt 0X00,0X00,0XFE,0X12,0X12,0X0C,0X00,0XFE,0X00,0X7C,0X82,0X82,0X44,0X00
  204.  
  205.  
  206.  
  207.  DATO_SPI
  208.     BSF     DC_NOKIA
  209.     BCF     LCD_NOKIA
  210.     BANKSEL SSP1BUF
  211.     MOVWF   SSP1BUF
  212.     BANKSEL PIR1
  213.     BCF     PIR1,SSP1IF
  214. WSPI
  215.     BTFSS   PIR1,SSP1IF
  216.     GOTO    WSPI
  217.     BCF     PIR1,SSP1IF
  218.     BANKSEL PORTA
  219.     BSF     LCD_NOKIA
  220.     RETURN
  221. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  222. COMANDO_SPI
  223.     BCF     DC_NOKIA
  224.     BCF     LCD_NOKIA
  225.     BANKSEL SSP1BUF
  226.     MOVWF   SSP1BUF
  227.     BANKSEL PIR1
  228.     BCF     PIR1,SSP1IF
  229. WSPIC
  230.     BTFSS   PIR1,SSP1IF
  231.     GOTO    WSPIC
  232.     BCF     PIR1,SSP1IF
  233.     BANKSEL PORTA
  234.     BSF     LCD_NOKIA
  235.     RETURN
  236. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  237.  
  238.    
  239. RETARDO
  240.     MOVLW   0X3F
  241.     MOVWF   RET
  242.     MOVWF   RET2
  243. ESP
  244.     DECFSZ  RET,F
  245.     GOTO    ESP
  246.     MOVLW   0XFF
  247.     MOVWF   RET
  248.     DECFSZ  RET2,F
  249.     GOTO    ESP
  250.     RETURN
  251.     END

Saludos y buenas noches
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: KILLERJC en 15 de Noviembre de 2015, 14:10:35
Bueno te dejo un codigo para que puedas reemplazar:

Lo tuyo:
Código: ASM
  1. CONVIERTE_ADC
  2.     SUBLW   .250
  3.     BTFSC   STATUS,C
  4.     GOTO    $+2
  5.     RETLW   .1
  6.     MOVF    ADC_VALUE,W
  7.     SUBLW   .223
  8.     BTFSC   STATUS,C
  9.     GOTO    $+2
  10.     RETLW   .2
  11.     MOVF    ADC_VALUE,W
  12.     SUBLW   .191
  13.     BTFSC   STATUS,C
  14.     GOTO    $+2
  15.     RETLW   .4
  16.     MOVF    ADC_VALUE,W
  17.     SUBLW   .159
  18.     BTFSC   STATUS,C
  19.     GOTO    $+2
  20.     RETLW   .8
  21.     MOVF    ADC_VALUE,W
  22.     SUBLW   .127
  23.     BTFSC   STATUS,C
  24.     GOTO    $+2
  25.     RETLW   .16
  26.     MOVF    ADC_VALUE,W
  27.     SUBLW   .95
  28.     BTFSC   STATUS,C
  29.     GOTO    $+2
  30.     RETLW   .32
  31.     MOVF    ADC_VALUE,W
  32.     SUBLW   .63
  33.     BTFSC   STATUS,C
  34.     GOTO    $+2
  35.     RETLW   .64
  36.     MOVF    ADC_VALUE,W
  37.     SUBLW   .31
  38.     BTFSC   STATUS,C
  39.     GOTO    $+2
  40.     RETLW   .128
  41.     RETLW   .128
(Que posee ese GOTO/BTFSC/RETLW de mas al final )

Por esto:

Código: ASM
  1. SWAPF   ADC_VALUE, F
  2.         LSRF    ADC_VALUE, W
  3.         SWAPF   ADC_VALUE, F
  4.         ANDLW   0x07
  5.         BRW
  6.         RETLW   .128
  7.         RETLW   .64
  8.         RETLW   .32
  9.         RETLW   .16
  10.         RETLW   .8
  11.         RETLW   .4
  12.         RETLW   .2
  13.         RETLW   .1

Explicacion, es simple.. vos estas usando solo 8 partes de 32 bits cada una. En resumen es como si dividiera por 32 el numero.

adc_result = aaax xxxx

Al dividirlo por 32 las x se irian y quedaria: 0000 0aaa
El SWAPF cambia los nibbles  ADC_RESULT = xxxx aaax
Luego una rotacion para que me quede W = 0xxx xaaa
Procedo a dejar como estaba antes ADC_RESULT ( en cosa que otra cosa lo necesite) ADC_RESULT = aaax xxxx
Finalmente le hago una AND a W para forzar el maximo a 0000 0111 como entrada en la tabla.
Fin.

Todo esto fue para no modificar el ADC_RESULT, si este valor ya no importaba. Entonces podria haber ahorrado un SWAPF mas.

PD: No te va a dar el mismo valor ya que al final no respetaste que las partes sean exactas, por ejemplo veo que tenes un 250 por ahi. Asi que tal ves difiera un poco.
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 23 de Noviembre de 2015, 03:21:24
Muy buenos consejos KillerJC para optimizacion de codigo. Pregunta como funciona esta parte del codigo que me has sugerido?
Código: ASM
  1. BRW
  2.         RETLW   .128
  3.         RETLW   .64
  4.         RETLW   .32
  5.         RETLW   .16
  6.         RETLW   .8
  7.         RETLW   .4
  8.         RETLW   .2
  9.         RETLW   .1

Saludos
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: KILLERJC en 23 de Noviembre de 2015, 03:41:42
Es una tabla ... Lo mismo que haces con:

ADDWF PCL
RETLW ...
...
...
RETLW ....


Nomas que ese PIC posee una instruccion que lo hace por uno.. que es BRW
Esa instruccion le suma al PC el valor de W. W vale de 0 a 7 (0000 0111) por las condiciones que le pusimos antes y eso se traduce en la tabla:

Código: ASM
  1. BRW
  2.         RETLW   .128   ;W=0
  3.         RETLW   .64    ;W=1
  4.         RETLW   .32    ;W=2
  5.         RETLW   .16    ;W=3
  6.         RETLW   .8     ;W=4
  7.         RETLW   .4     ;W=5
  8.         RETLW   .2     ;W=6
  9.         RETLW   .1     ;W=7

Lo bueno es que no tengo que ir al banco donde esta el PCL , se observa tambien que antes dije PC solamente, y no PCL, esto es por que la instruccion BRW le suma el valor de W a todo el PC ( 14bits ), y no me tengo que preocupar por las "paginas", en cambio con ADDWF si lo tenia que hacer, ya que solo modifica los 8 bits de menor peso ( PCL ) y debo cargar antes el valor de la parte superior en PCLATH si es que me excedo. Lo cual requiere un poco mas de cuidado si es que uno no posiciona la tabla en un lugar que evite esto.
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 03 de Diciembre de 2015, 22:41:25
Bueno retomando la parte de código que Killer me recomendó anexo un pequeño código que se ha ido acompletando que es para graficar la señal del ADC + mostrar el valor del ADC de 0 a 255. Por favor si hay algo que podamos mejorar me hacen los comentarios.

Código: ASM
  1. #INCLUDE "P16F1707.INC"
  2.  __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOREN_OFF & _CLKOUTEN_OFF
  3.  __CONFIG _CONFIG2, _WRT_OFF & _PPS1WAY_ON & _ZCDDIS_OFF & _PLLEN_ON & _STVREN_ON & _BORV_LO & _LPBOR_OFF & _LVP_OFF
  4.  
  5.     CBLOCK  0X020
  6.     RET
  7.     RET2
  8.     CONTADOR_BYTES
  9.     ADC_VALUE
  10.     GH
  11.     GL
  12.     CENTENAS
  13.     DECENAS
  14.     UNIDADES
  15.     BCD_AUX
  16.     X_POS
  17.     ENDC
  18. ;***********************************************************************************************
  19. ;********************************* VECTOR DE RESET DEL PIC *************************************
  20. ;***********************************************************************************************
  21.     ORG     0X00
  22.     GOTO    CONFIGURA_PIC
  23. ;***********************************************************************************************
  24. ;***************************** VECTOR DE INTERRUPCION DEL PIC **********************************
  25. ;***********************************************************************************************
  26.     ORG     0X04
  27.     RETURN
  28. ;***********************************************************************************************
  29. ;********************************* CONFIGURACION DEL PIC ***************************************
  30. ;***********************************************************************************************
  31.  CONFIGURA_PIC
  32.     BANKSEL OSCCON
  33.     MOVLW   B'11111011'
  34.     MOVWF   OSCCON
  35.     MOVLW   B'00011111'
  36.     MOVWF   OSCTUNE
  37. ;***********************************************************************************************
  38. ;*************************** CONFIGURACION DE PUERTOS DEL PIC **********************************
  39. ;***********************************************************************************************
  40.     BANKSEL PORTA
  41.     CLRF    PORTA
  42.     CLRF    PORTB
  43.     CLRF    PORTC
  44.     BANKSEL LATA
  45.     CLRF    LATA
  46.     CLRF    LATB
  47.     CLRF    LATC
  48.     BANKSEL ANSELA
  49.     CLRF    ANSELA
  50.     CLRF    ANSELB
  51.     CLRF    ANSELC
  52.     BANKSEL TRISA
  53.     CLRF    TRISA
  54.     CLRF    TRISB
  55.     CLRF    TRISC
  56. ;CONFIGURAMOS ADC
  57.     BANKSEL ADCON1          ; El mismo que el de TRISx
  58.     MOVLW   B'01100000'
  59.     MOVWF   ADCON1
  60.     MOVLW   B'00000001'     ;Select channel AN0
  61.     MOVWF   ADCON0          ;Turn ADC On  
  62.     BSF     TRISA,0    
  63.     BANKSEL ANSELA          ;
  64.     BSF     ANSELA,0
  65. ; NOS POSICIONAMOS EN BANCO DE PPSLOCK
  66. ; PARA DELBLOQUEARLO
  67.  
  68.     BANKSEL PPSLOCK
  69.     MOVLW   0X55
  70.     MOVWF   PPSLOCK
  71.     MOVLW   0XAA
  72.     MOVWF   PPSLOCK
  73.     BCF     PPSLOCK,PPSLOCKED
  74.     BANKSEL RC0PPS
  75.     MOVLW   B'00010010'
  76.     MOVWF   RC0PPS
  77.     MOVLW   B'00010000'
  78.     MOVWF   RC1PPS
  79. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  80.     BANKSEL PPSLOCK
  81.     MOVLW   0X55
  82.     MOVWF   PPSLOCK
  83.     MOVLW   0XAA
  84.     MOVWF   PPSLOCK
  85.     BSF     PPSLOCK,PPSLOCKED
  86. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  87.     BANKSEL SSP1CON1                ; ME HUBICO EN EL BANCO QUE CONTIENE EL REGISTRO SSP1CON
  88.     MOVLW   B'00110000'             ; CARGO EL VALOR DE CONFIGURACION PARA SPI
  89.     MOVWF   SSP1CON1                ; LO GUARDO EN SSP1CON PARA PODER USAR EL MODO SPI
  90.     BANKSEL PORTB                   ; ME REGRESO AL BANCO 0
  91. ;***********************************************************************************************
  92. ;****************** DEFINICION DE LOS PINES DEL PROGRAMA ***************************************
  93. ;***********************************************************************************************    
  94.     #DEFINE LCD_NOKIA   PORTC,2     ; DEFINE EL PIN DEL CHIP SELECT
  95.     #DEFINE RST_NOKIA   PORTC,3     ; DEFINE EL PIN DE RESET
  96.     #DEFINE DC_NOKIA    PORTC,4     ; DEFINE EL PIN DE INSTRUCCION/DATO DE LA LCD
  97.  
  98.     BSF     RST_NOKIA               ; PONGO EN ALTO EL RESET DE LA LCD
  99.     BSF     LCD_NOKIA               ; PONGO EN ALTO EL CHIP SELECT DE LA LCD
  100. ;***********************************************************************************************
  101. ;********************* RUTINIA DE INICIALIZACION DE LA LCD NOKIA 5110 **************************
  102. ;***********************************************************************************************
  103.     CALL    INI_LCD_NOKIA
  104. ;***********************************************************************************************
  105. ;**************************** LOOP PRINCIPAL DE FUNCIONAMIENTO *********************************
  106. ;***********************************************************************************************
  107.     CLRF    X_POS
  108.  PRINCIPAL
  109.     CALL    RETARDO                 ; LLAMAMOS UN RETARDO
  110.     MOVLW   .0                      ; CARGO EL VALOR DEL RENGLON DONDE DESEO ESCRIBIR
  111.     CALL    SET_Y                   ; LLAMO RUTINA DE SET POSICION EN Y
  112.     MOVLW   .0                      ; CARGO EL VALOR DE LA COLUMNA DONDE DESEO ESCRIBIR
  113.     CALL    SET_X                   ; LLAMO RUTINA DE SET POSICION EN X
  114.     MOVLW   LOW(ADC_TEXT)           ; MUEVO LA DIRECCION DE LA TABLA ADC_TEXT (LOW)
  115.     MOVWF   FSR0L                   ; A MI REGISTRO FSR0L
  116.     MOVLW   HIGH(ADC_TEXT)          ; MUEVO LA DIRECCION DE LA TABLA ADC_TEXT (HIGH)
  117.     MOVWF   FSR0H                   ; AL REGISTRO FSR0H
  118.     MOVLW   .17                     ; NUMERO DE BYTES A TRANSMITIR
  119.     CALL    MENSAJE_X_BYTES         ; LLAMO A SUBRUTINA DE TRANSMISION DE BYTES
  120.     CALL    MUESTRA_VALOR           ; LLAMAMOS A SUBRUTINA QUE MOSTRARA EL VALOR CONTENIDO DEL ADC 8 BITS
  121.     MOVLW   .2                      ; MUEVO MI CURSOR A RENGLON 2
  122.     CALL    SET_Y                   ; LLAMO MI SET POSICION Y
  123.     MOVF    X_POS,W                 ; MUEVO MI CURSOR A COLUMNA 0
  124.     CALL    SET_X                   ; LLAMO MI SET POSICION X
  125. ;***********************************************************************************************
  126. ;******************* RUTINA DE LECTURA Y PROCESAMIENTO DEL ADC CH=0 ****************************
  127. ;***********************************************************************************************
  128. UPDATE_ADC  
  129.     CALL    CONV_ADC                ; LLAMO A MI RUTINA DE CONVERSION ADC    
  130.     MOVF    ADC_VALUE,W             ; REGRESA CON ADRESH CARGADO A W Y LO MOVEMOS A ADC_VALUE
  131.     CALL    GRAFICA_ADC             ; LLAMAMOS A LA RUTINA DE CONVERSION PARA LA LCD
  132.     CALL    DATO_SPI                ; LLAMAMOS LA TRANSMISION DEL DATO
  133.     INCF    X_POS,F                 ; DESPUES DE ENVIAR DATO INCREMENTAMOS POS X PARA TENER MOVIMIENTO EN SEÑAL
  134.     MOVLW   .84                     ; DEBEMOS ASEGURAR NO PASAR DE 83
  135.     SUBWF   X_POS,W                 ; PARA ELLO RESTAMOS 84 PARA SABER SI HA LLEGADO Y REINICIAR POSICION
  136.     BTFSS   STATUS,Z                ; SI HA LLEGADO LA RESTA ARROJARA 0 Y PODREMOS REINICIAR
  137.     GOTO    PRINCIPAL               ; NO FUE CERO REGRESO A PRINCIPAL
  138.     CLRF    X_POS                   ; YA LLEGO AL LIMITE REINICIO VARIABLE
  139.     GOTO    PRINCIPAL               ; NOS REGRESAMOS A PRINCIPAL
  140. ;***********************************************************************************************
  141. ;************************ RUTINA PARA MOSTRAR VALOR ADC 8 BITS *********************************
  142. ;***********************************************************************************************  
  143. MUESTRA_VALOR
  144.     BANKSEL ADC_VALUE               ; ME ASEGURO ESTAR EN BANCO DONDE ESTA ADC_VALUE (MI REGISTRO)
  145.     MOVF    ADC_VALUE,W             ; MOVEMOS ADC_VALUE A W PARA OBTENER 3 BYTES CON EL DATO
  146.     CALL    CONVERSION_BCD          ; RUTINA DE CONVERISON BINARIO>>BCD
  147.     MOVF    CENTENAS,W              ; MOVEMOS CENTENAS A W PARA SABER CON QUE NÚMERO QUEDO
  148.     CALL    ENVIA_NUMERO            ; RUTINA DE ESCRITURA DE NUMEROS EN LCD
  149.     MOVF    DECENAS,W               ; MOVEMOS CENTENAS A W PARA SABER CON QUE NÚMERO QUEDO
  150.     CALL    ENVIA_NUMERO            ; RUTINA DE ESCRITURA DE NUMEROS EN LCD
  151.     MOVF    UNIDADES,W              ; MOVEMOS CENTENAS A W PARA SABER CON QUE NÚMERO QUEDO
  152.     CALL    ENVIA_NUMERO            ; RUTINA DE ESCRITURA DE NUMEROS EN LCD
  153.     RETURN  
  154. ENVIA_NUMERO
  155.     BRW                             ; INSTRUCCION CON FUNCION A TABLA SIN PCL
  156.     GOTO    SEND0                   ;
  157.     GOTO    SEND1
  158.     GOTO    SEND2
  159.     GOTO    SEND3
  160.     GOTO    SEND4
  161.     GOTO    SEND5
  162.     GOTO    SEND6
  163.     GOTO    SEND7
  164.     GOTO    SEND8
  165.     GOTO    SEND9
  166. ;***********************************************************************************************
  167. ;***************************** RUTINAS PARA MANDAR VALORES EN LCD ******************************
  168. ;***********************************************************************************************
  169. SEND9
  170.     MOVLW   B'01001100'             ; CONSTRUIMOS CON 4 BYTES
  171.     CALL    DATO_SPI                ; EL NUMERO 9
  172.     MOVLW   B'10010010'             ; DEJANDO UN ESPACIO
  173.     CALL    DATO_SPI                ; AL FINAL DEL NUMERO
  174.     MOVLW   B'10010010'             ; DADO POR 0X00
  175.     CALL    DATO_SPI                ; MANDAMOS 5 BYTES SEGUIDOS POR
  176.     MOVLW   B'01111100'             ; EL CANAL SPI
  177.     CALL    DATO_SPI                ; PARA CONSTRUIR COMPLETO EL NUMERO
  178.     MOVLW   B'00000000'             ; SIN PERDER FORMA
  179.     CALL    DATO_SPI
  180.     RETURN
  181. SEND8
  182.     MOVLW   B'01101100'             ; CONSTRUIMOS CON 4 BYTES
  183.     CALL    DATO_SPI                ; EL NUMERO 8
  184.     MOVLW   B'10010010'             ; DEJANDO UN ESPACIO
  185.     CALL    DATO_SPI                ; AL FINAL DEL NUMERO
  186.     MOVLW   B'10010010'             ; DADO POR 0X00
  187.     CALL    DATO_SPI                ; MANDAMOS 5 BYTES SEGUIDOS POR
  188.     MOVLW   B'01101100'             ; EL CANAL SPI
  189.     CALL    DATO_SPI                ; PARA CONSTRUIR COMPLETO EL NUMERO
  190.     MOVLW   B'00000000'             ; SIN PERDER FORMA
  191.     CALL    DATO_SPI
  192.     RETURN
  193. SEND7
  194.     MOVLW   B'01100010'             ; CONSTRUIMOS CON 4 BYTES
  195.     CALL    DATO_SPI                ; EL NUMERO 7
  196.     MOVLW   B'00010010'             ; DEJANDO UN ESPACIO
  197.     CALL    DATO_SPI                ; AL FINAL DEL NUMERO
  198.     MOVLW   B'00001010'             ; DADO POR 0X00
  199.     CALL    DATO_SPI                ; MANDAMOS 5 BYTES SEGUIDOS POR
  200.     MOVLW   B'00000110'             ; EL CANAL SPI
  201.     CALL    DATO_SPI                ; PARA CONSTRUIR COMPLETO EL NUMERO
  202.     MOVLW   B'00000000'             ; SIN PERDER FORMA
  203.     CALL    DATO_SPI
  204.     RETURN
  205. SEND6
  206.     MOVLW   B'01111100'             ; CONSTRUIMOS CON 4 BYTES
  207.     CALL    DATO_SPI                ; EL NUMERO 6
  208.     MOVLW   B'10010010'             ; DEJANDO UN ESPACIO
  209.     CALL    DATO_SPI                ; AL FINAL DEL NUMERO
  210.     MOVLW   B'10010010'             ; DADO POR 0X00
  211.     CALL    DATO_SPI                ; MANDAMOS 5 BYTES SEGUIDOS POR
  212.     MOVLW   B'01100100'             ; EL CANAL SPI
  213.     CALL    DATO_SPI                ; PARA CONSTRUIR COMPLETO EL NUMERO
  214.     MOVLW   B'00000000'             ; SIN PERDER FORMA
  215.     CALL    DATO_SPI
  216.     RETURN
  217. SEND5
  218.     MOVLW   B'01001110'             ; CONSTRUIMOS CON 4 BYTES
  219.     CALL    DATO_SPI                ; EL NUMERO 5
  220.     MOVLW   B'10001010'             ; DEJANDO UN ESPACIO
  221.     CALL    DATO_SPI                ; AL FINAL DEL NUMERO
  222.     MOVLW   B'10001010'             ; DADO POR 0X00
  223.     CALL    DATO_SPI                ; MANDAMOS 5 BYTES SEGUIDOS POR
  224.     MOVLW   B'01110010'             ; EL CANAL SPI
  225.     CALL    DATO_SPI                ; PARA CONSTRUIR COMPLETO EL NUMERO
  226.     MOVLW   B'00000000'             ; SIN PERDER FORMA
  227.     CALL    DATO_SPI
  228.     RETURN
  229. SEND4
  230.     MOVLW   B'00110000'             ; CONSTRUIMOS CON 4 BYTES
  231.     CALL    DATO_SPI                ; EL NUMERO 3
  232.     MOVLW   B'00101000'             ; DEJANDO UN ESPACIO
  233.     CALL    DATO_SPI                ; AL FINAL DEL NUMERO
  234.     MOVLW   B'00100100'             ; DADO POR 0X00
  235.     CALL    DATO_SPI                ; MANDAMOS 5 BYTES SEGUIDOS POR
  236.     MOVLW   B'11111110'             ; EL CANAL SPI
  237.     CALL    DATO_SPI                ; PARA CONSTRUIR COMPLETO EL NUMERO
  238.     MOVLW   B'00000000'             ; SIN PERDER FORMA
  239.     CALL    DATO_SPI
  240.     RETURN
  241. SEND3
  242.     MOVLW   B'01000100'             ; CONSTRUIMOS CON 4 BYTES
  243.     CALL    DATO_SPI                ; EL NUMERO 3
  244.     MOVLW   B'10010010'             ; DEJANDO UN ESPACIO
  245.     CALL    DATO_SPI                ; AL FINAL DEL NUMERO
  246.     MOVLW   B'10010010'             ; DADO POR 0X00
  247.     CALL    DATO_SPI                ; MANDAMOS 5 BYTES SEGUIDOS POR
  248.     MOVLW   B'01101100'             ; EL CANAL SPI
  249.     CALL    DATO_SPI                ; PARA CONSTRUIR COMPLETO EL NUMERO
  250.     MOVLW   B'00000000'             ; SIN PERDER FORMA
  251.     CALL    DATO_SPI
  252.     RETURN
  253. SEND2
  254.     MOVLW   B'11000100'             ; CONSTRUIMOS CON 4 BYTES
  255.     CALL    DATO_SPI                ; EL NUMERO 2
  256.     MOVLW   B'10100010'             ; DEJANDO UN ESPACIO
  257.     CALL    DATO_SPI                ; AL FINAL DEL NUMERO
  258.     MOVLW   B'10010010'             ; DADO POR 0X00
  259.     CALL    DATO_SPI                ; MANDAMOS 5 BYTES SEGUIDOS POR
  260.     MOVLW   B'10001100'             ; EL CANAL SPI
  261.     CALL    DATO_SPI                ; PARA CONSTRUIR COMPLETO EL NUMERO
  262.     MOVLW   B'00000000'             ; SIN PERDER FORMA
  263.     CALL    DATO_SPI
  264.     RETURN
  265. SEND1
  266.     MOVLW   B'00000000'             ; CONSTRUIMOS CON 4 BYTES
  267.     CALL    DATO_SPI                ; EL NUMERO 1
  268.     MOVLW   B'10000100'             ; DEJANDO UN ESPACIO
  269.     CALL    DATO_SPI                ; AL FINAL DEL NUMERO
  270.     MOVLW   B'11111110'             ; DADO POR 0X00
  271.     CALL    DATO_SPI                ; MANDAMOS 5 BYTES SEGUIDOS POR
  272.     MOVLW   B'10000000'             ; EL CANAL SPI
  273.     CALL    DATO_SPI                ; PARA CONSTRUIR COMPLETO EL NUMERO
  274.     MOVLW   B'00000000'             ; SIN PERDER FORMA
  275.     CALL    DATO_SPI
  276.     RETURN    
  277. SEND0
  278.     MOVLW   B'01111100'             ; CONSTRUIMOS CON 4 BYTES
  279.     CALL    DATO_SPI                ; EL NUMERO 0
  280.     MOVLW   B'10000010'             ; DEJANDO UN ESPACIO
  281.     CALL    DATO_SPI                ; AL FINAL DEL NUMERO
  282.     MOVLW   B'10000010'             ; DADO POR 0X00
  283.     CALL    DATO_SPI                ; MANDAMOS 5 BYTES SEGUIDOS POR
  284.     MOVLW   B'01111100'             ; EL CANAL SPI
  285.     CALL    DATO_SPI                ; PARA CONSTRUIR COMPLETO EL NUMERO
  286.     MOVLW   B'00000000'             ; SIN PERDER FORMA
  287.     CALL    DATO_SPI
  288.     RETURN
  289. ;***********************************************************************************************
  290. ;***************************** RUTINA PARA CONVERTIR BIN A BCD *********************************
  291. ;***********************************************************************************************  
  292. CONVERSION_BCD
  293.         MOVWF   BCD_AUX             ; MUEVO EL VALOR DE W A BCD_AUX
  294.         CLRF    UNIDADES            ; LIMPIO REGISTRO UNIDADES
  295.         CLRF    DECENAS             ; LIMPIO REGISTRO DECENAS
  296.         CLRF    CENTENAS            ; LIMPIO REGISTRO CENTENAS
  297. S_CENTENAS
  298.         MOVLW   .100                ; CARGO 100 A W
  299.         SUBWF   BCD_AUX,W           ; LE RESTO LOS 100 PARA SABER SI ES MAYOR O MENOR
  300.         BTFSC   STATUS,C            ; PREGUNTO SI HUBO ACARREO
  301.         GOTO    SUMA_CENTENAS       ; SI ES MAYOR SUMO CENTENAS
  302.         GOTO    S_DECENAS           ; SI ES MENOR DEJO EN 0 CENTENAS Y ACTUALIZO DECENAS
  303. SUMA_CENTENAS
  304.         MOVWF   BCD_AUX             ; GUARDAMOS EL ULTIMO VALOR
  305.         INCF    CENTENAS,F          ; INCREMENTO CENTENAS Y GUARDO
  306.         GOTO    S_CENTENAS          ; REGRESO A SUMAR SI ES AUN MAS GRANDE
  307. S_DECENAS  
  308.         MOVLW   .10                 ; CARGO 10 A W
  309.         SUBWF   BCD_AUX,W           ; LE RESTO 10 PARA SABER SI ES MAYOR O MENOR
  310.         BTFSC   STATUS,C            ; PREGUNTAMOS SI HAY ACARREO
  311.         GOTO    SUMA_DECENAS        ; SI HUBO VAMOS A SUMAR DECENAS
  312.         GOTO    SUMA_UNIDADES       ; SI NO VAMOS A SUMAR UNIDADES
  313. SUMA_DECENAS
  314.         MOVWF   BCD_AUX             ; GUARDAMOS VALOR
  315.         INCF    DECENAS,1           ; INCREMENTAMOS DECENAS EN 1 Y GUARDAMOS
  316.         GOTO    S_DECENAS           ; REGRESAMOS PARA SABER SI HAY MAS DECENAS EN VARIABLE
  317. SUMA_UNIDADES
  318.         MOVF    BCD_AUX,W           ; MOVEMOS AUXILIAR A UNIDADES
  319.         MOVWF   UNIDADES            ; YA QUE ES EL ÚLTIMO VALOR QUE NOS QUEDA
  320.         RETURN    
  321. ;***********************************************************************************************
  322. ;****************************** RUTINA PARA GRAFICAR 1 RENGLON *********************************
  323. ;***********************************************************************************************
  324. GRAFICA_ADC
  325.     SWAPF   ADC_VALUE, F            ; INTERCAMBIAMOS NIBLES
  326.     LSRF    ADC_VALUE, W            ; ROTAMOS A LA IZQUIERDA
  327.     SWAPF   ADC_VALUE, F            ; REGRESAMOS ADC_VALUE A SU VALOR ORIGINAL PARA POST PROCESAMIENTOS
  328.     ANDLW   0x07                    ; ANDEAMOS EL VALOR DADO PARA RESTRINGIR A 8 VALORES B'XXXXX111'
  329.     BRW                     ;
  330.     RETLW   .128            ; W=0
  331.     RETLW   .64             ; W=1
  332.     RETLW   .32             ; W=2
  333.     RETLW   .16             ; W=3
  334.     RETLW   .8              ; W=4
  335.     RETLW   .4              ; W=5
  336.     RETLW   .2              ; W=6
  337.     RETLW   .1              ; W=7
  338. ;***********************************************************************************************
  339. ;*************************************** RUTINA CONVERSION ADC *********************************
  340. ;***********************************************************************************************
  341. CONV_ADC
  342.         BANKSEL ADCON0              ; NOS UBICAMOS EN EL BANCO QUE CONTIENE A ADCON0
  343.         BSF     ADCON0,ADGO         ; PRENDEMOS EL BIT GO PARA INICIAR LA CONVERSION ADC
  344.         BTFSC   ADCON0,ADGO         ; SALTAMOS UNA INSTRUCCION SI ES QUE YA TERMINO LA CONVERSION ADC
  345.         GOTO    $-1                 ; REGRESAMOS UNA LINEA DE CODIGO PARA SABER SI YA TERMINO CONVERSION ADC
  346.         MOVF    ADRESH,W            ; MOVEMOS ADRESH A W UNA VEZ ACABADA LA CONVERSION
  347.         BANKSEL ADC_VALUE           ; NOS UBICAMOS EN BANCO QUE CONTIENE A VARIABLE DECLARADA
  348.         MOVWF   ADC_VALUE           ; MOVEMOS EL RESULTADO DE ADRESH A NUESTRA VARIABLE
  349.         RETURN
  350. ;***********************************************************************************************
  351. ;******************************* RUTINA DE ESCRITURA SPI X BYTES *******************************
  352. ;***********************************************************************************************
  353. MENSAJE_X_BYTES
  354.     MOVWF   CONTADOR_BYTES          ; MOVEMOS A NUESTRO REGISTRO CONTADOR BYTES EL # EN W
  355. WRITING_LCD    
  356.     MOVIW   FSR0++                  ; MOVEMOS INDF A W E INCREMENTAMOS FSR0 EN 1
  357.     CALL    DATO_SPI                ; TRASNMITIMOS VIA SPI EL BYTE EN W
  358.     DECFSZ  CONTADOR_BYTES,F        ; DECREMENTAMOS 1 EL CONTADOR Y SALTAMOS HASTA 0
  359.     GOTO    WRITING_LCD             ; REGRESAMOS A SEGUIR ESCRIBIENDO LA LCD
  360.     RETURN
  361. ;***********************************************************************************************
  362. ;************************** RUTINA DE INICIALIZACION DE LCD NOKIA5110 **************************
  363. ;***********************************************************************************************    
  364. INI_LCD_NOKIA
  365.     BCF     RST_NOKIA                ; CREAMOS UN SOFTWARE POR RESET EN LA LCD
  366.     NOP                              ; PERDEMOS UN CICLO DE INSTRUCCION
  367.     BSF     RST_NOKIA                ; REGRESAMOS DEL RESET
  368.     MOVLW   LOW(INICIA_NOKIA)
  369.     MOVWF   FSR0L
  370.     MOVLW   HIGH(INICIA_NOKIA)
  371.     MOVWF   FSR0H
  372. INIT_NOKIA
  373.     MOVIW   FSR0++
  374.     CALL    COMANDO_SPI
  375.     MOVIW   [FSR0]
  376.     BTFSS   STATUS,Z
  377.     GOTO    INIT_NOKIA
  378.     RETURN
  379. ;***********************************************************************************************
  380. ;************************** RUTINA DE POSICIONAMIENTO EN Y (RENGLONES) *************************
  381. ;***********************************************************************************************
  382. SET_Y
  383.     ADDLW   B'01000000'
  384.     CALL    COMANDO_SPI
  385.     RETURN
  386. ;***********************************************************************************************
  387. ;************************** RUTINA DE POSICIONAMIENTO EN X (COLUMNAS) **************************
  388. ;***********************************************************************************************
  389. SET_X
  390.     ADDLW   B'10000000'
  391.     CALL    COMANDO_SPI
  392.     RETURN
  393. ;***********************************************************************************************
  394. ;*************************** ZONA DE DECLARACION DE TABLAS PARA DATOS **************************
  395. ;***********************************************************************************************  
  396.     INICIA_NOKIA: dt 0X21,0XCF,0X20,0X0C,0X00
  397.     ADC_TEXT:     dt 0XFC,0X12,0X12,0XFC,0X00,0XFE,0X82,0X82,0X7C,0X00,0X7C,0X82,0X82,0X44,0X00,0X14,0X00
  398.     HOLA_MENSAJE: dt 0XFE,0X10,0X10,0XFE,0X00,0X7C,0X82,0X82,0X7C,0X00,0XFE,0X80,0X80,0X80,0X00,0XFC,0X12,0X12,0XFC,0X00;A
  399.     TODO_MENSAJE: dt 0X02,0X02,0XFE,0X02,0X02,0X00,0X7C,0X82,0X82,0X7C,0X00,0XFE,0X82,0X82,0X7C,0X00,0X7C,0X82,0X82,0X7C,0X00
  400.     PIC_MENSAJE:  dt 0X00,0X00,0XFE,0X12,0X12,0X0C,0X00,0XFE,0X00,0X7C,0X82,0X82,0X44,0X00
  401.  
  402.  
  403.  
  404.  
  405.  DATO_SPI
  406.     BSF     DC_NOKIA
  407.     BCF     LCD_NOKIA
  408.     BANKSEL SSP1BUF
  409.     MOVWF   SSP1BUF
  410.     BANKSEL PIR1
  411.     BCF     PIR1,SSP1IF
  412. WSPI
  413.     BTFSS   PIR1,SSP1IF
  414.     GOTO    WSPI
  415.     BCF     PIR1,SSP1IF
  416.     BANKSEL PORTA
  417.     BSF     LCD_NOKIA
  418.     RETURN
  419. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  420. COMANDO_SPI
  421.     BCF     DC_NOKIA
  422.     BCF     LCD_NOKIA
  423.     BANKSEL SSP1BUF
  424.     MOVWF   SSP1BUF
  425.     BANKSEL PIR1
  426.     BCF     PIR1,SSP1IF
  427. WSPIC
  428.     BTFSS   PIR1,SSP1IF
  429.     GOTO    WSPIC
  430.     BCF     PIR1,SSP1IF
  431.     BANKSEL PORTA
  432.     BSF     LCD_NOKIA
  433.     RETURN
  434. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  435.  
  436.    
  437. RETARDO
  438.     MOVLW   0X3F
  439.     MOVWF   RET
  440.     MOVWF   RET2
  441. ESP
  442.     DECFSZ  RET,F
  443.     GOTO    ESP
  444.     MOVLW   0XFF
  445.     MOVWF   RET
  446.     DECFSZ  RET2,F
  447.     GOTO    ESP
  448.     RETURN
  449.     END
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: KILLERJC en 04 de Diciembre de 2015, 05:52:27
Sigamos jugando con tablas y accesos indirectos!


Código: ASM
  1. MUESTRA_VALOR
  2.  
  3.     BANKSEL ADC_VALUE               ; ME ASEGURO ESTAR EN BANCO DONDE ESTA ADC_VALUE (MI REGISTRO)
  4.     MOVF    ADC_VALUE,W             ; MOVEMOS ADC_VALUE A W PARA OBTENER 3 BYTES CON EL DATO
  5.  
  6.     CALL    CONVERSION_BCD          ; RUTINA DE CONVERISON BINARIO>>BCD
  7.  
  8.     CLRF    FSR1H                   ; Set de puntero para el valor centena, las variables deben estar ubicadas en ORDEN y SEGUIDAS Centenas, Decenas, Unidades para que funcione
  9.     MOVLW   CENTENAS                ; No puse LOW() por que es una constante, aunque no se si afectaria
  10.     MOVWF   FSR1L
  11.  
  12. Loopete
  13.  
  14.     MOVLW   LOW(NUMS)               ; MUEVO LA DIRECCION DE LA TABLA NUMS (LOW)
  15.     MOVWF   FSR0L                   ; A MI REGISTRO FSR0L
  16.     MOVLW   HIGH(NUMS)              ; MUEVO LA DIRECCION DE LA TABLA NUMS (HIGH)
  17.     MOVWF   FSR0H                   ; AL REGISTRO FSR0H
  18.  
  19.     BCF     STATUS,C                ; Carry = 0, para la rotacion me aseguro
  20.     RLF     INDF1,W                 ; W = x*2
  21.     RLF     WREG,W                  ; W = x*2*2 = x*4
  22.     ADDWF   FSR0L,F                 ; Sumo a la base de la tabla para obtener el offset
  23.     BTFSC   STATUS,C                ; Correccion por si se excedio, una precaucion solo por si se puso en un borde la tabla
  24.     INCF    FSR0H,F
  25.  
  26.     MOVLW   .4                      ; NUMERO DE BYTES A TRANSMITIR
  27.     CALL    MENSAJE_X_BYTES         ; LLAMO A SUBRUTINA DE TRANSMISION DE BYTES
  28.  
  29.     CLRW                            ; Envio el 0x00 que habia que enviar siempre al final, es esto, o ocupar "9 bytes", en realiadad 9 palabras de memoria mas mas en tabla
  30.     CALL    DATO_SPI
  31.  
  32.     MOVLW   UNIDADES                ; El valor a que apunta es las unidades? es decir se envio las unidades recien?
  33.     SUBWF   FSR1L,W
  34.     BTFSC   STATUS,Z                ; Si: Sale
  35.     RETURN
  36.     INCF    FSR1L,F                 ; No: Envia el proximo
  37.     GOTO Loopete
  38.  
  39.  
  40.  
  41.  
  42. ;***********************************************************************************************
  43. ;***************************** RUTINAS PARA MANDAR VALORES EN LCD ******************************
  44. ;***********************************************************************************************
  45.  
  46.  
  47.  
  48. NUMS:   dt 0x7C, 0x82, 0x82, 0x7C               ;0
  49.         dt 0x00, 0x84, 0xFE, 0x80               ;1
  50.         dt 0xC4, 0xA2, 0x92, 0x8C               ;2
  51.         dt 0x44, 0x92, 0x92, 0x6C               ;3
  52.         dt 0x30, 0x28, 0x24, 0xFE               ;4
  53.         dt 0x4E, 0x8A, 0x8A, 0x72               ;5
  54.         dt 0x7C, 0x92, 0x92, 0x64               ;6
  55.         dt 0x62, 0x12, 0x0A, 0x06               ;7
  56.         dt 0x6C, 0x92, 0x92, 0x6C               ;8
  57.         dt 0x4C, 0x92, 0x92, 0x7C               ;9

Solo para jugar un poco mas con los accesos indirectos nada mas, podria haber puesto un contador en ves de verificar las direcciones.
Tambien se me ocurrio implementar una  Tabla que contenga las direcciones de los registros a enviar y el orden, de esa forma los registros podian estar en cualquier valor, pero para hacerlo simple requeria de al menos 3 punteros o utilizar mas registros como para tener un "almacenamiento temporal" y luego volver a cargarlo. Aunque solo sirve para registros del primer banco, necesitaria un registro mas para hacerlo para todos los bancos. Ya que necesitaria 2 bytes para la direccion por cada registro


Código: ASM
  1. ;***********************************************************************************************
  2. ;************************ RUTINA PARA MOSTRAR VALOR ADC 8 BITS *********************************
  3. ;***********************************************************************************************  
  4. MUESTRA_VALOR
  5.  
  6.     BANKSEL ADC_VALUE               ; ME ASEGURO ESTAR EN BANCO DONDE ESTA ADC_VALUE (MI REGISTRO)
  7.     MOVF    ADC_VALUE,W             ; MOVEMOS ADC_VALUE A W PARA OBTENER 3 BYTES CON EL DATO
  8.  
  9.     CALL    CONVERSION_BCD          ; RUTINA DE CONVERISON BINARIO>>BCD
  10.  
  11.     MOVLW   HIGH(REG_A_ENVIAR)      ; Valor de la tabla en FSR1
  12.     CLRF    FSR1H              
  13.     MOVLW   LOW(REG_A_ENVIAR)
  14.     MOVWF   FSR1L
  15.  
  16. Loopete
  17.  
  18.     MOVIW   FSR1++                  ; Es 0? salgo, se termino
  19.     BTFSC   STATUS,Z
  20.     RETURN
  21.  
  22.     MOVWF   FSR1H_AUX               ; Dato recuperado desde W, valores de direccion de registros, guardo momentaneamente
  23.     MOVF    FSR1L                   ; Guardo FSR1L - Tabla
  24.     MOVWF   FSR1L_AUX               ; Seteo FSR1L - Registro
  25.     MOVF    FSR1H_AUX               ; Guardo FSR1H - Tabla
  26.     MOVWF   FSR1L                   ; Seteo FSR1H = 0x00
  27.     MOVF    FSR1H
  28.     MOVWF   FSR1H_AUX
  29.     CLRF    FSR1H
  30.  
  31.  
  32.     MOVLW   LOW(NUMS)               ; MUEVO LA DIRECCION DE LA TABLA NUMS (LOW)
  33.     MOVWF   FSR0L                   ; A MI REGISTRO FSR0L
  34.     MOVLW   HIGH(NUMS)              ; MUEVO LA DIRECCION DE LA TABLA NUMS (HIGH)
  35.     MOVWF   FSR0H                   ; AL REGISTRO FSR0H
  36.  
  37.     BCF     STATUS,C                ; Carry = 0, para la rotacion me aseguro
  38.     RLF     INDF1,W                 ; W = x*2
  39.     RLF     WREG,W                  ; W = x*2*2 = x*4
  40.     ADDWF   FSR0L,F                 ; Sumo a la base de la tabla para obtener el offset
  41.     BTFSC   STATUS,C                ; Correccion por si se excedio, una precaucion solo por si se puso en un borde la tabla
  42.     INCF    FSR0H,F
  43.  
  44.     MOVLW   .4                      ; NUMERO DE BYTES A TRANSMITIR
  45.     CALL    MENSAJE_X_BYTES         ; LLAMO A SUBRUTINA DE TRANSMISION DE BYTES
  46.  
  47.     CLRW                            ; Envio el 0x00 que habia que enviar siempre al final, es esto, o ocupar "9 bytes", en realiadad 9 palabras de memoria mas mas en tabla
  48.     CALL    DATO_SPI
  49.  
  50.     MOVF    FSR1L_AUX               ; Recupero el valor de la tabla anterior
  51.     MOVWF   FSR1L
  52.     MOVF    FSR1H_AUX
  53.     MOVWF   FSR1H
  54.  
  55.     GOTO Loopete                    ; Repito hasta que sea 0x00 y salga
  56.  
  57.  
  58.  
  59.  
  60. ;***********************************************************************************************
  61. ;***************************** RUTINAS PARA MANDAR VALORES EN LCD ******************************
  62. ;***********************************************************************************************
  63.  
  64.  
  65. REG_A_ENVIAR:
  66.         dt CENTENAS,DECENAS,UNIDADES,0x00
  67.  
  68. NUMS:   dt 0x7C, 0x82, 0x82, 0x7C               ;0
  69.         dt 0x00, 0x84, 0xFE, 0x80               ;1
  70.         dt 0xC4, 0xA2, 0x92, 0x8C               ;2
  71.         dt 0x44, 0x92, 0x92, 0x6C               ;3
  72.         dt 0x30, 0x28, 0x24, 0xFE               ;4
  73.         dt 0x4E, 0x8A, 0x8A, 0x72               ;5
  74.         dt 0x7C, 0x92, 0x92, 0x64               ;6
  75.         dt 0x62, 0x12, 0x0A, 0x06               ;7
  76.         dt 0x6C, 0x92, 0x92, 0x6C               ;8
  77.         dt 0x4C, 0x92, 0x92, 0x7C               ;9
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 11 de Febrero de 2016, 02:57:45
Gracias KillerJC en unos minutos más lo implementó para saber como queda. Dos preguntas más. Como me recomiendas leer la frecuencia a la que esta entrando la señal del ADC? Y la otra pregunta es sobre como podría implementar una "ROM" con todos los caracteres ASCII? Digo si es posible
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: KILLERJC en 11 de Febrero de 2016, 03:12:01
Gracias KillerJC en unos minutos más lo implementó para saber como queda. Dos preguntas más. Como me recomiendas leer la frecuencia a la que esta entrando la señal del ADC? Y la otra pregunta es sobre como podría implementar una "ROM" con todos los caracteres ASCII? Digo si es posible

A no ser que tengas una senoidal y quieras medir eso es la unica razon por la que mediria "frecuencia". Si es una señal aleatoria se complica ( y no se por que lo harias realmente).
Creo que lo mejor es un circuito externo ( 2 diodos de clamping + resistencia ) y que observar cuando pasa de 1 a 0 y con un timer ver el tiempo del mismo, o podes hacer uso del CCP.

Respecto a los caracteres ASCII, si es posible, pero te va a llevar tiempo hacerlos todos o casi todos. Y luego los vas a tener que poner con .dt al igual que se hizo lo demas. Incluso los podes poner en una direccion especifica con un ORG antes. Eso depende de vos nomas. Y recorda que te va a consumir bastante flash.
Pero por que hacerlo uno mismo cuando podria sacarlo de otro lado?

http://sunge.awardspace.com/glcd-sd/node4.html

Agregar los .dt y quitar todo lo demas. WIN, tenes tu tabla ya realizada :P obviamente que comienza de 0x20 ( 32 ), asi que si usas la tabla esa al valor a escribir deberias restarle 0x20 asi coincide con los de la tabla :)
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 26 de Febrero de 2016, 03:57:04
jejej disculpa la demora KillerJC deberás que estas lleno de mucha información muy interesante. La verdad no he tenido mucho tiempo libre para seguir practicando, y bueno respecto a los caracteres eso haré para ya tener listos todos. Sobre el calculo de la frecuencia realmente solo lo decia pensado en alguna aplicación interesante como hacer un mini osciloscopio pero creo que es mas dificil. Alguna idea que tengas para seguir trabajando con esta LCD Nokia? Este PIC me ha gustado mucho respecto algunos otros mas maduros.
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 26 de Febrero de 2016, 04:02:17
Para complementar un poco este post. Me decidi a manejar ahora una LCD 1602 que básicamente muchos conocen, debido a la restriccion que hay en cuanto el numero de pines hice la interfaz de 4 bits. No me rompi la cabeza mucho para adecuar la muy famosa libreria de LCD 4BIT. Aqui el código de la Librería:

Código: ASM
  1. CBLOCK
  2. LCD_DATO
  3. LCD_GuardaDato
  4. LCD_Auxiliar1
  5. LCD_Auxiliar2
  6. ENDC
  7.  
  8. CHAR_X_LINEA    EQU     .16             ; Número de caracteres por línea de la pantalla.
  9.  
  10. #DEFINE  RS             PORTC,0
  11. #DEFINE  RE             PORTC,1
  12. #DEFINE  LCD_BUS        PORTB
  13.  
  14. INI_LCD
  15. ;*********************************************************
  16.     BANKSEL T1CON
  17.     MOVLW   B'00110000'             ; CONFIGURO TMR1
  18.     MOVWF   T1CON                   ; PARA RETARDOS
  19. ;*********************************************************
  20.        
  21.     BCF         RE                      ; DESHABILITAMOS PIN
  22.     BCF         RS                      ; ACTIVAMOS MODO COMANDO PONIENDO RS EN 0
  23.     CALL        RET_10ms                ; RETARDO PARA ESTABILIZACIÓN LCD
  24.     MOVLW       B'00110000'             ;
  25.     CALL        LCD_WRITE               ; ESCRIBIMOS DATO EN LCD
  26.     CALL        RET_5ms
  27.     MOVLW       B'00110000'    
  28.     CALL        LCD_WRITE
  29.     CALL        RET_100us
  30.     MOVLW       B'00110000'    
  31.     CALL        LCD_WRITE
  32.     CALL        RET_100us               ; Este retardo es necesario para simular en PROTEUS.
  33.     MOVLW       B'00100000'             ; Interface de 4 bits.
  34.     CALL        LCD_WRITE
  35.     CALL        RET_100us               ; Este retardo es necesario para simular en PROTEUS.
  36.     CALL        LCD_2Lineas4Bits5x7     ; LCD de 2 líneas y caracteres de 5x7 puntos.
  37.     CALL        LCD_CLEAR               ; Pantalla encendida y limpia. Cursor al principio
  38.     CALL        LCD_C_OFF               ; de la línea 1. Cursor apagado.
  39.     CALL        LCD_CursorIncr          ; Cursor en modo incrementar.
  40.     RETURN
  41. LCD_WRITE
  42.     ANDLW       B'11110000'             ; Se queda con el nibble alto del dato que es el
  43.     MOVWF       LCD_DATO                ; que hay que enviar y lo guarda.
  44.     MOVF        LCD_BUS,W               ; Lee la información actual de la parte baja
  45.     ANDLW       B'00001111'             ; del Puerto B, que no se debe alterar.
  46.     IORWF       LCD_DATO,F              ; Enviará la parte alta del dato de entrada
  47.     MOVF        LCD_DATO,W              ; Recupera el dato a enviar.
  48.     MOVWF       LCD_BUS                 ; Envía el dato al módulo LCD.
  49.     BSF         RE                      ; Permite funcionamiento del LCD mediante un pequeño
  50.     BCF         RE                      ; pulso y termina impidiendo el funcionamiento del LC
  51.     RETURN
  52. LCD_CursorIncr                          ; Cursor en modo incrementar.
  53.     MOVLW       B'00000110'
  54.     BRA         LCD_CMD
  55. LCD_L1                                                  ; Cursor al principio de la Línea 1.
  56.     MOVLW       B'10000000'                             ; Dirección 00h de la DDRAM
  57.     BRA         LCD_CMD
  58. LCD_L2                                                  ; Cursor al principio de la Línea 2.
  59.     MOVLW       B'11000000'                             ; Dirección 40h de la DDRAM
  60.     BRA         LCD_CMD
  61. LCD_L3                                                  ; Cursor al principio de la Línea 3
  62.     MOVLW       B'10010100'                             ; Dirección 14h de la DDRAM
  63.     BRA         LCD_CMD
  64. LCD_L4                                                  ; Cursor al principio de la Línea 4
  65.     MOVLW       B'11010100'                             ; Dirección 54h de la DDRAM
  66.     BRA         LCD_CMD
  67. LCD_PosicionLinea1                                      ; Cursor a posición de la Línea 1, a partir de la
  68.     IORLW       b'10000000'                             ; dirección 00h de la DDRAM más el valor del
  69.     BRA         LCD_CMD         ; registro W.
  70. LCD_PosicionLinea2                                      ; Cursor a posición de la Línea 2, a partir de la
  71.     IORLW       b'11000000'                             ; dirección 40h de la DDRAM más el valor del
  72.     BRA         LCD_CMD         ; registro W.
  73. LCD_OFF                                                         ; Pantalla apagada.
  74.     MOVLW       B'00001000'
  75.     BRA         LCD_CMD
  76. LCD_C_ON                                                ; Pantalla encendida y cursor encendido.
  77.     MOVLW       B'00001110'
  78.     BRA         LCD_CMD
  79. LCD_C_OFF                                               ; Pantalla encendida y cursor apagado.
  80.     MOVLW       B'00001100'
  81.     BRA         LCD_CMD
  82. LCD_CLEAR                                                       ; Borra toda la pantalla, memoria DDRAM y pone el
  83.     MOVLW       B'00000001'                             ; cursor a principio de la línea 1.
  84.     BRA LCD_CMD
  85. LCD_2Lineas4Bits5x7                                     ; Define la pantalla de 2 líneas, con caracteres
  86.     MOVLW       B'00101000'                             ; de 5x7 puntos y conexión al PIC mediante bus de
  87. LCD_CMD
  88.     BCF RS                              ; Activa el Modo Comando, poniendo RS=0.
  89.     BRA LCD_Envia
  90. ENVIAR_DATO
  91.     BSF RS                              ; Activa el "Modo Dato", poniendo RS=1.
  92.     CALL        LCD_CodigoCGROM                 ; Obtiene el código para correcta visualización.
  93. LCD_Envia
  94.     MOVWF       LCD_GuardaDato                  ; Guarda el dato a enviar.
  95.     CALL        LCD_WRITE                       ; Primero envía el nibble alto.
  96.     SWAPF       LCD_GuardaDato,W                ; Ahora envía el nibble bajo. Para ello pasa el
  97.                                                 ; nibble bajo del dato a enviar a parte alta del byte.
  98.     CALL        LCD_WRITE                       ; Se envía al visualizador LCD.
  99.     BTFSS       RS                              ; Debe garantizar una correcta escritura manteniendo
  100.     CALL        RET_1ms                         ; 2 ms en modo comando y 50 µs en modo cáracter.
  101.     CALL        RET_100us
  102.     RETURN     
  103. LCD_CodigoCGROM
  104.     MOVWF       LCD_DATO                                ; Guarda el valor del carácter y comprueba si es
  105. LCD_EnheMinuscula                                       ; un carácter especial.
  106.     SUBLW       'ñ'                                    ; ¿Es la "ñ"?
  107.     BTFSS       STATUS,Z
  108.     GOTO        LCD_EnheMayuscula               ; No es "ñ".
  109.     MOVLW       B'11101110'                             ; Código CGROM de la "ñ".
  110.     MOVWF       LCD_DATO
  111.     GOTO        LCD_FinCGROM
  112. LCD_EnheMayuscula
  113.     MOVF        LCD_DATO,W                              ; Recupera el código ASCII de entrada.
  114.     SUBLW       'Ñ'                                    ; ¿Es la "Ñ"?
  115.     BTFSS       STATUS,Z
  116.     GOTO        LCD_Grado                               ; No es "Ñ".
  117.     MOVLW       b'11101110'                             ; Código CGROM de la "ñ". (No hay símbolo para
  118.     MOVWF       LCD_DATO                                ; la "Ñ" mayúscula en la CGROM).
  119.     GOTO        LCD_FinCGROM   
  120. LCD_Grado
  121.     MOVF    LCD_DATO,W                          ; Recupera el código ASCII de entrada.
  122.     SUBLW       'º'                                    ; ¿Es el símbolo "º"?
  123.     BTFSS   STATUS,Z
  124.     GOTO    LCD_FinCGROM                        ; No es "º".
  125.     MOVLW   b'11011111'                         ; Código CGROM del símbolo "º".
  126.     MOVWF   LCD_DATO
  127. LCD_FinCGROM
  128.     MOVF        LCD_DATO,W                              ; En (W) el código buscado.
  129.     RETURN
  130. LCD_LineaEnBlanco
  131.     MOVLW   CHAR_X_LINEA
  132.     BRA     LCD_EnviaBlancos
  133. LCD_UnEspacioBlanco
  134.     MOVLW   .1
  135.     BRA     LCD_EnviaBlancos
  136. LCD_DosEspaciosBlancos
  137.     MOVLW   .2
  138.     BRA     LCD_EnviaBlancos
  139. LCD_TresEspaciosBlancos
  140.     MOVLW   .3
  141. LCD_EnviaBlancos
  142.     MOVWF   LCD_Auxiliar1                       ; (LCD_Auxiliar1) se utiliza como contador.
  143. LCD_EnviaOtroBlanco    
  144.     MOVLW       ' '                                             ; Esto es un espacio en blanco.
  145.     CALL        LCD_DATO                        ; Visualiza tanto espacios en blanco como se
  146.     DECFSZ      LCD_Auxiliar1,F                 ; haya cargado en (LCD_Auxiliar1).
  147.     GOTO        LCD_EnviaOtroBlanco
  148.     RETURN
  149.  
  150. ; Subrutinas "LCD_ByteCompleto" y "LCD_Byte" --------------------------------------------
  151. ;
  152. ; Subrutina "LCD_ByteCompleto", visualiza el byte que almacena el registro W en el
  153. ; lugar actual de la pantalla. Por ejemplo, si (W)=b'10101110' visualiza "AE".
  154. ;
  155. ; Subrutina "LCD_Byte" igual que la anterior, pero en caso de que el nibble alto sea cero
  156. ; visualiza en su lugar un espacio en blanco. Por ejemplo si (W)=b'10101110' visualiza "AE"
  157. ; y si (W)=b'00001110', visualiza " E" (un espacio blanco delante).
  158. ;
  159. ; Utilizan la subrutina "LCD_Nibble" que se analiza más adelante.
  160. LCD_Byte
  161.         movwf   LCD_Auxiliar2                   ; Guarda el valor de entrada.
  162.         andlw   b'11110000'                             ; Analiza si el nibble alto es cero.
  163.         btfss   STATUS,Z                                ; Si es cero lo apaga.
  164.         goto    LCD_VisualizaAlto               ; No es cero y lo visualiza.
  165.         movlw   ' '                                             ; Visualiza un espacio en blanco.
  166.         call    LCD_DATO
  167.         goto    LCD_VisualizaBajo
  168.  
  169. LCD_ByteCompleto
  170.         movwf   LCD_Auxiliar2                   ; Guarda el valor de entrada.
  171. LCD_VisualizaAlto
  172.         swapf   LCD_Auxiliar2,W                 ; Pone el nibble alto en la parte baja.
  173.         call    LCD_Nibble                              ; Lo visualiza.
  174. LCD_VisualizaBajo
  175.         movf    LCD_Auxiliar2,W                 ; Repite el proceso con el nibble bajo.
  176. LCD_Nibble
  177.         andlw   b'00001111'                             ; Se queda con la parte baja.
  178.         movwf   LCD_Auxiliar1                   ; Lo guarda.
  179.         sublw   0x09                                    ; Comprueba si hay que representarlo con letra.
  180.         btfss   STATUS,C       
  181.         goto    LCD_EnviaByteLetra
  182.         movf    LCD_Auxiliar1,W
  183.         addlw   '0'                                             ; El número se pasa a carácter ASCII sumándole
  184.         goto    LCD_FinVisualizaDigito  ; el ASCII del cero y lo visualiza.
  185. LCD_EnviaByteLetra
  186.         movf    LCD_Auxiliar1,W
  187.         addlw   'A'-0x0A                                ; Sí, por tanto, se le suma el ASCII de la 'A'.
  188. LCD_FinVisualizaDigito
  189.         goto    LCD_DATO                        ; Y visualiza el carácter. Se hace con un "goto"
  190.                                                                         ; para no sobrecargar la pila.
  191.  
  192. RET_37us
  193.         BCF     PIR1,TMR1IF
  194.         MOVLW   0XFF
  195.         MOVWF   TMR1H
  196.         MOVLW   0XDC
  197.         MOVWF   TMR1L
  198.         BSF     T1CON,TMR1ON
  199.         BTFSS   PIR1,TMR1IF
  200.         GOTO    $-1
  201.         BCF     T1CON,TMR1ON
  202.         RETURN
  203. RET_100us
  204.         BCF     PIR1,TMR1IF
  205.         MOVLW   0XFF
  206.         MOVWF   TMR1H
  207.         MOVLW   0X9C
  208.         MOVWF   TMR1L
  209.         BSF     T1CON,TMR1ON
  210.         BTFSS   PIR1,TMR1IF
  211.         GOTO    $-1
  212.         BCF     T1CON,TMR1ON
  213.         RETURN
  214. RET_1ms
  215.         BCF     PIR1,TMR1IF
  216.         MOVLW   0XFC
  217.         MOVWF   TMR1H
  218.         MOVLW   0X18
  219.         MOVWF   TMR1L
  220.         BSF     T1CON,TMR1ON
  221.         BTFSS   PIR1,TMR1IF
  222.         GOTO    $-1
  223.         BCF     T1CON,TMR1ON
  224.         RETURN
  225. RET_5ms
  226.         BCF     PIR1,TMR1IF
  227.         MOVLW   0XEC
  228.         MOVWF   TMR1H
  229.         MOVLW   0X78
  230.         MOVWF   TMR1L
  231.         BSF     T1CON,TMR1ON
  232.         BTFSS   PIR1,TMR1IF
  233.         GOTO    $-1
  234.         BCF     T1CON,TMR1ON
  235.         RETURN
  236. RET_10ms
  237.         BCF     PIR1,TMR1IF
  238.         MOVLW   0XD8
  239.         MOVWF   TMR1H
  240.         MOVLW   0XF0
  241.         MOVWF   TMR1L
  242.         BSF     T1CON,TMR1ON
  243.         BTFSS   PIR1,TMR1IF
  244.         GOTO    $-1
  245.         BCF     T1CON,TMR1ON
  246.         RETURN
  247. RET_50ms
  248.         BCF     PIR1,TMR1IF
  249.         MOVLW   0X3C
  250.         MOVWF   TMR1H
  251.         MOVLW   0XB0
  252.         MOVWF   TMR1L
  253.         BSF     T1CON,TMR1ON
  254.         BTFSS   PIR1,TMR1IF
  255.         GOTO    $-1
  256.         BCF     T1CON,TMR1ON
  257.         RETURN
  258. RET_100ms
  259.         BCF     PIR1,TMR1IF
  260.         MOVLW   0X3C
  261.         MOVWF   TMR1H
  262.         MOVLW   0XB0
  263.         MOVWF   TMR1L
  264.         BSF     T1CON,TMR1ON
  265.         BTFSS   PIR1,TMR1IF
  266.         GOTO    $-1
  267.         BCF     T1CON,TMR1ON
  268.         BCF     PIR1,TMR1IF
  269.         MOVLW   0X3C
  270.         MOVWF   TMR1H
  271.         MOVLW   0XB0
  272.         MOVWF   TMR1L
  273.         BSF     T1CON,TMR1ON
  274.         BTFSS   PIR1,TMR1IF
  275.         GOTO    $-1
  276.         BCF     T1CON,TMR1ON
  277.         RETURN
  278. RET_500ms
  279.         MOVLW   .5
  280.         MOVWF   TIME_AUX
  281.         CALL    RET_100ms
  282.         DECFSZ  TIME_AUX,F
  283.         GOTO    $-2
  284.         RETURN
  285. RET_1s
  286.         MOVLW   .10
  287.         MOVWF   TIME_AUX
  288.         CALL    RET_100ms
  289.         DECFSZ  TIME_AUX,F
  290.         GOTO    $-2
  291.         RETURN

Como se ve al final, genere unas rutinas para retardos con el timer 1. Fueron sustituidos en la libreria. Y para empezar este pequeño código de prueba.

Código: ASM
  1. #INCLUDE "P16F1707.INC"
  2.  __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOREN_OFF & _CLKOUTEN_OFF
  3.  __CONFIG _CONFIG2, _WRT_OFF & _PPS1WAY_ON & _ZCDDIS_OFF & _PLLEN_ON & _STVREN_ON & _BORV_LO & _LPBOR_OFF & _LVP_OFF
  4.  
  5.     CBLOCK  0X020
  6.     TIME_AUX
  7.     LCD_AUX
  8.     ENDC
  9. ;***********************************************************************************************
  10. ;********************************* VECTOR DE RESET DEL PIC *************************************
  11. ;***********************************************************************************************
  12.     ORG     0X00
  13.     GOTO    CONFIGURA_PIC
  14. ;***********************************************************************************************
  15. ;***************************** VECTOR DE INTERRUPCION DEL PIC **********************************
  16. ;***********************************************************************************************
  17.     ORG     0X04
  18.     RETURN
  19. ;***********************************************************************************************
  20. ;********************************* CONFIGURACION DEL PIC ***************************************
  21. ;***********************************************************************************************
  22.  CONFIGURA_PIC
  23.     BANKSEL OSCCON
  24.     MOVLW   B'11111011'
  25.     MOVWF   OSCCON
  26.     MOVLW   B'00011111'
  27.     MOVWF   OSCTUNE
  28. ;***********************************************************************************************
  29. ;*************************** CONFIGURACION DE PUERTOS DEL PIC **********************************
  30. ;***********************************************************************************************
  31.     BANKSEL PORTA                   ; ME COLOCO EN EL BANCO DE LOS PORTX
  32.     CLRF    PORTA                   ; LIMPIO PINES ASIGNADOS A PORTA
  33.     CLRF    PORTB                   ; LIMPIO PINEAS ASIGNADOS A PORTB
  34.     CLRF    PORTC                   ; LIMPIO PINEAS ASIGNADOS A PORTC
  35.     BANKSEL LATA                    ; NOS DIRIGIMOS A BANCO DE MEMORIA DONDE ESTA LATX
  36.     CLRF    LATA                    ; LIMPIAMOS LATCH DE PUERTO A
  37.     CLRF    LATB                    ; LIMPIAMOS LATCH DE PUERTO B
  38.     CLRF    LATC                    ; LIMPIAMOS LATCH DE PUERTO C
  39.     BANKSEL ANSELA                  ; ME HUBICO EN BANCO DONDE SE ENCUENTRA ANSELX
  40.     CLRF    ANSELA                  ; LIMPIO REGISTROS ADC ASIGNADOS A PORTA
  41.     CLRF    ANSELB                  ; LIMPIO REGISTROS ADC ASIGNADOS A PORTB
  42.     CLRF    ANSELC                  ; LIMPIO REGISTROS ADC ASIGNADOS A PORTC
  43.     BANKSEL TRISA                   ; ME HUBICO EN BANCO QUE CONTIENE A TRISX
  44.     CLRF    TRISA                   ; CONFIGURO PORTA COMO SALIDAS
  45.     CLRF    TRISB                   ; CONFIGURO PORTB COMO SALIDAS
  46.     CLRF    TRISC                   ; CONFIGURO PORTC COMO SALIDAS
  47. ;;CONFIGURAMOS ADC
  48. ;    BANKSEL ADCON1          ; El mismo que el de TRISx
  49. ;    MOVLW   B'01100000'
  50. ;    MOVWF   ADCON1
  51. ;    MOVLW   B'00000001'     ;Select channel AN0
  52. ;    MOVWF   ADCON0          ;Turn ADC On  
  53. ;    BSF     TRISA,0    
  54. ;    BANKSEL ANSELA          ;
  55. ;    BSF     ANSELA,0
  56.  
  57.    
  58.    
  59. ;***************************************************************************************************
  60. ;********************** DEFINICION DE PINES Y BUS DE CONTROL LCD 16X2 ******************************
  61. ;***************************************************************************************************    
  62.         CALL    INI_LCD
  63.  PRINCIPAL
  64.         CALL    LCD_L1
  65.         CALL    MENSAJE_UNO
  66.         CALL    RET_1s
  67.         CALL    LCD_L2
  68.         CALL    MENSAJE_DOS
  69.         CALL    RET_1s
  70.         CALL    LCD_CursorIncr
  71.         GOTO    PRINCIPAL
  72.        
  73. MENSAJE_UNO
  74.         MOVLW   HIGH(MENSAJE_PIC)
  75.         MOVWF   FSR0H
  76.         MOVLW   LOW(MENSAJE_PIC)
  77.         MOVWF   FSR0L
  78.         GOTO    SENDING_TEXT
  79. MENSAJE_DOS
  80.         MOVLW   HIGH(MENSAJE_PIC2)
  81.         MOVWF   FSR0H
  82.         MOVLW   LOW(MENSAJE_PIC2)
  83.         MOVWF   FSR0L
  84.         GOTO    SENDING_TEXT
  85. SENDING_TEXT
  86.         CALL    RET_100ms
  87.         MOVIW   FSR0++
  88.         CALL    ENVIAR_DATO
  89.         MOVIW   [FSR0]
  90.         BTFSS   STATUS,Z
  91.         BRA     SENDING_TEXT
  92.         RETURN
  93.  
  94. ;***************************************************************************************************
  95. ;******************************* ZONA DE DECLARACION DE TABLAS PARA DATOS **************************
  96. ;***************************************************************************************************  
  97.  
  98.         MENSAJE_PIC:  dt "Hola Amigos del Foro", 0X00
  99.         MENSAJE_PIC2: dt "Prueba de Tablas", 0X00
  100.  
  101.   #INCLUDE<LCD_4BIT.INC>
  102.  
  103.     END


Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: KILLERJC en 26 de Febrero de 2016, 04:18:46
Te quedo muy bueno. Felicidades!
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 29 de Febrero de 2016, 23:11:26
Bueno gracias KillerJC es muy bueno recibir una felicitacion de tu parte.  ;-) ahora trabajare en un pequeño proyecto donde debo implementar un menu de configuración. Hice el código para poder navegar solo con dos opciones.

Código: ASM
  1. #INCLUDE "P16F1707.INC"
  2.  __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOREN_OFF & _CLKOUTEN_OFF
  3.  __CONFIG _CONFIG2, _WRT_OFF & _PPS1WAY_ON & _ZCDDIS_OFF & _PLLEN_ON & _STVREN_ON & _BORV_LO & _LPBOR_OFF & _LVP_OFF
  4.  
  5.     CBLOCK  0X020
  6.     TIME_AUX
  7.     LCD_AUX
  8.     C1
  9.     C2
  10.     ENDC
  11. ;***********************************************************************************************
  12. ;********************************* VECTOR DE RESET DEL PIC *************************************
  13. ;***********************************************************************************************
  14.     ORG     0X00
  15.     GOTO    CONFIGURA_PIC
  16. ;***********************************************************************************************
  17. ;***************************** VECTOR DE INTERRUPCION DEL PIC **********************************
  18. ;***********************************************************************************************
  19.     ORG     0X04
  20.     RETURN
  21. ;***********************************************************************************************
  22. ;********************************* CONFIGURACION DEL PIC ***************************************
  23. ;***********************************************************************************************
  24.  CONFIGURA_PIC
  25.     BANKSEL OSCCON
  26.     MOVLW   B'11111011'
  27.     MOVWF   OSCCON
  28.     MOVLW   B'00011111'
  29.     MOVWF   OSCTUNE
  30. ;***********************************************************************************************
  31. ;*************************** CONFIGURACION DE PUERTOS DEL PIC **********************************
  32. ;***********************************************************************************************
  33.     BANKSEL PORTA                   ; ME COLOCO EN EL BANCO DE LOS PORTX
  34.     CLRF    PORTA                   ; LIMPIO PINES ASIGNADOS A PORTA
  35.     CLRF    PORTB                   ; LIMPIO PINEAS ASIGNADOS A PORTB
  36.     CLRF    PORTC                   ; LIMPIO PINEAS ASIGNADOS A PORTC
  37.     BANKSEL LATA                    ; NOS DIRIGIMOS A BANCO DE MEMORIA DONDE ESTA LATX
  38.     CLRF    LATA                    ; LIMPIAMOS LATCH DE PUERTO A
  39.     CLRF    LATB                    ; LIMPIAMOS LATCH DE PUERTO B
  40.     CLRF    LATC                    ; LIMPIAMOS LATCH DE PUERTO C
  41.     BANKSEL ANSELA                  ; ME HUBICO EN BANCO DONDE SE ENCUENTRA ANSELX
  42.     CLRF    ANSELA                  ; LIMPIO REGISTROS ADC ASIGNADOS A PORTA
  43.     CLRF    ANSELB                  ; LIMPIO REGISTROS ADC ASIGNADOS A PORTB
  44.     CLRF    ANSELC                  ; LIMPIO REGISTROS ADC ASIGNADOS A PORTC
  45.     BANKSEL TRISA                   ; ME HUBICO EN BANCO QUE CONTIENE A TRISX
  46.     CLRF    TRISA                   ; CONFIGURO PORTA COMO SALIDAS
  47.     CLRF    TRISB                   ; CONFIGURO PORTB COMO SALIDAS
  48.     CLRF    TRISC                   ; CONFIGURO PORTC COMO SALIDAS
  49.    
  50.     BSF     TRISC,7                 ; PINES DEFINIDOS COMO ENTRADA
  51.     BSF     TRISC,6                 ; CORRESPONDIENTE A BOTONES USUARIO
  52.    
  53.    
  54. #DEFINE UP      PORTC,7             ; BOTON PARA INCREMENTAR
  55. #DEFINE DOWN    PORTC,6             ; BOTON PARA DECREMENTAR
  56.  
  57.     CURSOR  EQU B'01111110'
  58.    
  59.    
  60. ;***************************************************************************************************
  61. ;********************** DEFINICION DE PINES Y BUS DE CONTROL LCD 16X2 ******************************
  62. ;***************************************************************************************************    
  63.         CALL    INI_LCD
  64. MAIN_SCREEN
  65.         MOVLW   CURSOR
  66.         MOVWF   C1
  67.         CALL    LCD_L1MENU
  68.         CALL    MENSAJE_UNO
  69.         CALL    LCD_L2MENU
  70.         CALL    MENSAJE_DOS
  71.         CALL    WRITE_CURSOR
  72. PRINCIPAL
  73.         BTFSS   UP
  74.         BRA     CAMBIA_CURSOR
  75.         BTFSS   DOWN
  76.         BRA     CAMBIA_CURSOR
  77.         GOTO    PRINCIPAL
  78. CAMBIA_CURSOR
  79.         BTFSS   UP
  80.         GOTO    CAMBIA_CURSOR
  81.         BTFSS   DOWN
  82.         GOTO    CAMBIA_CURSOR
  83.         MOVF    C1,W
  84.         SUBLW   CURSOR
  85.         BTFSS   STATUS,Z
  86.         GOTO    CAMBIA_C1
  87.         MOVLW   ' '
  88.         MOVWF   C1
  89.         MOVLW   CURSOR
  90.         MOVWF   C2
  91.         CALL    WRITE_CURSOR
  92.         GOTO    PRINCIPAL
  93. CAMBIA_C1
  94.         MOVLW   CURSOR
  95.         MOVWF   C1
  96.         MOVLW   ' '
  97.         MOVWF   C2
  98.         CALL    WRITE_CURSOR
  99.         GOTO    PRINCIPAL
  100. WRITE_CURSOR
  101.         CALL    LCD_L1
  102.         MOVF    C1,W
  103.         CALL    ENVIAR_DATO
  104.         CALL    LCD_L2
  105.         MOVF    C2,W
  106.         CALL    ENVIAR_DATO
  107.         RETURN
  108.        
  109. MENSAJE_UNO
  110.         MOVLW   HIGH(MENSAJE_PIC)
  111.         MOVWF   FSR0H
  112.         MOVLW   LOW(MENSAJE_PIC)
  113.         MOVWF   FSR0L
  114.         GOTO    SENDING_TEXT
  115. MENSAJE_DOS
  116.         MOVLW   HIGH(MENSAJE_PIC2)
  117.         MOVWF   FSR0H
  118.         MOVLW   LOW(MENSAJE_PIC2)
  119.         MOVWF   FSR0L
  120.         GOTO    SENDING_TEXT
  121. SENDING_TEXT
  122.         MOVIW   FSR0++
  123.         CALL    ENVIAR_DATO
  124.         MOVIW   [FSR0]
  125.         BTFSS   STATUS,Z
  126.         BRA     SENDING_TEXT
  127.         RETURN
  128.  
  129. ;***************************************************************************************************
  130. ;******************************* ZONA DE DECLARACION DE TABLAS PARA DATOS **************************
  131. ;***************************************************************************************************  
  132.  
  133. ;        MENSAJE_PIC:  dt "Absoluto x 2 Ch", 0X00
  134. ;       MENSAJE_PIC2: dt "Diferencial", 0X00
  135.        
  136.         MENSAJE_PIC:  dt "Opcion 1", 0X00
  137.         MENSAJE_PIC2: dt "Opcion 2", 0X00
  138.  
  139.   #INCLUDE<LCD_4BIT.INC>
  140.  
  141.     END

Saludos
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 16 de Marzo de 2016, 22:33:20
Bueno pues me quiero hacer un espacio, esta vez para diseñarme una tarjeta entrenadora para este PIC. Entonces quisiera que me dieran su punto de vista que puedo implementar?

Pensaba lo siguiente, electronica de alimentacion basica, conexion para LCD Nokia 5110 y LCD 16x2. Pero la pregunta es que mas puedo incorporar?

Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: KILLERJC en 16 de Marzo de 2016, 23:19:16
La verdad que yo solo hice una ves una tarjeta entrenadora. Luego me di cuenta de lo limitado que era y ahora la tengo guardada y no la toque nunca mas. Limitado en el sentido que no se adapta a todas las situaciones sino que terminas rebuscandotela para poder hacer funcionar algo que tal ves si tuvieras la libertad de acomodar los pines seria muy facil.
No quiero decir que no sirva, muchos aca han realizado tarjetas entrenadoras para varios PICs, algunos ejemplos creo que Suky hizo una, LABmouse otra dsRRBOARD, y hay miles mas que han usado una en proyectos y me parece excelente. Recuerdo una que tenia CAN/ LIN / etc etc etc, creo que era de MGLSOFT.

Pero al menos mi intento no me gusto para nada ejeje. Y termina siendo mas rapido poner un par de cablecitos en el protoboard.

Asi que no te podria ayudar demasiado en eso.

Si tiene UART tiene que tener una salida UART, ya que hay muchas cosas UART, a no ser que incorpores algunas en la placa y las demas lo dejes aparte.
Si tiene I2C podes conectar muchas cosas por I2C, esta esta mucho mejor por que podes poner lo que quieras que se maneje por I2C y dejar un conector para agregar en cualquier caso.
SPI Comparte normalmente con I2C, asi que en ese sentido lo veo un poco mas complejo tener los 2 juntos, a no ser que pueda remapearse el SPI a otro pin que no sea I2C.
Tener salidas de puertos al exterior.

Recuerdo que la placa que habia realizado ( encima la habia hecho con bastantes errores ) podia con jumpers pasar de leds a jumpers y 2 canales con potenciometros + 1 con un pin que podia tomar de afuera. Todo eso llevo a una placa bastante grande y con muchas muchas vias soldadas todas a mano, en un laburo para nada lindo.

EDIT: lo unico que sobrevivio fue un video:
La placa supereior izquierda posee simplemente un boton de reset, cristal para el oscilador, cristal 32Khz para timer1 + 1 pin de GND para conectar la masa del osciloscopio. Todos los demas conectores son los puertos, el cual tienen ademas salidas de tension +5V,+3.3V y GND. La hice para conectarle el dsPIC33FJ32MC202 que tengo y un PIC32MX795L512 ( o algo asi eran, no recuerdo bien ). La de la derecha es la que comentaba. Creo que esa fue una prueba de la interrupcion del timer.

Pero bueno eso fue hace 5 años atras, cuando recien retomaba los PICs ya que hacia mucho que no los tocaba, y cuando pedi ayuda sobre los dsPIC en ASM y nadie ayudo xD jeje, que momentos tristes  :(
http://www.todopic.com.ar/foros/index.php?topic=35392.msg294820#msg294820
Eso me paso por aficionado al ASM y bueno eso hace que no quiero que nadie se quede sin una respuesta al menos ( aunque sea una respuesta pobre ).
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 01 de Abril de 2016, 05:05:38
 :shock: Killer JC tenías toda la razón sobre este entrenador que estaba planeando por ahí hice dos o tres intentos diferentes pero no me convencieron ya que cada uno lo hice pensando en aplicaciones distintas Jaja mejor seguiré complementando más este post con algunos ejemplos.

Bueno ya encarrerados con SPI quisiera pedir tu opinión sobre que otros dispositivos con este protocolo puedo hacer funcionar, verás me ha llamado mucho la atención manejar memorias SD con este micro, no he leído mucho al respecto pero te pregunto de acuerdo a tu experiencia que tan complejo es hacerlo en Asm? Y también si el micro tiene suficiente memoria para poder hacer lecturas y escrituras de la SD?

Así mismo me gustaría me recomendaras otro dispositivo interesante para usarlo con SPI?


Muchas gracias
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: KILLERJC en 01 de Abril de 2016, 06:04:06
Bueno ya encarrerados con SPI quisiera pedir tu opinión sobre que otros dispositivos con este protocolo puedo hacer funcionar, verás me ha llamado mucho la atención manejar memorias SD con este micro, no he leído mucho al respecto pero te pregunto de acuerdo a tu experiencia que tan complejo es hacerlo en Asm? Y también si el micro tiene suficiente memoria para poder hacer lecturas y escrituras de la SD?

Así mismo me gustaría me recomendaras otro dispositivo interesante para usarlo con SPI?

Si solo vas a grabar la SD como si fuera una memoria comun, deberias investigar como es la rutina de inicializacion de la SD para que funcione con SPI ( creo que lo podes sacar de cualquier libreria FAT ) y luego grabar directamente (no recuerdo si hay algo mas que hacer aca), ya que implementar FAT en ASM realmente no le veo sentido, seria complicarse demasiado para algo que usando C lo tendrias realizado. Y si lo haces luego te sirva unicamente para ese solo micro, o tengas que implementar muchisimos cambios para llevarlo a otro, lo cual deja de ser viable gastarse cientos de horas en eso. Incluso si lo haces en C , lo compilas y luego lo "mejoras" desde alli.

Respecto a la memoria del micro son 2 , el mayor limitador es la Flash, y la otra es la RAM, para poder crear un buffer grande y continuo.
Que ese PIC lo tiene un poco mas facil, pero como decia implementar FAT creo que seria un suicidio jeje. Si grabarlo en crudo.

Y dispositivos con SPI no se realmente, hay muchos y no se me ocurre ninguno. Ademas hay que ver que conseguis por que tal ves supongamos un acelerometro lo conseguis pero posee interfaz I2C, a pesar que exista uno con SPI.
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 07 de Abril de 2016, 04:23:49
Que tal, amigos. Bueno el planteamiento es el siguiente:

Para la complementación de este post deseo implementar un lector de temperatura. Después de hacerlo para seguir manejando SPI comenzare con la uSD como le había comentado a KillerJC. Bueno como tengo a la mano un MAX31855J y Termopar J, son los que deseo implementar. Anteriormente con otro micro ya lo había realizado con un SPI por software tratando bit a bit, en vista de que manejarlo vía hardware es mucho mejor implemente el siguiente código:

Código: ASM
  1. GET_TEMP1
  2.         CLRF    BYTE1
  3.         CLRF    BYTE2
  4.         CLRF    BYTE3
  5.         CLRF    BYTE4
  6.         BANKSEL SSP1BUF
  7.         CLRF    SSP1BUF
  8.         BANKSEL PIR1
  9.         BCF     PIR1,SSP1IF
  10.         BCF     MAX1
  11.         BTFSS   PIR1,SSP1IF
  12.         GOTO    $-1
  13.         BCF     PIR1,SSP1IF
  14.         BANKSEL SSP1BUF
  15.         MOVF    SSP1BUF,W
  16.         BANKSEL BYTE1
  17.         MOVWF   BYTE1
  18.  
  19.         BANKSEL SSP1BUF
  20.         CLRF    SSP1BUF
  21.         BANKSEL PIR1
  22.         BCF     PIR1,SSP1IF
  23.         BTFSS   PIR1,SSP1IF
  24.         GOTO    $-1
  25.         BCF     PIR1,SSP1IF
  26.         BANKSEL SSP1BUF
  27.         MOVF    SSP1BUF,W
  28.         BANKSEL BYTE2
  29.         MOVWF   BYTE2
  30.        
  31.         BANKSEL SSP1BUF
  32.         CLRF    SSP1BUF
  33.         BANKSEL PIR1
  34.         BCF     PIR1,SSP1IF
  35.         BTFSS   PIR1,SSP1IF
  36.         GOTO    $-1
  37.         BCF     PIR1,SSP1IF
  38.         BANKSEL SSP1BUF
  39.         MOVF    SSP1BUF,W
  40.         BANKSEL BYTE3
  41.         MOVWF   BYTE3
  42.  
  43.         BANKSEL SSP1BUF
  44.         CLRF    SSP1BUF
  45.         BANKSEL PIR1
  46.         BCF     PIR1,SSP1IF
  47.         BTFSS   PIR1,SSP1IF
  48.         GOTO    $-1
  49.         BCF     PIR1,SSP1IF
  50.         BANKSEL SSP1BUF
  51.         MOVF    SSP1BUF,W
  52.         BANKSEL BYTE4
  53.         MOVWF   BYTE4
  54.        
  55.         BSF     MAX1
  56.        
  57.         MOVLW   '+'
  58.         MOVWF   SIGNO_AUX
  59.         BTFSS   BYTE1,7
  60.         GOTO    KEEP_WS1
  61.         MOVLW   '-'
  62.         MOVWF   SIGNO_AUX
  63.  
  64.         BCF     BYTE1,7
  65.         MOVF    BYTE1,W
  66.         MOVWF   TEMP_AUX
  67.         SWAPF   TEMP_AUX,F
  68.         BCF     TEMP_AUX,0
  69.         BCF     TEMP_AUX,1
  70.         BCF     TEMP_AUX,2
  71.         BCF     TEMP_AUX,3
  72.         MOVF    BYTE2,W
  73.         MOVLW   B'11110000'
  74.         ANDWF   BYTE2,F
  75.         SWAPF   BYTE2,F
  76.         MOVF    BYTE2,W
  77.         ADDWF   TEMP_AUX,F
  78.         MOVF    TEMP_AUX,W
  79.         RETURN

El punto es que si logro la lectura pero deseo me ayuden a obtener la temperatura real. En la simulación con proteus mis datos no coinciden para nada.

En la imagen anexa obtenida de la hoja de datos del MAX me dice que en los primeros 2 bytes tengo la temperatura del termopar bien con mi programa pretendo hacer lo siguiente:

BYTE1 = SIGNO + 7 BITS DE TEMPERATURA       
BYTE2= 4 BITS DE TEMPERATURA + 2 BITS DE DECIMALES + BIT RESERVADO + BIT FAULT

Dados estos primeros Bytes. Solo quiero primero obtener el Byte Bajo de temperatura que es donde encontrare temperaturas de 0 a 255°C

Para ello el procedimiento de acuerdo al código es:

- Pregunto por Signo, después limpio Bit 7 del Byte 1. Me quedan los 3 bits del Byte Alto de temperatura y los 4 bits altos del Byte Bajo
- Aplico un SWAPF para despues limpiar los bits correspondientes al Byte alto.
- Aplico una and con el Byte 2 y la literal b'11110000' para quedarme solo con el nible alto del byte 2 que segun yo es en realidad el nible bajo del Byte bajo de temperatura.
- Despues de la operacion and vuelvo a realizar un SWAP para cambiar los nibles y poder sumarlos directamente.

Bueno segun yo deberia quedarme al final el Byte Low de temperatura. Me queda un numero muy distante al de la simulacion. Las preguntas son:

¿Es correcto mi planteamiento?
¿Existe una forma mas corta para obtener ese byte?

Se que sonara extraño pero solo deseo poder leer de 0 a 250°C maximo por ello no me preocupan los bits altos.

Espero su apoyo colegas.

Saludos
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: KILLERJC en 07 de Abril de 2016, 06:59:35
No se donde esta el problema, personalmente lo haria de otra forma al envio/recepcion, con direccionamiento indirecto, con postincremento seria lo idea para tener un buffer, aunque bueno veo que estas borrando 2 veces sin sentido el flag, asi que quedaria algo asi:

Código: ASM
  1. BANKSEL SSP1BUF
  2.         CLRF    SSP1BUF
  3.         BANKSEL PIR1
  4.         BTFSS   PIR1,SSP1IF
  5.         GOTO    $-1
  6.         BCF     PIR1,SSP1IF          ; Aca borro el flag, no hace falta hacerlo 2 veces
  7.         BANKSEL SSP1BUF
  8.         MOVF    SSP1BUF,W
  9.         BANKSEL BYTE2
  10.         MOVWF   BYTE2

Lo recibido es:

- 1 bit de signo de Temperatura del sensor
- 13 bits de temperatura los cuales 2 son decimales, es decir 0000 0000 000,0 0
- 1 bit que es siempre 0
- 1 bit que deberia si o si ser 0, sino indica falla, es lo primero a ver.
- 1 bit de signo de temperatura interna del MAX
- 11 bits de temperatura interna del MAX, 4 son decimales. 0000 000,0 0000
- 1 bit que siempre es 0
- 3 bits mas que indican cuales fueron las fallas.


Entonces comenzando con el tratamiento lo primero es ver si existe una falla (bit 16 - Bit0 del 2do byte ). Luego tratarlo.

Código: ASM
  1. ANALIZAR_BYTES
  2.         BTFSC   BYTE2,0
  3.         GOTO    CON_FALLA
  4. SIN_FALLA
  5.  
  6.         ;Aca codigo para sacar ambas temperaturas.
  7.  
  8.         ; Primero temperatura interna que es la mas simple
  9.         ; En el segundo byte se encuentra el signo y el entero de esta misma
  10.         MOVLW   '+'
  11.         BTFSC   BYTE3,7
  12.         MOVLW   '-'
  13.         MOVWF   SIGNO_TEMP_INT          ; Signo en ASCII '+' o '-'
  14.         MOVLW   0x7F
  15.         ANDWF   BYTE3, W
  16.         MOVWF   ENTERO_TEMP_INT         ; Valor Entero de esa temperatura
  17.         SWAPF   BYTE4, W
  18.         ANDLW   0x0F
  19.         MOVWF   FRACCION_TEMP_INT       ; Fraccionario ( 4 bits )
  20.  
  21.         ; Segundo temperatura termopar
  22.         ; siii iiii | iiii, ff        - s = signo, i = entero, ff = Fraccion , en Byte1 y 2
  23.  
  24.         MOVLW   '+'
  25.         BTFSC   BYTE1,1
  26.         MOVLW   '-'
  27.         MOVWF   SIGNO_TEMP_TERMOPAR
  28.         RRF     BYTE2, W
  29.         MOVWF   FRACCION_TEMP_TERMOPAR          ; Registro = xiii iffx
  30.         RRF     FRACCION_TEMP_TERMOPAR, F       ; Registro = xxii iiff
  31.         MOVLW   0x03
  32.         ANDWF   FRACCION_TEMP_TERMOPAR, F       ; Registro = 0000 00ff
  33.         SWAPF   BYTE2, W                        ; W = xxff iiii
  34.         ANDLW   0x0F
  35.         MOVWF   ENTERO_LOW_TEMP_TERMOPAR        ; Registro_low = 0000 iiii
  36.         SWAPF   BYTE1, W                        ; W = iiii siii
  37.         MOVWF   ENTERO_HIGH_TEMP_TERMOPAR, F    ; Registro_high = iiii siii
  38.         ANDLW   0xF0                            ; W = iiii 0000
  39.         IORWF   ENTERO_LOW_TEMP_TERMOPAR, F     ; Registro_low = iiii iiii
  40.         MOVLW   0x07
  41.         ANDWF   ENTERO_HIGH_TEMP_TERMOPAR, F    ; Registro_high = 0000 0iii
  42.        
  43.         RETLW   0
  44.  
  45.  
  46. CON_FALLA
  47.         BTFSC   BYTE4,0
  48.         GOTO    FALLA_OC
  49.         BTFSC   BYTE4,1
  50.         GOTO    FALLA_SCG
  51. FALLA_SVC
  52.         ;Aca entra si hay una falla de corto a VCC
  53.         RETLW -1
  54. FALLA_SCG
  55.         ;Aca entra si hay una falla de corto a GND
  56.         RETLW -1
  57. FALLA_OC
  58.         ;Aca entra si no hay nada conectado
  59.         RETLW -1

No tuve en cuenta ningun banco, asi que ojo con eso, y seguro que debe haber un error por ahi, tambien jamas modifico los valores de BYTE1/2/3/4 quedan con sus valores originales por si queres debugearlo.
Pero tu codigo al menos saca el valor entero ( los 8 bits mas bajos obviamente ), Asi que no veo cual seria el problema.
Estas respetando los tiempos de transmision, es decir con una frecuencia de menos de 5Mhz y tambien por ahora mejor tener el CS del MAX en 0, ya que creo que este es el CS:

Código: ASM
  1. BCF     MAX1

Si lo estas haciendo asi, observa que ya enviaste 0x00 para que el SPI comienze a transmitir y luego pones el CS en 0. Esto tal ves te introduzca uno o 2 ceros mas sin querer. El tiempo entre el CS en bajo y el comienzo de envio es de 100ns minimo, asi que si estas a 20Mhz solo pone el BCF del CS antes del los CLRF y vas sobrado. El BSF esta bien, ya que se termino la comunicacion.
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 12 de Abril de 2016, 03:22:42
Siguiendo en el desarrollo de la practica me encontre con esto  :oops: KillerJC que debo hacer?

Código: ASM
  1. Error - section '.org_1' can not fit the absolute section. Section '.org_1' start=0x00000004, length=0x0000107c

Lei varios post donde recomiendan partir el programa. Como lo hago? Si es que se puede, que mas puedo hacer.


Saludos
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: KILLERJC en 12 de Abril de 2016, 05:01:41
Pregunta... que micro estas usando? Si es el PIC16F1707 entonces te quedaste sin memoria..

Pero estamos hablando que te pasaste por MUCHO en la memoria. Por mas que lo dividas es imposible
El PIC16F1707 puede almacenar un maximo de 2048 palabras de flash, desde 0x000 a 0x7FF , por eso mismo ves en el archivo del linker :

16f1707_g.lkr
Citar
CODEPAGE   NAME=page0      START=0x0               END=0x7FF                   
CODEPAGE   NAME=.idlocs    START=0x8000            END=0x8003         PROTECTED
CODEPAGE   NAME=.devid     START=0x8006            END=0x8006         PROTECTED
CODEPAGE   NAME=.config    START=0x8007            END=0x8008         PROTECTED

Normalmente uno lo que hace es poner un ORG (0x00) en el reset, y luego un ORG en el vector de interrupcion, entonces comienza de 0x04 todo lo que esta debajo de esa ORG (por eso dice start 0x04), El problema comienza cuando el compilador linker intenta meter ese pedazo de instrucciones/datos de un largo de 0x107C palabras en la memoria ( 4220 palabras! ) en el unico lugar que posee en flash que es de 0x0 a 0x7FF. Y por lo cual es evidente que no va a entrar ni queriendo en 2044 lugares (4 menos por los vectores). Entonces te dice "la org_1 (por que no le diste nombre) que comienza en 0x04 no entra en el espacio asignado(can not fit) y el largo que intentas meter es de 0x107C"

Si queres ver que es eso, trata de comentar 1 sola instruccion cualquiera (que no sea un MOVIW/MOVWI que ocupan 2 lugares)y fijate que el length deberia cambiar a 0x107B

----------------------------------------------------------------------------------------------------

Otra forma de probarlo. El 16F1708 tiene hasta 4096 palabras y el 16F1709 tiene hasta 8192

Archivo linker del 16F1709:

16f1709_g.lkr
Citar
CODEPAGE   NAME=page0      START=0x0               END=0x7FF                   
CODEPAGE   NAME=page1      START=0x800             END=0xFFF                   
CODEPAGE   NAME=page2      START=0x1000            END=0x17FF                   
CODEPAGE   NAME=page3      START=0x1800            END=0x1FFF                  
CODEPAGE   NAME=.idlocs    START=0x8000            END=0x8003         PROTECTED
CODEPAGE   NAME=.devid     START=0x8006            END=0x8006         PROTECTED
CODEPAGE   NAME=.config    START=0x8007            END=0x8008         PROTECTED

Como ves en este ultimo esta separado en paginas, cada pagina con 2048 palabras, abarcando desde 0x0 a 0x1FFF.  Si lo "compilas" con este PIC (ya que es de la misma familia y no tendiras problemas) deberias tener aproximadamente el 51.5% ocupado del micro. Y que nuevamente te va a dar una idea de que el problema es la falta de espacio en flash.

----------------------------------------------------------------------------------------------------

Tambien otra forma simple de que aparezca este error en el PIC16F1707 sin necesidad de escribir demasiado codigo ( solo 3 lineas ) es asi:

Código: ASM
  1. test ORG 0x7FF
  2.         MOVLW   0x10            ; <- Correcto ya que ocupa la direccion 0x7FF
  3.         MOVLW   0x15            ; <- Problema no hay mas lugar, no existe 0x800

El cual el error deberia ser:

Código: ASM
  1. Error - section '.test' can not fit the absolute section. Section '.test' start=0x000007FF, length=0x00000002

Podes probar si gustas :P, no estoy muy seguro que ocurra asi, pero no le voy a errar tanto.
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 25 de Abril de 2016, 03:01:36
Gracias nuevamente KillerJC por esa explicacion. Efectivamente di con el error que era la memoria, migre el codigo para esa aplicacion a un 18F13K22. Sin problemas, bueno para darle seguimiento a lo de la MicroSD me puse a buscar informacion y hay bastante. En particular os dejo este link para que lo revisen:

https://prezi.com/pudfdp-ploth/micro-sd-bajo-comunicacion-spi/
http://elm-chan.org/docs/mmc/mmc_e.html

Me parecio muy intuitivo. Respecto a la informacion presentada en este link comprendo lo siguiente:

- La velocidad Máxima de transmisión es de 400khz antes de la incialización, despues puede ser mayor?
- Se envian comandos de 6 Bytes y se reciben de 1 u 2 bytes.
- Seguido del bloque de datos que deseamos leer/escribir respectivamente.

Despues seguimos con la rutina de incializcion:
- Delay para estabilizacion de alimentacion
- Configurar SPI en baja velocidad
- Mandar 74 pulsos de reloj
- Mandar Comando 00 que pone la tarjeta en SPI y recibe como respuesta tipo R1 con el IDLE STATE. (Se requiere un CRC 00x95) Esto ultimo no me quedo tan claro.
- Si funciono el Comando 00 mandamos ahora el comando 08 con argumento 0x1AA y CRC 0x87
- Si no fue aceptado el comando 08 mandamos ahora el comando 37 seguido del comando 29 no se precisan argumentos pero se recomienda manda 4 bytes en 0 despues de los comandos?
- Si lo acepto mandamos de nuevo el comando 01 con argumento 0 y CRC cualquiera
- Despues de esto se puede utilizar el comando BLOCKLEN para especificar el tamaño del bloque. Pero para escritura siempre son 512 Bytes y para lectura puede ser desde 1
- Por ultimo se puede utilizar una velocidad mas alta.

Bueno pues parece algo sencillo aunque me quedan un par de preguntas, los CRC son bytes especificos que se tienen que mandar con los comandos?

Bueno y dado que hay que mandar muchos bytes u leer que metodo de escritura lectura me recomiendan?

Saludos
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: KILLERJC en 25 de Abril de 2016, 09:14:40
Citar
- Se envian comandos de 6 Bytes y se reciben de 1 u 2 bytes.

Supuestamente la mayoria de las respuestas son R1, 8 bits y que con que lleguen con 0x00 significa correcto, las R1b poseen un bit extra que es un flag de busy, las R3/R7 ya son 5 bytes, en la cual es una R1 + 4 bytes. Lo que no dice nada es de R2, pero no lo veo como respuesta a ningun comando.

Supuestamente el CRC del comando que vos envias, no es verificado. Asi que no te molestarias en ponerlo. ESTO EN SPI!

Citar
- Mandar Comando 00 que pone la tarjeta en SPI y recibe como respuesta tipo R1 con el IDLE STATE. (Se requiere un CRC 00x95) Esto ultimo no me quedo tan claro.

Ahi lo explica, como todavia NO esta en modo SPI (sino en el nativo de SD ), el CRC debe ser correcto. Entonces el comando que tenes que enviar que es : 01 + Index + Argumento + CRC

Deberia ser

Index: 0x00
Argumento: 0x00000000
CRC = 0x95

De ahi deberias obtener una respuesta, y deberias obtener un 0x01, diciendo que la tarjeta esta en Idle Mode.
No se por que existe que el comando CMD08 sea enviado tambien con CRC, pero no es necesario que lo calcules, simplemente tener el CRC ya precalculado para esos 2 casos, incluso podes ver los archivos .c para guiarte un poco.

Citar
Bueno pues parece algo sencillo aunque me quedan un par de preguntas, los CRC son bytes especificos que se tienen que mandar con los comandos?

Creo que lo respondi arriba, pero solo se necesitan 2 CRC con los valores precalculados, asi que no tenes que crear ninguna rutina para calcular eso.
Y si se envian con los comandos, fijate los bits a enviar en lso comandos

Citar
Bueno y dado que hay que mandar muchos bytes u leer que metodo de escritura lectura me recomiendan?

Depende de tamaño de buffer que poseas, si tenes 2 buffer de 128 en el cual 1 se va llenando y el otro se transmite a la SD, entonces que sean paquetes de 128bytes. O tal ves tenes 2 buffer de lectura de 128bytes tambien y vas llenando uno mientras el otro lees, depende exclusivamente de tu uso.

Y tenes en cuenta que solo estas escribiendo la SD en RAW, no vas a poder abrirlo con la PC y encontrar un archivo, ya que no estas usando ningun formato ( FAT es el mas comun )
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: Pinolillo16 en 25 de Abril de 2016, 23:44:21
Entendido, entonces CRC sólo cuando es nativo, a simple vista no parece sencillo. Pero bien el objetivo si es implementar un FAT para poder abrirlos en la PC. Que debo investigar para poder lograrlo? Es decir cual es el más común que existe y que con este micro pueda implementar?


Gracias
Título: Re:PIC16F1707 Ejemplos básicos
Publicado por: KILLERJC en 26 de Abril de 2016, 06:58:00
Para FAT, esta pequeñes:

https://en.wikipedia.org/wiki/File_Allocation_Table
https://en.wikipedia.org/wiki/Design_of_the_FAT_file_system
https://staff.washington.edu/dittrich/misc/fatgen103.pdf

:P

Lo mejor es que una ves visto eso puedas comprenderlo usando un visor hexadecimal de la SD para comprobar los campos. Y ver que ocurre exactamente como dice.
Pero como comienzo haria lo del SPI con la SD, es decir grabar los datos en RAW sin ningun formato, luego si probaria implementar el FAT.