#include "uart.h" static INT8U uart1_tx_buf[UART1_TX_LEN] = {0}; static INT8U uart1_rx_buf[UART1_REC_LEN] = {0}; // static INT8U uart5_tx_buf[UART3_TX_LEN] = {0}; // static INT8U uart5_rx_buf[UART3_REC_LEN] = {0}; UartFrame_TypeDef Uart1FrameStruct[MAX_MSG_NUM]; // UartFrame_TypeDef Uart5FrameStruct[MAX_MSG_NUM]; extern OS_EVENT *uart1_mbox; // extern OS_EVENT *uart5_mbox; /*! \brief configure DMA interrupt \param[in] none \param[out] none \retval none */ void uart1_nvic_config(void) { NVIC_InitTypeDef NVIC_InitStructure; // Usart1 NVIC 配置 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //串口1中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器 } /*! \brief configure DMA \param[in] none \param[out] none \retval none */ void uart1_dma_init(void) { DMA_InitTypeDef DMA_InitStructure; /* deinitialize UART0_DMA channel7(USART0 tx) */ DMA_DeInit(DMA1_Stream7); /* 配置 DMA Stream */ DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(USART1->DR)); // DMA外设地址 DMA_InitStructure.DMA_BufferSize = UART1_TX_LEN; //数据传输量 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设非增量模式 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //存储器增量模式 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据长度:8位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //存储器数据长度:8位 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // 使用普通模式 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //中等优先级 DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //存储器突发单次传输 DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //外设突发单次传输 DMA_InitStructure.DMA_Channel = DMA_Channel_4; //通道选择 DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; //存储器到外设模式 DMA_InitStructure.DMA_Memory0BaseAddr = (u32)uart1_tx_buf; // DMA 存储器0地址 DMA_Init(DMA1_Stream7, &DMA_InitStructure); //初始化DMA Stream /* deinitialize UART0_DMA channel2 (USART0 rx) */ DMA_DeInit(DMA1_Stream2); /* 配置 DMA Stream */ DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(USART1->DR)); // DMA外设地址 DMA_InitStructure.DMA_BufferSize = UART1_REC_LEN; //数据传输量 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设非增量模式 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //存储器增量模式 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据长度:8位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //存储器数据长度:8位 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; // 使用循环模式 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //中等优先级 DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //存储器突发单次传输 DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //外设突发单次传输 /* 配置 RX DMA */ DMA_InitStructure.DMA_Channel = DMA_Channel_4; /* 配置接收通道 */ DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; /* 设置从外设到内存 */ DMA_InitStructure.DMA_Memory0BaseAddr = (u32)uart1_rx_buf; /* 设置内存地址 */ DMA_Init(DMA1_Stream2, &DMA_InitStructure); /* 使能 DMA USART TX Stream */ USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE); // 使能串口DMA接收数据 } void uart1_config(void) { USART_InitTypeDef USART_InitStructure; // USART1 初始化设置 USART_InitStructure.USART_BaudRate = 9600U; //波特率设置 USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为8位数据格式 USART_InitStructure.USART_StopBits = USART_StopBits_1; //一个停止位 USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验位 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件数据流控制 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式 USART_Init(USART1, &USART_InitStructure); //初始化串口1 USART_Cmd(USART1, ENABLE); //使能串口1 } void uart1_init(void) { uart1_config(); uart1_dma_init(); uart1_nvic_config(); // /* USART DMA enable*/ USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE); /*configure DMA0 interrupt*/ USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); //开启空闲中断 USART_ITConfig(USART1, USART_IT_TC, ENABLE); UART1_RX_ENABLE; } //开启一次DMA传输 // DMA_Streamx:DMA数据流,DMA1_Stream0~7/DMA2_Stream0~7 // count:数据传输量 void Uart1DMA_Enable(DMA_Stream_TypeDef *DMA_Streamx, u16 count) { DMA_Cmd(DMA_Streamx, DISABLE); //关闭DMA传输 while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE) { } //确保DMA可以被设置 DMA_SetCurrDataCounter(DMA_Streamx, count); //数据传输量 DMA_Cmd(DMA_Streamx, ENABLE); //开启DMA传输 } void Uart1_dma_Send_Data(const INT8U *buf, INT16U len) { // INT16U cnt = 0; if (RESET != USART_GetFlagStatus(UART1_DMA, USART_FLAG_TC)) { DMA_ClearFlag(DMA1_Stream2, DMA_FLAG_TCIF5); } UART1_TX_ENABLE; if (len > UART1_TX_LEN) { len = UART1_TX_LEN; } memcpy(uart1_tx_buf, buf, len); USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); // 使能DMA串口发送数据 Uart1DMA_Enable(DMA1_Stream7, len); } void USART1_IRQHandler(void) { static INT8U u0_index = 0; volatile INT8U clear = 0; INT8U rec_cnt = 0; if (RESET != USART_GetITStatus(USART1, USART_IT_IDLE)) { clear = USART1->SR; clear = USART1->DR; // 先读SR, 再读DR, 就是为了消除IDLE中断 DMA_Cmd(DMA1_Stream2, DISABLE); DMA_ClearFlag(DMA1_Stream2, DMA_FLAG_TCIF5); rec_cnt = UART1_REC_LEN - DMA_GetCurrDataCounter(DMA1_Stream2); // 获得接收帧帧长 特别注意: 帧长不是DMA_GetCurrDataCounter(DMA2_Stream5) // dma_channel_disable(UART0_DMA, UART0_DMA_RXCH); // dma_flag_clear(UART0_DMA, UART0_DMA_RXCH, DMA_FLAG_FTF); // rec_cnt = dma_transfer_number_get(UART0_DMA, UART0_DMA_RXCH); // rec_cnt = UART0_REC_LEN - rec_cnt; memcpy(Uart1FrameStruct[u0_index].buf, uart1_rx_buf, rec_cnt); Uart1FrameStruct[u0_index].len = rec_cnt; OSMboxPost(uart1_mbox, &Uart1FrameStruct[u0_index]); if (u0_index < MAX_MSG_NUM - 1) { u0_index++; } else { u0_index = 0; } DMA_SetCurrDataCounter(DMA1_Stream7, UART1_REC_LEN); DMA_Cmd(DMA1_Stream7, ENABLE); // dma_channel_enable(UART0_DMA, UART0_DMA_RXCH); } else if (RESET != USART_GetITStatus(USART1, USART_IT_TC)) { USART_ClearITPendingBit(USART1, USART_IT_TC); // 清除发送完成标标志位 UART1_RX_ENABLE; // 485接收使能 Uart1DMA_Enable(DMA1_Stream2, UART1_REC_LEN); // DMA接收使能 DMA_Cmd(DMA1_Stream7, DISABLE); // 关闭发送DMA DMA_SetCurrDataCounter(DMA1_Stream7, 0); // 清除发送数据长度 // usart_interrupt_flag_clear(USART0, USART_INT_FLAG_TC); // UART1_RX_ENABLE; // dma_channel_enable(UART0_DMA, UART0_DMA_RXCH); // usart_dma_transmit_config(USART0, USART_DENT_DISABLE); // dma_channel_disable(UART0_DMA, UART0_DMA_TXCH); } } // //uart5 // /*! // \brief configure DMA interrupt // \param[in] none // \param[out] none // \retval none // */ // void uart5_nvic_config(void) // { // nvic_irq_enable(USART5_IRQn, 0, 0); // } // /*! // \brief configure DMA // \param[in] none // \param[out] none // \retval none // */ // void uart5_dma_init(void) // { // dma_single_data_parameter_struct dma_init_struct; // /* deinitialize UART5_DMA channel6(USART5 tx) */ // dma_single_data_para_struct_init(&dma_init_struct); // dma_deinit(UART5_DMA, UART5_DMA_TXCH); // dma_init_struct.direction = DMA_MEMORY_TO_PERIPH; // dma_init_struct.memory0_addr = (uint32_t)uart5_tx_buf; // dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; // dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT; // dma_init_struct.number = UART5_TX_LEN;//ARRAYNUM(uart0_tx_buf); // dma_init_struct.periph_addr = (uint32_t)&USART_DATA(USART5); // dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; // dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; // dma_single_data_mode_init(UART5_DMA, UART5_DMA_TXCH, &dma_init_struct); // /* configure DMA mode */ // dma_circulation_disable(UART5_DMA, UART5_DMA_TXCH); // dma_channel_subperipheral_select(UART5_DMA, UART5_DMA_TXCH, DMA_SUBPERI5); // /* enable UART5_DMA channel7 */ // dma_channel_enable(UART5_DMA, UART5_DMA_TXCH); // /* deinitialize UART5_DMA channel2 (USART5 rx) */ // dma_deinit(UART5_DMA, UART5_DMA_RXCH); // dma_init_struct.direction = DMA_PERIPH_TO_MEMORY; // dma_init_struct.memory0_addr = (uint32_t)uart5_rx_buf; // dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; // dma_init_struct.number = UART5_REC_LEN;//10; // dma_init_struct.periph_addr = (uint32_t)&USART_DATA(USART5); // dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; // dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT; // dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; // dma_single_data_mode_init(UART5_DMA, UART5_DMA_RXCH, &dma_init_struct); // /* configure DMA mode */ // dma_circulation_disable(UART5_DMA, UART5_DMA_RXCH); // dma_channel_subperipheral_select(UART5_DMA, UART5_DMA_RXCH, DMA_SUBPERI5); // /* enable UART5_DMA channel2 */ // dma_channel_enable(UART5_DMA, UART5_DMA_RXCH); // } // void uart5_config(void) // { // /* USART configure */ // usart_deinit(USART5); // usart_baudrate_set(USART5,115200U); // usart_parity_config(USART5, USART_PM_NONE); // usart_word_length_set(USART5, USART_WL_8BIT); // usart_stop_bit_set(USART5, USART_STB_1BIT); // usart_receive_config(USART5, USART_RECEIVE_ENABLE); // usart_transmit_config(USART5, USART_TRANSMIT_ENABLE); // usart_enable(USART5); // } // void uart5_init(void) // { // uart5_config(); // uart5_dma_init(); // uart5_nvic_config(); // /* USART DMA enable*/ // usart_dma_receive_config(USART5, USART_DENR_ENABLE); // // usart_dma_transmit_config(USART5, USART_DENT_ENABLE); // /*configure DMA5 interrupt*/ // usart_interrupt_enable(USART5, USART_INT_IDLE); // usart_interrupt_enable(USART5, USART_INT_TC); // UART5_RX_ENABLE; // } // void Uart5_Send_Data(const INT8U *buf, INT16U len) // { // INT8U i; // UART5_TX_ENABLE; // 485 发送使能 // for(i=0; i UART5_TX_LEN) // { // len = UART5_TX_LEN; // } // memcpy(uart5_tx_buf, buf, len); // uart_dma_enable(UART5_DMA, UART5_DMA_TXCH, len); // usart_dma_transmit_config(USART5, USART_DENT_ENABLE); // } // void USART5_IRQHandler(void) // { // static INT8U u5_index = 0; // volatile INT8U clear = 0; // INT8U rec_cnt = 0; // if(RESET != usart_interrupt_flag_get(USART5, USART_INT_FLAG_IDLE)) // { // clear = USART_STAT0(USART5); // // clear = usart_data_receive(USART5); // clear = USART_DATA(USART5); // dma_channel_disable(UART5_DMA, UART5_DMA_RXCH); // // dma_interrupt_flag_clear(UART5_DMA, UART5_DMA_RXCH, DMA_INT_FLAG_FTF); // dma_flag_clear(UART5_DMA, UART5_DMA_RXCH, DMA_FLAG_FTF); // rec_cnt = dma_transfer_number_get(UART5_DMA, UART5_DMA_RXCH); // rec_cnt = UART5_REC_LEN - rec_cnt; // memcpy(Uart5FrameStruct[u5_index].buf, uart5_rx_buf, rec_cnt); // Uart5FrameStruct[u5_index].len = rec_cnt; // OSMboxPost(uart5_mbox, &Uart5FrameStruct[u5_index]); // if(u5_index < MAX_MSG_NUM - 1) // { // u5_index++; // } // else // { // u5_index = 0; // } // // dma_transfer_number_config(UART5_DMA, UART5_DMA_RXCH, 0); // dma_channel_enable(UART5_DMA, UART5_DMA_RXCH); // } // else if(RESET != usart_interrupt_flag_get(USART5, USART_INT_FLAG_TC)) // { // usart_interrupt_flag_clear(USART5, USART_INT_FLAG_TC); // UART5_RX_ENABLE; // dma_channel_enable(UART5_DMA, UART5_DMA_RXCH); // usart_dma_transmit_config(USART5, USART_DENT_DISABLE); // dma_channel_disable(UART5_DMA, UART5_DMA_TXCH); // } // }