stm32 dual machine (f1 and f4) serial communication sends multi-byte symbol number

When I looked for serial port communication information on the Internet, most of it was communication between the host computer and the board. I rarely saw communication between two computers. I will record my thoughts in this article and hope it will be helpful.

Interface connection: Select serial port one for f103, select serial port three for f429 (the ground wire must be connected!)

f103c8t6 sender

f103 sending end serial port configuration

void uart_init(u32 bound){
  //GPIO port settings
  GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
\t 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //Enable USART1, GPIOA clock
  
//USART1_TX GPIOA.9
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //Multiplex push-pull output
  GPIO_Init(GPIOA, & amp;GPIO_InitStructure);//Initialize GPIOA.9
   
  //USART1_RX GPIOA.10 initialization
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//Floating input
  GPIO_Init(GPIOA, & amp;GPIO_InitStructure);//Initialize GPIOA.10

  //Usart1 NVIC configuration
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//Preemption priority 3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //Sub priority 3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ channel enable
NVIC_Init( & amp;NVIC_InitStructure); //Initialize the VIC register according to the specified parameters
  
   //USART initialization settings
USART_InitStructure.USART_BaudRate = bound;//Serial port baud rate
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//The word length is 8-bit data format
USART_InitStructure.USART_StopBits = USART_StopBits_1;//A stop bit
USART_InitStructure.USART_Parity = USART_Parity_No;//No parity bit
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//No hardware data flow control
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //Transceiver mode

  USART_Init(USART1, & amp;USART_InitStructure); //Initialize serial port 1
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//Enable the serial port to accept interrupts
  USART_Cmd(USART1, ENABLE); //Enable serial port 1
}

f103 serial port basic functions

Pay a little attention to the Usart_SendArrayaa() function that sends an array. In this function, we send 16-bit array data each time. This function will be mainly called in the subsequent experiments.

/************************ Send a byte **********************/
void Usart_SendByte( USART_TypeDef * pUSARTx, uint16_t ch)
{
/* Send one byte of data to USART */
USART_SendData(pUSARTx,ch);
\t\t
/* Wait for the sending data register to be empty */
while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
}
/************************ Send a 16-digit number **********************/
void Usart_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t ch)
{
uint8_t temp_h, temp_l;
\t
/* Take out the upper eight bits */
temp_h = (ch & amp;0XFF00)>>8;
/* Take out the lower eight bits */
temp_l = ch &0XFF;
\t
/* Send the upper eight bits */
USART_SendData(pUSARTx,temp_h);
while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
\t
/* Send the lower eight bits */
USART_SendData(pUSARTx,temp_l);
while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
}
/****************** Send 16-bit array ************************/
void Usart_SendArrayaa( USART_TypeDef * pUSARTx, uint16_t *array, uint16_t num)
{
  uint8_t i;
\t
for(i=0; i<num; i + + )
  {
      Usart_SendHalfWord(pUSARTx, array[i]);
  }
/* Wait for sending to complete */
while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET);
}

The serial port sends a data packet, that is, simply packaging the data, adding a frame header of 0xFF and a frame tail of 0xFE, and sending one data packet at a time. Sending format such as 0xFF 0102 0304 0506 0xFE

void Serial_SendPacket(void)
{
Usart_SendByte(USART1,0xFF);
Usart_SendArrayaa(USART1,Serial_TxPacket, 3);
Usart_SendByte(USART1,0xFE);
\t
/* Wait for sending to complete */
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
}

Main function

Initialize the serial port, assign an initial value to the array (this is just an example, you can send different data continuously when you send data later), and call the send data packet function

uint16_t Serial_TxPacket[3]; //Define the send data packet array, data packet format: FF 0001 0002 0003 FE
int main(void)
{
uart_init(115200);

while(1)
{
Serial_TxPacket[0] = 0102;
Serial_TxPacket[1] = 0304;
Serial_TxPacket[2] = 0506;
\t\t
Serial_SendPacket(); //Serial port sends data packet Serial_TxPacket

}
}

f429 host accepts multiple data

f429 serial port configuration

static void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  
  /* Nested vector interrupt controller group selection */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  
  /* Configure USART as interrupt source */
  NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;
  /* Stealing priority is 1 */
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  /* Sub-priority is 1 */
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  /* Enable interrupts */
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  /* Initialize configuration NVIC */
  NVIC_Init( & amp;NVIC_InitStructure);
}


 /**
  * @brief DEBUG_USART GPIO configuration, working mode configuration. 115200 8-N-1, interrupt reception mode
  * @param none
  * @retval None
  */
void Debug_USART_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;
\t\t
  RCC_AHB1PeriphClockCmd(DEBUG_USART_RX_GPIO_CLK|DEBUG_USART_TX_GPIO_CLK,ENABLE);

  /* Enable USART clock */
  RCC_APB1PeriphClockCmd(DEBUG_USART_CLK, ENABLE);
  
  /* GPIO initialization */
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  
  /* Configure the Tx pin as a multiplex function */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_PIN;
  GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);

  /* Configure the Rx pin as an alternate function */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_PIN;
  GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);
  
 /* Connect PXx to USARTx_Tx*/
  GPIO_PinAFConfig(DEBUG_USART_RX_GPIO_PORT,DEBUG_USART_RX_SOURCE,DEBUG_USART_RX_AF);

  /* Connect PXx to USARTx__Rx*/
  GPIO_PinAFConfig(DEBUG_USART_TX_GPIO_PORT,DEBUG_USART_TX_SOURCE,DEBUG_USART_TX_AF);
  
  /* Configuration string DEBUG_USART mode */
  /* Baud rate setting: DEBUG_USART_BAUDRATE */
  USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;
  /* Word length (data bits + check bits): 8 */
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  /* Stop bit: 1 stop bit */
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  /* Check digit selection: do not use check */
  USART_InitStructure.USART_Parity = USART_Parity_No;
  /* Hardware flow control: do not use hardware flow */
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  /* USART mode control: enable reception and transmission at the same time */
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  /* Complete USART initialization configuration */
  USART_Init(DEBUG_USART, & amp;USART_InitStructure);
\t
  /* Nested vector interrupt controller NVIC configuration */
NVIC_Configuration();
  
/* Enable serial port reception interrupt */
USART_ITConfig(DEBUG_USART, USART_IT_RXNE, ENABLE);
\t
  /* Enable serial port */
  USART_Cmd(DEBUG_USART, ENABLE);
}

Serial port basic acceptance function

This function is included in the standard library stm32f4xx_usart.c and does not need to be written by yourself. Note that although the function is 16-bit, it only returns 8-bit data because the serial port data register can only accept 8-bit data at a time.

uint16_t USART_ReceiveData(USART_TypeDef* USARTx)
{
  /* Check the parameters */
  assert_param(IS_USART_ALL_PERIPH(USARTx));
  
  /*Receive Data */
  return (uint16_t)(USARTx->DR & amp; (uint16_t)0x01FF);
}

Serial port accepts interrupt function

The acceptance function uses the concept of a state machine. It first determines whether the state is 0. If it is and the data is 0xFF, it jumps to state 1. It accepts and processes the data in the data packet at state 1 because the sender only sends 8 at a time. bit data. After consulting the data, we found that the sending end sends the high bit first, so when pRxPacket=0, the high 8 bits of the first data are stored in the array. When pRxPacket=1, the low 8 bits of the first data are stored. At this time We synthesize it into 16-bit data, shift the high bit to the left by 8 bits, and store it in the array: Serial_RxPacket[pRxPacket-1] = RxData|(Serial_RxPacket[pRxPacket-1]<<8). The next 2 digits of data are deduced in the same way. At this point we have already accomplished sending and receiving multiple 16-bit data. It is also necessary to solve the problem of sending and receiving signed data. At the beginning, I defined the data to be all unsigned numbers. At this time, if I assign a negative number to the array, the received value will be 0. This means that the negative number defaults to 0. The solution is to change the definition to a signed number. And first add a loop in state one to determine whether the 8th bit data is 1 when receiving the high-bit data. If so, subtract 1 and negate it (state that my data range does not use the highest bit, so I can use this to judge)

void USART3_IRQHandler(void)
{
static uint8_t RxState = 0; //Define static variables representing the current state machine state
static uint8_t pRxPacket = 0; //Define a static variable representing the current received data location
if (USART_GetITStatus(USART3, USART_IT_RXNE) == SET) //Determine whether the interrupt is triggered by the reception event of USART1
{
uint16_t RxData = USART_ReceiveData(USART3); //Read the data register and store it in the received data variable
\t\t
/*Use the idea of a state machine to process different parts of the data packet in sequence*/
\t\t
/*The current status is 0, receiving the data packet header*/
if (RxState == 0)
{
if (RxData == 0xFF) //If the data is indeed the header
{
RxState = 1; //Set the next state
pRxPacket = 0; //Reset the position of the data packet to zero
}
}
/*The current status is 1, receiving packet data*/
else if (RxState == 1)
{
if(pRxPacket%2 == 0)
{
if(RxData & amp;(1<<7) != 0)
{RxData= ~(RxData - 1);
RxData = -RxData;
}
Serial_RxPacket[pRxPacket] = RxData; }//Save data to the specified location in the packet array
else
Serial_RxPacket[pRxPacket-1] = RxData|(Serial_RxPacket[pRxPacket-1]<<8);
pRxPacket + + ; //The position of the data packet is incremented
\t\t\t
\t\t\t
if (pRxPacket >= 6) //If enough 6 data are collected
{
RxState = 2; //Set the next state
}
}
/*The current status is 2, receiving the end of the data packet*/
else if (RxState == 2)
{
if (RxData == 0xFE) //If the data is indeed the end of the packet
{
RxState = 0; //Return state to 0
Serial_RxFlag = 1; //Receive data packet flag position 1, successfully receive a data packet
}
}
\t\t
USART_ClearITPendingBit(USART3, USART_IT_RXNE); //Clear the flag bit
}
}

f429 main function

int main(void)
{
  /*Initialize USART configuration mode to 115200 8-N-1, interrupt reception*/
  Debug_USART_Config();

  while(1)
{
      if (Serial_GetRxFlag() == 1) //If a data packet is received
{
#ifdef USE_LCD_DISPLAY
{
char cStr [70];
sprintf ( cStr, "Gyro :?",Serial_RxPacket[0],Serial_RxPacket[2],Serial_RxPacket[4] ); //angular raw data
LCD_DisplayStringLine(LINE(8),(uint8_t* )cStr);
}
#endif
}
}
}