I used the following code to send out an USART asynchronous transmission of a string "AT\n\r" using a PIC18F4550.

// PIC18F4550 Configuration Bit Settings

// 'C' source line config statements

#pragma config PLLDIV = 5       // PLL Prescaler Selection bits (No prescale (4 MHz oscillator input drives PLL directly))
#pragma config CPUDIV = OSC1_PLL2// System Clock Postscaler Selection bits ([Primary Oscillator Src: /1][96 MHz PLL Src: /2])
#pragma config USBDIV = 1       // USB Clock Selection bit (used in Full-Speed USB mode only; UCFG:FSEN = 1) (USB clock source comes directly from the primary oscillator block with no postscale)

#pragma config FOSC = HSPLL_HS  // Oscillator Selection bits (HS Oscillator, PLL enabled)
#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 PWRT = OFF       // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOR = ON         // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 3         // Brown-out Reset Voltage bits (Minimum setting 2.05V)
#pragma config VREGEN = OFF     // USB Voltage Regulator Enable bit (USB voltage regulator disabled)

#pragma config WDT = OFF         // Watchdog Timer Enable bit (WDT enabled)
#pragma config WDTPS = 32768    // Watchdog Timer Postscale Select bits (1:32768)

#pragma config CCP2MX = ON      // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = ON      // PORTB A/D Enable bit (PORTB<4:0> pins are configured as analog input channels on Reset)
#pragma config LPT1OSC = OFF    // Low-Power Timer 1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = ON       // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)

#pragma config STVREN = ON      // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = OFF         // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled)
#pragma config ICPRT = OFF      // Dedicated In-Circuit Debug/Programming Port (ICPORT) Enable bit (ICPORT disabled)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))

#pragma config CP0 = OFF        // Code Protection bit (Block 0 (000800-001FFFh) is not code-protected)
#pragma config CP1 = OFF        // Code Protection bit (Block 1 (002000-003FFFh) is not code-protected)
#pragma config CP2 = OFF        // Code Protection bit (Block 2 (004000-005FFFh) is not code-protected)
#pragma config CP3 = OFF        // Code Protection bit (Block 3 (006000-007FFFh) is not code-protected)

#pragma config CPB = OFF        // Boot Block Code Protection bit (Boot block (000000-0007FFh) is not code-protected)
#pragma config CPD = OFF        // Data EEPROM Code Protection bit (Data EEPROM is not code-protected)

#pragma config WRT0 = OFF       // Write Protection bit (Block 0 (000800-001FFFh) is not write-protected)
#pragma config WRT1 = OFF       // Write Protection bit (Block 1 (002000-003FFFh) is not write-protected)
#pragma config WRT2 = OFF       // Write Protection bit (Block 2 (004000-005FFFh) is not write-protected)
#pragma config WRT3 = OFF       // Write Protection bit (Block 3 (006000-007FFFh) is not write-protected)

#pragma config WRTC = OFF       // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) are not write-protected)
#pragma config WRTB = OFF       // Boot Block Write Protection bit (Boot block (000000-0007FFh) is not write-protected)
#pragma config WRTD = OFF       // Data EEPROM Write Protection bit (Data EEPROM is not write-protected)

#pragma config EBTR0 = OFF      // Table Read Protection bit (Block 0 (000800-001FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF      // Table Read Protection bit (Block 1 (002000-003FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF      // Table Read Protection bit (Block 2 (004000-005FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF      // Table Read Protection bit (Block 3 (006000-007FFFh) is not protected from table reads executed in other blocks)

#pragma config EBTRB = OFF      // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) is not protected from table reads executed in other blocks)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>
#include <pic18f4550.h>

#define _XTAL_FREQ 20000000

void USART_send_string(char *msg);

void main(void) {
    TRISCbits.TRISC6 = 1; 
    TRISCbits.TRISC7 = 1; 
    BAUDCONbits.BRG16 = 0;
    TXSTA = 0x24;
    RCSTA = 0x90;
    SPBRG = 25;


void USART_send_string(char *msg)
    while (*msg != '\0')
        while(TXIF == 0);
        TXREG = *msg;

Based on the datasheet, as soon as the data from the TXREG register is transferred to the TSR register, the TXIF interrupt flag is set. So, the USART_send_string function is used to keep loading the TXREG register based on the TXIF flag as long as the string input is not "NULL" ("\0").

enter image description here

While this transmits the desired string "AT\n\r" correctly, upon closer inspection with the logic analyzer, it appears that the USART transmission is repeated continuously approximately around every 100 ms for no apparent reason, as shown below.

enter image description here

What could be the cause of this continuous transmission?

I have included the assembly listing of the code in case it is helpful in any way:

70:            #include <xc.h>
71:            #include <pic18f4550.h>
73:            #define _XTAL_FREQ 20000000
75:            void USART_send_string(char *msg);
77:            void main(void) {
78:                TRISCbits.TRISC6 = 1; 
084A  8C94     BSF TRISC, 6, ACCESS
79:                TRISCbits.TRISC7 = 1; 
084C  8E94     BSF TRISC, 7, ACCESS
81:                INTCONbits.GIE = 0;
084E  9EF2     BCF INTCON, 7, ACCESS
82:                INTCONbits.PEIE = 0;
0850  9CF2     BCF INTCON, 6, ACCESS
84:                BAUDCONbits.BRG16 = 0;
0852  96B8     BCF BAUDCON, 3, ACCESS
85:                TXSTA = 0x24;
0854  0E24     MOVLW 0x24
86:                RCSTA = 0x90;
0858  0E90     MOVLW 0x90
87:                SPBRG = 25;
085C  0E19     MOVLW 0x19
89:                USART_send_string("AT\r\n");
0860  0E01     MOVLW 0x1
0862  6E01     MOVWF __pcstackCOMRAM, ACCESS
0864  0E08     MOVLW 0x8
0866  6E02     MOVWF 0x2, ACCESS
0868  EC04     CALL 0x808, 0
086A  F004     NOP
90:                while(1)
91:                 {}
086C  EF36     GOTO 0x86C
086E  F004     NOP
0870  EF00     GOTO 0x0
0872  F000     NOP
92:                 }
94:            void USART_send_string(char *msg)
95:            {
96:                while (*msg != '\0')
0808  EF16     GOTO 0x82C
080A  F004     NOP
082C  C001     MOVFF __pcstackCOMRAM, TBLPTR
082E  FFF6     NOP
0830  C002     MOVFF 0x2, TBLPTRH
0832  FFF7     NOP
0834  0008     TBLRD*
0836  50F5     MOVF TABLAT, W, ACCESS
0838  0900     IORLW 0x0
083C  EF22     GOTO 0x844
083E  F004     NOP
0840  EF24     GOTO 0x848
0842  F004     NOP
0844  EF06     GOTO 0x80C
0846  F004     NOP
97:                {
98:                    while(TXIF == 0);
080C  A89E     BTFSS PIR1, 4, ACCESS
080E  EF0B     GOTO 0x816
0810  F004     NOP
0812  EF0D     GOTO 0x81A
0814  F004     NOP
0816  EF06     GOTO 0x80C
0818  F004     NOP
99:                    TXREG = *msg;
081A  C001     MOVFF __pcstackCOMRAM, TBLPTR
081C  FFF6     NOP
081E  C002     MOVFF 0x2, TBLPTRH
0820  FFF7     NOP
0822  0008     TBLRD*
0826  FFAD     NOP
100:                   *msg++;
0828  4A01     INFSNZ __pcstackCOMRAM, F, ACCESS
082A  2A02     INCF 0x2, F, ACCESS
101:               }
102:           }
0848  0012     RETURN 0
  • 1
    \$\begingroup\$ Perhaps the watchdog timer is enabled by default and it is causing the device to reset and rerun the program every 100 ms. \$\endgroup\$
    – kkrambo
    Oct 25, 2022 at 17:06
  • \$\begingroup\$ @kkrambo My WDT configuration bit is set to OFF so probably not. \$\endgroup\$
    – Chris Aung
    Oct 25, 2022 at 17:26
  • 1
    \$\begingroup\$ *msg++; is nonsense (it will work here but likely produce warnings). It should be msg++; instead. \$\endgroup\$
    – Lundin
    Oct 28, 2022 at 11:15

1 Answer 1


I have found that the issue was caused by the CONFIG2L brown-out reset bit.

#pragma config BOR = ON // Brown-out Reset Enable bits 

After changing it to OFF appeared to have eliminated the problem.

EDIT 1: More Info

After scoping the Vdd pin of the PIC18 microcontroller, it appears that there are corresponding voltage drop of around 500mV when the Brown out reset is triggered. Though it should not be low enough for PIC to trigger it. I currently have a 0.1uF decoupling capacitor between the Vdd and Vss pin of the PIC but I am thinking if I should increase the capacitance.

enter image description here


It appears that it is my ESP8266 module that is causing the voltage drops. As soon as the ESP8266 module is disconnected, the low voltage spikes disappeared.

enter image description here

  • 2
    \$\begingroup\$ You have #pragma config BORV = 3 this means BORV1:BORV0 = 11 2.00 2.05 2.16 (page 369 of datasheet: Brown-out Reset Voltage). The PIC is resetting because the voltage is dropping to somewhere between 2.00v - 2.16v. You should check why the voltage is dropping. \$\endgroup\$
    – Rodo
    Oct 25, 2022 at 17:53
  • \$\begingroup\$ "It appears that it is my ESP8266 module that is causing the voltage drops. As soon as the ESP8266 module is disconnected, the low voltage spikes disappeared." So maybe your voltage regulator is incorrectly designed for the amount of current required by this board? \$\endgroup\$
    – Lundin
    Oct 28, 2022 at 11:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.