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 enable_receiver(void);
            void write_USART(unsigned char);
            unsigned char read_USART(void);

            int main(){
                unsigned char i = 0;
            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

            void enable_receiver(){
                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
                TXREG = input;

            unsigned char read_USART(){
                while(!RCIF) //interrupt flag - buffer not ready
                return RCREG;
  • 1
    \$\begingroup\$ 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? \$\endgroup\$
    – nvd
    Jul 4, 2014 at 17:38
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – PeterJ
    Jul 5, 2014 at 3:07
  • \$\begingroup\$ @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. \$\endgroup\$
    – JahMyst
    Jul 7, 2014 at 10:12
  • \$\begingroup\$ @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. \$\endgroup\$
    – JahMyst
    Jul 7, 2014 at 10:13

2 Answers 2


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 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.
  • \$\begingroup\$ 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 \$\endgroup\$
    – JahMyst
    Jul 7, 2014 at 10:16
  • \$\begingroup\$ 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. \$\endgroup\$
    – fgrieu
    Jul 7, 2014 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;
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – JahMyst
    Jul 7, 2014 at 10:20

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.