STM32F103C8T6 Configuration Using CubeMX + HAL Library

Open STM32CubeMX and select STM32F103C8T6.

Enable two UART interfaces:

USART1

USART2

Select Asynchronous mode and enable UART interrupts.

Baud rate settings:

Note: Ensure the baud rate settings match the radar and voice module requirements.


UART Data Processing Rd-03D UART Data

The Rd-03D module communicates with external devices via UART (TTL level).

The radar outputs detected target information, including:

By default, the radar operates in single-target detection mode and must be switched to multi-target detection mode for this application.


Data Frame Format

Example data frame:

AA FF 03 00 0E 03 B1 86 10 00 68 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 CC

AA FF 03 00 0E 03 B1 86 10 00 68 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 CC


In this demo, only presence detection is required, so it is sufficient to check whether valid target data exists in the corresponding frame.

6. VC-02 UART Data The VC-02 UART protocol is user-defined. Development resources and documentation can be found on the VC series official website:

https://docs.ai-thinker.com/voice_module 

Below is a custom-defined UART protocol and voice command table. All UART outputs are in hexadecimal format.

7. STM32 Data Processing Logic

This implementation uses flag-based logic to process data, preventing repeated voice announcements when radar data is updated too frequently.

uint8_t RX_BUF[64] = {0};          // Receive buffer

uint8_t RX_count = 0;              // Buffer counter

uint8_t RX_temp;                   // Temporary received byte

 

uint8_t Radar_1 = 0;               // Target 1 flag

uint8_t Radar_2 = 0;               // Target 2 flag

uint8_t Radar_3 = 0;               // Target 3 flag

 

uint8_t Speaker_1 = 0;             // Voice announcement flag for target 1

uint8_t Speaker_2 = 0;             // Voice announcement flag for target 2

uint8_t Speaker_3 = 0;             // Voice announcement flag for target 3

 

uint8_t Single_Target_Detection_CMD[] = {

    0xFD,0xFC,0xFB,0xFA,0x02,0x00,0x80,0x00,0x04,0x03,0x02,0x01

}; // Single-target detection mode command (detects only one target)

 

uint8_t Multi_Target_Detection_CMD[] = {

    0xFD,0xFC,0xFB,0xFA,0x02,0x00,0x90,0x00,0x04,0x03,0x02,0x01

}; // Multi-target detection mode command (detects multiple targets)

 

uint8_t SpeakerCMD_0[5] = {0x5A,0x00,0x00,0x00,0x00}; // No-target voice announcement command

uint8_t SpeakerCMD_1[5] = {0x5A,0x00,0x00,0x00,0x01}; // One-target voice announcement command

uint8_t SpeakerCMD_2[5] = {0x5A,0x00,0x00,0x00,0x02}; // Two-target voice announcement command

uint8_t SpeakerCMD_3[5] = {0x5A,0x00,0x00,0x00,0x03}; // Three-target voice announcement command

 

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) // Callback function, called when one frame of data is received

{

    if (huart == &huart2) {   // UART2 interrupt triggered

        RX_BUF[RX_count++] = RX_temp; // Store received byte into buffer

 

        // Receive VC UART command to query current number of people

        if ((RX_BUF[RX_count - 1] == 0x00) && (RX_BUF[RX_count - 2] == 0xFF)) {

            if ((Radar_3 == 0) && (Radar_2 == 0) && (Radar_1 == 0)) {

                HAL_UART_Transmit(&huart2, (uint8_t *)&SpeakerCMD_0, sizeof(SpeakerCMD_0), 0xFFFF); // Trigger no-target voice announcement

            }

            else if (Radar_3 == 1) {

                HAL_UART_Transmit(&huart2, (uint8_t *)&SpeakerCMD_3, sizeof(SpeakerCMD_3), 0xFFFF); // Trigger three-target voice announcement

            }

            else if (Radar_2 == 1) {

                HAL_UART_Transmit(&huart2, (uint8_t *)&SpeakerCMD_2, sizeof(SpeakerCMD_2), 0xFFFF); // Trigger two-target voice announcement

            }

            else if (Radar_1 == 1) {

                HAL_UART_Transmit(&huart2, (uint8_t *)&SpeakerCMD_1, sizeof(SpeakerCMD_1), 0xFFFF); // Trigger one-target voice announcement

            }

 

            while (HAL_UART_GetState(&huart2) == HAL_UART_STATE_BUSY_TX); // Wait until transmission is complete

 

            memset(RX_BUF, 0x00, sizeof(RX_temp)); // Clear receive buffer

            RX_count = 0;                          // Reset buffer counter

        }

        HAL_UART_Receive_IT(&huart2, &RX_temp, 1); // Continue receiving data on UART2

    }

 

    if (huart == &huart1) {   // UART1 interrupt triggered

        RX_BUF[RX_count++] = RX_temp; // Store received byte into buffer

 

        if ((RX_BUF[RX_count - 1] == 0xCC) && (RX_BUF[RX_count - 2] == 0x55)) {

            // Logic check: trigger voice announcement for target 1

            if ((Radar_1 == 1) && (Speaker_1 == 0)) {

                HAL_UART_Transmit(&huart2, (uint8_t *)&SpeakerCMD_1, sizeof(SpeakerCMD_1), 0xFFFF);

                Speaker_1 = 1;

            }

            // Logic check: trigger voice announcement for target 2

            else if ((Radar_2 == 1) && (Speaker_2 == 0)) {

                HAL_UART_Transmit(&huart2, (uint8_t *)&SpeakerCMD_2, sizeof(SpeakerCMD_2), 0xFFFF);

                Speaker_2 = 1;

            }

            // Logic check: trigger voice announcement for target 3

            else if ((Radar_3 == 1) && (Speaker_3 == 0)) {

                HAL_UART_Transmit(&huart2, (uint8_t *)&SpeakerCMD_3, sizeof(SpeakerCMD_3), 0xFFFF);

                Speaker_3 = 1;

            }

            // Data comparison: no target detected

            else if ((RX_BUF[5] == 0x00) && (RX_BUF[14] == 0x00) && (RX_BUF[22] == 0x00)) {

                Radar_1 = 0;

                Radar_2 = 0;

                Radar_3 = 0;

                Speaker_1 = 0;

                Speaker_2 = 0;

                Speaker_3 = 0;

            }

            // Data comparison: one target detected

            else if ((RX_BUF[5] != 0x00) && (RX_BUF[14] == 0x00) && (RX_BUF[22] == 0x00)) {

                Radar_1 = 1;

                Radar_2 = 0;

                Radar_3 = 0;

                Speaker_2 = 0;

                Speaker_3 = 0;

            }

            // Data comparison: two targets detected

            else if ((RX_BUF[5] != 0x00) && (RX_BUF[14] != 0x00) && (RX_BUF[22] == 0x00)) {

                Radar_1 = 0;

                Radar_2 = 1;

                Radar_3 = 0;

                Speaker_1 = 0;

                Speaker_3 = 0;

            }

            // Data comparison: three targets detected

            else if ((RX_BUF[5] != 0x00) && (RX_BUF[14] != 0x00) && (RX_BUF[22] != 0x00)) {

                Radar_1 = 0;

                Radar_2 = 0;

                Radar_3 = 1;

                Speaker_1 = 0;

                Speaker_2 = 0;

            }

 

            // HAL_UART_Transmit(&huart1, (uint8_t *)&RX_BUF, RX_count, 0xFFFF); // Send buffer data via UART (optional debug)

 

            while (HAL_UART_GetState(&huart2) == HAL_UART_STATE_BUSY_TX); // Wait until transmission is complete

            memset(RX_BUF, 0x00, sizeof(RX_temp)); // Clear receive buffer

            RX_count = 0;                          // Reset buffer counter

        }

        HAL_UART_Receive_IT(&huart1, &RX_temp, 1); // Continue receiving data on UART1

    }

}

8. Source Code & Firmware

Source code repository:

https://e.coding.net/axk/stm32_rd-03/STM32_Rd-03D_VC-02.git