Problem with USART programming

cpicuart

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;
                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
            }

            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
                    continue;
                TXREG = input;
            }

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

Best Answer

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.