# Problem with USART programming

I have got a problem with an USART module I wrote in C for PIC12F1822, related to USART transmission.

Everything happens to be fine when I debug in MPLAB with PICKIT3 (TXREG changes value and every register is updated correctly as I defined it).

But the PIC won't send anything to the TX port, as there is no signal at all observed at the oscilloscope.

I followed the steps in the datasheet found here (see page 287 for USART setup)

Here is my code :

            #include <stdio.h>
#include <htc.h>

void init_ports(void);
void enable_transmitter(void);
void write_USART(unsigned char);

int main(){
unsigned char i = 0;
init_ports();
enable_transmitter();
while(1){
write_USART(i);
i++;
}
return 0;
}

void init_ports(){
//RA0 = TX/CK and RA1 = RX/DT
TXCKSEL = 0;
RXDTSEL = 0;

//Baud rate configuration - clock @ 1*4(PLL) MHz, refer to p.300 datasheet
BRGH   = 1;
BRG16  = 0;
SPBRGL = 0x31;
SPBRGH = 0x00;

//Disabling eventual analog I/O function
ANSA0  = 0;
ANSA1  = 0;
}

void enable_transmitter(){
SPEN   = 1; //enables the EUSART and automatically configures the TX/CK I/O pin as an output
SYNC   = 0; //configures the EUSART for asynchronous operation
TX9    = 0; //8-bits transmission
TXEN   = 1; //enables the transmitter circuitry of the EUSART
TRISA0 = 0; //TX on RA0 = OUTPUT
}

SPEN   = 1; //enables the EUSART
SYNC   = 0; //configures the EUSART for asynchronous operation
RX9    = 0; //8-bits transmission
CREN   = 1; //enables the transmitter circuitry of the EUSART
TRISA1 = 1; //RX on RA1 = INPUT
}

void write_USART(unsigned char input){
while(!TXIF) //interrupt flag - buffer not ready
continue;
TXREG = input;
}

while(!RCIF) //interrupt flag - buffer not ready
continue;
return RCREG;
}

• I have not used PIC and can only suggest. What is the default status of that pin i.e. any other purpose than GPIO? Do you need to enable the GPIO buffer along with USART? Do you need to disable any other hardware connected to that pin?
– nvd
Jul 4 '14 at 17:38
• I don't see any apparent problems with your code but I wonder if there is a chance of a hardware problem, maybe the pin is shorted to ground / Vcc or has been damaged previously? It'd be worth checking for a short on the board and trying another chip. If you don't have one maybe try toggling the PIN as a standard I/O and see if that works. Jul 5 '14 at 3:07
• @nvd The default status of that pin is GPIO at reset so this should not be a problem. I don't see anything in the datasheet about a GPIO buffer that needs to be activated. No other hardware is connected on that pin. Jul 7 '14 at 10:12
• @PeterJ The pin is not shorted to ground or Vcc. I don't think it has been damaged because PICKIT3 recognize it and success at programming it. I will try another chip though. Jul 7 '14 at 10:13

Things to try:

• That's an 8-pins device, and you are looking at pin 7 with a properly triggered scope.
• No other thing is forcing that pin.
• The code actually runs (option bits in Configuration Words are OK, Vcc is OK, /MCLR is high); perhaps, make a variant with a simple loop toggling an/this output port.
• It is good practice to perform all settings with SPEN = 0, and set SPEN = 1 at the very end. That's the order recommended in 26.1.1.6 of the latest data sheet
• Also, write SPBRGH before SPBRGL; that's the order stated, and on some PIC devices, order matters (though there is no indication of that in this one)
• TRISA0 = 1, for perhaps TRISA0 = 0 overrides SPEN = 1 to define the state of PortA, pin 0 (although my reading of the Data Sheet is that it should not).
• ABDEN = 0
• SDOSEL = 1, SSSEL = 0, P1BSEL = 0 to disable other overrides of that pin.
• I may have some problems with configuration words, as I am forced to use an internal clock oscillator and have trouble setting it up. My configuration words are INTOSC, WDTEN = 0, PWRTEN = 0, MCLR/VPP pin function is MCLR, CP = 0, CPD = 0, BOREN = 1, WRT = 0, PLLEN = 1, STVREN = 1, LVP = 0. I added OSCCON = 1011010; IRCF = 1011; //Internal Oscillator Frequency Select Bits SCS = 10; //Internal Oscillator selected Jul 7 '14 at 10:16
• I thnk you should ascertain that configuration words and programming are such that the code runs at all, by performing some very simple action on reset, perhaps for(TRISA = 0xFE; ; LATA^=1); which will output a square wave on PortA0, if the code runs. Jul 7 '14 at 11:44

You didn't set any interrupt bits. TXIF could be dependent on them. Try remove while loop for test and set interrupt bits.

void write_USART(unsigned char input){
//while(!TXIF) //interrupt flag - buffer not ready
//    continue;
TXREG = input;
}

• Directly from the datasheet : " The TXIF interrupt can be enabled by setting the TXIE interrupt enable bit of the PIE1 register. However, the TXIF flag bit will be set whenever the TXREG is empty, regardless of the state of TXIE enable bit." PAGE 287. Jul 7 '14 at 10:20