Home | Projects | Notes > MCU Peripheral Drivers > USART Application 2: Tx Rx (Interrupt) (usart_02_tx_rx_interrupt.c
)
usart_02_tx_rx_interrupt.c
)
USART communication between STM32 Discovery board and Arduino Uno board.
Write a program for STM32 board which transmits different messages to the Arduino board over UART communication.
For every message the STM32 board sends, the Arduino code will change the case of alphabets (lower case to upper case and vice versa) and sends the message back to the STM32 board.
The STM32 board shall capture the response from the Arduino board and display it on the STM32CubeIDE data console.
Write a program to send some message over USART from STM32 board to Arduino board. The Arduino board will display the message sent from the STM32 board on the Arduino IDE serial monitor
Baudrate - 115200 bps
Frame format - 1 stop bit, 8-bit user data, no parity
Arduino board
STM32 board
Logic level converter
Breadboard and jumper wires
To work around the voltage level difference, a logic level shifter will be necessary.
printf()
to Print Messages in STM32CubeIDE Console
For this application, USART communication lines Tx, Rx will be used. Find out the GPIO pins over which USART can communicate! Look up the "Alternate function mapping" table in the datasheet.
USART2_TX
USART2_RX
Be careful not to directly supply 5 volts to the STM32 board pins when the board is not powered up as they may be damaged. When the logic level shifter is used, you don't need to worry about this issue.
To analyze the communication with the logic analyzer, connect the channels as follows:
CH0 - STM32 USART Tx
CH1 - STM32 USART Rx
GND - Common GND of the bread board
Sketch name: 002UARTTxString.ino
You don't need to write an application for Arduino board. It is already provided as a sketch.
As soon as you upload this sketch to the Arduino board, it will operate as a UART counterpart.
If you face an issue while uploading the sketch to the Arduino board, simply remove the Rx line, upload the sketch again and connect back the Rx line.
usart_02_tx_rx_interrupt.c
Path: Project/Src/
xxxxxxxxxx
2261/*******************************************************************************
2 * File : usasrt_02_tx_rx_interrupt.c
3 * Brief : Program to test USART Tx and Rx (both blocking-based and
4 * interrupt-based) functionalities.
5 * Test all possible cases using blocking/interrupt-based Tx and Rx
6 * APIs.
7 * Author : Kyungjae Lee
8 * Date : Jun 21, 2023
9 ******************************************************************************/
10
11/**
12 * Pin selection for USART communication
13 *
14 * USART_TX - PA2 (AF7)
15 * USART_RX - PA3 (AF7)
16 */
17
18/* strlen() */
19/* printf() */
20
21
22/* Global variables */
23
24/* Messages to transmit to Arduino board */
25char* msg[3] = {"hello world", "my name is", "kyungjae lee!"};
26/* Buffer to stored the messages to be received by the Arduino board */
27char rxBuff[1024];
28/* USART2 handle structure */
29USART_Handle_TypeDef USART2Handle;
30/* Flag that indicates completion of reception */
31uint8_t rxCmplt = RESET;
32
33/**
34 * delay()
35 * Brief : Spinlock delays the program execution
36 * Param : None
37 * Retval : None
38 * Note : N/A
39 */
40void delay(void)
41{
42 /* Appoximately ~200ms delay when the system clock freq is 16 MHz */
43 for (uint32_t i = 0; i < 500000 / 2; i++);
44} /* End of delay */
45
46/**
47 * USART2_PinsInit()
48 * Brief : Initializes and configures GPIO pins to be used as USART2 pins
49 * Param : None
50 * Retval : None
51 * Note : N/A
52 */
53void USART2_PinsInit(void)
54{
55 GPIO_Handle_TypeDef USART2Pins;
56
57 /* Zero-out all the fields in the structures (Very important! USASRT2Pins
58 * is a local variables whose members may be filled with garbage values before
59 * initialization. These garbage values may set (corrupt) the bit fields that
60 * you did not touch assuming that they will be 0 by default. Do NOT make this
61 * mistake!
62 */
63 memset(&USART2Pins, 0, sizeof(USART2Pins));
64
65 USART2Pins.pGPIOx = GPIOA;
66 USART2Pins.GPIO_PinConfig.GPIO_PinMode = GPIO_PIN_MODE_ALTFCN;
67 USART2Pins.GPIO_PinConfig.GPIO_PinOutType = GPIO_PIN_OUT_TYPE_PP;
68 USART2Pins.GPIO_PinConfig.GPIO_PinPuPdControl = GPIO_PIN_PU;
69 USART2Pins.GPIO_PinConfig.GPIO_PinAltFcnMode = 7;
70 USART2Pins.GPIO_PinConfig.GPIO_PinSpeed = GPIO_PIN_OUT_SPEED_HIGH;
71
72 /* Tx */
73 USART2Pins.GPIO_PinConfig.GPIO_PinNumber = GPIO_PIN_2;
74 GPIO_Init(&USART2Pins);
75
76 /* Rx */
77 USART2Pins.GPIO_PinConfig.GPIO_PinNumber = GPIO_PIN_3;
78 GPIO_Init(&USART2Pins);
79} /* End of USART2_PinsInit */
80
81/**
82 * USART2_Init()
83 * Brief : Initializes USART2 handle
84 * Param : None
85 * Retval : None
86 * Note : N/A
87 */
88void USART2_Init(void)
89{
90 USART2Handle.pUSARTx = USART2;
91 USART2Handle.USART_Config.USART_Baud = USART_STD_BAUD_115200;
92 USART2Handle.USART_Config.USART_HWFlowControl = USART_HW_FLOW_CTRL_NONE;
93 USART2Handle.USART_Config.USART_Mode = USART_MODE_TXRX;
94 USART2Handle.USART_Config.USART_NumOfStopBits = USART_STOPBITS_1;
95 USART2Handle.USART_Config.USART_WordLength = USART_WORDLEN_8BITS;
96 USART2Handle.USART_Config.USART_ParityControl = USART_PARITY_DISABLE;
97
98 USART_Init(&USART2Handle);
99} /* End of USART2_Init */
100
101/**
102 * GPIO_ButtonInit()
103 * Brief : Initializes a GPIO pin for button
104 * Param : None
105 * Retval : None
106 * Note : N/A
107 */
108void GPIO_ButtonInit(void)
109{
110 GPIO_Handle_TypeDef GPIOBtn;
111
112 /* Zero-out all the fields in the structures (Very important! GPIOBtn
113 * is a local variables whose members may be filled with garbage values before
114 * initialization. These garbage values may set (corrupt) the bit fields that
115 * you did not touch assuming that they will be 0 by default. Do NOT make this
116 * mistake!
117 */
118 memset(&GPIOBtn, 0, sizeof(GPIOBtn));
119
120 /* GPIOBtn configuration */
121 GPIOBtn.pGPIOx = GPIOA;
122 GPIOBtn.GPIO_PinConfig.GPIO_PinNumber = GPIO_PIN_0;
123 GPIOBtn.GPIO_PinConfig.GPIO_PinMode = GPIO_PIN_MODE_IN;
124 GPIOBtn.GPIO_PinConfig.GPIO_PinSpeed = GPIO_PIN_OUT_SPEED_HIGH; /* Doesn't matter */
125 //GPIOBtn.GPIO_PinConfig.GPIO_PinOutType = GPIO_PIN_OUT_TYPE_PP; /* N/A */
126 GPIOBtn.GPIO_PinConfig.GPIO_PinPuPdControl = GPIO_PIN_NO_PUPD;
127 /* External pull-down resistor is already present (see the schematic) */
128 GPIO_Init(&GPIOBtn);
129} /* End of GPIO_ButtonInit */
130
131
132int main(int argc, char *argv[])
133{
134 printf("Application Running\n");
135
136 uint32_t cnt = 0;
137
138 /* Initialize GPIO pin for button */
139 GPIO_ButtonInit();
140
141 /* Initialize USART2 pins */
142 USART2_PinsInit();
143
144 /* Initialize USART2 peripheral */
145 USART2_Init();
146
147 /* Enable USART2 interrupts */
148 USART_IRQInterruptConfig(IRQ_NO_USART2, ENABLE);
149
150 /* Enable USART2 peripheral */
151 USART_PeriControl(USART2, ENABLE);
152
153 while (1)
154 {
155 /* Wait until button is pressed */
156 while (!GPIO_ReadFromInputPin(GPIOA, GPIO_PIN_0));
157
158 /* Introduce debouncing time for button press */
159 delay();
160
161 /* Next message index; make sure that cnt value doesn't cross 2 */
162 cnt %= 3;
163
164 /* Enable Rx interrupt */
165 while (USART_RxInterrupt(&USART2Handle, (uint8_t *)rxBuff, strlen(msg[cnt])) != USART_READY);
166
167 /* Send the message indexed by cnt using interrupt based transmission */
168 USART_TxInterrupt(&USART2Handle, (uint8_t *)msg[cnt], strlen(msg[cnt]));
169
170 printf("Tx message: %s\n", msg[cnt]);
171
172 /* Wait until all the bytes are received from the Arduino board.
173 * When all the bytes are received rxCmplt will be SET in application
174 * callback.
175 */
176 while (rxCmplt != SET);
177
178 /* Add terminating null character. Otherwise %s fails when printing. */
179 rxBuff[strlen(msg[cnt])] = '\0';
180
181 /* Print the received message from Arduino */
182 printf("Rx message: %s\n", rxBuff);
183
184 /* Invalidate the rxCmplt flag */
185 rxCmplt = RESET;
186
187 /* Move on to the next message indexed in msg[] */
188 cnt++;
189 }
190
191 return 0;
192} /* End of main */
193
194/**
195 * USART2_IRQHandler()
196 * Brief : Handles USART IRQ
197 * Param : None
198 * Retval : None
199 * Note : This function calls 'USART_IRQHandling()' function which
200 * implements the actual event IRQ handling functionality.
201 */
202void USART2_IRQHandler(void)
203{
204 USART_IRQHandling(&USART2Handle);
205} /* End of USART2_IRQHandler */
206
207/**
208 * USART_ApplicationEventCallback()
209 * Brief : Notifies the application of the event occurred
210 * Param : @pUSARTHandle - pointer to USART handle structure
211 * @appEvent - USART event occurred
212 * Retval : None
213 * Note : Contents of this function depends on the USART transactions used
214 * in the application.
215 */
216void USART_ApplicationEventCallback(USART_Handle_TypeDef *pUSARTHandle, uint8_t appEvent)
217{
218 if (appEvent == USART_EV_RX_CMPLT)
219 {
220 rxCmplt = SET;
221 }
222 else if (appEvent == USART_EV_TX_CMPLT)
223 {
224 ;
225 }
226} /* End of USART_ApplicationEventCallback */
002UARTTxString.ino
)xxxxxxxxxx
301void setup() {
2 Serial.begin(115200);
3
4 // Define the LED pin as Output
5 pinMode (13, OUTPUT);
6
7 // Serial.println("Arduino Case Converter program running");
8 // Serial.println("-------------------------------------");
9}
10
11char changeCase(char ch)
12{
13 if (ch >= 'A' && ch <= 'Z')
14 ch = ch + 32;
15 else if (ch >= 'a' && ch <= 'z')
16 ch = ch - 32;
17
18 return ch;
19}
20void loop() {
21
22 digitalWrite(13, LOW);
23 //wait until something is received
24 while(! Serial.available());
25 digitalWrite(13, HIGH);
26 //read the data
27 char in_read=Serial.read();
28 //print the data
29 Serial.print(changeCase(in_read));
30}
The following snapshots are taken using the Logic Analyzer.