Buenas. Trato de escribir y enviar por el puerto RS232 del PIC18F2480 desde hace algún tiempo. Conseguí que escribiese y leyese aunque lo hacía desplazado: le enviaba 123 y guardaba "espacio12" y si luego enviaba 456, guardaba "345". Pues bien, tratando de arreglar este problemame comenzó a dar problemas en la escritura (función que he hecho yo, que diferencia entre caracter y cadena para enviar mediante TXREG como veréis en el cóigo que pongo más adelante).
Pues bien, me pasó una cosa extrañísima: un día toqué algo que solo me imprimía los caracteres sueltos pero no las cadenas y continuaba con el problema de lectura. Al día siguiente, el mismo código, enviaba basura, pero solo corriendo normal, es decir, en debug sí escribe bien y recibe correctamente en ambos tipos de funcionamiento. No lo entiendo.
Además, cuando le hago debug, me aparece un aviso de que la memoria está protegida pero en la configuracion lo tengo todo OFF. Tampoco sé que pasa aquí, aunque no me supone un problema (a menos que esté relacionado con lo anterior).
Uso un portatil con puerto serie, MPLAB y C18. Tengo una placa perforada que he soldado yo mismo pero no creo que sea problema del hardware y he cambiado ya el PIC y el MAX232 que uso para comunicarme con el PC para descartar, pero nada. Os paso el código:
Archivo V7_define:
#define COLGADO 10000 //Se establece a 5s el tiempo para admitir que el programa está colgado
#define CR 13 //Retorno de carro
#pragma config OSC = IRCIO67 // Oscillator Selection bits (Internal oscillator block, CLKO function on RA6, port function on RA7)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)
#pragma config PBADEN = OFF // PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)
#pragma config WDT = OFF, LVP = OFF //0 = Single-Supply ICSP disabled
#pragma config MCLRE=ON, LPT1OSC = OFF, XINST = OFF, DEBUG=OFF
#pragma config CPB = OFF, CPD = OFF, CP0 = OFF, CP1 = OFF
#pragma config WRT0 = OFF, WRT1 = OFF, WRTB = OFF, WRTC = OFF, WRTD = OFF
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTRB = OFF, BBSIZ = 1024 // 1K words (2K bytes) Boot Block
Archivo V7_Declaracion_Funciones
void ConfigOSC (void);
void InicializacionPuertos(void);
void ConfigRS232(void);
void Escribe(char*, char, int);
void EsperaTSR (void);
void Lee(void);
Main principal:
#include <xc.h> // include processor files - each processor file is guarded.
#include <stdio.h>
#include <stdlib.h>
#include "V7_Define.h"
#include "V7_Declaracion_Funciones.c"
void main() {
for (esperainicio=0;esperainicio<100000;esperainicio++);
ConfigOSC();
InicializacionPuertos();
ConfigRS232();
while(1){
Escribe("HOLA", NULL, 4);
Lee();
}
void ConfigOSC (void){
OSCCONbits.SCS=0b11; //Seleccion del reloj interno
OSCCONbits.IRCF0=1; //Reloj seleccionado a 8MHz
OSCCONbits.IRCF1=1;
OSCCONbits.IRCF2=1;
}
void InicializacionPuertos(void) {
ADCON1=0x0F; //Todos entrada/salida digitales.//DESHABILITA CONEERTIDORES A/D
TRISA=0xFF; //Puerto completo como entrada
TRISB=0xF0; //S1~3 como salida y E15~7 como entrada
TRISCbits.TRISC0=1;
TRISCbits.TRISC1=1;
TRISCbits.TRISC2=1;
TRISCbits.TRISC3=1;
TRISCbits.TRISC4=1;
TRISCbits.TRISC5=1;
TRISCbits.TRISC6=0; //TRISC <6> (TX) puesto a cero (salida). Los demas a uno (entradas).
TRISCbits.TRISC7=1; //TRISC <7>(RX) a 1 (entrada).
//Nota: El control EUSART reconfigurará automáticamente el pin de entrada a salida según sea necesario.
PORTA = 0; //Initialize PORTA by clearing output data latches
PORTB = 0; //Tambien se puede hacer limpiando el LAT
PORTC = 0;
}
void ConfigRS232(void) {
//Configuración de los pines RC6 y RC7 del Puerto C como USART
SPBRG = 103; //Con las variables anteriores a 0, 1 y 0, velocidad = 2400
BRG16 = 0; //Establece la comunicación en 8 bits. Está a 0 de forma predeterminada
//así que no es necesario especificarlo. Para 16 bits, ponerlo a 1.
BRGH = 0; //Comunicación a alta velocidad. "0" para baja
SYNC = 0; //Hace que sea asíncrono. Para síncrono hacerlo igual a uno.
SPEN = 1; //Serial Port Enable bit
CREN = 1; //Habilita la recepcion
TXEN = 1; //Habilita la transmision
}
void Escribe(char *c1, char c2, int tam){
int cont3=0;
if (c1==NULL && TXEN==1){
TXREG=c2;
EsperaTSR();
}
else if (c2==NULL && TXEN==1){
for(cont3=0;cont3<tam;cont3++){ //Recorre las direcciones de memoria de comando
TXREG=c1[cont3];
EsperaTSR();
}
}
}
void EsperaTSR (void){
unsigned long int watchdogEscribe=0;
while(TRMT==0){ //Mientras haya datos esperando en TSR, esperar.
if(watchdogEscribe==COLGADO){ //Si no se puede poner en cola...
TXEN=0; //Deshabilita la escritura
watchdogEscribe=0; //Resetea el contador
}
watchdogEscribe++;
}
watchdogEscribe=0; //El ultimo fuera del if, para que siempre sea reseteado.
}
void Lee(void){
if (RCIF==1){
mensajeR[cont7]=RCREG;
cont7++;
if(OERR==1){
CREN = 0;
CREN = 1;
}
}
}