Autor Tema: pequeños proyectos  (Leído 55179 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado groundman

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1870
    • www.ingeniopic.com
Re: pequeños proyectos
« Respuesta #75 en: 23 de Enero de 2014, 19:18:43 »
Hola.me he decicado a crear una libreria para el uso de un teclado resistivo.cuyo valor sera introducido en una entrada analogica del pic.
en este programa la entrada sera por el pin AN0.asi que con solo dos hilos podemos utilizar muchas teclas.

el teclado puede configurarse con un numero determinado de teclas.en el programa esta configurado para el uso de un teclado de 4x4.
que son 16 teclas.pero puede modificarse un valor para un mayor o menor numero de teclas.

tal y como se muestra en la imagen:



en modo reposo a la entrada AN0 se le aplica un valor positivo de tension 0xff.y cuando se pulsa una tecla el valor varia entre los valores
 0x00 y 0xff ambos no inclusive.

el programa esta preparado para pregrabar en la memoria eeprom las teclas que vallamos pulsando.las teclas adquiriran los valores o,1,2,3,4....
hasta la cantidad de teclas que definemos.por defecto son hasta 16 teclas.

si hemos definido 16 teclas.cuando terminemos de meter la numero 16.el programa saldra del modo de pregrabado.aunque si queremos menos teclas
tambien podemos finalizar el pregrabado pulsando la primera tecla que se pulso.


este programa tiene un metodo "anti rebote" que consiste en la comparacion de 10 valores analogicos capurados desde AN0.y escoger el
valor mas repetido.


Código: [Seleccionar]
;Este programa devuelbe en el registro TEMP_TECLA ,el indice de la tecla pregrabada.

;la peculariedad de que este programa sea tan grande,es que tiene un sistema de comprovacion de errores,que al pulsar
;una tecla.se almazenan en memoria 10 valores de esa tecla y se coje el valor mas repetido.de esa forma se evita el que al
;pulsar un boton resistivo,no cojamos el valor mas aproximado al real de ese boton.y que nos falle la identificacion de esa tecla.

;el programa tarda en ejecutarse

;La memorizacion de teclas esta limitada a 16 para mas teclas modificar: (#define N_BYTES .16)
;pero habra que tener en cuenta un byte en la posicion 17 para el valor de numeros de teclas memorizadas
;La memorizacion se realiza pulsando el numero de teclas definido.en el caso de que las teclas sean inferiores a las definidas
;solo haria falta pulsar la primera tecla que se presiono para la finalizacion del aprendizaje.

;la primera tecla sera asignada con el valor .0 la siguiente .1 .2 .3 - etc y asi hasta que finalizemos.

;Para el borrado de teclas y reaprendizage,poner a masa la entrada analogica.

CBLOCK BOTON_PULS_VAR
TEMP_ANALOG ;registro de tecla pulsada
COMPARADOR
TEMP_KEY
TEMP_KEY2
CONT_REG
CONT_COINC
CONT_ALMAC ;contador de las teclas almacenadas
PRIMR_TECL ;primera tecla plsada en el aprendizaje
FLAGS_KEY
N_KEYS       ;numero de teclas aprendidas
TEMP_TECLA
  ENDC


#define INI_RAM 0XF6 ;zona donde se ubicaran los datos analogicos de tecla pulsada
#define INI_TABLA 0XEC
#define KEY_OK bsf FLAGS_KEY,0
#define KEY_NOK bcf FLAGS_KEY,0
#define KEY_OK2 bsf FLAGS_KEY,1
#define FIND_OFF bsf FLAGS_KEY,2
#define FLASH_OK bsf FLAGS_KEY,3
#define N_BYTES .16 ;numero de teclas a gestionar y direccion de la eeprom donde se metera el dato del numero de bytes guardados


BOTON_PULS setf PRIMR_TECL
setf TEMP_KEY2
btfsc FLAGS_KEY,3 ;comprueba si ha habido pregrabacion en la eeprom de datos
goto SEARCH ;si la ha habido salta a busqueda de tecla pulsada
bt2 clrf DIR_EEPROM
call ALMAC ;salta a almacenamiento de aprendizage de teclas pulsadas en la eeprom

btfss FLAGS_KEY,2 ;comprueba si se termino con el aprendizage del teclado
goto bt3
call EEP_RAM ;si es asi,traspasa los bytes de la eeprom a la ram
return

bt3 setf TEMP_KEY2 ;en caso contrario setea el registro
goto bt2 ;y sigue el aprendizage




;********************************************************** KEYB ***********************************************************************
;adquisicion de valor de tecla pulsada

KEYB call TECLA ;lee valor de tecla pulsada
btfss FLAGS_KEY,0 ;comprueba si se ha pulsado una tecla
return ;si no es si,retorna
movff TEMP_KEY,TEMP_KEY2 ;guarda valor de tecla pulsada
kb1 call TECLA ;lee valor de tecla pulsada
btfsc FLAGS_KEY,0 ;comprueba si se ha soltado la tecla
goto kb1 ;si no es asi,vuelbe a leer valor de tecla pulsada
return ;retorna


;************************************************************ TECLA ********************************************************************
;Lectura de la entrada analogica y transferencia de 10 valores a la ram


TECLA setf TEMP_KEY
movlw INI_RAM
movwf FSR0L
movlw BANCO_GENERAL
movwf FSR0H

REPE call DAT_AN ;lee dato analogico
call BORRA_TECL ;opcion a borrado de teclado

setf WREG ;valor 0xff.tecla sin pulsar
cpfseq TEMP_ANALOG ;compara con el valor analogico de tecla
goto tec1
KEY_NOK
return ;si el valor analogico de la teclaes 0xff repite busqueda analogica(VALOR DE TECLA SIN PULSAR)
tec1 movff TEMP_ANALOG,INDF0
incf FSR0L,F ;incrementa FSR
clrf WREG
cpfseq FSR0L
goto REPE ;si no se ha llegado al tope de la ram repite


; aqui leemos la ram y buscamos el dato mas repetido
; en esta rutina se cogen los valores almacenados entre las direcciones seleccionadas y se coge valor que tenga mas numeros repetidos.

BUSCA_REP movlw BANCO_GENERAL ;banco donde trabajaremos con los registros generales
movwf FSR2H ;selecciona bancos de direccionamiento indirecto
movwf FSR1H
movwf FSR0H

movlw INI_TABLA ;inicio de tabla ram donde estan los valores a comparar
movwf FSR0L ;selecciona indice de tabla
decf FSR0L,F ;decrementa una direccion para luego incrementarla

movlw INI_RAM ;inicio de tabla ram donde se introduciran cantidad de coincidencias
movwf FSR2L ;selecciona indice de tabla
decf FSR2L,F ;decrementa una direccion para luego incrementarla

movlw .11 ;bytes a comparar menos 1
movwf CONT_COINC ;contador de comparaciones
regsig2 dcfsnz CONT_COINC,F ;decrementa el contador de comparaciones
goto discrim ;si se ha terminado de comprobar las coincidencias salta a esta direccion


movlw INI_RAM ;inicio de tabla ram donde se introduciran cantidad de coincidencias
movwf FSR1L ;selecciona indice de tabla
incf FSR2L,F ;incrementa indice de tabla
decf FSR1L,F

movff INDF2,COMPARADOR ;introduce valor de la tabla en registro comparador
movlw .11 ;registros a comparar
movwf CONT_REG ;contador de registros a comparar
incf FSR0L,F ;incrementa  indice de registros

regsig1 incf FSR1L,F ;incrementa indice de comparaciones
movf INDF1,W ;lee el registro indexado
dcfsnz CONT_REG,F ;decrementa contador de registros
goto regsig2 ;si se ha llegado al limite salta a lectura de siguiente registro
cpfseq COMPARADOR ;comprueba si w es igual a COMPARADOR
goto regsig1 ;siguiente comparacion
incf INDF0,F ;incrementa direccion seleccionada si hay coincidencia
goto regsig1 ;siguiente comparacion


;busca el valor mas alto
discrim movlw .9 ;cantidad de registros a comparar
movwf CONT_REG ;registro contador
movlw INI_TABLA ;inicio de tabla
movwf FSR0L ;direcciona tabla ram
movff INDF0,TEMP_KEY ;introduce el valor contenido en ram al registro prevalescente
dis1 incf FSR0L,F ;siguiente direccion
movf INDF0,W ;carga valor direccionado en W
cpfsgt TEMP_KEY ;comprueba si es mayor
movff INDF0,TEMP_KEY ;si es mayor introduce el valor en el registro prevalescente
decfsz CONT_REG,F ;decrementa contador de comprobaciones
goto dis1 ;siguiente comprovacion

;busca el valor mas alto de las coincidencias
movlw INI_TABLA ;carga inicio de tabla
movwf FSR0L
pre1 movf INDF0,W ;carga el valor direccionado en W
xorwf TEMP_KEY,W ;comparalo con el valor mas alto
btfsc STATUS,Z ;si se ha encontrado,
goto pre2 ;salta a pre2
incf FSR0L,F ;incrementa direccion
goto pre1 ;repite comparacion
pre2 movlw .10 ;valor de salto a tabla de valores
addwf FSR0L ;salta al valor
movff INDF0,TEMP_KEY ;introduce valor en W
KEY_OK
KEY_OK2
return ;retorna CON EL VALOR ANALOGICO DE LA TECLA PULSADA

;******************************************************* BORRA_TECL **********************************************************************
;Borrado de teclas para nuevo aprendizage "entrada analogica a masa para el borrado"

BORRA_TECL clrf WREG ;valor 0x00
cpfseq TEMP_ANALOG ;comprueba si la tecla pulsada esta a masa
return ;retorna en caso de que no este a masa
clrf DIR_EEPROM ;direccion 0x00 de la eeprom
setf DATO_EEPROM ;valor 0xff a grabar en la eeprom
call ESCRIBIR_DATO ;graba el dato
pop ;salir de todas las llamadas
pop
pop
pop
return ;retorna



;//////////////////////////////////(conversor A/D)////////////////////////////////////////////////////////////////////////////////////////////////
;///////////////busca el dato analogico introducido por el pin seleccionado/////////////////////////////////////////////////////////////////////
;////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
;Si queremos que funcionen todas las entradas analogicas.hay que habilitar las lineas deshabilitadas

DAT_AN bsf ADCON0,GO_DONE ;inicia la conversion
AD_GOIN btfsc ADCON0,GO_DONE ;comprueva si la conversion ha finalizado
goto AD_GOIN ;si la conversion ha finalizado continua
movf ADRESH,w ;carga dato analogico en el acumulador
movwf TEMP_ANALOG ;carga el dato de w en TEMP_ANALOG
;movf ADCON0,W
;movwf CANAL ;mete el contenido de ADCON0 en CANAL
;movf CONT_AD,W ;dato que se suma a ADCON0 para que a la siguiente lectura sea en el proximo canal de AD
;addwf ADCON0,F ;incrementa el canal analogico(AN0->AN4)
;movlw b'00100001';valor para usar AN5 -> b'00101001' ;valor del ultimo registro del conversor analogico
;xorwf ADCON0,w
;btfss STATUS,Z ;si llega a este valor
;return
;movlw 0x01 ;selecciona de nuevo el conversor AN0
;movwf ADCON0
return

;******************************************************** ALMAC *******************************************************************
;Aprendizaje del teclado.
ALMAC clrf FLAGS_KEY
call KEYB ;devuelve dato de tecla pulsada

movlw 0x02
cpfseq FLAGS_KEY

goto ALMAC

AL2 clrf WREG ;valor 0x00
cpfsgt DIR_EEPROM ;comprueba si es la primera tecla pulsada
movff TEMP_KEY2,PRIMR_TECL;almacena la primera tecla pulsada en PRIMR_TRCL.
cpfsgt DIR_EEPROM ;comprueba si es la primera tecla pulsada
goto al1

movf PRIMR_TECL,w ;comprueba si se ha vuelto a pulsar la primera tecla.
cpfseq TEMP_KEY2 ;si no se ha pulsado,-
goto al1 ;salta a al1

al3 movff DIR_EEPROM, N_KEYS  ;guardar el numero de teclas aprendidas
movff N_KEYS,DATO_EEPROM ;pasalo a DATO_EEPROM
movlw N_BYTES ;direccion de la eeprom donde se metera el dato del numero de bytes guardados
movwf DIR_EEPROM ;carga direccion de la eeprom
call ESCRIBIR_DATO ;graba el dato
FIND_OFF ;finalizacion de la memorizacion de teclas
return ;retorna.fin del programa

al1 movff TEMP_KEY2,DATO_EEPROM;carga valor analogico de tecla pulsada en registro de dato eeprom
call ESCRIBIR_DATO ;graba el dato en la eeprom
incf DIR_EEPROM,F ;incrementa la direccion

movlw N_BYTES ;carga tope de bytes a grabar
cpfseq DIR_EEPROM ;comprueba si ha llegado al tope
goto ALMAC ;si no ha llegado salta a ALMAC para siguiente tecla
goto al3 ;en caso contrario salta a al3 para ultima grabacion de numero de bytes y finaliza.

;*************************************************** SEARCH *******************************************************************
;Compara entre tecla pulsada y los valores de tecla almacenados en la eeprom
SEARCH setf TEMP_TECLA
call KEYB ;lee valor de tecla
setf WREG ;valor para tecla sin pulsar
cpfseq TEMP_KEY2 ;comprueba si la tecla esta pulsada.
goto sr1 ;si esta pulsada salta a sr1
return ;en caso contrario.retorna

sr1 clrf DIR_EEPROM ;direccion 0 de la eeprom
sr3 call LEER_DATO ;lee el dato
cpfseq TEMP_KEY2 ;comparalo con la tecla pulsada
goto sr2 ;siguiente direccion a comparar
goto SELEC ;si se ha encontrado la tecla pulsada selecciona valor de tecla.

sr2 incf DIR_EEPROM,F ;increenta la direccion a leer de la eeprom
movf DIR_EEPROM,W ;introducela en el acumulador

cpfsgt N_KEYS ;si la tecla pulsada no esta memorizada,
return ;retorna
goto sr3 ;en caso contrario compara siguiente tecla


SELEC movff DIR_EEPROM,TEMP_TECLA ;almacena en TEMP_TECLA el valor de tecla pulsada.
return ;retorna

;******************************************************* COPM_FLASH *************************************************************

COMP_MEMO clrf FLAGS_KEY ;borra flags
clrf WREG ;dato 0x00
movwf DIR_EEPROM ;direccion a leer de la eeprom de datos 0x00
call LEER_DATO ;lee el dato
setf WREG ;valor 0xFF
cpfseq TEMP_EEP ;comprueba si se ha grabado algo en la direccion 0x00


call EEP_RAM;FLASH_OK ;si se ha grabado algo activa flag de aprendizage
return ;retorna
;***************************************************** EEP_RAM  *****************************************************************
;Traspaso de keys de la eeprom de datos a la ram
EEP_RAM btfsc FLAGS_KEY,2 ;comprueba si es primer reinicio del pic
goto eep2 ;si es el primero,salta a eep2.en caso contrario lee de la eeprom el valor de bytes almacenados

movlw N_BYTES ;direccion de numero de bytes a leer
movwf DIR_EEPROM ;carga la direccion
call LEER_DATO ;lee el dato almacenado en la eeprom
movff TEMP_EEP,N_KEYS ;carga el valor en numero de teclas pulsadas

eep2 lfsr 0,0X07EB ;principio de direccion donde se introduciran los datos leidos de la eeprom de datos
clrf WREG ;dato 0x00
movwf DIR_EEPROM ;direccion a leer de la eeprom de datos 0x00
eep1 call LEER_DATO ;lee el dato
movff TEMP_EEP,INDF0 ;traspasa el dato ledo de la eeprom a la ram
decf FSR0L ;direccion anterior de la ram
incf DIR_EEPROM,f ;siguiente dato a leer de la eeprom
movf N_KEYS,w ;numero de bytes previamente almacenados
cpfseq DIR_EEPROM ;comprueba si se ha llegdo al final de la lectura
goto eep1 ;si no ha llegado.tarspasa siguente byte
FLASH_OK ;flag de datos grabados en flash
return ;retorna


aparte de configurar los puertos al programa se le llamara de esta forma:

Código: [Seleccionar]
call COMP_MEMO ;comprueba si hay algun dato guardado en la direccion 0x00 de la eeprom de datos.y restablece valores de teclas pulsadas
;pr call BOTON_PULS ;deteccion de tecla pulsada
; setf WREG
; cpfseq TEMP_TECLA
; NOP
; goto pr

cuando pulsemos una tecla el programa pasara por el NOP

Código: [Seleccionar]
;libreria para manejo de la eeprom

;//////////////////////////////////////////////ESCRIBIR DATO EN EEPROM///////////////////////////////////////////////////
ESCRIBIR_DATO ;clrwdt
GIE_OFF
;BANK0          ;selecciona banco 0
    movf   DIR_EEPROM,W    ;temporal de direccion de la eeprom de datos
;BANK1 ;selecciona banco 1
    movwf   EEADR ;direccion a acceder
;BANK0 ;selecciona banco 0
movf DATO_EEPROM,W ;temporal de dato de la eeprom de datos
;BANK1 ;selecciona banco 1
      movwf   EEDATA ;dato a grabar
bcf EECON1,EEPGD ;Puntero a la memoria de datos
bcf EECON1,CFGS ;Acceso a la EEPROM

      bsf    EECON1,WREN     ;habilita escritura
;GIE0
movlw   0X55 ;valores imprencindibles para la grabacion de datos en eeprom de datos
      movwf   EECON2 ;"
      movlw   0XAA ;"
        movwf   EECON2 ;"
;GIE1
    bsf    EECON1,WR      ;inicia escritura

      btfsc   EECON1,WR ;comprueva si se grabo el dato
    goto  $-2 ;si lo ha grabado continua.en caso contrario repite la comprobacion.
GIE_ON
bcf    EECON1,WREN ;deshabilitar escritura en eeprom
movf EEADR,W;DIR_EEPROM ;carga el valor de DIR_EEPROM en W
call VERIFICA ;salta a subprograma de verificacion de la correcta grabacion en eeprom de datos
;GIE1
return ;retorna

VERIFICA call LEER_DATO ;salta a subprograma de lectura de dato de la eeprom de datos
movf TEMP_EEP,W ;carga el contenido de TEMP_EEP en W
xorwf DATO_EEPROM,W ;comprueva si es el dato se ha grabado correctamente
btfsc STATUS,Z
return ;si es correcto.retorna

call ESCRIBIR_DATO ;en caso contrario,vuelve a grabar el dato
return ;retorna


;///////////////////////////////////////////LEER DATO DE MEMORIA EEPROM ///////////////////////////////////////////////////////

LEER_DATO    ;BANK1
    bcf EECON1,EEPGD ;Puntero a la memoria de datos
bcf EECON1,CFGS ;Acceso a la EEPROM
movf DIR_EEPROM,W      
      movwf   EEADR ;escribir direccion de memoria eeprom
bsf    EECON1,RD    ;ORDEN DE LECTURA

LEE     btfsc   EECON1,RD ;espera a que se realize la lectura del dato
      goto    LEE
movf  EEDATA,W ;carga valor de eeprom en el registro W
;BANK0 ;selecciona banco 0
movwf   TEMP_EEP ;carga el valor leido de eeprom de datos al registro TEMP_EEP
return ;retorna

« Última modificación: 23 de Enero de 2014, 19:28:58 por groundman »
Montando mi primera impresora 3D (Raprep Prusa i3)

Desconectado tapi8

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1506
Re: pequeños proyectos
« Respuesta #76 en: 24 de Enero de 2014, 14:45:03 »
Gracias por todos estos programas/librerias groundman.

Algo parecido a esto lo habia hecho tu paisano Redpic basandose en una nota de aplicacion de Microchip ¿No?.

Llevas una temporada que estas de un currante  :lol: :lol:

Desconectado groundman

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1870
    • www.ingeniopic.com
Re: pequeños proyectos
« Respuesta #77 en: 24 de Enero de 2014, 18:40:30 »
si. :D estoy con un proyecto de termostato y tengo que crear diferentes librerias que me van a serivir para muchos de los proyectos que haga con los 18f.

lo del teclado resistivo ya hize un proyecto para los mandos del volante de mi coche para usar el casette.pero tube muchos problemas a la hora
de la identificacion de las teclas.porque no realizaba la multiple coincidencia.y si pones un margen superior e inferior para cada tecla.se limita mucho la cantidad
de botones a configurar.y fallaban mucho las pulsaciones.

la idea de usar un teclado matricial ha sido de Redpic.y es muy buena idea.yo solo hubiera puesto resistencias a cada boton.como el caso de lso botones
de volante.

en el caso de los botones del coche.se usan mas de una entrada analogica.asi que este programa lo modificare en un futuro para usar mas entradas.



PD:respecto a la temporada que llevo de currante.tengo algo mas preparado. he creado una libreria para el manejo del sensor DS18B20.con el protocolo one wire.
     pronto lo pondre por aqui.tengo que perfeccionarlo algo mas.
Montando mi primera impresora 3D (Raprep Prusa i3)

Desconectado groundman

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1870
    • www.ingeniopic.com
Re: pequeños proyectos
« Respuesta #78 en: 25 de Enero de 2014, 05:59:17 »
aqui pongo un pequeño proyecto que visualiza la temperatura en una lcd con el sensor DS18B20.




en este uso la libreria que mas destaca es la del uso del DS18B20.aunque no esta terminada del todo.si lo esta para este proyecto.la libreria es muy extensa
y puede gestionar practicamente todos los comandos del DS18B20.me he tirado semanas para crearla.incluso esta implementado la comprobacion del CRC.

de esta forma nos evitamos errores de visualizacion en la LCD.aunque se puede visualizar la identidad del dispositivo.solo es para que practiquemos en el isis
ya que podemos cambiarla en la simulacion para experimentar.aunque no se hace uso de esta para el uso del DS18B20.he usado los comandos para la lectura de la temperatura sin identidad para facilitar la comprension y para que funcione cualquier sensor que conectemos al proyecto.

hay multitud de combinaciones de uso de esta libreria con el sensor.desde localizar todas las identidades de varios sensores conectados en paralelo como la
deteccion de alarmas para realizar por ejemplo un termostato.eso si con la gestion del CRC en todo momento.

proximamente hare MODs para otros circuitos como el preostato.o el uso de varios sensores a la vez.


PD: para que en el circuito real la pantalla gire correctamnte.cambiar el comando movlw   B'00011100'  por   movlw   B'00011000' ya que hay un problema
      entre lo que es la simulacion y lo que es el circuito real.
« Última modificación: 18 de Febrero de 2014, 17:56:50 por groundman »
Montando mi primera impresora 3D (Raprep Prusa i3)

Desconectado groundman

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1870
    • www.ingeniopic.com
Re:pequeños proyectos
« Respuesta #79 en: 26 de Octubre de 2016, 11:19:04 »
hola a todos de nuevo.el tiempo no pasa en valde.ya hace mas de dos años desde la utima respueta.pero aqui estoy y seguire con el posteo de pequeños proyectos.
bien practicar o para coger lo que nos haga falta.


DS1307_18F2550.asm
Código: [Seleccionar]

;************************************************** www.ingeniopic.com ***************************************************
; PROGRAMA : DS1307_18f2550.asm
; Funcion : gestion del reloj DS1307
;           
;   
;  Revision : 1.0        25/10/2016            Programa para : PIC18F2550
; CPU Clock : 48 MHz                     Reloj instruccion :
;       WDT : Deshabilitado                  Tipo de reloj : HSPLL_HS
; Code Prot : OFF     xtal    :4Mhz
;************************************************* www.ingeniopic.com **************************************************
;
LIST P=18F2550 ; Se emplea el PIC 18F2550
RADIX HEX ; Sistema de numeraci¢n hexadecimal
INCLUDE  "P18F2550.INC"

   CONFIG PLLDIV =12
  CONFIG USBDIV = 1
  CONFIG CPUDIV = OSC1_PLL2
  CONFIG FOSC = HSPLL_HS      ;Osc por XTAL 4mhz
 
 
  CONFIG DEBUG = OFF
      CONFIG PWRT = OFF
      CONFIG BOR  = OFF
      CONFIG WDT = OFF;ON
  CONFIG WDTPS = 256
      CONFIG MCLRE = ON
      CONFIG PBADEN = OFF
      CONFIG LVP = OFF
      CONFIG CP0 = OFF
      CONFIG CP1 = OFF
      CONFIG CP2 = OFF
      CONFIG CP3 = OFF
      CONFIG CPB = OFF
      CONFIG CPD = OFF
  CONFIG CCP2MX= OFF
ERRORLEVEL -302

;ZONA DE ETIQUETAS
CBLOCK 0X20
HI_W_TEMP
LO_W_TEMP
HI_STATUS_TEMP
LO_STATUS_TEMP

TEMP_FSR1L
TEMP_FSR2L
TEMP_FSR2L_LO
TEMP_FSR2H_LO
TEMP_FSR1L_LO
TEMP_FSR1H_LO
TEMP_FSR2L_HI
TEMP_FSR2H_HI

HI_TEMP_STATUS
LO_TEMP_STATUS
HI_TEMP_BSR
LO_TEMP_BSR
TEMP_PCL_HI
TEMP_PCL_LO



CONT_BYTE_RTC ;contador de numero de bytes
DIR_I2C ;principio de direccion de dispositivo
DATO_I2C


ENDC



RETARDOS_VAR EQU 0X00A ;variables de la libreria "retardos.inc" hubicados en una zona de memoria accedida desde todos los bancos

EEP_VAR EQU 0X220

HI_POP_REG MACRO ;restaura registros
MOVLB 0X00 ;asegura que este seleccionado el banco0

;MOVFF TEMP_BANK_HI,BSR
movff HI_STATUS_TEMP,STATUS
movff HI_TEMP_BSR,BSR
movf HI_W_TEMP,W


movff TEMP_FSR2H_LO,FSR2H
movff TEMP_FSR2L_LO,FSR2L
movff TEMP_FSR1H_LO,FSR1H
movff TEMP_FSR1L_LO,FSR1L

movff HI_TEMP_STATUS,STATUS

ENDM

HI_PUSH_REG MACRO ;salva registros
MOVLB 0X00 ;asegura que este seleccionado el banco0

movff STATUS,HI_STATUS_TEMP
movff BSR,HI_TEMP_BSR
movwf HI_W_TEMP
movff FSR2H,TEMP_FSR2H_LO
movff FSR2L,TEMP_FSR2L_LO
movff FSR1H,TEMP_FSR1H_LO
movff FSR1L,TEMP_FSR1L_LO

movff STATUS,HI_TEMP_STATUS


ENDM


LO_POP_REG MACRO ;restaura registros
MOVLB 0X07 ;asegura que este seleccionado el banco7

movff LO_STATUS_TEMP,STATUS
movf LO_W_TEMP,W
movff LO_TEMP_BSR,BSR
movff TEMP_FSR2H_HI,FSR2H
movff TEMP_FSR2L_HI,FSR2L

movff LO_TEMP_STATUS,STATUS

ENDM

LO_PUSH_REG MACRO ;salva registros
MOVLB 0X07 ;asegura que este seleccionado el banco7

movff STATUS,LO_STATUS_TEMP
movwf LO_W_TEMP
movff BSR,LO_TEMP_BSR
movff FSR2H,TEMP_FSR2H_HI
movff FSR2L,TEMP_FSR2L_HI

movff STATUS,LO_TEMP_STATUS

ENDM


;***************Bit Definitions****************************************
#define BANK0 movlb 0x00
#define BANK1 movlb 0x01
#define BANK2 movlb 0x02
#define BANK3 movlb 0x03
#define BANK4 movlb 0x04
#define BANK5 movlb 0x05
#define BANK6 movlb 0x06
#define BANK7 movlb 0x07
#define BANK8 movlb 0x08
#define BANK9 movlb 0x09
#define BANK10 movlb 0x0A
#define BANK11 movlb 0x0B
#define BANK12 movlb 0x0C
#define BANK13 movlb 0x0D
#define BANK14 movlb 0x0E
#define BANK15 movlb 0x0F

#define GIE_HI_ON bsf INTCON,7
#define GIE_HI_OFF bcf INTCON,7
#define GIE_LO_ON bsf INTCON,6
#define GIE_LO_OFF bcf INTCON,6


#define I2C_18F 0X0750 ;direccion donde hubicaremos las rutinas de temporizacion
#define retardos 0X0950 ;direccion donde hubicaremos las rutinas de temporizacion

;<<<<<<---------------------- VECTOR DE RESET ------------------------>>>>>>>
ORG    0x00      ;Inicio en el Vector de Reset
  goto   INICIO      ;ir a la primera instruccion del programa
;<<<<<<---------------------- VECTOR DE INTERRUPCIONES ALTA PRIORIDAD ---------------->>>>>>>>>>
ORG 0X08
goto INTERRUP_HI
;<<<<<<---------------------- VECTOR DE INTERRUPCIONES BAJA PRIORIDAD ---------------->>>>>>>>>>
ORG 0X18
goto INTERRUP_LO


ORG 0X001C
;<<<<<<----------------- INICIO PROGRAMA PRINCIPAL ------------------->>>>>>>
INICIO    BANK15


clrf UCON,1


movlw b'01110000' ;activa resistencias pull-up (evitar fallo lectura BUSY LCD)
movwf INTCON2

movlw b'11111110'
movwf LATA
movlw b'11111000'
movwf TRISA
movlw   0x0F
movwf   ADCON1
movlw 0x07
movwf CMCON
clrf PORTB
clrf LATB
setf TRISB

movlw b'10000001' ;configura TMR0
movwf T0CON
bsf INTCON2,TMR0IP ;alta prioridad para tmr0
bcf INTCON2,RBIP ;baja prioridad para portb
clrf TMR0

bsf RCON,IPEN ;activa prioridad de interrupciones

movf PORTB,w ;leer puerto para el posterior borrad e flag RBIF
bcf INTCON,RBIF
bsf INTCON,RBIE




GIE_LO_OFF
GIE_HI_OFF
GIE_LO_OFF
GIE_HI_OFF

call DS1307_INI
;***********************************************PRINCIPIO DEL PROGRAMA********************************************************************
;antes de ejecutar la linea ESCRIBE.hay que poner los datos a grabar en la direccion ox100.ejemplo:
;0x30,0x50,0x12,0x02,0x25,0x10,0x16 = segundos,minutos,hora,(martes),dia,mes,año

PRINCIPAL ;call ESCRIBE ;escribir en el DS1307
call LEE ;leer del DS1307
rep goto rep
goto PRINCIPAL
return





;escritura de datos al DS1307.los datos deben de introducirse a partir de la direccion 0x100
ESCRIBE lfsr FSR2,0X100 ;principio de ram donde se introduciran los datos leidos del dispositivo I2C
movlw 0x00 ;principio de direccion a leer
movwf DIR_I2C
movlw .7 ;nuemro de bytes a escribir
call WRITE_RTC
return

;lectura de datos del DS1307.los datos seran hubicados a partir de la direccion 0x100
LEE lfsr FSR2,0X100 ;principio de ram donde se introduciran los datos leidos del dispositivo I2C
movlw 0x00 ;principio de direccion a leer
movwf DIR_I2C
movlw .7 ;nuemro de bytes a leer
call READ_RTC
return

;fin del programa.




;<<<<<<<<-------------------COMPROBACION DE TIPO DE INTERRUPCION DE ALTA PRIORIDAD------------>>>>>>>>>>>>>>
   
INTERRUP_HI HI_POP_REG


HI_PUSH_REG
retfie             ;retorna y habilita interrupciones generales
;<<<<<<<<-------------------COMPROBACION DE TIPO DE INTERRUPCION DE BAJA PRIORIDAD------------>>>>>>>>>>>>>>
;evento de temporizaciones.1s aproximadamente.para la activacion/desactivacion de salidas.

INTERRUP_LO LO_POP_REG


LO_PUSH_REG
retfie ;retorna y habilita interrupciones



DS1307_INI BANK15
bsf PIE1,SSPIE ;habilita interrupciones para la camara
;bsf ODCON1,7 ;habilita open drain para RC4, SDA1
bsf TRISB,0 ;configura pins como entrada
bsf TRISB,1 ;configura pins como entrada

movlw 0x28        ; I2C master, SSPEN enabled
movwf SSPCON1      ;
movlw   0x80 ; 400Khz compat,
movwf   SSPSTAT             
movlw .159 ; configurar I2C a 100kHz (para fosc de 64Mhz) clock=Fosc/(4*(SSPxADD+1))
;movlw .39 ; configurar I2C a 400kHz (para fosc de 64Mhz) clock=Fosc/(4*(SSPxADD+1))
movwf SSPADD

clrf PIR1

return


org retardos
include "retardos.inc"


org I2C_18F
include "I2C_18F.inc"

 

end


I2C_18F.inc

Código: [Seleccionar]
LIST

; CBLOCK I2C_VAR
; CONT_BYTE_RTC ;contador de numero de bytes
; DIR_I2C ;principio de direccion de dispositivo
; DATO_I2C
; ENDC



;-------------------------------------------------------------------------------------------;
;                                  SUBRUTINAS DE I2C                                        ;
;-------------------------------------------------------------------------------------------;

;Lectura de los datos internos del DS1307
READ_RTC movwf CONT_BYTE_RTC     ;numero de bytes a leer
call Start_I2C     ;Llama a la subrutina de START
rcall retardo_5us
movlw 0xd0     ;modo lectura del RTC
movwf SSPBUF     ;Lo carga en el Buffer de salida
call Write_I2C     ;Llama a la subrutina de escritura
rcall retardo_5us
movff DIR_I2C,SSPBUF     ;Lo carga en el Buffer de salida
call Write_I2C     ;Llama a la subrutina de escritura
rcall retardo_5us
call Restart_I2C         ;Llama a la subrutina de RESTART
   
rcall retardo_5us
movlw 0xd1     ;modo escritura del RTC
movwf SSPBUF,0     ;Lo carga en el Buffer de salida
call Write_I2C     ;Llama a la subrutina de escritura
rcall retardo_5us

Bucle_Leer call Read_I2C            ;Llama a la subrutina de lectura
movff SSPBUF,POSTINC2     ;Guarda el dato en la Ram e incrementa el puntero
rcall retardo_5us
   
decfsz CONT_BYTE_RTC,F     ;repite hasta que sea cero
bra ACK     ;envia ACK y continúa leyendo
call Send_I2C_NoAck      ;llama a la subrutina de ACKNOWLEDGE
rcall retardo_5us
call Stop_I2C            ;Llama a la subrutina de STOP
rcall retardo_5us
return     ;Retorna de la subrutina

ACK call Send_I2C_Ack        ;Llama a la subrutina de ACKNOWLEDGE
rcall retardo_5us
goto Bucle_Leer        
   


;Escritura en el DS1307 antes de la llamada a esta rutina.cargar en FSR2 el inicio de la ram donde se leeran los datos a transferir al DS1307
; y en WREG la cantidad de datos a transferir.
   
WRITE_RTC movwf   CONT_BYTE_RTC     ;numero de bytes a escribir
call    Start_I2C     ;Llama a la subrutina de START
rcall retardo_5us
movlw   0xd0     ;modo escritura del RTC
movwf   SSPBUF     ;Lo carga en el Buffer de salida
call    Write_I2C     ;Llama a la subrutina de escritura
rcall retardo_5us
movff   DIR_I2C,SSPBUF     ;Lo carga en el Buffer de salida
call    Write_I2C     ;Llama a la subrutina de escritura
                rcall retardo_5us
Bucle_Escribir1 movff   POSTINC2,SSPBUF     ;Carga el dato de la Ram en SSP1BUF e incrementa el puntero
                call    Write_I2C     ;Llama a la subrutina de escritura
rcall retardo_5us
decfsz  CONT_BYTE_RTC,F     ;repite hasta que sea cero
bra Bucle_Escribir1     ;continúa enviando datos
                call    Stop_I2C     ;Llama a la subrutina de STOP
rcall retardo_5us
                return     ;Retorna de la subrutina

;retardo de 5us
retardo_5us movlw .11
call retardo_us
return



;*********************************************************************************************************    
i2c_idle btfsc   SSPSTAT,R_W
goto    i2c_idle
reps movf    SSPCON2,w
andlw   0x1F
btfss   STATUS,Z
goto    reps
return    
   



Start_I2C       BANK15
bsf SSPCON2,SEN     ;Pone a uno el bit de START
S2              btfsc   SSPCON2,SEN     ;Espera a que se ponga a cero el bit de START
                bra     S2
S3              btfss   PIR1,SSPIF     ;Espera a que la condicion de START haya sido completada
                bra     S3     ;cuando se ponga a 1 la bandera de interrupción
BCF     PIR1,SSPIF     ;Borra la bandera de la interrupción
                return     ;Retorna de la subrutina
                                                     

Write_I2C       btfsc   SSPSTAT,R_W     ;Verifica que se ponga a cero el bit R/W
                bra     Write_I2C     ;Espera a que termine de enviar el dato
W2              btfsc   SSPCON2,ACKSTAT     ;Espera a que reciba el bit de ACKNOWLEDGE
                bra     W2
BCF     PIR1,SSPIF     ;borra la bandera de la interrupción
                return     ;Retorna de la subrutina


Restart_I2C     bsf     SSPCON2,RSEN     ;Pone a uno el bit de RESTART
R2              btfsc   SSPCON2,RSEN     ;Espera a que se ponga a cero el bit de RESTART
                bra     R2
R3              BTFSS   PIR1,SSPIF     ;Espera a que la condicion de RESTART haya sido completada
                bra     R3     ;cuando se ponga a 1 la bandera de interrupción
                bcf     PIR1,SSPIF     ;Borra la bandera de la interrupción
                return     ;Retorna de la subrutina


Read_I2C        bsf     SSPCON2,RCEN     ;Habilita la recepción de datos mediante el bit RCEN
Rea2            btfsc   SSPCON2,RCEN     ;Espera a que se ponga a cero el bit RCEN
                bra     Rea2
Rea3            BTFSS   SSPSTAT,BF     ;Dato disponible en SSPBUF para ser leidos?
                bra     Rea3     ;No, esperar
Rea4            BTFSS   PIR1,SSPIF     ;Espera a que la condicion de Lectura haya sido completada
                bra     Rea4     ;cuando se ponga a 1 la bandera de interrupción
                bcf     PIR1,SSPIF     ;Borra la bandera de la interrupción
                return     ;Retorna de la subrutina


Send_I2C_Ack    bcf     SSPCON2,ACKDT     ;Pone a cero el bit de ACKNOWLEDGE DATA
                bsf     SSPCON2,ACKEN      ;Genera la condición de ACKNOWLEDGE Poniendo a 1 el bit ACKEN
                btfss   PIR1,SSPIF     ;Espera a que la condicion de ACK haya sido completada
                bra     Rea4     ;cuando se ponga a 1 la bandera de interrupción
                bcf     PIR1,SSPIF     ;Borra la bandera de la interrupción
                return     ;Retorna de la subrutina


Send_I2C_NoAck  bsf     SSPCON2,ACKDT     ;Pone a 1 el bit de ACKNOWLEDGE DATA
                bsf     SSPCON2,ACKEN     ;Genera la condición de NO ACKNOWLEDGE Poniendo a 1 el bit ACKEN
                btfss   PIR1,SSPIF     ;Espera a que la condicion de No ACK haya sido completada
                bra     Rea4     ;cuando se ponga a 1 la bandera de interrupción
                bcf     PIR1,SSPIF     ;Borra la bandera de la interrupción
                return     ;Retorna de la subrutina


Stop_I2C bsf     SSPCON2,PEN     ;Genera la condición de STOP poniendo a 1 el bit PEN
P2 btfsc   SSPCON2,PEN     ;Espera a que se ponga a cero el bit PEN
                bra     P2
        btfss   PIR1,SSPIF     ;Espera a que la condicion de Stop haya sido completada
                bra     Rea4     ;cuando se ponga a 1 la bandera de interrupción
                bcf     PIR1,SSPIF     ;Borra la bandera de la interrupción
                return 

LIST


retardos.inc

Código: [Seleccionar]

CBLOCK RETARDOS_VAR

PDel0
PDel1
PDel2
PDel5
PDel6
PDel7


ENDC

;************************************************************** RETARDO DE 1 SEGUNDO *****************************************************

retardo_s movwf     PDel0     ; 1 |11000000 'À'
PLoop0  movlw     .79       ; 1 set numero de repeticion  (B)
        movwf     PDel1     ; 1 |
PLoop1  movlw     .192      ; 1 set numero de repeticion  (A)
        movwf     PDel2     ; 1 |
PLoop2  clrwdt              ; 1 clear watchdog
        clrwdt              ; 1 ciclo delay
        decfsz    PDel2, 1  ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop2    ; 2 no, loop
        decfsz    PDel1,  1 ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop1    ; 2 no, loop
        decfsz    PDel0,  1 ; 1 + (1) es el tiempo 0  ? (C)
        goto      PLoop0    ; 2 no, loop
return              ; 2+2 Fin.


retardo_ms movwf     PDel5     ; 1 |
PLoop1a  movlw     .255       ; 1 set numero de repeticion  (A)
        movwf     PDel6     ; 1 |
PLoop2a  clrwdt              ; 1 clear watchdog
        clrwdt              ; 1 ciclo delay
        decfsz    PDel6, 1  ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop2a    ; 2 no, loop
        decfsz    PDel5,  1 ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop1a    ; 2 no, loop
PDelL1a  goto PDelL2a         ; 2 ciclos delay
PDelL2a 
        return              ; 2+2 Fin.
;
;;----------------------------------------------- RETARDOS EN MICROSEGUNDOS -----------------------------------------
retardo_us movwf     PDel7     ; 1 |
PLoop0b  clrwdt              ; 1 clear watchdog
        decfsz    PDel7, 1  ; 1 + (1) es el tiempo 0  ?
        goto      PLoop0b    ; 2 no, loop
PDelL1b  goto PDelL2b         ; 2 ciclos delay
PDelL2b  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.



en este caso he hecho un programa para configurar un circuito reloj como es el DS1307.y que se usara un pic18f2550 que va a trabajar a 48Mhz pero con un cristal de 4Mhz
ya que usamos el pll interno del pic.

en la linea PRINCIPAL.tenemos dos rutinas que  se llaman ESCRIBE y LEE .las llamadas a estas rutinas hacen que el PIC se comunique via I2C con el DS1307.
a una velocidad de 100Khz.

para leer solo tenemos que realizar la llamada a esta rutina.y los datos del DS1307 seran mandados a la direccion 0x100 de la ram de nuestro pic.

para escribir.antes de la llamada a esta rutina hay que introducir los datos apartir de la direccion 0x100 esta inclusive.y realizar la llamada.
algunos DS1307 hay que ponerlos en hora para que empiezen a trabajar.si no lo hizieramos podriamos intentar leerlos y solo leeriamos estos datos:

0x80,0x00,0x00,0x01,0x01,0x01,0x00,0x03

aqui pongo una direccion donde explico mejor esto:  http://www.todopic.com.ar/foros/index.php?topic=46426.0
* DS1307_18f2550.X.zip
(176.07 kB - descargado 231 veces)
« Última modificación: 27 de Octubre de 2016, 10:34:12 por groundman »
Montando mi primera impresora 3D (Raprep Prusa i3)

Desconectado pibe

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 635
Re:pequeños proyectos
« Respuesta #80 en: 20 de Noviembre de 2016, 00:56:41 »
Hola groundman y bienvenido de vuelta!
Mira las casualidades, yo vuelvo luego de varios años alejado de los pics. Pero ya sabes... esto es una enfermedad que no tiene cura XD
Mi jefe mirando el prototipo que estoy creando: "Y eso va a funcionar?"

Desconectado groundman

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1870
    • www.ingeniopic.com
Re:pequeños proyectos
« Respuesta #81 en: 20 de Noviembre de 2016, 14:03:12 »
si.todo depende de nuestras necesidades.yo tengo varios proyectos en mente y poco tiempo para desarrollarlos.y lo peor es que cada vez necesito mas velocidad para los proyectos.
si embargo los pic que estan fabricando son mas complejos.y ya hay que utilizar librerias avanzadas.asi que el ASM no va a ser una opcion a partir de las versiones superiores a la 18F

en la proxima generacion voy a tener que aprender CCS.ya veremos lo que pasa. un salud.
Montando mi primera impresora 3D (Raprep Prusa i3)

Desconectado pibe

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 635
Re:pequeños proyectos
« Respuesta #82 en: 20 de Noviembre de 2016, 22:27:40 »
Joder groundman, si parecemos mellizos del destino.
Yo tambien, estoy viendo una nueva alternativa economica a mi magro sueldo. Y tambien he dejado el ASM de lado y estoy empezando con el XC8.
Me duele tener que recordar los comandos de C, me los olvido y debo volver a releerlos. Ademas necesito una salida rapida y no puedo perder tiempo aprendiendo, asi que voy aprendiendo sobre la marcha.
Mi jefe mirando el prototipo que estoy creando: "Y eso va a funcionar?"