/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file usart.c * @brief This file provides code for the configuration * of the USART instances. ****************************************************************************** * @attention * * Copyright (c) 2024 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "usart.h" /* USER CODE BEGIN 0 */ #include "string.h" #include "tim.h" #define USART3_RXSIZE 1024 //一帧接收数据的最大值 #define USART3_TXSIZE 1024 //一帧发送数据的最大值 uint8_t usart3_rx_buf[USART3_RXSIZE]; //发送数据缓冲数组 uint8_t usart3_tx_buf[USART3_TXSIZE]; //接收数据缓冲数据 uint8_t usart6_rx_buf[64]; //发送数据缓冲数组 uint8_t usart6_tx_buf[64]; //接收数据缓冲数据 int usart6_cnt = 0; UART_BUF usart3; //串口结构体实体 uint8_t RxBuffer; //接收数据中间变量 //uint8_t mfc_ins_buf[8] = {0x01,0x03,0x00,0x10,0x00,0x02,0xC5,0xCE};//读取流量计瞬时流量命令 //uint8_t mfc_cum_buf[8] = {0x01,0x03,0x00,0x1A,0x00,0x02,0xE5,0xCC};//读取流量计累积流量命令 //uint8_t mfc_data_buf[8];//流量计返回数组 /* USER CODE END 0 */ /* USART1 init function */ void MX_USART1_UART_Init(void) { /* USER CODE BEGIN USART1_Init 0 */ /* USER CODE END USART1_Init 0 */ LL_USART_InitTypeDef USART_InitStruct = {0}; LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; /* Peripheral clock enable */ LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA); /**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */ GPIO_InitStruct.Pin = LL_GPIO_PIN_9; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; GPIO_InitStruct.Alternate = LL_GPIO_AF_7; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = LL_GPIO_PIN_10; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; GPIO_InitStruct.Alternate = LL_GPIO_AF_7; LL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USART1 interrupt Init */ NVIC_SetPriority(USART1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),2, 1)); NVIC_EnableIRQ(USART1_IRQn); /* USER CODE BEGIN USART1_Init 1 */ /* USER CODE END USART1_Init 1 */ USART_InitStruct.BaudRate = 115200; USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; USART_InitStruct.StopBits = LL_USART_STOPBITS_1; USART_InitStruct.Parity = LL_USART_PARITY_NONE; USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE; USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; LL_USART_Init(USART1, &USART_InitStruct); LL_USART_ConfigAsyncMode(USART1); LL_USART_Enable(USART1); /* USER CODE BEGIN USART1_Init 2 */ /* USER CODE END USART1_Init 2 */ } /* USART2 init function */ void MX_USART2_UART_Init(void) { /* USER CODE BEGIN USART2_Init 0 */ /* USER CODE END USART2_Init 0 */ LL_USART_InitTypeDef USART_InitStruct = {0}; LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; /* Peripheral clock enable */ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2); LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOD); /**USART2 GPIO Configuration PD5 ------> USART2_TX PD6 ------> USART2_RX */ GPIO_InitStruct.Pin = LL_GPIO_PIN_5; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; GPIO_InitStruct.Alternate = LL_GPIO_AF_7; LL_GPIO_Init(GPIOD, &GPIO_InitStruct); GPIO_InitStruct.Pin = LL_GPIO_PIN_6; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; GPIO_InitStruct.Alternate = LL_GPIO_AF_7; LL_GPIO_Init(GPIOD, &GPIO_InitStruct); /* USART2 DMA Init */ /* USART2_TX Init */ LL_DMA_SetChannelSelection(DMA1, LL_DMA_STREAM_6, LL_DMA_CHANNEL_4); LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_STREAM_6, LL_DMA_DIRECTION_MEMORY_TO_PERIPH); LL_DMA_SetStreamPriorityLevel(DMA1, LL_DMA_STREAM_6, LL_DMA_PRIORITY_LOW); LL_DMA_SetMode(DMA1, LL_DMA_STREAM_6, LL_DMA_MODE_CIRCULAR); LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_STREAM_6, LL_DMA_PERIPH_NOINCREMENT); LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_STREAM_6, LL_DMA_MEMORY_INCREMENT); LL_DMA_SetPeriphSize(DMA1, LL_DMA_STREAM_6, LL_DMA_PDATAALIGN_BYTE); LL_DMA_SetMemorySize(DMA1, LL_DMA_STREAM_6, LL_DMA_MDATAALIGN_BYTE); LL_DMA_DisableFifoMode(DMA1, LL_DMA_STREAM_6); /* USART2 interrupt Init */ NVIC_SetPriority(USART2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),2, 1)); NVIC_EnableIRQ(USART2_IRQn); /* USER CODE BEGIN USART2_Init 1 */ /* USER CODE END USART2_Init 1 */ USART_InitStruct.BaudRate = 38400; USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; USART_InitStruct.StopBits = LL_USART_STOPBITS_1; USART_InitStruct.Parity = LL_USART_PARITY_NONE; USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE; USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; LL_USART_Init(USART2, &USART_InitStruct); LL_USART_ConfigAsyncMode(USART2); LL_USART_Enable(USART2); /* USER CODE BEGIN USART2_Init 2 */ uart2_init(); /* USER CODE END USART2_Init 2 */ } /* USART3 init function */ void MX_USART3_UART_Init(void) { /* USER CODE BEGIN USART3_Init 0 */ /* USER CODE END USART3_Init 0 */ LL_USART_InitTypeDef USART_InitStruct = {0}; LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; /* Peripheral clock enable */ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART3); LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOD); /**USART3 GPIO Configuration PD8 ------> USART3_TX PD9 ------> USART3_RX */ GPIO_InitStruct.Pin = LL_GPIO_PIN_8; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; GPIO_InitStruct.Alternate = LL_GPIO_AF_7; LL_GPIO_Init(GPIOD, &GPIO_InitStruct); GPIO_InitStruct.Pin = LL_GPIO_PIN_9; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; GPIO_InitStruct.Alternate = LL_GPIO_AF_7; LL_GPIO_Init(GPIOD, &GPIO_InitStruct); /* USART3 DMA Init */ /* USART3_TX Init */ LL_DMA_SetChannelSelection(DMA1, LL_DMA_STREAM_3, LL_DMA_CHANNEL_4); LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_STREAM_3, LL_DMA_DIRECTION_MEMORY_TO_PERIPH); LL_DMA_SetStreamPriorityLevel(DMA1, LL_DMA_STREAM_3, LL_DMA_PRIORITY_LOW); LL_DMA_SetMode(DMA1, LL_DMA_STREAM_3, LL_DMA_MODE_NORMAL); LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_STREAM_3, LL_DMA_PERIPH_NOINCREMENT); LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_STREAM_3, LL_DMA_MEMORY_INCREMENT); LL_DMA_SetPeriphSize(DMA1, LL_DMA_STREAM_3, LL_DMA_PDATAALIGN_BYTE); LL_DMA_SetMemorySize(DMA1, LL_DMA_STREAM_3, LL_DMA_MDATAALIGN_BYTE); LL_DMA_DisableFifoMode(DMA1, LL_DMA_STREAM_3); /* USART3 interrupt Init */ NVIC_SetPriority(USART3_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 1)); NVIC_EnableIRQ(USART3_IRQn); /* USER CODE BEGIN USART3_Init 1 */ /* USER CODE END USART3_Init 1 */ USART_InitStruct.BaudRate = 115200; USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; USART_InitStruct.StopBits = LL_USART_STOPBITS_1; USART_InitStruct.Parity = LL_USART_PARITY_NONE; USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE; USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; LL_USART_Init(USART3, &USART_InitStruct); LL_USART_ConfigAsyncMode(USART3); LL_USART_Enable(USART3); /* USER CODE BEGIN USART3_Init 2 */ /*发送配置*/ //设置外设地址,因为这个是DMA串口发送, LL_DMA_SetPeriphAddress(DMA1,LL_DMA_STREAM_3,(uint32_t)&USART3->DR); //使能DMA串口发送 LL_USART_EnableDMAReq_TX(USART3); //使能DMA2发送完成中断 LL_DMA_EnableIT_TC(DMA1,LL_DMA_STREAM_3); /* USER CODE END USART3_Init 2 */ } /* USART6 init function */ void MX_USART6_UART_Init(void) { /* USER CODE BEGIN USART6_Init 0 */ /* USER CODE END USART6_Init 0 */ LL_USART_InitTypeDef USART_InitStruct = {0}; LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; /* Peripheral clock enable */ LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART6); LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOC); /**USART6 GPIO Configuration PC6 ------> USART6_TX PC7 ------> USART6_RX */ GPIO_InitStruct.Pin = LL_GPIO_PIN_6; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; GPIO_InitStruct.Alternate = LL_GPIO_AF_8; LL_GPIO_Init(GPIOC, &GPIO_InitStruct); GPIO_InitStruct.Pin = LL_GPIO_PIN_7; GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.Pull = LL_GPIO_PULL_UP; GPIO_InitStruct.Alternate = LL_GPIO_AF_8; LL_GPIO_Init(GPIOC, &GPIO_InitStruct); /* USART6 DMA Init */ /* USART6_RX Init */ LL_DMA_SetChannelSelection(DMA2, LL_DMA_STREAM_1, LL_DMA_CHANNEL_5); LL_DMA_SetDataTransferDirection(DMA2, LL_DMA_STREAM_1, LL_DMA_DIRECTION_PERIPH_TO_MEMORY); LL_DMA_SetStreamPriorityLevel(DMA2, LL_DMA_STREAM_1, LL_DMA_PRIORITY_LOW); LL_DMA_SetMode(DMA2, LL_DMA_STREAM_1, LL_DMA_MODE_CIRCULAR); LL_DMA_SetPeriphIncMode(DMA2, LL_DMA_STREAM_1, LL_DMA_PERIPH_NOINCREMENT); LL_DMA_SetMemoryIncMode(DMA2, LL_DMA_STREAM_1, LL_DMA_MEMORY_INCREMENT); LL_DMA_SetPeriphSize(DMA2, LL_DMA_STREAM_1, LL_DMA_PDATAALIGN_BYTE); LL_DMA_SetMemorySize(DMA2, LL_DMA_STREAM_1, LL_DMA_MDATAALIGN_BYTE); LL_DMA_DisableFifoMode(DMA2, LL_DMA_STREAM_1); /* USART6_TX Init */ LL_DMA_SetChannelSelection(DMA2, LL_DMA_STREAM_6, LL_DMA_CHANNEL_5); LL_DMA_SetDataTransferDirection(DMA2, LL_DMA_STREAM_6, LL_DMA_DIRECTION_MEMORY_TO_PERIPH); LL_DMA_SetStreamPriorityLevel(DMA2, LL_DMA_STREAM_6, LL_DMA_PRIORITY_LOW); LL_DMA_SetMode(DMA2, LL_DMA_STREAM_6, LL_DMA_MODE_CIRCULAR); LL_DMA_SetPeriphIncMode(DMA2, LL_DMA_STREAM_6, LL_DMA_PERIPH_NOINCREMENT); LL_DMA_SetMemoryIncMode(DMA2, LL_DMA_STREAM_6, LL_DMA_MEMORY_INCREMENT); LL_DMA_SetPeriphSize(DMA2, LL_DMA_STREAM_6, LL_DMA_PDATAALIGN_BYTE); LL_DMA_SetMemorySize(DMA2, LL_DMA_STREAM_6, LL_DMA_MDATAALIGN_BYTE); LL_DMA_DisableFifoMode(DMA2, LL_DMA_STREAM_6); /* USART6 interrupt Init */ NVIC_SetPriority(USART6_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),2, 1)); NVIC_EnableIRQ(USART6_IRQn); /* USER CODE BEGIN USART6_Init 1 */ /* USER CODE END USART6_Init 1 */ USART_InitStruct.BaudRate = 9600; USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; USART_InitStruct.StopBits = LL_USART_STOPBITS_1; USART_InitStruct.Parity = LL_USART_PARITY_NONE; USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE; USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; LL_USART_Init(USART6, &USART_InitStruct); LL_USART_ConfigAsyncMode(USART6); LL_USART_Enable(USART6); /* USER CODE BEGIN USART6_Init 2 */ /*接收配置*/ //使能空闲中断 LL_USART_EnableIT_IDLE(USART6); /*发送配置*/ //设置外设地址,因为这个是DMA串口发送, LL_DMA_SetPeriphAddress(DMA2,LL_DMA_STREAM_6,(uint32_t)&USART6->DR); //使能DMA串口发送 LL_USART_EnableDMAReq_TX(USART6); //使能DMA2发送完成中断 LL_DMA_EnableIT_TC(DMA2,LL_DMA_STREAM_6); LL_USART_EnableIT_RXNE(USART6); //开启接收中断 /* USER CODE END USART6_Init 2 */ } /* USER CODE BEGIN 1 */ /*****************************重写回调函数,实现串口数据接收**********************/ void modbus_init(void) { usart3.rx_buf = usart3_rx_buf; //接收数据变量初始化 usart3.rx_buf_cnt = 0; usart3.rx_size = 0; usart3.rx_flag = 0; usart3.tx_buf = usart3_rx_buf; //发送数据变量初始化 usart3.tx_buf_cnt = USART3_TXSIZE; usart3.tx_size = 0; LL_USART_EnableIT_RXNE(USART3); //开启接收中断 } void modbus_callback(void) { if(step_cnt >= 3) { if(usart3.rx_buf_cnt >= USART3_RXSIZE-1) //接收数据量超限,错误 { usart3.rx_buf_cnt = 0; memset(usart3.rx_buf, 0x00, sizeof(usart3.rx_buf)); LL_USART_TransmitData8(USART3, 0xEE); } else //接收正常 { RxBuffer = LL_USART_ReceiveData8(USART3); usart3.rx_buf[usart3.rx_buf_cnt++] = RxBuffer; //接收数据存储到rx_buf LL_TIM_DisableCounter(TIM7); LL_TIM_SetCounter(TIM7,0);//将定时器7的计数值清零后重新计数 LL_TIM_EnableCounter(TIM7);//TIM7计数使能 } } } void modbus_send(USART_TypeDef *Luart,uint8_t *Tx_Buf,uint16_t Size) { //配置内存地址 LL_DMA_SetMemoryAddress(DMA1,LL_DMA_STREAM_3,(uint32_t)Tx_Buf); //配置数据长度 LL_DMA_SetDataLength(DMA1,LL_DMA_STREAM_3,Size); //使能DMA STREAM 也就是发送数据 LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_3); } void usart2_laser_send(USART_TypeDef *Luart,uint8_t *Tx_Buf,uint16_t Size) { //配置内存地址 LL_DMA_SetMemoryAddress(DMA1,LL_DMA_STREAM_6,(uint32_t)Tx_Buf); //配置数据长度 LL_DMA_SetDataLength(DMA1,LL_DMA_STREAM_6,Size); //使能DMA STREAM 也就是发送数据 LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_6); // LL_DMA_ConfigAddresses(): } void usart6_send(uint8_t *Tx_Buf,uint16_t Size) { //配置内存地址 LL_DMA_SetMemoryAddress(DMA2,LL_DMA_STREAM_6,(uint32_t)Tx_Buf); //配置数据长度 LL_DMA_SetDataLength(DMA2,LL_DMA_STREAM_6,Size); //使能DMA STREAM 也就是发送数据 LL_DMA_EnableStream(DMA2, LL_DMA_STREAM_6); } //串口接收中断回调函数,激光 void usart6_rx_cb(void)//uint8_t uart_index, uint8_t *data, uint16_t len { // 空闲中断,表明接收到了1帧所有的数据 if(LL_USART_IsActiveFlag_IDLE(USART6)) { //清除空闲中断 LL_USART_ClearFlag_IDLE(USART6); usart6_cnt = 0; } // Rx非空中断,表明接收到了一个字节 // 读取Rx可自动清除中断标志位 if(LL_USART_IsActiveFlag_RXNE(USART6)) { // 如果数组长度大于设置的data最大长度,直接停止接收 if(usart6_cnt > 50) usart6_cnt = 0; // wait for the next data usart6_rx_buf[usart6_cnt] = LL_USART_ReceiveData8(USART6); usart6_cnt ++; } } /* USER CODE END 1 */