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

#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");
}