The Arduino core includes numerous software interfaces mimicking the hardware interfaces provided by the chip and even extending beyond. My question is, if in a project I can either use software or hardware protocol, what would be the difference in stability, speed and versatility? Is there a reason why hardware interfaces are preferred? Because anyways the protocol is handled by the CPU or am I mistaking something?
In your question you ask about all communication interfaces in general, so the answer will be as general as your question.
Hardware interfaces should always be preferred to software interfaces, though there are situations, where it is a better or needed to use a software interface due to limited resources.
Because anyways the protocol is handled by the CPU
That is mostly wrong. The communication protocol is done by the hardware in most cases, if you use hardware interfaces. Serial (UART) for example automatically sends out the byte, that is placed in the hardware buffer, with the set configuration. It does not rely on any software for that. The same goes for SPI or I2C. The protocol of the interface is handled via hardware.
Though at least for Arduino Core/library users there is more to it, that get's handled automatically. Since the interface hardware is limited, the software have to take care of the resulting or needed data. For example: All the interfaces mentioned above use a 1 byte buffer for the data. The software must read or write this data, so that the hardware can work. If you don't read the byte of data, that was received by the Serial interface, it might get overwritten by the next byte. The hardware cannot provide a buffer, that is generally big enough, since the manufacturer cannot know, how long the transmissions will be. So the interfaces get a 1 byte buffer and the software has to do the rest. For this reason all the libraries use a bigger buffer in their software, that gets filled, when the hardware sends a corresponding interrupt.
So: Hardware interfaces implement the basic interface protocol (how the bits get transmitted) in hardware, thus the software only has to provide and read the byte data. The stability, speed and versatility is only determined by how the manufacturer build the hardware of that interface. This limit is clearly specified in the datasheet and does not change with the code.
For software interfaces, everything is done in software. This also involves monitoring and setting the corresponding pins with the correct timing. In the best case the software can utilize general hardware functions like a pin interrupt, but if it cannot do this, it has to constantly monitor (poll) the pins to receive something. Software interfaces are often called "bit banged", because the software manually pushes out each individual bit with the exact needed timing. That is a tedious task, which often blocks the execution of other code, since the timing often is critical. Especially the timing introduces limits, since doing things in software often involves many clock cycles more, than it could be done by dedicated hardware (consider all the code to poll a pin and the multiple if statements to react to specific situations). For example: When you write data with
SoftwareSerial the call to the write function will block, because is manually pushes out bit after bit. Or with SPI: With hardware SPI you can go to incredible clock speeds in the MHz range. You won't every get near that with software, because the software simply cannot run this fast.
Note, that depending on the actual hardware of the used chip, a library may need to implement parts of the protocol in software. For example this is the case for using I2C on an ATtiny85, which does not have full I2C hardware support. Instead the USI (Universal Serial Interface) can be used to implement some functions of the protocol in hardware and the rest in software.
- Hardware interfaces lift the heavy duty of handling the low level protocol (transmitting the bits by the needed standard) (which can be rather complex) from the software
- The Software then only handles the byte data, not it's transmission
- Translating complex protocols from dedicated hardware to software (bit banging the data through simple pins) imposes great limits on speed and reliability.
Using a hardware interface takes a lot of load from the CPU. Let's take an asynchronous serial interface for example.
With the UART built-in hardware you'll get parallel-serial conversion and back done in hardware. The CPU "just" needs to store the data to be sent in a register. The receiving part is handled completely by the hardware and the CPU "just" needs to look at the "received" flag before reading the data. Or it sets up an interrupt as callback.
If you use a software interface the CPU needs to convert the parallel data to serial with several instructions and, really important, needs to maintain a certain timing. For receiving this might be even harder because of the asynchronous nature of the protocol. A timer might be usable to clock the communication, for example by an interrupt, but this puts a lot of load on the CPU. Certain conditions might make this usage impossible, too.
Now you might think about the issues you mentioned:
Stability: If done correctly both approaches are equally stable, meant as reliable function. If you have more tasks to be done you might not be able to meet the requirements. This comes "earlier" with software interfaces than with hardware interfaces due to the higher load.
Speed: Hardware interfaces can be faster than software interfaces because the hardware is commonly clocked faster than what is possible by software which needs multiple instructions for one step. But speed is always a relative issue. There are libraries implementing USB1.1 via software, and the USB1.1 protocol is both fast and really complex.
Versatility: Software interfaces are more versatile because hardware interfaces are limited in their capabilities. If a hardware interface can't do what you need there is no way to make it do this. Software can do "anything" as long as the CPU has enough time and resources for this.
Hardware interfaces are preferred because they are simpler to use and commonly don't put hard requirements on your software architecture.