1
\$\begingroup\$

I need a second serial async output channel on the MSP430G2553 and would like to use the SPI USCI to do this.

Is the USCI SPI baud rate stable enough to do this at 300 baud, 2400 baud or 9600 baud? I am currently using the 8 MHz clock.

Is there any other option that can save me from bit-banging?

My current thinking for 300 bd Tx is as follows:

  1. set prescaler to 26666 LSB first
  2. load byte into Txbuf
  3. load 0x7F into Txbuf to generate stop and start bits
  4. repeat 2-3
  5. send final stop bits 0xFF

It might also be possible to send ten bits of data on other members of the MSP430 family that contains a SPI.

Thanks for your responses.

\$\endgroup\$
  • \$\begingroup\$ Why do you need Rx for an output channel? \$\endgroup\$ – CL. Feb 26 '17 at 9:46
  • \$\begingroup\$ @CL. The Rx is part of a follow-up question. The main question is about Tx. Edit done for clarity. \$\endgroup\$ – skvery Feb 26 '17 at 10:13
1
\$\begingroup\$

Using SPI to output more than eight bits is possible, as long as you can ensure that TXBUF is always filled.

Your scheme of using 0x7F every second byte becomes unreliable if a delay happens; it might be a better idea to distribute the actual data over two bytes:

1110xxxx xxxx1111
iiisdddd ddddSiii

(i = idle, s = start bit, S = stop bit, d = data)

Then you only have to keep these two bytes together and can allow a pause after them.

  1. Wait for TXBUF empty (TXIFG);
  2. disable interrupts;
  3. write 1st byte to TXBUF;
  4. wait for TXBUF empty;
  5. write 2nd byte to TXBUF;
  6. enable interrupts.

However, check that the SPI module of your MCU actually outputs 1 (the most recent value) when it's idle. It might output the first bit of the last byte instead; in that case, you need to send 0xFF afterwards (or the next valid two-byte combination).

Receiving with SPI might be more dangerous. Any interupt latency will affect the at which you sample the data bits, so you will have a delay that, in practice, is uncontrollable.


Alternatively, you can use a timer output to emulate a UART. Use continuous mode, program a CCR for the time of the next signal edge, and with set or reset output mode as needed. In the interrupt handler, program the following edge (add the bit length to the CCR, and switch set/reset mode, if needed). This is similar to bit-banging, but guarantees the timing as long as you can handle the interrupt for each bit fast enough.

Similarly, you can use a timer for receiving: program a CCR in capture mode on the falling edge. When you get an interrupt, you get the exact time of the edge in the CCR register, and you can then reprogram the CCR for compare mode, triggering in the middle of the respective next bit; in the interrupt handler, the SCCI bit shows the value of the timer input when it was triggered.

\$\endgroup\$
  • \$\begingroup\$ Thanks your idea will work with other family members where 10 bits can be configured. In the MSP430G2553 I now see that USCI_B0 Tx and Rx registers are only byte wide. (I think both byte schemes will be reliable as long as you can ensure no delay.) What do you think about Rx? \$\endgroup\$ – skvery Feb 26 '17 at 10:46
  • \$\begingroup\$ Please post your interrupt driven bit-banging solution as a separate answer. \$\endgroup\$ – skvery Feb 26 '17 at 13:27
  • \$\begingroup\$ I am now further down the line. Using your terminology, you have to do iiiiiisd dddddddS for one stop bit or iiiiisdd ddddddSSfor two to ensure that you can turn to Rx in time. I am sure the very simple iiiiiiis dddddddd iiiiiiis dddddddd Siiiiiii will work when Rx turn around is longer than one character. (remember `i = S' ) \$\endgroup\$ – skvery Feb 28 '17 at 9:19
  • \$\begingroup\$ I now know how to do it, it but concede defeat. I am ordering a development kit with four UARTs! \$\endgroup\$ – skvery Mar 2 '17 at 20:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.