Autor Tema: Necesito un poco de ayuda  (Leído 1996 veces)

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

Desconectado cronomus

  • PIC10
  • *
  • Mensajes: 3
Necesito un poco de ayuda
« en: 12 de Noviembre de 2008, 05:59:49 »
Hola les comento que hace poco comenze a programar pics usando la guia del usuario micro_cadaver como referecia al que agredezco muchisimo porque me re sirvio bueno estoy haciendo un proyecto de comunicar 2 pics mediante la USART donde estos puedan mandarse mensajes mediante un teclado matricial y se pueda vizualizar los caracteres en los lcd como pics uso 2 p18f452 con lcd de 16x2, bueno mi problema viene debido a que trabajo con interrupcines del trm0 para manejar el tiempo q se precionan las rb 4-7 para saber q fila se preciono y la usart q comunicaria los pics.Uso el mplab ide v8.10 y el mcc 18 y simulo con proteus.

El problema q tengo es q creo q para poder deterctar las interrupciones provenientes del pin Rx de la usart tengo q habilitar las interrupciones perifericas Bit 6 del registo INTCON al hacer esto mi programa entra en el ciclo de las interrupciones y no sale de hai, yo necesito q salga al main como pasaba antes de habilitarlo, pienso q entra en el ciclo porque estaria alguna bandera de interrupcion levantada pero puse a 0 todos los registros de PIR1 y PIR2 y los q encontre q podian traeme una interrupcion, bueno nose como hacer para q funcione si alguien puede echarle un ojo aca dejo el codigo q tengo hasta el momento y gracias!.

Perdon por el desorden del codigo ya q todavia falta mucho esta todo desordenado y varias banderas innecesarias q me sirve para ir viendo que ocurre

El siguiente codigo es una vercion reducida q hice para probar el funcionamiento de la usart y me anda bien porque en el main no realizo nada pero tengo el mismo problema necesitaria q el bucle donde se quede sea el while y no en las interrupciones
Código: [Seleccionar]
//aca los include y pragmas
#include <p18f452.h>
#include <delays.h>// Rutinas de retardo
#include <usart.h>
#include <lcd.h>

int contador,inter;
int rb,re,tecla,teclax,itecla;
char msg[17]="";
char letra[2];
char DT[]="Desborde TMR0 \r";
char T[]="ENVIANDO MSG";
char recepcion[16];
int i=0;int aux;
int FlagBorrar=0;
int FlagUSARTTx=0;
int FlagML=0;
void interrupciones(void);//prototipo de la interrupción


//------------------ubicacion de la interrupcion--------------
#pragma code prioridad_nomal = 0X0008
void interrupcion_normal (void)
{
_asm goto interrupciones _endasm
}
#pragma code    //fin de la interrupcion


//--------------Rutina de interrupciones-----------------------

#pragma interrupt interrupciones
void interrupciones(void)
{
if(PIR1bits.RCIF)
{
//hacer algo
while(BusyUSART());
//esperamos caracter del virtual terminal
while(!DataRdyUSART());
recepcion[aux]= getcUSART();
aux++;
lcd_home();
lcd_puts(recepcion);
inter=0;
}

}//interrupciones


//--------------------------Main------------------------
void main (void)
{

INTCON=0b11001000;

//-----------------LCD------------------------
TRISD=0b00000000;
PORTB=0x00;
lcd_init();
//--------------------------------------

//--------------------prueba usart-----------
// configuramos el EUSART para 9.6K baudios
OpenUSART( USART_TX_INT_ON &
USART_RX_INT_ON &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH,
64);

TRISCbits.TRISC6 = 0; // Defino el elemento 6 del puerto C como salida  TX
TRISCbits.TRISC7 = 1; // Defino el elemento 7 del puerto C como entrada RX

TRISB = 0b11111111;
TRISE = 0b11100000;
INTCON2 = 0X80;//deshabilitamos las pull-up
//---------------------fin prueba usart---------

while(1)
{}
}//Main


//---------------------------ntecla--------------------------------



Este es el codigo del programa en cuestion pero es mas largo para analizar con resolver el de arriba es lo mismo para este.
Código: [Seleccionar]
//aca los include y pragmas
#include <p18f452.h>
#include <delays.h>// Rutinas de retardo
#include <usart.h>
#include <lcd.h>


int contador,inter;
int rb,re,tecla,teclax,itecla;
char msg[17]="";
char letra[2];
char DT[]="Desborde TMR0 \r";
char T[]="ENVIANDO MSG";
char recepcion[16];
int i=0;int aux;
int FlagBorrar=0;
int FlagUSARTTx=0;
int FlagML=0;

void interrupciones(void);//prototipo de la interrupción
void ntecla(void);
void escribir(void);


//------------------ubicacion de la interrupcion--------------
#pragma code prioridad_nomal = 0X0008
void interrupcion_normal (void)
{
_asm goto interrupciones _endasm
}
#pragma code    //fin de la interrupcion


//--------------Rutina de interrupciones-----------------------

#pragma interrupt interrupciones
void interrupciones(void)
{

if(INTCONbits.RBIF)
{
Delay1KTCYx(250); //esperamos 100ms para evitar rebotes
if(PORTB==0) // si se produce al soltar el pulsador
{
INTCONbits.RBIF = 0;  //limpia bandera
return; // salimos de la interrupcion
}
inter=1;              //flag interrupcion tipo 1 (rb)
rb=PORTB;
re=LATE;
//Delay1KTCYx(250);
INTCONbits.RBIF = 0;  //limpia bandera
PORTB= 0x00;
}

if(INTCONbits.TMR0IF)
{
inter=2;
INTCONbits.TMR0IF=0;
}

if(PIR1bits.RCIF)
{
inter=3;
PIR1bits.RCIF=0;
}

}//interrupciones


//--------------------------Main------------------------

void main (void)
{
PIR1=0x00;
PIR2=0x00;
PIE1=0b00110000;
PIE2=0x00;
INTCONbits.RBIF=0; // RBIF al inicio del programa
INTCONbits.T0IF = 0; //borrar bandera overflow
PIR1bits.RCIF=0;
PIR1bits.TXIF=0;

INTCON = 0b10001000;  //ACA CREO Q ESTA MI PROBLEMA AL PONER INTCON = 0b10001000; NO DETECTA LA INTERRUPCION DE LA USART
//INTCONbits.PEIE=1;    //PERO AL HABILITARLO ENTRO EN UN BUCLE INFINITO
//Configuracion TMR0
T0CON = 0b00000101;//configuramos el timer0
//TMR0H = 0X00,TMR0L = 0X00;//0.5seg: H0xB3 L0xB3
               //10mseg: H0xFE L0x78
               //1seg:   H0x67 L0x68 
RCON = 0X00;//IPEN = 0 no habilita prioridades de interrupciones
INTCONbits.TMR0IE = 1 ;//configuramos la interrupcion del timer0
PORTB= 0x00; // con estas 2 lineas, se borra
INTCONbits.RBIF=0; // RBIF al inicio del programa

//-----------------LCD------------------------
TRISD=0b00000000;
lcd_init();
//--------------------------------------

//--------------------prueba usart-----------
// configuramos el EUSART para 9.6K baudios
OpenUSART( USART_TX_INT_ON &
USART_RX_INT_ON &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH,
64);

TRISCbits.TRISC6 = 0; // Defino el elemento 6 del puerto C como salida  TX
TRISCbits.TRISC7 = 1; // Defino el elemento 7 del puerto C como entrada RX


TRISB = 0b11111111;
TRISE = 0x00;
INTCON2 = 0X80;//deshabilitamos las pull-up


//---------------------fin prueba usart---------

while(1)
{
PORTE=0b00000001;
Delay1KTCYx(25); //10milisegundos en rotar columna
PORTE=0b00000010;
Delay1KTCYx(25);
PORTE=0b00000100;
Delay1KTCYx(25);
     
if(inter)
{
switch (inter)
{
case 1:
//rb
T0CONbits.TMR0ON=0; //desabilitamos el timer
INTCONbits.T0IF = 0; //borrar bandera overflow
tecla=((rb & 0b11110000)|(re & 0b00000111));
//revisar codigo porque los operadores son solo para int o bol
if (tecla==teclax)
{
if(contador==5)
{
contador=1;
}
else
{
contador++;
}
}
else
{
teclax=tecla;
contador=1;
}
ntecla();

escribir();

inter=0; //ya realizo la interrupcion
break;

case 2:
//tmr0
//while(BusyUSART());
//envia caracter
//putsUSART(DT);
FlagML=0;
lcd_cursor_right();
msg[i]=letra[0];
T0CONbits.TMR0ON=0; //desabilitamos el timer
INTCONbits.T0IF = 0; //borrar bandera overflow
contador=0;
inter=0;
if(FlagBorrar!=1)
{i++;}
FlagBorrar=0;
break;

case 3:
//usart
//esperar a que el buffer de transmisión
//este vacio o disponible
while(BusyUSART());
//esperamos caracter del virtual terminal
while(!DataRdyUSART());
recepcion[aux]= getcUSART();
lcd_puts(recepcion);
inter=0;
break;
}
}
}
}//Main


//---------------------------ntecla--------------------------------
void ntecla(void)
{
switch (tecla)
{
case 0b10000100:
//tecla n°3
switch (contador)
{
case 1: letra[0]='I';break; //I
case 2: letra[0]='J';break; //J
case 3: letra[0]='K';break; //K
case 4: letra[0]='L';break; //L
case 5: letra[0]='3';break; //3
}
break;

case 0b10000010:
//tecla n°2
switch (contador)
{
case 1: letra[0]='E';break; //E
case 2: letra[0]='F';break; //F
case 3: letra[0]='G';break; //G
case 4: letra[0]='H';break; //H
case 5: letra[0]='2';break; //2
}
break;

case 0b10000001:
//tecla n°1
switch (contador)
{
case 1: letra[0]='A';break; //A
case 2: letra[0]='B';break; //B
case 3: letra[0]='C';break; //C
case 4: letra[0]='D';break; //D
case 5: letra[0]='1';break; //1
}
break;

case 0b01000100:
//tecla n°6
switch (contador)
{
case 1: letra[0]='T';break; //T
case 2: letra[0]='U';break; //U
case 3: letra[0]='V';break; //V
case 4: letra[0]='W';break; //W
case 5: letra[0]='6';break; //6
}
break;

case 0b01000010:
//tecla n°5
switch (contador)
{
case 1: letra[0]='O';break; //P
case 2: letra[0]='Q';break; //Q
case 3: letra[0]='R';break; //R
case 4: letra[0]='S';break; //S
case 5: letra[0]='5';break; //5
}
break;

case 0b01000001:
//tecla n°4
switch (contador)
{
case 1: letra[0]='M';break; //M
case 2: letra[0]='N';break; //N
case 3: letra[0]='Ñ';break; //Ñ
case 4: letra[0]='O';break; //O
case 5: letra[0]='4';break; //4
}
break;

case 0b00100100:
//tecla n°9
switch (contador)
{
case 1: letra[0]='+';break; //+
case 2: letra[0]='-';break; //-
case 3: letra[0]='/';break; ///
case 4: letra[0]='*';break; //*
case 5: letra[0]='9';break; //9
}
break;

case 0b00100010:
//tecla n°8
switch (contador)
{
case 1: letra[0]='¿';break; //¿
case 2: letra[0]='?';break; //?
case 3: letra[0]='!';break; //!
case 4: letra[0]='¡';break; //¡
case 5: letra[0]='8';break; //8
}
break;

case 0b00100001:
//tecla n°7
switch (contador)
{
case 1: letra[0]='X';break; //X
case 2: letra[0]='Y';break; //Y
case 3: letra[0]='Z';break; //Z
case 4: letra[0]='.';break; //.
case 5: letra[0]='7';break; //7
}
break;

case 0b00010100:
//tecla n°12
switch (contador)
{
default : FlagUSARTTx++;break; //SEND
}
break;

case 0b00010010:
//tecla n°11
switch (contador)
{
default : letra[0]=' ';break; //ESPACIO
}
break;

case 0b00010001:
//tecla n°10
switch (contador)
{
default : letra[0]=' ';lcd_cursor_left();FlagBorrar++;break; //BORRAR
}
break;

}

}//ntecla


//----------------------------escribir----------------------------
void escribir(void)
{

if(FlagUSARTTx==0)
{
if(FlagML!=0)
{
lcd_puts(letra);
lcd_cursor_left();
}

if(FlagML == 0)
{
lcd_puts(letra);
lcd_cursor_left();
FlagML++;
}

if (FlagBorrar!=0)
{
lcd_cursor_left();
//letra[0]='\0';
//FlagBorrar=0;
i--;
}


TMR0H = 0X67,TMR0L = 0X68;
T0CONbits.TMR0ON=1; //deberia empezar a correr el trm0 para desborde


}
else
{
lcd_clear();
lcd_home();
lcd_puts(T);
Delay1KTCYx(25);
lcd_goto(0x40);
Delay1KTCYx(25);
msg[i]='\0';
lcd_puts(msg);
//esperar a que el buffer de transmisión
//este vacio o disponible
while(BusyUSART());
//envia caracter
putsUSART(msg);
FlagUSARTTx=0;
}
}//escribir




Desconectado micro_cadaver

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2102
    • blog microembebidos
Re: Necesito un poco de ayuda
« Respuesta #1 en: 12 de Noviembre de 2008, 15:09:02 »
hola,
sucede que en el ISI proteus (tengo entendido que también sucede en el picbasic ide simulator) cuando usas la interrupcion por cambio de estado en los pines del rb (RBIE) éste se queda enganchado debido a que su bit de flag RBIF no baja a cero después de finalizada la interrupción, entonces para que este bit baje a cero debes leer el portb a cualquier registro por ejemplo tengo un codigo asi:

interrupcion
{
   ....
   teclado_int=1;//parte del codigo de la interrupcion

   proteus=portb;//artificio para el proteus.
}//fin de interrupcion

puedes intentar con ello, si sigue el asunto entonces meteremos bisturi al codigo.

saludos  :-/
a cosechar!!!... :P
pic32... ahi voy....
aguante el micro 16f84  !!!!

visita mi pagina: http://www.microembebidos.wordpress.com

Desconectado cronomus

  • PIC10
  • *
  • Mensajes: 3
Re: Necesito un poco de ayuda
« Respuesta #2 en: 12 de Noviembre de 2008, 16:25:27 »
Gracias por responder, segui el codigo paso a paso y vi algo q no habia notado antes q hasta la linea "lcd_init();" donde inicializa el lcd el codigo corre perfectamente el main luego de esto salta a configurar la USART carga el 64 para trabajar a 9.6k con un oscilador de 10k luego salta a setiar High Baud Rate y luego de esto en vez de seguir configurando en el main salta directamente a la interrupcion lo q hice fue comentar esa parte del codigo y el programa se ejecuta en el main como yo quiero que es que se quede en el main rotando la columna de 1 hasta q sale una interrupcion por lo q me parece que aca esta el problema no en habilitar el bit de interrupciones perifericas aunque todo apunta a lo mismo la usart me esta dando problemas  :mrgreen:
Código: C
  1. OpenUSART(      USART_TX_INT_ON &
  2.                 USART_RX_INT_ON &
  3.                         USART_ASYNCH_MODE &
  4.                 USART_EIGHT_BIT &
  5.                 USART_CONT_RX &
  6.                 USART_BRGH_HIGH,
  7.                 64);

Desconectado micro_cadaver

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2102
    • blog microembebidos
Re: Necesito un poco de ayuda
« Respuesta #3 en: 12 de Noviembre de 2008, 16:44:51 »
entonces... puedes subir el archivo del proteus para facilitarnos el ayudar?.

saludos
a cosechar!!!... :P
pic32... ahi voy....
aguante el micro 16f84  !!!!

visita mi pagina: http://www.microembebidos.wordpress.com

Desconectado cronomus

  • PIC10
  • *
  • Mensajes: 3
Re: Necesito un poco de ayuda
« Respuesta #4 en: 12 de Noviembre de 2008, 16:55:29 »
Gracias por responder maestro micro_cadaver  :-/ me sirvieron de muchisimo tus guias, paso a comentarte sigo avanzando no estoy probando con el codigo largo que postie sino con el corto ya que el error se les da a los 2 por igual, lo que hice fue desabilitar primero como decia el openUSART como vi que era eso empese a ve q podia ser y desabilite ambas interrupciones y hay dejo de saltar el error o sea q la interrupcion se producia al activar al recepcion o la transmicion entonses desabilite la transmicion y wuala el programa corre con total normalidad mientras tenga la transmicion desabilitada, ahora el problema esta en como habilitar la transmicion para que no salte la interrupcion ya q yo todavia no estoy enviando nada o eso creo voy a seguir revisando.


 

anything