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
//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.
//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