Lately I have started using PIC16F1516 as my jelly bean PIC. It is cheap, has lot of memory (whooping 512 bytes) and it is fairly well feature-equipped. Best of all, it is almost completely compatible with my old favorite PIC16F1936.
Yes, PIC16F1936 has EEPROM built-in and both feature list and speed are superior. However, not all projects need all features and speed nor is lack of EEPROM something catastrophic.
As always I started programming by copy/pasting old code. Small adjustments were all that was needed. I copy pasted my UART routines and created simple echoing program on chip. And chip stayed quiet.
After some debugging it was obvious that both my timing routines and UART formulas are correct. And code was same as what I used on PIC16F1936:
void uart_init(int desiredBaudRate) {
TRISC7 = 1; //RX
TRISC6 = 0; //TX
SPBRG = (unsigned char)(_XTAL_FREQ / desiredBaudRate / 16 - 1);
BRG16 = 0; //8-bit
BRGH = 1; //high speed
SYNC = 0; //asynchronous mode
SPEN = 1; //serial port enabled
TXEN = 1;
CREN = 1;
asm("CLRWDT");
}
In moment of desperation I turned my attention to datasheet. And there, under Asynchronous Transmission Set-up chapter it said “Set the RXx/DTx and TXx/CKx TRIS controls to ‘1’.”
In all other PICs (I had opportunity to play with) TRIS for TX pin either does not matter or you set it to output. For some reason designers of this PIC decided that TX pin needs to be input in order for USART to work. Quite a trap.
Only change that was required was setting TRISC6 to 1 and my board became alive:
void uart_init(int desiredBaudRate) {
TRISC7 = 1; //RX
TRISC6 = 1; //TX
SPBRG = (unsigned char)(_XTAL_FREQ / desiredBaudRate / 16 - 1);
BRG16 = 0; //8-bit
BRGH = 1; //high speed
SYNC = 0; //asynchronous mode
SPEN = 1; //serial port enabled
TXEN = 1;
CREN = 1;
asm("CLRWDT");
}
PS: Do not forget to set ANSELC = 0
.