I'm trying to establish UART communication. I can send data from CC430F6137 to other MCU .However I couldn't handle receive operation. I'm sure that other MCU sends the data through UART Tx pin , but I couldn't get this datas from CC430 Rx pin.
My code is that :
#include <stdio.h>
#include <msp430.h>
#include "cc430x613x.h"
char buffer_0[5] ;
char terminal_read();
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
UART_open();
UCA0IE |= UCRXIE ;
while(1)
{
terminal_read();
// __delay_cycles(1e5);
}
return 0;
}
char terminal_read()
{
char c ;
while (!(UCA0IFG & UCRXIFG));
c = UCA0RXBUF ;
printf("%c" , &c);
return UCA0RXBUF;
}
void terminal_write(char *info)
{
unsigned int i;
unsigned int len = strlen(info) ;
for(i=0;i<len;i++)
{
UCA0TXBUF=info[i];
__delay_cycles(10000);
}
}
void UART_open()
{
P1SEL |= BIT5 + BIT6;
//UART Settings
UCA0CTL1 |= UCSWRST;
UCA0CTL1 |= UCSSEL0 ; // ACLK
UCA0BR0=3; //UCA0BR0 = 3 ; //32Khz / 9600 –>> 3
UCA0BR1=0; //UCA0BR1=0; // BAUD 9600; ( UCABR1 * 256 ) + UCABR0 = UCABRx see "slau259e.pdf"
UCA0MCTL=UCBRS0 + UCBRS1 ; // see "slau259e.pdf" page 602 //
//UCA0MCTL =| BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0 |
// |------- UCBRFx --------------|----UCBRSx----------|UCOS16|
// for 9600 baudrate at 32kHz UCBRFx = 0 , UCBRSx = 3 , UCOS16 = 0
// | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 |
// 0b00000110 = 0x06 = 6
UCA0CTL1 &=~ UCSWRST;//
// UCA0CTL1 |= UCDORM;
}
void UART_close()
{
P1SEL &= ~(BIT5 + BIT6);
P1DIR |= BIT5 + BIT6;
P1OUT &= ~(BIT5 + BIT6);
UCA0CTL1 |= UCSWRST;
UCA0CTL1 &=~ UCDORM;
}
char* String_int(int data)
{
char* ret_data;
ret_data = ltoa(data , buffer_0 , 10 );
return ret_data;
}
What's wrong with my code? I always read the UCRXIFG as '0'. So 'terminal_read' function always stuck on this line.
Since you are polling for the interrupt flag in the terminal_read() function, then you don't need to enable interrupt with UCA0IE |= UCRXIE; because that will cause the CPU to go to the interrupt vector, which your code doesn't provide. Instead, remove the UCA0IE |= UCRXIE; and continue polling.
Also, the printf() will go to the terminal of the Debug window only if you have the JTAG debugger attached, otherwise it could get stuck. I agree with Peter that it could get stuck here if you don't have the debugger attached. Try removing that and replace with an LED blinker so you know the terminal_read() isn't getting stuck.
Related
Hi Everyone and thank you for your time.
I have been working on interfacing the STM32f446RE Nucleo board with the TLV5628 8 Bit Octal Serial DAC. I have ran into multiple issues, but the current issue has been one of two things:
1) The data and clock lines showing the exact same information
or
2) The data line showing information, but nothing on the clock line.
Regardless, the information coming out is completely incorrect.
Here is my setup code:
void SPI_INIT(void){
// Enable clocks for C
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;
// SPI GPIO
GPIOC->MODER |= 2 << 3*2; // PC3 data pin
GPIOC->MODER |= 2 << 7*2; // PC7 clock pin
GPIOC->MODER |= 1 << 2*2; //pc2 load
GPIOC->MODER |= 1 << 4*2; //pc4 ldac - probably set low permanently
// Pins default to push-pull
// set all to high speed
GPIOC->OSPEEDR |= (3 << 2*2) | (3 << 3*2) | (3 << 4*2) | (3 << 7*2);
GPIOC->AFR[0] |= 5<< 6*2; // Alt func 5 pc3 - SPI2
GPIOC->AFR[0] |= 5 << 7*2; // Alt func 5 pc7 - SPI2
// SPI Setup
RCC->APB1ENR |= RCC_APB1ENR_SPI2EN; // Enable SPI Clock
RCC->APB1RSTR |= RCC_APB1RSTR_SPI2RST; // reset SPI2
RCC->APB1RSTR &= ~RCC_APB1RSTR_SPI2RST;// clear the reset
// Control Register 1
SPI2->CR1 &= ~SPI_CR1_SPE; // Disable SPI
SPI2->CR1 |= SPI_CR1_MSTR; // master mode
SPI2->CR1 &= ~SPI_CR1_RXONLY; // transmit, 0 == full duplex
SPI2->CR1 &= ~SPI_CR1_DFF; // 8 bit format
SPI2->CR1 &= ~SPI_CR1_LSBFIRST; // MSB first
SPI2->CR1 &= ~SPI_CR1_CPOL;// low polarity, so 0 when idle
SPI2->CR1 |= 4 << 3; // (180M/4)/32 = 1.41 MHz
SPI2->CR1 |= SPI_CR1_CPHA; // first edge, look in data sheet
//Questionable settings
// Biderectional data line
SPI2->CR1 |= SPI_CR1_BIDIMODE; // 1/17/2019 --> Check to see if this fixes something
SPI2->CR1 |= SPI_CR1_BIDIOE; // idk if i need this
// CRC Polynomial Register
SPI2->CRCPR = 10;
// Control Register 2
SPI2->CR2 |= 1<<2; // SS output enabled
SPI2->CR1 |= SPI_CR1_SPE; // enable, has to be last
}
And here is my SPI Write code:
void SPI_Write(int dacSelect, int adcData){
while((SPI2->SR & SPI_SR_TXE) != 0);
GPIOC->ODR |= 1 << 2; // load set high to read data
SPI2->DR = dacArray[dacSelect]; // send address
SPI2->DR = adcData; // send adc data
while((SPI2->SR & SPI_SR_BSY) == SPI_SR_BSY);
GPIOC->ODR &= ~(1 << 2); // Send load low to load data
Delay(10); // short delay
GPIOC->ODR |= 1 << 2;
}
You can use STMCubeMX to generate codes for STM microprocessors and boards. Following code blocks are generated from STM32ubeMX for STM32F4. You should change baudrate for your sensor.
SPI_HandleTypeDef hspi;
SPI_HandleTypeDef SpiHandle;
void Spi_Initialize(void)
{
/*##-1- Configure the SPI peripheral #######################################*/
/* Set the SPI parameters */
SpiHandle.Instance = SPI2;
SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
SpiHandle.Init.Direction = SPI_DIRECTION_2LINES;
SpiHandle.Init.CLKPhase = SPI_PHASE_1EDGE;
SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW;
SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT;
SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB;
SpiHandle.Init.TIMode = SPI_TIMODE_DISABLE;
SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
SpiHandle.Init.CRCPolynomial = 7;
SpiHandle.Init.NSS = SPI_NSS_SOFT;
SpiHandle.Init.Mode = SPI_MODE_MASTER;
if(HAL_SPI_Init(&SpiHandle) != HAL_OK)
{
while(1){};
}
}
void Spi_Read(void )
{
uint8_t SpiData[2];
uint8_t tempmessage = 8;
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_8,RESET); // CS pin
HAL_SPI_TransmitReceive(&hspi,&tempmessage,SpiData,2,5000); // Read Data
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_8,SET); // CS Pin
}
void Spi_Write(uint8_t *Data, uint8_t size)
{
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_8,RESET); // CS pin
HAL_SPI_Transmit(&hspi, Data, size, 5000); // Write Data
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_8,SET); // CS Pin
}
I'm running some tests on STM32L152 by trying to control a DC motor speed by selecting 3 different speeds using a push button, as following:
ideal mode, motor is off.
push button pressed, motor runs at speed-1
push button pressed again, motor runs at speed-2
push button pressed again, motor stops.
I've already tried to run the motor directly by setting CCR1 (TIM4), and it works perfectly. so I believe the only issue is with the push button part. here's the code:
#include <stdio.h>
#include "stm32l1xx.h" // Keil::Device:Startup
// initialization of GPIOB, GPIOA & PWM/TIM4
void GPIO_Init()
{
// initialization of GPIOB
RCC->AHBRSTR |= RCC_AHBRSTR_GPIOBRST; /* Reset GPIOB clock */
RCC->AHBENR |= RCC_AHBENR_GPIOBEN; /* Enable GPIOB clock*/
GPIOB->MODER &= ~(0x03 << (2 * 6)); /* Clear bit 12 & 13 Output mode*/
GPIOB->MODER |= 0x01 << (2 * 6); /* set as Output mode*/
GPIOB->OSPEEDR &= ~(0x03 << (2 * 6)); /* 40 MHz speed */
GPIOB->OSPEEDR |= 0x03 << (2 * 6); /* 40 MHz speed*/
GPIOB->PUPDR &= ~(1 << 6); /* NO PULL-UP PULL-DOWN*/
GPIOB->OTYPER &= ~(1 << 6); /* PUSH-PULL*/
GPIOB->AFR[0] |= 0x2 << (4 * 6);
// initialization of GPIOA
RCC->AHBRSTR |= RCC_AHBRSTR_GPIOARST; /* Reset GPIOA clock*/
RCC->AHBENR |= RCC_AHBENR_GPIOAEN; /* Enable GPIOA clock*/
GPIOA->MODER &= ~(0x03); /* Clear & set as input*/
GPIOA->OSPEEDR &= ~(0x03); /* 2 MHz speed */
GPIOA->OSPEEDR |= 0x01; /* 2 MHz speed */
GPIOA->PUPDR &= ~(0x03); /* No PULL-UP/DOWN */
GPIOA->OTYPER &= ~(0x1); /* PUSH-PULL */
//initialization of PWM & TIM4
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
TIM4->PSC = 100;
TIM4->ARR = 414; // F=2.097MHz , Fck= 2097000/(100+1)= 20.762KHz, Tpwm = 0.02, ARR= (Fck x Tpwm)-1
TIM4->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; // 111: PWM mode 1
TIM4->CCMR1 |= TIM_CCMR1_OC1PE;
TIM4->CR1 |= TIM_CR1_ARPE;
TIM4->CCER |= TIM_CCER_CC1E;
TIM4->EGR |= TIM_EGR_UG;
TIM4->SR &= ~TIM_SR_UIF;
TIM4->DIER |= TIM_DIER_UIE;
TIM4->CR1 |= TIM_CR1_CEN;
}
// Delay conf
void setSysTick(void)
{
// ---------- SysTick timer (1ms) -------- //
if (SysTick_Config(SystemCoreClock / 1000))
{
// Capture error
while (1)
{
};
}
}
volatile uint32_t msTicks; //counts 1ms timeTicks
void SysTick_Handler(void)
{
msTicks++;
}
static void Delay(__IO uint32_t dlyTicks)
{
uint32_t curTicks = msTicks;
while ((msTicks - curTicks) < dlyTicks);
}
int returnVal = 0;
int updatedpress = 0;
int buttonpress() // function to check & add, if the pushbutton is pressed
{
if (GPIOA->IDR & GPIO_IDR_IDR_0) //condition: if PA0 is set
{
Delay(500); // avoid debouncing
if (GPIOA->IDR & GPIO_IDR_IDR_0) //confirm condition: if PA0 is set
{
returnVal = 1 + updatedpress;
while (GPIOA->IDR & GPIO_IDR_IDR_0)
{
}
}
}
return returnVal;
}
int main(void)
{
GPIO_Init();
setSysTick();
while (1)
{
int buttonpress();
updatedpress = returnVal;
if (updatedpress == 1)
TIM4->CCR1 = 30;
else if (updatedpress == 2)
TIM4->CCR1 = 37;
else if (updatedpress == 3)
TIM4->CCR1 = 46;
else if (updatedpress > 3)
returnVal = 0;
}
}
When I run the code, nothing works physiclly. I tried to run the debugger and I found that it exits the buttonpress function immedtialy after reaching
if(GPIOA->IDR & GPIO_IDR_IDR_0)
Any idea why it doesn't work as it should?
The GPIO peripherals are held in reset, you should clear the reset bits:
RCC->AHBRSTR |= RCC_AHBRSTR_GPIOBRST
RCC->AHBRSTR &= ~RCC_AHBRSTR_GPIOBRST
/* ... */
RCC->AHBRSTR |= RCC_AHBRSTR_GPIOARST;
RCC->AHBRSTR &= ~RCC_AHBRSTR_GPIOARST;
Ok it worked, and here are the corrections made:
1/ PB6 (which is connected to the DC motor) was mistakenly set as output. changed to Alternate Function.
2/ If-Conditions used for comparing the number of button-press and select motor speed is shifted to a separate function called runmotor
3/ The read instruction if(GPIOA->IDR & 0x0001) is moved into the while loop within the main function to ensure a continuous check of the pushbutton condition.
4/ Reset of GPIOs are cleared, as advised by #berendi
here's the updated code:
#include <stdio.h>
#include "stm32l1xx.h" // Keil::Device:Startup
// initialization of GPIOB, GPIOA & PWM/TIM4
void GPIO_Init(){
// initialization of GPIOB
RCC->AHBRSTR |= RCC_AHBRSTR_GPIOBRST; /* Reset GPIOB clock*/
RCC->AHBRSTR &= ~RCC_AHBRSTR_GPIOBRST; /* Clear Reset */
RCC->AHBENR |= RCC_AHBENR_GPIOBEN; /* Enable GPIOB clock*/
GPIOB->MODER &= ~(0x03 << (2*6)); /* Clear bit 12 & 13 */
GPIOB->MODER |= 0x02 << (2*6); /* set as Alternate function*/
GPIOB->OSPEEDR &= ~(0x03<< (2*6)); /* 40 MHz speed*/
GPIOB->OSPEEDR |= 0x03<< (2*6); /* 40 MHz speed */
GPIOB->PUPDR &= ~(1<<6); /* NO PULL-UP PULL-DOWN*/
GPIOB->OTYPER &= ~(1<<6); /* PUSH-PULL*/
GPIOB->AFR[0] |= 0x2 << (4*6);
// initialization of GPIOA
RCC->AHBRSTR |= RCC_AHBRSTR_GPIOARST; /* Reset GPIOA clock */
RCC->AHBRSTR &= ~RCC_AHBRSTR_GPIOARST; /* Clear Reset */
RCC->AHBENR |= RCC_AHBENR_GPIOAEN; /* Enable GPIOA clock */
GPIOA->MODER &= ~(0x03); /* Clear & set as input */
GPIOA->OSPEEDR &= ~(0x03); /* 2 MHz speed */
GPIOA->OSPEEDR |= 0x01; /* 2 MHz speed */
GPIOA->PUPDR &= ~(0x03); /* reset PULL-DOWN */
GPIOA->OTYPER &= ~(0x1); /* PUSH-PULL */
//initialization of PWM & TIM4
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
TIM4->PSC = 100;
TIM4->ARR = 414; // F=2.097MHz , Fck= 2097000/(100+1)= 20.762KHz, Tpwm = 0.02, ARR= (Fck x Tpwm)-1
TIM4->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; // 111: PWM mode 1
TIM4->CCMR1 |= TIM_CCMR1_OC1PE;
TIM4->CR1 |= TIM_CR1_ARPE;
TIM4->CCER |= TIM_CCER_CC1E;
TIM4->EGR |= TIM_EGR_UG;
TIM4->SR &= ~TIM_SR_UIF;
TIM4->DIER |= TIM_DIER_UIE;
TIM4->CR1 |= TIM_CR1_CEN;
}
void setSysTick(void){
// ---------- SysTick timer (1ms) -------- //
if (SysTick_Config(SystemCoreClock / 1000)) {
// Capture error
while (1){};
}
}
volatile uint32_t msTicks; //counts 1ms timeTicks
void SysTick_Handler(void) {
msTicks++;
}
static void Delay(__IO uint32_t dlyTicks){
uint32_t curTicks = msTicks;
while ((msTicks - curTicks) < dlyTicks);
}
int buttonpress=0;
static void runmotor(void)
{
if (buttonpress ==1){
TIM4->CCR1 = 30;
return;
}
if (buttonpress ==2){
TIM4->CCR1 = 37;
return;
}
if (buttonpress ==3){
TIM4->CCR1 = 46;
return;
}
if (buttonpress > 3){
TIM4->CCR1 = 0;
buttonpress = 0;
return;
}
}
int main(void){
GPIO_Init();
setSysTick();
while (1){
if(GPIOA->IDR & 0x0001)
{
Delay(5);
if(GPIOA->IDR & 0x0001)
buttonpress = buttonpress + 1;
runmotor();
}
}
}
I have a problem to communicate from an Atmega3216PU to a at42qt2100.
The datasheets are: Atmega32PU16 and AT42QT2100
This is my code:
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#define F_CPU 16000000
#define UART_BAUD_RATE 9600
#define UART_BAUD_REGISTERS (((F_CPU / (UART_BAUD_RATE * 16UL))) - 1)
int printCHAR(char character, FILE *stream)
{
while ((UCSRA & (1 << UDRE)) == 0) {};
UDR = character;
return 0;
}
FILE uart_str = FDEV_SETUP_STREAM(printCHAR, NULL, _FDEV_SETUP_RW);
void setup(){
// Init SIO
UCSRB |= (1 << RXEN) | (1 << TXEN);
UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1);
UBRRL = UART_BAUD_REGISTERS;
fprintf(&uart_str, "");
stdout = &uart_str;
printf("");
//Init spi
//set MOSI, SCK and SS output, all others input
DDRB |= (1<<DDB7)|(1<<DDB5)|(1<<DDB4);
SPCR |= (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0)|(1<<CPHA)|(1<<CPOL);
}
void loop(){
uint8_t data = 0b01000000; //Sending this sequence should return device id
printf("Sending: %d \n",data);
_delay_ms(10000);
PORTB &= 0b11101111; // SS auf LOW!! (Pin4)
SPDR = data;
while(!(SPSR & (1<<SPIF)));
PORTB |= (1<<PB4); // SS auf HIGH!! (Pin4)
printf("Receiving: %d \n",SPDR);
_delay_ms(10000);
}
void main(){
setup();
while(1){
loop();
}
}
I should get an answer from the at42qt2100 with the device id 108 but i always get 0. This ist the output: Sending: 64 Receiving: 0
Does anybody see a misconfiguration?
I did a quick overview of the AT42QT2100 datasheet that you reference and I see a couple of problems right away:
After SS is set low, the host must wait >2us (in Free Run mode) before starting SCK. You are immediately initiating a SPI transfer and, if you are running a 16MHz, that means you may be starting the transmission as soon as 62.5ns after setting SS low.
The datasheet also says that the host must send 3 data bytes within 10ms or the transaction will be treated as an error and the communication exchange will be reset. You are sending 1 byte and then waiting 20s before sending the next byte.
The datasheet says that the device settings become active after the 3 bytes have been sent. That means that 3 more bytes must be sent to get the response to your command.
You should be doing something more along the lines of this:
#define NUM_DATA_BYTES 3
void loop(){
uint8_t sendData[NUM_DATA_BYTES] =
{
0b01000000, /* Device Version Command and default values. */
0b00000000, /* Default Value for Byte 2. */
0b11000000, /* Default Value for Byte 3. */
};
uint8_t receiveData[NUM_DATA_BYTES] = { 0 };
uint8_t i;
PORTB &= 0b11101111; // SS auf LOW!! (Pin4)
/* Ensure that >2us delay requirement is met. Although, the
for() loop below will probably introduce enough delay. */
_delay_ms(1);
/* Send command data. */
for (i = 0; i < NUM_DATA_BYTES; i++)
{
SPDR = sendData[i];
while(!(SPSR & (1<<SPIF)));
}
PORTB |= (1<<PB4); // SS auf HIGH!! (Pin4)
/* Delay here may be unnecessary, but it ensures that timing
issues do not occur. */
_delay_ms(1);
PORTB &= 0b11101111; // SS auf LOW!! (Pin4)
_delay_ms(1);
/* Receive device response data. */
for (i = 0; i < NUM_DATA_BYTES; i++)
{
SPDR = sendData[i];
while(!(SPSR & (1<<SPIF)));
receiveData[i] = SPDR;
printf("Receiving byte %d: %d \n", (i + 1), receiveData[i]);
}
PORTB |= (1<<PB4); // SS auf HIGH!! (Pin4)
_delay_ms(10000);
}
I am sure this code is not perfect, but it should help to get you on the right track. Good luck!
I am trying to send data from the Msp430fr5969 Launchpad to the rn-52-ek so it can pass the data along through bluetooth.
#include <msp430.h>
void uartSend(unsigned char *pucData, unsigned char ucLength)
{
while(ucLength>0)
{
// Wait for TX buffer to be ready for new data
while(!(UCA1IFG & UCTXIFG));
// Push data to TX buffer
UCA1TXBUF = *pucData;
// Update variables
ucLength--;
pucData++;
}
}
void initUART()
{
/* Place UCA0 in Reset to be configured */
UCA0CTL1 = UCSWRST;
//Set BRCLK = SMCLK
UCA0CTL1 |= UCSSEL_2;
//Values found using table for 16Mhz and 115200 baudrate
UCA0BR0=8;
UCA0BR1=0;
UCA0MCTLW = 0xF7 << 8;
UCA0MCTLW |= 10 << 4;
UCA0MCTLW |= UCOS16;
//UCA0 out of reset
UCA0CTL1 &= ~UCSWRST;
}
int main(void) {
// disable watchdog timer
//------------------------
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
initUART();
unsigned char sendString[] = "Banana";
unsigned char length=6;
while(1)
{
uartSend(sendString,length);
}
return 0;
}
Nothing is happening when I run the above code, not even reading anything on the multimeter. What am I missing?
I know there are some bad practices, I just want to get it working and I'll add the interrupt based sending later.
You should set Port 2.5 as Tx for the UART
I am attempting to program two MSP430s to essentially instant message through PuTTY, but cannot figure out how to get typed information onto the MSP430 without the debugger. I'm using CCS and it's an MSP430 F2274. I have one program in which the user inputs in morse code on the button on one MSP430 that successfully outputs to PuTTY off another MSP430 via the following method.
void displayString(char array[], char size) {
WDTCTL = WDTPW + WDTHOLD; // Disable WDT
DCOCTL = CALDCO_8MHZ; // Load 8MHz constants
BCSCTL1 = CALBC1_8MHZ; //
P3SEL |= 0x30; // P3.4,5 = USCI_A0 TXD/RXD
UCA0CTL1 |= UCSSEL_2; // SMCLK
UCA0BR0 = 0x41; // 8MHz 9600
UCA0BR1 = 0x03; // 8MHz 9600
UCA0MCTL = UCBRS1; // Modulation UCBRSx = 2
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state
int count;
for(count=0; count<size; count++){
while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready?
UCA0TXBUF = array[count]; // TX -> RXed character
}
}
Can someone send code that does the reverse (types information onto MSP430) with a similar setup? thanks.
I used picocom:
$ picocom -r -b 9600 /dev/ttySxxxx
Code for UART initialization:
void uart_setup()
{
// Configure UART pins
P2SEL1 |= BIT0 + BIT1;
P2SEL0 &= ~(BIT0 + BIT1);
// Configure UART 0
UCA0CTL1 |= UCSWRST; // perform reset
UCA0CTL1 = UCSSEL_1; // Set ACLK = 32768 as UCBRCLK
UCA0BR0 = 3; // 9600 baud
UCA0BR1 = 0;
UCA0MCTLW |= 0x5300; // 32768/9600 - INT(32768/9600)=0.41
// UCBRSx value = 0x53 (See UG)
UCA0CTL1 &= ~UCSWRST; // release from reset
//UCA0IE |= UCRXIE; // Enable RX interrupt
}
Override putchar():
int putchar(int c)
{
if (c == '\n') putchar('\r');
while (!(UCA0IFG & UCTXIFG));
UCA0TXBUF = c;
return 0;
}
And then you can simple call printf(...) to output text from the MSP430 to the serial port.
If you still want to leave putchar() and prtinf() for debug purpose - printing into debug window of debugger, then you can have separate read function:
unsigned char ReadByteUCA_UART(void)
{
//while ((IFG2&UCA0RXIFG)==0); // wait for RX buffer (full)
while(UCA0STAT&UCBUSY);
return (UCA0RXBUF);
}