Estoy usando este mcu de 8 bits y 8 pines para asíncrono EUSART.
A veces, cuando lo enciendo, me da los caracteres correctos (por ejemplo, envío 'w', devuelve 'w'), pero a veces cuando lo enciendo, devuelve caracteres extraños (por ejemplo, envío 'w', devuelve 'w' o 'u' o 'W', etc.). Este problema surge únicamente al encender el mcu en diferentes momentos ( por lo tanto, no es un sistema invariante en el tiempo, ¡pero debería serlo! ).
Tenga en cuenta que no programo el mcu de manera diferente entre estas dos instancias.
- Oscilador de cristal externo: 4 MHz
- Voltaje: 3.2 V
- Consumo actual: cuando UART funciona con precisión: 300 uA
- Consumo actual: cuando UART no funciona con precisión: 1200 uA
Estoy usando la interrupción de recepción para recibir los caracteres y transmitir el mismo carácter de vuelta.
Estoy usando MPLAB X IDE v3.20 y el compilador XC8. El código completo utilizado se adjunta a continuación. Por favor ayuda.
/ * * Archivo: LF18313_uart_1.c * * /
#include <stdio.h>
#include <stdlib.h>
#include <pic16lf18313.h>
#define _XTAL_FREQ (4000000UL)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
// CONFIG1
#pragma config FEXTOSC = XT // FEXTOSC External Oscillator mode Selection bits (XT (crystal oscillator) from 100 kHz to 4 MHz)
#pragma config RSTOSC = EXT1X // Power-up default value for COSC bits (EXTOSC operating per FEXTOSC bits)
#pragma config CLKOUTEN = OFF // Clock Out Enable bit (CLKOUT function is disabled; I/O or oscillator function on OSC2)
#pragma config CSWEN = ON // Clock Switch Enable bit (Writing to NOSC and NDIV is allowed)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config MCLRE = ON // Master Clear Enable bit (MCLR/VPP pin function is MCLR; Weak pull-up enabled )
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config WDTE = OFF // Watchdog Timer Enable bits (WDT disabled; SWDTEN is ignored)
#pragma config LPBOREN = OFF // Low-power BOR enable bit (ULPBOR disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bits (Brown-out Reset disabled)
#pragma config BORV = LOW // Brown-out Reset Voltage selection bit (Brown-out voltage (Vbor) set to 2.45V)
#pragma config PPS1WAY = OFF // PPSLOCK bit One-Way Set Enable bit (The PPSLOCK bit can be set and cleared repeatedly (subject to the unlock sequence))
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable bit (Stack Overflow or Underflow will cause a Reset)
#pragma config DEBUG = OFF // Debugger enable bit (Background debugger disabled)
// CONFIG3
#pragma config WRT = OFF // User NVM self-write protection bits (Write protection off)
#pragma config LVP = ON // Low Voltage Programming Enable bit (Low voltage programming enabled. MCLR/VPP pin function is MCLR. MCLRE configuration bit is ignored.)
// CONFIG4
#pragma config CP = ON // User NVM Program Memory Code Protection bit (User NVM code protection enabled)
#pragma config CPD = ON // Data NVM Memory Code Protection bit (Data NVM code protection enabled)
unsigned char rxc = 'a';
void UART_Init(unsigned long int desiredBaud) {
TRISA1 = 1; // PORT A1 is 'RX' and set as input
ANSELA = 0x00; // Disable analog functioning on analog pins
RA0PPS = 0b10100; // RA0 output source is UART TX
RXPPS = 0b00001; // RA1 input source is UART RX
unsigned int baudReg;
baudReg = (_XTAL_FREQ - desiredBaud*16UL)/(desiredBaud*16UL);
BRGH = 1; // BRG counter clock rates
BRG16 = 0;
SYNC = 0; // Setting Asynchronous Mode
SPBRG = baudReg; // Writing SPBRG Register
SPEN = 1; // Enables Serial Port
RCIE = 1; // Enables Receiver Interrupt
PEIE = 1; // Enables Peripheral Interrupt
GIE = 1; // Enables Global Interrupt
CREN = 1; // Enables Continuous Reception
TXEN = 1; // Enables Transmission
}
void UART_Write(unsigned char data) {
while(!TXIF) {}
TXREG = data;
}
int main() {
TRISA = 0x00; //PORTA as Output
UART_Init(9600);
while(1) {
}
return 0;
}
void __interrupt ISR() {
if (RCIF) {
rxc = RCREG;
UART_Write(rxc);
}
}
Editar: No hay condensador entre VCC y GND
Editar: He configurado MCLRE = OFF y PWRTE = ON, según se solicita. También he añadido un condensador de 1uF entre VCC y amp; GND. Pero esto no afectó el problema en cuestión. Intenté operar el mcu sin el oscilador de cristal de 4 MHz, mientras que el código se mantuvo igual con algunos cambios menores como se indica en esta Edición. El consumo de corriente permaneció igual, y los caracteres transmitidos y recibidos tenían casi la misma aleatoriedad que cuando usé el oscilador de 4 MHz. Por lo tanto, significaba que el cristal de 4MHz no funcionaba correctamente. Pero no funcionó incluso cuando reemplacé este cristal con un cristal de 4 MHz diferente.
Para un cambio, probé el cristal de 16 MHz y configuré el BRGH = 0 en el código anterior. ¡Ahora funciona con precisión! Y es invariante en el tiempo. Pero el consumo actual es 1100uA. Por lo tanto, todavía me gustaría saber las posibles causas de error con el cristal de 4MHz, ya que utiliza 300uA (ya que quiero el menor consumo de energía).