#include "rs485.h" #include "delay.h" #include "User_Systick_Config.h" #include #include uint8_t rs_ul1_dma_tx_buf[RS_UL1_DMA_TX_BUF_SIZE]; uint8_t rs_ul2_dma_tx_buf[RS_UL2_DMA_TX_BUF_SIZE]; uint8_t rs_ul3_dma_tx_buf[RS_UL3_DMA_TX_BUF_SIZE]; uint8_t rs_dl1_dma_tx_buf[RS_DL1_DMA_TX_BUF_SIZE]; uint8_t rs_dl2_dma_tx_buf[RS_DL2_DMA_TX_BUF_SIZE]; uint8_t rs_dl3_dma_tx_buf[RS_DL3_DMA_TX_BUF_SIZE]; uint8_t rs_ul1_dma_rx_buf[RS_UL1_DMA_RX_BUF_SIZE]; uint8_t rs_ul2_dma_rx_buf[RS_UL2_DMA_RX_BUF_SIZE]; uint8_t rs_ul3_dma_rx_buf[RS_UL3_DMA_RX_BUF_SIZE]; uint8_t rs_dl1_dma_rx_buf[RS_DL1_DMA_RX_BUF_SIZE]; uint8_t rs_dl2_dma_rx_buf[RS_DL2_DMA_RX_BUF_SIZE]; uint8_t rs_dl3_dma_rx_buf[RS_DL3_DMA_RX_BUF_SIZE]; void Rs485_DL_1_Init(RS485_T *rs485) { rs485->name = "Rs485_DL_1"; // 字符串名称,调试打印使用 // UART2(原理图的通道1) PC8和PC9 rs485->UART = USART2; // 串口号 rs485->UART_CLK = RCC_APB1_PERIPH_USART2; // 串口时钟 rs485->UART_APBxClkCmd = RCC_EnableAPB1PeriphClk; // 串口时钟配置函数 rs485->UART_RxGPIO = GPIOC; // 接收管脚GPIO组 rs485->UART_RxPin = GPIO_PIN_9; // 接收管脚Pin值 rs485->UART_RxGPIO_CLK = RCC_APB2_PERIPH_GPIOC; // 接收管脚时钟 rs485->UART_TxGPIO = GPIOC; // 发送脚GPIO组 rs485->UART_TxPin = GPIO_PIN_8; // 发送脚Pin值 rs485->UART_TxGPIO_CLK = RCC_APB2_PERIPH_GPIOC; // 发送脚时钟 rs485->UART_IRQn = USART2_IRQn; // 接收中断通道 /* Remap GPIO */ GPIO_ConfigPinRemap(GPIO_RMP2_USART2, ENABLE); rs485->DMA_RCC_AHBPeriph = RCC_AHB_PERIPH_DMA1 ; // DMA时钟 rs485->DMAy = DMA1 ; // DMA1\DMA2 rs485->PeriphAddr = USART2_BASE + 0x04 ; // 指定 DMAy Channelx 的外设基地址 rs485->TxBuf = rs_dl1_dma_tx_buf ; // rs485->TxMemAddr = (uint32_t)rs_dl1_dma_tx_buf ; // 指定 DMAy Channelx 的内存基地址 rs485->TxBufSize = RS_DL1_DMA_TX_BUF_SIZE ; // 指定指定通道的缓冲区大小,以数据为单位 rs485->TxDMAyChx = DMA1_CH7 ; // Tx DMA通道 rs485->TxMAy_REMAP = DMA1_REMAP_USART2_TX ; // rs485->RxBuf = rs_dl1_dma_rx_buf ; // rs485->RxMemAddr = (uint32_t)rs_dl1_dma_rx_buf ; // 指定 DMAy Channelx 的内存基地址 rs485->RxBufSize = RS_DL1_DMA_RX_BUF_SIZE ; // 指定指定通道的缓冲区大小,以数据为单位 rs485->RxDMAyChx = DMA1_CH6 ; // Rx DMA通道 rs485->RxMAy_REMAP = DMA1_REMAP_USART2_RX ; // rs485->DMAyFlagHC = DMA1_FLAG_HT6 ; // 半满标志位 rs485->DMAyFlagTC = DMA1_FLAG_TC6 ; // 全满标志位 rs485->DMAy_IT_HC = DMA1_INT_HTX6 ; // 半满中断标志位 rs485->DMAy_IT_TC = DMA1_INT_TXC6 ; // 全满中断标志位 rs485->DMA_IRQn = DMA1_Channel6_IRQn ; // DMA中断通道 } void Rs485_DL_2_Init(RS485_T *rs485) { rs485->name = "Rs485_DL_2"; // 字符串名称,调试打印使用 // UART3(原理图的通道2) PB10和PB11 rs485->UART = USART3; // 串口号 rs485->UART_CLK = RCC_APB1_PERIPH_USART3; // 串口时钟 rs485->UART_APBxClkCmd = RCC_EnableAPB1PeriphClk; // 串口时钟配置函数 rs485->UART_RxGPIO = GPIOB; // 接收管脚GPIO组 rs485->UART_RxPin = GPIO_PIN_11; // 接收管脚Pin值 rs485->UART_RxGPIO_CLK = RCC_APB2_PERIPH_GPIOB; // 接收管脚时钟 rs485->UART_TxGPIO = GPIOB; // 发送脚GPIO组 rs485->UART_TxPin = GPIO_PIN_10; // 发送脚Pin值 rs485->UART_TxGPIO_CLK = RCC_APB2_PERIPH_GPIOB; // 发送脚时钟 rs485->UART_IRQn = USART3_IRQn; // 接收中断通道 rs485->DMA_RCC_AHBPeriph = RCC_AHB_PERIPH_DMA1 ; // DMA时钟 rs485->DMAy = DMA1 ; // DMA1\DMA2 rs485->PeriphAddr = USART3_BASE + 0x04 ; // 指定 DMAy Channelx 的外设基地址 rs485->TxBuf = rs_dl2_dma_tx_buf ; // rs485->TxMemAddr = (uint32_t)rs_dl2_dma_tx_buf ; // 指定 DMAy Channelx 的内存基地址 rs485->TxBufSize = RS_DL2_DMA_TX_BUF_SIZE ; // 指定指定通道的缓冲区大小,以数据为单位 rs485->TxDMAyChx = DMA1_CH2 ; // Tx DMA通道 rs485->TxMAy_REMAP = DMA1_REMAP_USART3_TX ; // rs485->RxBuf = rs_dl2_dma_rx_buf ; // rs485->RxMemAddr = (uint32_t)rs_dl2_dma_rx_buf ; // 指定 DMAy Channelx 的内存基地址 rs485->RxBufSize = RS_DL2_DMA_RX_BUF_SIZE ; // 指定指定通道的缓冲区大小,以数据为单位 rs485->RxDMAyChx = DMA1_CH3 ; // Rx DMA通道 rs485->RxMAy_REMAP = DMA1_REMAP_USART3_RX ; // rs485->DMAyFlagHC = DMA1_FLAG_HT3 ; // 半满标志位 rs485->DMAyFlagTC = DMA1_FLAG_TC3 ; // 全满标志位 rs485->DMAy_IT_HC = DMA1_INT_HTX3 ; // 半满中断标志位 rs485->DMAy_IT_TC = DMA1_INT_TXC3 ; // 全满中断标志位 rs485->DMA_IRQn = DMA1_Channel3_IRQn ; // DMA中断通道 } void Rs485_DL_3_Init(RS485_T *rs485) { rs485->name = "Rs485_DL_3"; // 字符串名称,调试打印使用 // UART7(原理图的通道3) PC2和PC3 rs485->UART = UART7; // 串口号 rs485->UART_CLK = RCC_APB2_PERIPH_UART7; // 串口时钟 rs485->UART_APBxClkCmd = RCC_EnableAPB2PeriphClk; // 串口时钟配置函数 rs485->UART_RxGPIO = GPIOC; // 接收管脚GPIO组 rs485->UART_RxPin = GPIO_PIN_3; // 接收管脚Pin值 rs485->UART_RxGPIO_CLK = RCC_APB2_PERIPH_GPIOC; // 接收管脚时钟 rs485->UART_TxGPIO = GPIOC; // 发送脚GPIO组 rs485->UART_TxPin = GPIO_PIN_2; // 发送脚Pin值 rs485->UART_TxGPIO_CLK = RCC_APB2_PERIPH_GPIOC; // 发送脚时钟 rs485->UART_IRQn = UART7_IRQn; // 接收中断通道 /* Remap GPIO */ GPIO_ConfigPinRemap(GPIO_RMP1_UART7, ENABLE); rs485->DMA_RCC_AHBPeriph = RCC_AHB_PERIPH_DMA2 ; // DMA时钟 rs485->DMAy = DMA2 ; // DMA1\DMA2 rs485->PeriphAddr = UART7_BASE + 0x04 ; // 指定 DMAy Channelx 的外设基地址 rs485->TxBuf = rs_dl3_dma_tx_buf ; // rs485->TxMemAddr = (uint32_t)rs_dl3_dma_tx_buf ; // 指定 DMAy Channelx 的内存基地址 rs485->TxBufSize = RS_DL3_DMA_TX_BUF_SIZE ; // 指定指定通道的缓冲区大小,以数据为单位 rs485->TxDMAyChx = DMA2_CH7 ; // Tx DMA通道 rs485->TxMAy_REMAP = DMA2_REMAP_UART7_TX ; // rs485->RxBuf = rs_dl3_dma_rx_buf ; // rs485->RxMemAddr = (uint32_t)rs_dl3_dma_rx_buf ; // 指定 DMAy Channelx 的内存基地址 rs485->RxBufSize = RS_DL3_DMA_RX_BUF_SIZE ; // 指定指定通道的缓冲区大小,以数据为单位 rs485->RxDMAyChx = DMA2_CH6 ; // Rx DMA通道 rs485->RxMAy_REMAP = DMA2_REMAP_UART7_RX ; // rs485->DMAyFlagHC = DMA2_FLAG_HT6 ; // 半满标志位 rs485->DMAyFlagTC = DMA2_FLAG_TC6 ; // 全满标志位 rs485->DMAy_IT_HC = DMA2_INT_HTX6 ; // 半满中断标志位 rs485->DMAy_IT_TC = DMA2_INT_TXC6 ; // 全满中断标志位 rs485->DMA_IRQn = DMA2_Channel6_IRQn ; // DMA中断通道 } void Rs485_UL_1_Init(RS485_T *rs485) { rs485->name = "Rs485_UL_1"; // 字符串名称,调试打印使用 // UART4(原理图的通道5) PC10和PC11 rs485->UART = UART4; // 串口号 rs485->UART_CLK = RCC_APB1_PERIPH_UART4; // 串口时钟 rs485->UART_APBxClkCmd = RCC_EnableAPB1PeriphClk; // 串口时钟配置函数 rs485->UART_RxGPIO = GPIOC; // 接收管脚GPIO组 rs485->UART_RxPin = GPIO_PIN_11; // 接收管脚Pin值 rs485->UART_RxGPIO_CLK = RCC_APB2_PERIPH_GPIOC; // 接收管脚时钟 rs485->UART_TxGPIO = GPIOC; // 发送脚GPIO组 rs485->UART_TxPin = GPIO_PIN_10; // 发送脚Pin值 rs485->UART_TxGPIO_CLK = RCC_APB2_PERIPH_GPIOC; // 发送脚时钟 rs485->UART_IRQn = UART4_IRQn; // 接收中断通道 rs485->DMA_RCC_AHBPeriph = RCC_AHB_PERIPH_DMA2 ; // DMA时钟 rs485->DMAy = DMA2 ; // DMA1\DMA2 rs485->PeriphAddr = UART4_BASE + 0x04 ; // 指定 DMAy Channelx 的外设基地址 rs485->TxBuf = rs_ul1_dma_tx_buf ; // rs485->TxMemAddr = (uint32_t)rs_ul1_dma_tx_buf ; // 指定 DMAy Channelx 的内存基地址 rs485->TxBufSize = RS_UL1_DMA_TX_BUF_SIZE ; // 指定指定通道的缓冲区大小,以数据为单位 rs485->TxDMAyChx = DMA2_CH5 ; // Tx DMA通道 rs485->TxMAy_REMAP = DMA2_REMAP_UART4_TX ; // rs485->RxBuf = rs_ul1_dma_rx_buf ; // rs485->RxMemAddr = (uint32_t)rs_ul1_dma_rx_buf ; // 指定 DMAy Channelx 的内存基地址 rs485->RxBufSize = RS_UL1_DMA_RX_BUF_SIZE ; // 指定指定通道的缓冲区大小,以数据为单位 rs485->RxDMAyChx = DMA2_CH3 ; // Rx DMA通道 rs485->RxMAy_REMAP = DMA2_REMAP_UART4_RX ; // rs485->DMAyFlagHC = DMA2_FLAG_HT3 ; // 半满标志位 rs485->DMAyFlagTC = DMA2_FLAG_TC3 ; // 全满标志位 rs485->DMAy_IT_HC = DMA2_INT_HTX3 ; // 半满中断标志位 rs485->DMAy_IT_TC = DMA2_INT_TXC3 ; // 全满中断标志位 rs485->DMA_IRQn = DMA2_Channel3_IRQn ; // DMA中断通道 } void Rs485_UL_2_Init(RS485_T *rs485) { rs485->name = "Rs485_UL_2"; // 字符串名称,调试打印使用 // UART5(原理图的通道6) PC12和PD2 rs485->UART = UART5; // 串口号 rs485->UART_CLK = RCC_APB1_PERIPH_UART5; // 串口时钟 rs485->UART_APBxClkCmd = RCC_EnableAPB1PeriphClk; // 串口时钟配置函数 rs485->UART_RxGPIO = GPIOD; // 接收管脚GPIO组 rs485->UART_RxPin = GPIO_PIN_2; // 接收管脚Pin值 rs485->UART_RxGPIO_CLK = RCC_APB2_PERIPH_GPIOD; // 接收管脚时钟 rs485->UART_TxGPIO = GPIOC; // 发送脚GPIO组 rs485->UART_TxPin = GPIO_PIN_12; // 发送脚Pin值 rs485->UART_TxGPIO_CLK = RCC_APB2_PERIPH_GPIOC; // 发送脚时钟 rs485->UART_IRQn = UART5_IRQn; // 接收中断通道 rs485->DMA_RCC_AHBPeriph = RCC_AHB_PERIPH_DMA1 ; // DMA时钟 rs485->DMAy = DMA1 ; // DMA1\DMA2 rs485->PeriphAddr = UART5_BASE + 0x04 ; // 指定 DMAy Channelx 的外设基地址 rs485->TxBuf = rs_ul2_dma_tx_buf ; // rs485->TxMemAddr = (uint32_t)rs_ul2_dma_tx_buf ; // 指定 DMAy Channelx 的内存基地址 rs485->TxBufSize = RS_UL2_DMA_TX_BUF_SIZE ; // 指定指定通道的缓冲区大小,以数据为单位 rs485->TxDMAyChx = DMA1_CH1 ; // Tx DMA通道 rs485->TxMAy_REMAP = DMA1_REMAP_UART5_TX ; // rs485->RxBuf = rs_ul2_dma_rx_buf ; // rs485->RxMemAddr = (uint32_t)rs_ul2_dma_rx_buf ; // 指定 DMAy Channelx 的内存基地址 rs485->RxBufSize = RS_UL2_DMA_RX_BUF_SIZE ; // 指定指定通道的缓冲区大小,以数据为单位 rs485->RxDMAyChx = DMA1_CH8 ; // Rx DMA通道 rs485->RxMAy_REMAP = DMA1_REMAP_UART5_RX ; // rs485->DMAyFlagHC = DMA1_FLAG_HT8 ; // 半满标志位 rs485->DMAyFlagTC = DMA1_FLAG_TC8 ; // 全满标志位 rs485->DMAy_IT_HC = DMA1_INT_HTX8 ; // 半满中断标志位 rs485->DMAy_IT_TC = DMA1_INT_TXC8 ; // 全满中断标志位 rs485->DMA_IRQn = DMA1_Channel8_IRQn ; // DMA中断通道 } void Rs485_UL_3_Init(RS485_T *rs485) { rs485->name = "Rs485_UL_3"; // 字符串名称,调试打印使用 // UART6(原理图的通道4) PB0和PB1 rs485->UART = UART6; // 串口号 rs485->UART_CLK = RCC_APB2_PERIPH_UART6; // 串口时钟 rs485->UART_APBxClkCmd = RCC_EnableAPB2PeriphClk; // 串口时钟配置函数 rs485->UART_RxGPIO = GPIOC; // 接收管脚GPIO组 rs485->UART_RxPin = GPIO_PIN_1; // 接收管脚Pin值 rs485->UART_RxGPIO_CLK = RCC_APB2_PERIPH_GPIOC; // 接收管脚时钟 rs485->UART_TxGPIO = GPIOC; // 发送脚GPIO组 rs485->UART_TxPin = GPIO_PIN_0; // 发送脚Pin值 rs485->UART_TxGPIO_CLK = RCC_APB2_PERIPH_GPIOC; // 发送脚时钟 rs485->UART_IRQn = UART6_IRQn; // 接收中断通道 /* Remap GPIO */ GPIO_ConfigPinRemap(GPIO_RMP2_UART6, ENABLE); rs485->DMA_RCC_AHBPeriph = RCC_AHB_PERIPH_DMA2 ; // DMA时钟 rs485->DMAy = DMA2 ; // DMA1\DMA2 rs485->PeriphAddr = UART6_BASE + 0x04 ; // 指定 DMAy Channelx 的外设基地址 rs485->TxBuf = rs_ul3_dma_tx_buf ; // rs485->TxMemAddr = (uint32_t)rs_ul3_dma_tx_buf ; // 指定 DMAy Channelx 的内存基地址 rs485->TxBufSize = RS_UL3_DMA_TX_BUF_SIZE ; // 指定指定通道的缓冲区大小,以数据为单位 rs485->TxDMAyChx = DMA2_CH2 ; // Tx DMA通道 rs485->TxMAy_REMAP = DMA2_REMAP_UART6_TX ; // rs485->RxBuf = rs_ul3_dma_rx_buf ; // rs485->RxMemAddr = (uint32_t)rs_ul3_dma_rx_buf ; // 指定 DMAy Channelx 的内存基地址 rs485->RxBufSize = RS_UL3_DMA_RX_BUF_SIZE ; // 指定指定通道的缓冲区大小,以数据为单位 rs485->RxDMAyChx = DMA2_CH1 ; // Rx DMA通道 rs485->RxMAy_REMAP = DMA2_REMAP_UART6_RX ; // rs485->DMAyFlagHC = DMA2_FLAG_HT1 ; // 半满标志位 rs485->DMAyFlagTC = DMA2_FLAG_TC1 ; // 全满标志位 rs485->DMAy_IT_HC = DMA2_INT_HTX1 ; // 半满中断标志位 rs485->DMAy_IT_TC = DMA2_INT_TXC1 ; // 全满中断标志位 rs485->DMA_IRQn = DMA2_Channel1_IRQn ; // DMA中断通道 } /*************************************************************************************************/ /********************************************* 0 *************************************************/ /*************************************************************************************************/ void Rs485_Init(RS485_T *rs485, uint32_t BaudRate, uint16_t WordLength, uint16_t StopBits, uint16_t Parity) { DMA_InitType DMA_InitStructure; NVIC_InitType NVIC_InitStructure; GPIO_InitType GPIO_InitStructure; USART_InitType USART_InitStructure; RingBuf_Init(&(rs485->rx_ringbuff)); /**************************************** 时钟 *********************************************/ /* Enable DMA clock */ RCC_EnableAHBPeriphClk(rs485->DMA_RCC_AHBPeriph, ENABLE); /* Enable GPIO clock */ RCC_EnableAPB2PeriphClk(rs485->UART_TxGPIO_CLK | rs485->UART_RxGPIO_CLK | RCC_APB2_PERIPH_AFIO, ENABLE); /* Enable USART and USARTz Clock */ rs485->UART_APBxClkCmd(rs485->UART_CLK, ENABLE); /**************************************** 配置NVIC *********************************************/ /* Enable the USARTx Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = rs485->UART_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 中断抢占优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 中断子优先级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = rs485->DMA_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /**************************************** 收发管脚 *********************************************/ /* Configure USARTx Tx as alternate function push-pull */ GPIO_InitStructure.Pin = rs485->UART_TxPin; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitPeripheral(rs485->UART_TxGPIO, &GPIO_InitStructure); /* Configure USARTx Rx as input floating */ GPIO_InitStructure.Pin = rs485->UART_RxPin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitPeripheral(rs485->UART_RxGPIO, &GPIO_InitStructure); /**************************************** DMA配置 *********************************************/ /* USART TX DMA1 Channel (triggered by USART Tx event) Config */ /* USART TX DMA1 通道(由 USART Tx 事件触发)配置 */ DMA_DeInit(rs485->TxDMAyChx); DMA_InitStructure.PeriphAddr = rs485->PeriphAddr ; /*!< 指定 DMAy Channelx 的外设基址。 */ DMA_InitStructure.MemAddr = rs485->TxMemAddr ; /*!< 指定 DMAy Channelx 的内存基地址。 */ DMA_InitStructure.Direction = DMA_DIR_PERIPH_DST ; /*!< 指定外设是源还是目标。这个参数可以是@ref DMA_data_transfer_direction 的值 */ DMA_InitStructure.BufSize = rs485->TxBufSize ; /*!< 指定指定通道的缓冲区大小,以数据为单位。根据传输方向,数据单元等于 PeriphDataSize 或 MemDataSize 成员中设置的配置。 */ DMA_InitStructure.PeriphInc = DMA_PERIPH_INC_DISABLE ; /*!< 指定外设地址寄存器是否递增。这个参数可以是@ref DMA_peripheral_incremented_mode 的值 */ DMA_InitStructure.DMA_MemoryInc = DMA_MEM_INC_ENABLE ; /*!< 指定内存地址寄存器是否递增。这个参数可以是@ref DMA_memory_incremented_mode 的值 */ DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_BYTE ; /*!< 指定外设数据宽度。这个参数可以是@ref DMA_peripheral_data_size 的值 */ DMA_InitStructure.MemDataSize = DMA_MemoryDataSize_Byte ; /*!< 指定内存数据宽度。这个参数可以是@ref DMA_memory_data_size 的值 */ DMA_InitStructure.CircularMode = DMA_MODE_NORMAL ; /*!< 指定 DMAy Channelx 的操作模式。该参数可以是@ref DMA_circular_normal_mode 的值。 */ DMA_InitStructure.Priority = DMA_PRIORITY_VERY_HIGH ; /*!< 指定 DMAy Channelx 的软件优先级。这个参数可以是@ref DMA_priority_level 的值 */ DMA_InitStructure.Mem2Mem = DMA_M2M_DISABLE ; /*!< 指定 DMAy Channelx 是否将用于内存到内存传输。这个参数可以是@ref DMA_memory_to_memory 的值 */ DMA_Init(rs485->TxDMAyChx, &DMA_InitStructure); // 设置 DMA Channelx 的重新映射请求。 DMA_RequestRemap(rs485->TxMAy_REMAP, rs485->DMAy, rs485->TxDMAyChx, ENABLE); printf("------------------------------------------------------------\r\n"); printf("DMA_InitStructure.PeriphAddr =%d\r\n",DMA_InitStructure.PeriphAddr ); printf("DMA_InitStructure.MemAddr =%d\r\n",DMA_InitStructure.MemAddr ); printf("DMA_InitStructure.Direction =%d\r\n",DMA_InitStructure.Direction ); printf("DMA_InitStructure.BufSize =%d\r\n",DMA_InitStructure.BufSize ); printf("DMA_InitStructure.PeriphInc =%d\r\n",DMA_InitStructure.PeriphInc ); printf("DMA_InitStructure.DMA_MemoryInc =%d\r\n",DMA_InitStructure.DMA_MemoryInc ); printf("DMA_InitStructure.PeriphDataSize=%d\r\n",DMA_InitStructure.PeriphDataSize); printf("DMA_InitStructure.MemDataSize =%d\r\n",DMA_InitStructure.MemDataSize ); printf("DMA_InitStructure.CircularMode =%d\r\n",DMA_InitStructure.CircularMode ); printf("DMA_InitStructure.Priority =%d\r\n",DMA_InitStructure.Priority ); printf("DMA_InitStructure.Mem2Mem =%d\r\n",DMA_InitStructure.Mem2Mem ); /* USART RX DMA1 Channel (triggered by USART Rx event) Config */ DMA_DeInit(rs485->RxDMAyChx); DMA_InitStructure.PeriphAddr = rs485->PeriphAddr; DMA_InitStructure.MemAddr = rs485->RxMemAddr; DMA_InitStructure.Direction = DMA_DIR_PERIPH_SRC; DMA_InitStructure.BufSize = rs485->RxBufSize; DMA_InitStructure.CircularMode = DMA_MODE_CIRCULAR; DMA_Init(rs485->RxDMAyChx, &DMA_InitStructure); // 设置 DMA Channelx 的重新映射请求。 DMA_RequestRemap(rs485->RxMAy_REMAP, rs485->DMAy, rs485->RxDMAyChx, ENABLE); printf("------------------------------------------------------------\r\n"); printf("DMA_InitStructure.PeriphAddr =%d\r\n",DMA_InitStructure.PeriphAddr ); printf("DMA_InitStructure.MemAddr =%d\r\n",DMA_InitStructure.MemAddr ); printf("DMA_InitStructure.Direction =%d\r\n",DMA_InitStructure.Direction ); printf("DMA_InitStructure.BufSize =%d\r\n",DMA_InitStructure.BufSize ); printf("DMA_InitStructure.PeriphInc =%d\r\n",DMA_InitStructure.PeriphInc ); printf("DMA_InitStructure.DMA_MemoryInc =%d\r\n",DMA_InitStructure.DMA_MemoryInc ); printf("DMA_InitStructure.PeriphDataSize=%d\r\n",DMA_InitStructure.PeriphDataSize); printf("DMA_InitStructure.MemDataSize =%d\r\n",DMA_InitStructure.MemDataSize ); printf("DMA_InitStructure.CircularMode =%d\r\n",DMA_InitStructure.CircularMode ); printf("DMA_InitStructure.Priority =%d\r\n",DMA_InitStructure.Priority ); printf("DMA_InitStructure.Mem2Mem =%d\r\n",DMA_InitStructure.Mem2Mem ); //DMA_ConfigInt(rs485->RxDMAyChx, DMA_INT_HTX, ENABLE);//半满中断使能 //DMA_ConfigInt(rs485->RxDMAyChx, DMA_INT_TXC, ENABLE);//全满中断是能 //DMA_ClearFlag(rs485->DMAyFlagHC, rs485->DMAy); //清除标志位,避免第一次传输出错 //DMA_ClearFlag(rs485->DMAyFlagTC, rs485->DMAy); //清除标志位,避免第一次传输出错 //DMA_ClrIntPendingBit(rs485->DMAy_IT_HC, rs485->DMAy); //DMA_ClrIntPendingBit(rs485->DMAy_IT_TC, rs485->DMAy); // //printf("CH=%d, HTX=%d, TXC=%d\r\n", (uint32_t)(rs485->RxDMAyChx), DMA_INT_HTX, DMA_INT_TXC); //printf("DMA=%d, HT=%d, TC=%d, HTX=%d, TXC=%d\r\n", // (uint32_t)(rs485->DMAy), // rs485->DMAyFlagHC, rs485->DMAyFlagTC, rs485->DMAy_IT_HC, rs485->DMAy_IT_TC); /**************************************** 串口配置 *********************************************/ /* USART configuration ------------------------------------------------------*/ USART_InitStructure.BaudRate = BaudRate; USART_InitStructure.WordLength = WordLength; USART_InitStructure.StopBits = StopBits; USART_InitStructure.Parity = Parity; USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE; USART_InitStructure.Mode = USART_MODE_RX | USART_MODE_TX; /* Configure USARTx */ USART_Init(rs485->UART, &USART_InitStructure); /* Enable USART Receive and Transmit interrupts */ //USART_ConfigInt(rs485->UART, USART_INT_RXDNE, ENABLE); // 接收中断 //USART_ConfigInt(rs485->UART, USART_INT_TXDE, ENABLE); // 发送中断 USART_ConfigInt(rs485->UART, USART_INT_IDLEF, ENABLE); // 空闲中断 /* Enable USART DMA Rx and TX request */ /* 启用 USART DMA Rx 和 TX 请求 */ USART_EnableDMA(rs485->UART, USART_DMAREQ_RX | USART_DMAREQ_TX, ENABLE); /* Enable USART TX DMA1 Channel */ /* 启用 USART TX DMA1 通道 */ DMA_EnableChannel(rs485->TxDMAyChx, ENABLE); /* Enable USART RX DMA1 Channel */ DMA_EnableChannel(rs485->RxDMAyChx, ENABLE); /* Enable the USARTx */ USART_Enable(rs485->UART, ENABLE); } void Rs485_DMA_send(RS485_T *rs485, uint16_t BufferLength) { DMA_EnableChannel(rs485->TxDMAyChx, DISABLE); // 设置当前 DMAy Channelx 传输中的数据单元数。 DMA_SetCurrDataCounter(rs485->TxDMAyChx, BufferLength); DMA_EnableChannel(rs485->TxDMAyChx, ENABLE); while (USART_GetFlagStatus(rs485->UART, USART_FLAG_TXDE) == RESET) { } } void Rs485_DMA_Revice_EN(RS485_T *rs485, uint16_t BufferLength) { DMA_EnableChannel(rs485->RxDMAyChx, DISABLE); // 设置当前 DMAy Channelx 传输中的数据单元数。 DMA_SetCurrDataCounter(rs485->RxDMAyChx, BufferLength); DMA_EnableChannel(rs485->RxDMAyChx, ENABLE); } void RS485_Send(RS485_T *rs485, uint8_t *_buf, uint16_t _len) { uint8_t i = 0; printf("[%s] Send: ", rs485->name); for(i = 0; i < _len; i++) { printf("0x%02X ", _buf[i]); } printf("\r\n"); memcpy((rs485->TxBuf), _buf, _len); Rs485_DMA_send(rs485, _len); } void RS485_Recieve_Process(RS485_T *rs485) { uint8_t data = 0; printf("[%s] Recv: ", rs485->name); while(!RingBuf_Read(&(rs485->rx_ringbuff), &data)) { printf("0x%02X ", data); } printf("\r\n"); }