TXREG and RCREG are registers, but they are special function registers. The actual addresses of TXREG and RCREG are in the .h file, and for the 16F877A they are 0x19 and 0x1A in bank 0. Broadly, special function registers do something physical as well as, or instead of, storing a number. The ports are special function registers, so when you write:-
all the pins that make up port A, that are outputs, will go to a low voltage. Similarly PORTA can be read by the code, and it's value will change depending on the logic levels applied to the pins.
TXREG and RCREG are the special function registers that are used for sending and receiving data on the USART. You cannot store data in them in the normal way.
Where the code has:-
the value of ch is written into TXREG, and the action of writing causes one byte to be transmitted by the USART, starting immediately. The TX pin, pin 25 on a DIP40 pic16F877A, will be high when nothing is being transmitted. It will go low for 1 bit period to send the start bit, then it will send the 8 data bits, LSB first, by being low for 1 bit period if the bit is 0, and high for one bit period if the bit is 1. At the end of the 8 bits, there is a stop bit, which is high for 1 bit period and then the USART is ready to transmit another byte. (The stop bit is high. At the end of the stop bit the TX pin remains high. The end of the stop bit is just the point in time when another byte can be transmitted.
If the program includes:-
Code:
TXREG=ch
some code that waits for 10 bit periods or more
TXREG=ch
then the value of ch will be sent twice.
RCREG is the receiving register.
When data arrives on the RX pin, pin 26 of the DIP40 pic16F877A, in the same format that the USART uses to transmit, when the whole byte has finished, the value of the byte becomes available to be read on RCREG. The program has to read the RCIF bit to see if data is available. When data is available, RCREG can be read.
As with writing to TXREG, reading from RCREG causes something to happen. Reading RCREG causes the USART to consider the register as empty, so that RCIF is cleared by the USART, and the USART can put more data into RCREG if more arrives. Note that empty does not mean equal to 0x00. Any value from 0x00 to 0xFF can arrive at the RX pin and the USART will put the value into RCREG, which makes it full, and RCIF is 1. Reading the register makes the register empty and RCIF becomes 0.
If too much data arrives and the program never reads it, the USART turns on the overrun flag.
The code sample you have has an error, but not one that matters.
is incorrect, because the RCIF flag cannot be written by the program in a pic16F877A. It can only be read by the program. Trying to write it will do nothing.