- A bit counter will be needed for both transmitting and receiving, if you're to be able to do them simultaneously. This takes another 8 bytes of memory, of course.
- While not necessary for the UART aspect, this code uses interrupts on two pins of P1. Any output on GPIO, even if interrupts are disabled for the pin, will set the corresponding bit of P1IFG on a rising or falling edge, depending on the setting of the corresponding bit in P1IES. Because the two LEDs are being used, any time the LED is turned on we have a rising edge on that GPIO, which sets the bit in P1IFG. The method used in this code to deal with P1 interrupts fails in those cases, since P1IFG would not be exactly P1RX or BTN1. To fix this, a mask is introduced so the switch statement in the P1 ISR only considers the bits for P1RX and BTN1, ignoring any others set bits of P1IFG. There is one disadvantage to this particular scheme: if the UART receives a start bit at the same time as a button press occurs, one or both will be ignored (depending on the order and timing of the two events).
- A new function is introduced to encapsulate sending a string of characters over UART. This function makes use of a pointer, allowing us to write new values to the variable message. Be aware that other values in RAM could be overwritten if you're not careful. Also, the function assumes a message length of exactly 16 characters, and will print garbage (or remnants of the last message) if you write a shorter message. A longer message will be truncated.
- Because the DCO is executing commands at a faster rate than the transmission, a short delay of bit_time is added to tx_byte(). This delay lets the transmission start before returning control to the main() function. Without it, the code could call tx_byte() again before transmitting actually starts, changing the value of TXBuffer before it has a chance to get sent.
The transceiver code can be found in uartTXCVRG2231.c. I've added a few features to demonstrate the full-duplex capability of the transceiver. The commands 'r', 'g', and 'z' are retained from the receiver tutorial. To this has been added 'c', which prints a continuous message until another command (eg. 'z' to sleep) is sent. Note that the command can be sent in the midst of a byte transmission and still work, since the receiver is operating on a separate timer/interrupt configuration. I verified this to be the case using my logic analyzer, and found that a command was correctly received even while starting in the middle of a transmission.
In addition to the 'c' command, another command is set from a button press (using a non-keyboard ASCII character 0xAF), and can be done at any time, showing that the code can also work with physical interface interrupts as well as the serial transmission of commands. The button will also stop the continual printing of a 'c' command as well, as it also resets the command variable to 'z'.
Remember to use 9600 baud transmission and to configure CCS to build and link to the header file with the UART calibration, as well as not erase the information memory segment containing the UART DCO calibration.
And with that, we've reached the conclusion of what I'll term as the "basic" tutorials for the MSP430. A big "Thank you!" to all of you; I've received numerous notes of encouragement from many of my readers, and it's been very helpful. This project and blog have been a great deal of fun, and wer a key addition to the training I received as a Ph.D. student. This isn't the end of the blog, of course. I'll be back with more advanced tutorials, and, more importantly, examples of scientific measurements and experiments done with the MSP430. In fact, my next post will start describing a project I've had in mind for a while. In the mean time, I will start recompiling these first 18 tutorials into a single volume. I have as-yet to decide just how it would be distributed, and exactly what form it would take. In any case, I hope all of you stay with me and enjoy exploring the MSP430.