You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
428 lines
26 KiB
428 lines
26 KiB
#include "rs485.h" |
|
#include "delay.h" |
|
#include "User_Systick_Config.h" |
|
#include <stdio.h> |
|
#include <string.h> |
|
|
|
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"); |
|
}
|
|
|