TODOPIC
Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: Nary en 14 de Octubre de 2017, 11:20:07
-
Ayuda!!! :?
Necesito realizar un programa con el PIC16F877A con ccp2, timer 1 y que tenga retardo, utilizando MPLAB y proteus. El programa debe comparar entre un 1 y 0. Cuando es 1 enciende el led y al ser 0 se apagara.
-
El programa debe comparar entre un 1 y 0. Cuando es 1 enciende el led y al ser 0 se apagara.
Para eso no es necesario usar nada de lo que pedis, y por otra parte, ¿que tenes realizado?, ¿en que parte necesitas ayuda?, ¿Que no entendes?
Porque darte el codigo completo no le veo sentido.
-
Me puedes ayudar, ya me explicaron bien lo que debo hacer
-
Por supuesto, no deberias haber creado otro tema, deberias haber seguido aca, pero ya que lo hiciste, para aquel que busque, voy a poner el link en el otro tema.
Apenas me haga un tiempito te explico y luego vos vas a llegar a una solucion.
http://www.todopic.com.ar/foros/index.php?topic=48209.0;topicseen#msg401251
-
Te lo agradeceria mucho :oops:
-
Lo puedes revisar, por favor.
#pragma config FOSC = XT // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = ON // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = ON // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3/PGM pin has PGM function; low-voltage programming enabled)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
#define _XTAL_FREQ 4000000 //Oscilador de 4Mhz, frecuencia para las instrucciones de retardo
#include <xc.h> //Libreria del compilador C en XC8
unsigned char cambia=0; //Utilizado para cambiar el evento por comparación que se obtendrá en el pin CCP2
void main (void) {
TRISCbits.TRISC1=0; //Pin CCP2 como salida
PORTCbits.RC1=0; //Salida inicial a 0
INTCON=0b11000000; //Habilita las interrupciones
CCP2CON=0b00001000; //CCP2 en modo comparación, el pin CCP2 se pondrá a 1
//Al producirse la igualdad entre CCPR2 y TIMER1
T1CON=0b00000001; //TIMER1 como temporizador, habilitado
//TIMER1 aumenta su valor en una unidad cada microsegundo
TMR1=0; //Se carga con 0
PIE2bits.CCP2IE=1 //Habilita las interrupciones del módulo CCP2
PIR2bits.CCP2IF=0; //Para detectar al producirse la igualdad entre el registro CCPR2 y el TIMER1
CCPR2=1000; //Al llegar el timer1 a este valor se pondrá a 1 el bit CCP2IF
while (1) {
//Por ahora no se hace nada en el ciclo principal
//el pin CCP2 se obtendrá utilizando el módulo CCP2 en modo captura
}
return;
}
void interrupt int_CCP2(){ //Rutina de interrupciones
if(PIR2bits.CCP2IF) { //Si el bit CCPIF se pone en 1
if (cambia==0) { //Cuando cambia_evento sea igual a 0
CCP2CON==0b00001001; //El pin CCP2 y TMR1 en comparación
cambia=1; //para que en la siguiente interrupción se vuelva
//a cambiar la salida por el pin CCP2 al ocurrir la igualdad
//entre el TMR1 y el CCPR2
}
else { //Cuando cambia_evento sea igual a 1
CCP2CON=0b00001000; //El pin CCP2 se pondrá a 1 al producirse
//La igualdad entre CCPR2 y TMR1 en la comparacion
cambia=0; //Para que en la siguiente interrupción se vuelva a
//cambiar la salida por el pin CCP2 al ocurrir la igualdad
//entre el TMR1 y el CCPR2
}
TMR1=0; //Se pone nuevamente a 0 despues de cada interrupcion para que al
//llegar nuevamente a 1000 se vuelva a producir otra interrupcion por comparacion
PIR2bits.CCP2IF=0 //El bit CCP2IF nuevamente a 0 para seguir detectando
//el momento en que se produce la igualdad y a la vez
//utilizarce con las interrupciones
}
}
-
Segun el otro post, estabas usando ASM, ahora tenes un codigo en C. Lo cual en cierta forma difiere un poco lo que hay que hacer pero no demasiado.
Hay algunas preguntas que todavia no contestaste.. Que es lo que debe igualar el CCP? se que es el TMR1 pero ahora veo que lo estas haciendo correr con el reloj. A cuanto tiempo debe ocurrir esa igualdad?.
Pregunto por que uno podria plantearse de que la igualdad genere una interrupcion cada 0.25s o cada 0.5s, y como debes apagarlo luego de 1 segundo, mejor configurarlo para eso. En resumen estariamos en el caso de hacer lo mismo que un Timer, y siendo la interrupcion quien active la salida.
Explicate mejor que es lo que debe realizar el programa, ya que como ves hay preguntas sin respuestas todavia.
-
En el programa se utiliza el TIMER1 como comparador, compara el valor del TIMER1 con el valor de CCPR2. Para los registros de 16 bits, se le asigno a CCPR2:FF FF (maximo valor), y a
TIMER1 00 01. Con la finalidad de que traten de igualarse en la mayor cantidad de tiempo posible para lograr visualizarlo.
Ya que esto ocurre muy rapido, la salida de esta igualdad viene dada por el PIN CCP2 (de acuerdo a la configuración hecha, cuando son iguales=1, cuando son distintos=0), a este se conecta un led que indica los cambios, dado que
ocurren muy rapido se conectaran 4 leds al puerto B, con retardo de 1 segundo, los primeros dos encienden cuando son iguales, y los otros dos encienden cuando la comparacion no es igual.
Logre el funcionamiento del programa con el PIC16F887 ahora necesito cambiarlo al PIC16F877A (ya que el material con el que cuento para llevarlo en fisico, es realizado con este pic).
Aqui te dejo el funcionamiento con PIC16F887, espero contar con su ayuda para realizar el cambio a PIC16F877A
LIST p=16F887
INCLUDE <P16F887.inc>
__CONFIG _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
__CONFIG _CONFIG2, _WRT_OFF & _BOR21V
CONTA EQU 0x20
CONTB EQU 0x21
CONTC EQU 0x22
ORG 0x00
BANKSEL ANSEL
CLRF ANSEL
CLRF ANSELH
BANKSEL TRISC
CLRF TRISB
CLRF TRISC
BANKSEL PORTB
CLRF PORTB
CLRF PORTC
BANKSEL OPTION_REG
MOVLW 0x80;DESABILITA TIMER0
BANKSEL T1CON
MOVLW 0x01; SELECCION DEL HABILITA TIMER1
MOVWF T1CON
MOVLW 0x08; MODO COMPARACION: CCP1 SE PONE A 1, Y CUANDO TMR1=CCR1,Y
MOVWF CCP2CON;CCP2IF SE PONE A UNO
INICIO CLRF PORTB
MOVLW 0xFF
MOVWF CCPR2L;CARGA A LA PARTE BAJA DE CCPR
MOVLW 0xFF
MOVWF CCPR2H;CARGA A LA PARTE ALTA DEL CCPH
MOVLW 0x01
MOVWF TMR1L;CARGA A LA PARTE BAJA DE TIMER1
MOVLW 0x00
MOVWF TMR1H;CARGA A LA PARTE BAJA DE TIMER1
PRE BTFSS PIR1, CCP2IF; PREGUNTA POR BANDERA, SI SON IGUALES=1 SINO=0
GOTO RETAR1
MOVLW 0x0C
MOVWF PORTB
CALL RETARD
BCF PIR1, CCP2IF
GOTO INICIO
RETARD MOVLW d'100'
MOVWF CONTA
CICLO3 MOVLW d'80'
MOVWF CONTB
CICLO2 MOVLW d'60'
MOVWF CONTC
CICLO1 DECFSZ CONTC,F
GOTO CICLO1
DECFSZ CONTB,F
GOTO CICLO2
DECFSZ CONTA,F
GOTO CICLO3
RETURN
RETAR1 MOVLW 0x03
MOVWF PORTB
CALL RETARD
CLRF PORTB
GOTO PRE
END
-
Disculpa pero lo que estas/estan haciendo no tiene ningun sentido, ni siquiera para aprender a usar el CCP. Ya que lo estan usando MAL.
Estoy mas que seguro que el profesor esta buscando otra cosa totalmente distinta, pero por no preguntar están haciendo cualquier cosa, Ademas de usar codigos de uno u otro lado, ya que venis con codigos en C y luego en ASM.
Totalmente sin sentido la comparación, para eso ni usarla, dejen correr el TMR1 y listo. El uso del Timer no tiene ni comentado el tiempo transcurrido o no se le presta atencion, cualquiera usaria un preescaler grande pero solo lo activaron y nada mas, se esta reasignando valor al Timer1 luego de 1s de DEMORA! y encima cuando se esta usando el CCP, que el objetivo es que eso NO ocurra, se vuelve a cargar los registros CCPRxx sin sentido ya que nunca cambiaron, tampoco se estan usando las interrupciones, etc.
Si queres pasarlo al PIC16F877A simplemente busca el modulo CCP si cambia algo, el modulo del Timer si es que cambia algo, pero creo que no va a cambiar nada en esto.
Lo mas seguro es que cambie la configuracion de los puertos, para pasarlos analogicos/digital (sean disintos registros ).
Viendo la cantidad de codigos y que encima uno es en ASM y otro en C, veo que lo unico que estan haciendo es tirar codigos y ver cual funciona, y que haga masomenos lo que quieren. No puedo ayudarte con esto.
Lo que seguramente les pide el profesor es:
- Usar el Timer1, configurarlo con el mayor preescaler, buscar un valor que me permita tener una base de tiempo simple, ejemplo, interrupcion cada 0.2s, 0.1s , 0.25s, etc.
- Usar la interrupcion y contar cuantas interrupciones pasaron, de esa forma encender el led y apagarlo cada 1 segundo.
- Aprender a configurar el CCP para que esto ocurra.
No veo nada de eso en sus codigos. Y acabo de decirles que deben hacer, solo tienen que ponerse a investigar un poco mas como lograrlo con lo que tienen. Intenten entender como es que funciona cada uno de los modulos.
PD: Nuevamente pido disculpas porque seguramente lo tomen a mal, pero prefiero decirles lo correcto antes que hacerlos seguir con lo que estan intentando.