Autor Tema: PIC16F84A  (Leído 3292 veces)

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

Desconectado bel03

  • PIC10
  • *
  • Mensajes: 6
PIC16F84A
« en: 07 de Diciembre de 2014, 09:49:16 »
No se como hacer el programa tendria que hacer lo siguiente:
INICIO:
 -El led rojo y el led verde al principio esten apagados.
CHEQUEO:
-Encender led verde durante 1 segundo.
-Apagar led verde.
-Encender led rojo durante 1 segundo.
-Apagar led rojo.
PROGRAMA:
-Pulsar menos de 1 segundo se enciende el led
-Pulsar mas de 1 segundo se apaga
El program a utilizar es el MPLAB IDE
Adjunto el exquema.

Esperando una contestación gracias.


Desconectado gera

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2188
Re: PIC16F84A
« Respuesta #1 en: 07 de Diciembre de 2014, 11:03:02 »
No quiero ser grosero, pero pareciera que querés que te hagamos la tarea para la escuela.
Te recomiendo que te pongas a navegar por el foro (hay una sección para principiantes con ejemplos y todo), estudies y trates de hacerlo por tus medios. Si te surge alguna duda puntual, con gusto te ayudaremos.

Saludos y suerte.

"conozco dos cosas infinitas: el universo y la estupidez humana. Y no estoy muy seguro del primero." A.Einstein

Desconectado bel03

  • PIC10
  • *
  • Mensajes: 6
Re: PIC16F84A
« Respuesta #2 en: 07 de Diciembre de 2014, 14:27:24 »
ya tengo configurados los puertos y tal  se como se encienden los led pero no se como hacer que duren un tiempo encendido ni como saber si es una pulsación larga o corta seria con el timer pero no se como utilizarlo

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: PIC16F84A
« Respuesta #3 en: 07 de Diciembre de 2014, 16:25:01 »
ya tengo configurados los puertos y tal  se como se encienden los led pero no se como hacer que duren un tiempo encendido ni como saber si es una pulsación larga o corta seria con el timer pero no se como utilizarlo

En que estas programando? en C, ASM, Basic, etc

Creo que deberias usar una interrupcion (cambio en el portb) saber que "flanco" asi poner a 0 el timer cuando detectas un 1 y contar lo que necesites para saber si se tuvo presionado un segundo o no ( sabiendo cuando solto por que leerias un 0 ).
PORTB<7:4> interrupt-on-change
o mejor
External RB0/INT pin ( te permite configurar los flancos )

Con respecto al pulsador deberias tener un circuito antirebote fuera para facilitar la programacion

Mas interrupciones en el timer por si se pasa, es decir ocurre un overflow y el tiempo no te da lo suficiente.
TMR0 timer overflow

Los prendidos de los leds podes hacerlo tambien con el TMR si la queres complicar un poco obvio o con retardos.

Todo lo que expuse hay ejemplos para nadar en ellos por internet, el PIC16F84A aunque no tiene nada y es caro a comparacion de otros, es excelente para aprender ASM, exactamente por que no tiene nada y no tenes que complicarte con tantas cosas. Si tu programacion es en ASM SI o SI deberias leer datasheet completo, En C podes obviarte algunas cositas (y revisarlas cuando veas que no anda algo). Bueno como decia el PIC16F84 esta lleno de ejemplos por internet. podes sacar ideas de ahi, hay tutoriales, etc. Pero todo depende tambien en que programes y con que compilador.

Desconectado bel03

  • PIC10
  • *
  • Mensajes: 6
Re: PIC16F84A
« Respuesta #4 en: 08 de Diciembre de 2014, 07:18:26 »
En ASM, y unos de los diodos esta puesto en inversa asique cada diodo se enciende de distinta forma uno con 0 y otro con 1
me esta volviendo loca el programa la verdad suelo utilizar una plantilla que hice hace un tiempo pero he llegado a un punto de bloqueo


;    Archivos requeridos: p16F84A.INC   (C:\Program Files (x86)\Microchip\MPASM Suite)
;
;****************************************************************************************
;
;    Notas:
;
;****************************************************************************************

            PROCESSOR 16F84A

            RADIX HEX
         
;----------------------------------------------------------------------------------------
;                        REGISTROS SFR / BITs DE CONFIGURACIÓN
;----------------------------------------------------------------------------------------

            INCLUDE "p16F84A.inc"

            __config _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC

;----------------------------------------------------------------------------------------
;                                    REGISTROS GPR
;----------------------------------------------------------------------------------------

            CBLOCK 20h         ;Dirección inicio reserva memoria RAM 020h.
W_TPRAL      
S_TPRAL

            ENDC

;----------------------------------------------------------------------------------------
;                                 DEFINICION DE CONSTANTES
;----------------------------------------------------------------------------------------

            EQU
 

;****************************************************************************************
;                                  ÁREA DE PROGRAMA
;****************************************************************************************

;----------------------------------------------------------------------------------------
;                                       VECTORES
;----------------------------------------------------------------------------------------

;----------   VECTOR RESET         -----------------------------------------------------
         
            ORG 00h
            goto IniConfig
         
;----------   VECTOR INTERRUPCIÓN      -----------------------------------------------------

            ORG 04h

GlobalInt              movwf W_TPRAL         ;Copia W a un registro Temporal.
            swapf STATUS,W         ;Invierte nibles de STATUS.
            movwf S_TPRAL         ;Guarda STATUS en un registro temporal
   
;            btfsc INTCON,1         ;¿Activado flag int. EXT?
;            call Int_RB0         ;SI.
      
;            btfsc INTCON,2         ;¿Activado flag int. TMR0?
;            call Int_TMR0         ;SI.
      
            swapf S_TPRAL,W           ;Restaura valores de W y STATUS.
            movwf STATUS
            swapf W_TPRAL,F
            swapf W_TPRAL,W
            retfie   
         
         
;----------------------------------------------------------------------------------------
;                        CONFIGURACIÓN INICAL DE PERIFERICOS
;----------------------------------------------------------------------------------------

IniConfig      bsf STATUS,RP0              ;Seleción banco 1. En este banco se
                        ;encuetran los reg. de configuración.


;----------   CONFIG. INTCON (INTERRUPCIONES)   ---------------------------------------------

            movlw b'00000000'
            movwf INTCON      ;Todas las interrupciones desactivadas.


;----------   CONFIG. OPTION      ---------------------------------------------------------

            movlw b'10000000'   ;1000 0000
            movwf OPTION_REG      


;----------   CONFIG. TRIS (PUERTOS) -----------------------------------------------------

            movlw b'00011111'           ;Los bits del reg. TRISA establecen la
            movwf TRISA         ;config. del puerto RA.
                           ;1=Ent., 0=Sal.
   
            movlw b'11111111'         ;Los bist del reg. TRISB establecen la
            movwf TRISB         ;config. del puerto RB.
                           ;1=Ent., 0=Sal.
                        
;----------

            bcf   STATUS,RP0      ;Fin de la configuración de inicio.
                           ;Borrando el bit 5 del reg. STATUS
                           ;se regresa al banco 0, lugar donde
                           ;estan los reg. que más se emplean.

;----------------------------------------------------------------------------------------
;                           PROGRAMA PRINCIPAL
;----------------------------------------------------------------------------------------


         







;----------------------------------------------------------------------------------------


            END                        

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: PIC16F84A
« Respuesta #5 en: 08 de Diciembre de 2014, 12:14:16 »
Tenes una buena estructura del programa y es como lo deberias estar haciendo. Lo unico que te falta es crear las funciones para Rb0, tmr0 y principal,etc

Todo va a depender del cristal que uses. es la velocidad que va a contar, te voy a ir dando pistas y un pseudocodigo para que busques como hacerlo vos misma.

La entrada al TMR0 puede ser externa o interna usando el cristal a un pulso cada cada 4/Fosc , si usas 4Mhz son 4/4Mhz = 1uS, Pero antes que entre lo podes hacer pasar por un prescaler (un divisor de frecuencia ) asi obtenes tiempos mas largos.
En el 16f84a esta compartido con el WDT y se modifica en el registro OPTION (fijate en el diagrama del TMR0 en el datasheet), el minimo que corresponde al TMR0 es de 1:2 y el maximo 1:256, utilizaremos el de  1:64.

Asi que tu tiempo seria: 1uS * 64 = 64uS
Para que tu TMR llegue a 1 segundo necesitarias que cuente hasta = 1s / 64uS = 15625 (elegi 1:64 por que da entero y facilita mucho las cosas)
Pero tu TMR0 tiene un registro de 8 bits , es decir 2^8 = 256

Por lo cual vas a tener que tener una variable que cuente al menos 15625 / 256  = 61.03515625 veces que entra a la interrupcion.
Si te fijas no es un entero, 61 vueltas al TMR0 contaria 15616 y nos faltaria 9, por lo tanto cuando cuente llegue a 61 tenes que cargar el TMR0 con otro valor y no 0x00, el TMR0 es ascendente por lo que tendrias que cargarlo con su complemento a 2. El complemento de 0x09 (9) es el negado y sumado 1, es decir 0xF7 (247).

Con eso ya tenes tu TMR0 a 1s Cuando se cumpla esas condiciones, es decir cuando ocurra la interrupcion y tengas 61 vueltas en tu contador.
Obviamente una ves todo inicializado activas las interrupciones y luego al final activas la interrupcion global, recorda borrar el TMR0 antes.

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

Para tu boton.... podes usar tanto Rb0 como Rb4 a Rb7, Rb0 simplifica un poco las cosas por que tiene una interrupcion segun flanco.
Para detectar el boton, haces una interrupcion en el flanco ascendente, entra a tu interrupcion, cambias al flanco de bajada, guardas unas variables mas y salis de tu interrupcion, Cuando entre de nuevo es por que solto y ahi es cuando volves a flanco ascendente y te fijas si las variables tienen lo que pedis.

El flanco con el que se dispara el RB0 esta dado por el registro OPTION y la habilitacion de la interrupcion en el INTCON junto con el flag de todas las interrupciones.

Para utilizar nuevamente nuestro TMR0 como lo teniamos configurado. Podes hacerlo de 2 formas una mas simple que es perder un poco de precision pero te va a ahorrar bastante codigo que es la de contar solamente las vueltas y sino
la forma "correcta" ( asi es un segundo exacto ) necesitarias 2 variables, una va a contener el valor del TMR0 y otra la cantidad de vueltas mientras esta presionado el boton ( asi que en el codigo del TMR0 tenes que pensar en sumar esa variable si es que esta presionado un boton )

Hago la mas simple:

Interrupcion:
Desabilito interrupciones globales
leo si es la interrupcion del RB0
Voy a la funcion
Fue por flanco ascendente?
SI: {
Habilito alguna flag asi el codigo del TMR0 sabe que deberia contar
cambio el flanco a descendente
}
NO(flanco descendente): {
Reviso que se dieron la cantidad necesaria de vueltas, es decir + de 61, si se dieron menos quiere decir que se presiono por menos de 1s.
Se dieron la cantidad de vueltas del TMR0 correctas?
SI: {
Activo flag para el programa principal, diciendo que se activo un segundo
}
NO : {
Activo flag para el programa principal, diciendo que se pulso por menos de un segundo
}
Borro cantidad de vueltas de mi contador de este pulsador
Vuelvo a flanco ascendente
}
Limpio flag de interrupciones antes de habilitar de nuevo.
Habilito interrupciones. ; Aunque esto iria en tu funcion de interrupciones general




Y tu programa principal quedaria muy simple:

principal:
Pregunto por flag de boton > 1s: {
Pongo a 0 los leds
Borro el flag
}
Pregunto por flag de boton < 1s: {
Borro el flag del boton de menos de 1s
Pongo a 0 contador propio del TMR ( me refiero a tu variable que deberia contar 61 que hable en el TMR0, no confundir con el contador del pulsador que el trabajo es el mismo pero esta destinado al boton )
Borro mi flag propia del TMR0
Prendo verde
Pregunto por flag propia cuando ocurra la vuelta 61 + el pedacito ese ( 62 ) si es asi paso 1 seg
Apago rojo
Pongo a 0 contador propio del TMR
Borro mi flag propia del TMR0
Prendo rojo
Pregunto por flag propia cuando ocurra la vuelta 61 + el pedacito ese ( 62 ) si es asi paso 1 seg
Apago rojo
}
Volver a Principal


En si este programa prenderia los leds como queres solo cuando presionas por menos de 1 segundo, Aunque no verias exactamente cuando borras todo por la forma que hice el programa principal, pero solo deberias modificar el programa principal.
En el caso que te di solo utilizarias 3 posiciones de memoria ( no me acuerdo si me olvido de alguna variable que use ademas xD) que pondrias en tu Cblock
ContadorTMR0
ContadorRB0
Flags
« Última modificación: 08 de Diciembre de 2014, 12:20:18 por KILLERJC »

Desconectado bel03

  • PIC10
  • *
  • Mensajes: 6
Re: PIC16F84A
« Respuesta #6 en: 10 de Diciembre de 2014, 13:26:37 »
asi es como lo llevo:
;----------   CONFIG. TRIS (PUERTOS) -----------------------------------------------------

            movlw b'00011111'   ;Los bits del reg. TRISA establecen la
            movwf TRISA         ;config. del puerto RA.
                           ;1=Ent., 0=Sal.
   
            movlw b'11011101'    ;Los bist del reg. TRISB establecen la
            movwf TRISB         ;config. del puerto RB.
                           ;1=Ent., 0=Sal.
                        
;----------

            bcf   STATUS,RP0      ;Fin de la configuración de inicio.
                           ;Borrando el bit 5 del reg. STATUS
                           ;se regresa al banco 0, lugar donde
                           ;estan los reg. que más se emplean.

;----------------------------------------------------------------------------------------
;                           PROGRAMA PRINCIPAL
;-------------------------------------------------------------------------------------
               
                  
                   movlw .2      ;Mueve el valor 1 a W.
                     movwf PORTB   ;Apagado de los led.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: PIC16F84A
« Respuesta #7 en: 10 de Diciembre de 2014, 14:32:02 »
no se si no llegaste a copiar todo o que pero quedo a la mitad tu codigo.
Si eso es todo solo hiciste 2 lineas de codigo. Para programar en ASM vas a tener que comerte el datasheet del micro quieras o no.

ademas pone tu codigo dentro de (code]  Aca iria tu codigo (/code]
Reemplaza los ( por [

Código: [Seleccionar]
y te queda asi

Desconectado tapi8

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1506
Re: PIC16F84A
« Respuesta #8 en: 10 de Diciembre de 2014, 15:47:10 »
¿Has mirado esto?

http://www.todopic.com.ar/foros/index.php?topic=24720.0

Ahi estan las respuestas a casi todo lo que quieres saber, es obligatorio leerlo para que te ayudemos  :lol: :lol:

Estudialo un poco despues empieza a hacer el programa "de verdad" y despues consulta tus dudas y te ayudaremos, te lo prometo. Pero no te vamos a hacer el programa, porque seguro que el profesor que te mando hacerlo anda por aqui, a ver como vas.

Desconectado bel03

  • PIC10
  • *
  • Mensajes: 6
Re: PIC16F84A
« Respuesta #9 en: 10 de Diciembre de 2014, 17:08:02 »
He hwcho ya unos cuantos programas pero este se me esta atravesando

Desconectado bel03

  • PIC10
  • *
  • Mensajes: 6
Re: PIC16F84A
« Respuesta #10 en: 10 de Diciembre de 2014, 17:11:49 »
mi primer programa antes de hacer la plantilla y funciono perfectamente:

      ;Etiquetas:

               Porta                    equ 05h
               portatemp                equ 04fh
               trisa                    equ 085h
               trisb                    equ 086h
               status                   equ 003h
 
      ;Configuracion inicial:

              ORG     00h
             
              Goto    incipgm
             
              ORG     0fh

              Clrf    portb              ;ponemos el puertob a 0 para que empiecen los led apagados.
              bsf     status5           
              movlw   b"00011111"         
              movwf   trisa              ;configurando puertoa como entrada
              clrf    trisb              ;configurando puertob como salida
              bcf     status5            ;vuelvo al banco 0

      ;Programa inicial:
     
           
INIPGM       movf    porta0             ;movemos el numero que nos entra por el puertoa en w.
             movwf   portatemp          ;mover de w a una posicion de memoria para evitar que se borre.
             btfsc   portatemp          ;se salta a la siguiente linea de codigo si el bit0 del porta es 0.
             
             Goto    impar
           
             movlw   b"00001111"       
             moovwf  portb              ;el literal primero al registro de trabajo y luego al portb, se enciende el LED.
             

             Goto    inicio
   
Impar        movlw   b"11110000"     
             movwf   portb              ;activamos el nibble alto donde estará el LED ya que es numero impar
             

             Goto    inicio

             END   
             
       
             
             


 

anything