I am using this 8-bit, 8-pin mcu for asynchronous EUSART.
Sometimes when I power it up, it gives me correct characters (e.g. I send 'w', it returns 'w'), but sometimes when I power it up, it returns strange chars (e.g. I send 'w', it returns 'w' or 'u' or 'W', etc.). This problem arises solely with powering up the mcu at different times (hence, it is not a time-invariant system, but it should be!).
Note that I do not program the mcu differently between these two instances.
- External crystal oscillator: 4 MHz
- Voltage: 3.2 V
- Current consumption: When UART works accurately: 300 uA
- Current consumption: When UART doesn't works accurately: 1200 uA
I am using receive interrupt to receive the chars and transmit the same char right back.
I am using MPLAB X IDE v3.20 and XC8 compiler. Complete code used is attached below. Please help.
/* * File: 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);
}
}
Edit: There is no capacitor between VCC and GND
Edit: I have set MCLRE = OFF and PWRTE = ON, as requested. I have also added a 1uF capacitor between VCC & GND. But these did not affect the problem at hand. I tried to operate the mcu without 4MHz crystal oscillator while the code remained same with some minor changes as put in this Edit. The current consumption remained same, and the chars transmitted and received were having almost the same randomness as that when I used the 4MHz oscillator. So, it meant that the 4MHz crystal was not working properly. But it did not work even when I replaced this crystal with a different 4MHz crystal.
For a change, I tried 16MHz crystal and set the BRGH = 0 in the above code. Now, it works accurately! And it is time-invariant. But the current consumption is 1100uA. So, I would still like to know the possible causes of error with 4MHz crystal, because it uses 300uA (since I want the least power consumption).