#define ARRAYNUM(arr_name) (uint32_t)(sizeof(arr_name)/sizeof(*(arr_name))) #define USART0_DATA_ADDRESS ((uint32_t)0x40011004) uint8_t tx_buffer[UART1_REC_BUF_LEN]; uint8_t rx_buffer[UART1_REC_BUF_LEN]; void UART0_DMA_RX_INIT(void); void UART0_DMA_TX_INIT(void); void RS485En_txmode(void); uint8_t uart0_tx_flag=0x00; uint8_t uart0_wait_tx_flag=0x00;
/************************************************************ * 函数: UART0串口初始配置 * 说明: * 输入: 波特率 * 其他: ************************************************************/ void USART0_Init(uint32_t baud) { rcu_periph_clock_enable(RCU_GPIOA); // 使能GPIO时钟 rcu_periph_clock_enable(RCU_USART0); // 使能串口时钟 //RS485收发控制引脚 gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_PIN_8); // GPIO 模式设置 gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8); // 输出参数设置 gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_9 | GPIO_PIN_10); //UART0 Tx gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_9); // GPIO 模式设置 gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9); // 输出参数设置 //UART0 Rx gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_10); // GPIO 模式设置 gpio_output_options_set(GPIOA, GPIO_MODE_ANALOG, GPIO_OSPEED_50MHZ, GPIO_PIN_10); // 输出参数设置
usart_deinit(USART0); // 串口复位 usart_word_length_set(USART0, USART_WL_8BIT); // 字长 usart_stop_bit_set(USART0, USART_STB_1BIT); // 停止位 usart_parity_config(USART0, USART_PM_NONE); usart_baudrate_set(USART0, 115200U); // 波特率 usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE); usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE); usart_receive_config(USART0, USART_RECEIVE_ENABLE); // 接收使能 usart_transmit_config(USART0, USART_TRANSMIT_ENABLE); // 发送使能 usart_dma_receive_config(USART0, USART_DENR_ENABLE); usart_dma_transmit_config(USART0, USART_DENT_ENABLE);
usart_enable(USART0); //串口使能 nvic_irq_enable(USART0_IRQn, 6, 0); //串口中断配置 usart_interrupt_enable(USART0, USART_INT_IDLE); //串口接空闲中断 UART0_DMA_RX_INIT(); //DMA接收配置 UART0_DMA_TX_INIT(); //DMA发送配置 RS485En_rxmode(); //上电初始RS485为接收模式 } /******************************************************************* ******************************************************************** * 函数功能:UART0 采用DMA1通道2接收初始化 * ******************************************************************** ********************************************************************/ void UART0_DMA_RX_INIT(void) { dma_single_data_parameter_struct dma_init_struct; rcu_periph_clock_enable(RCU_DMA1); dma_deinit(DMA1, DMA_CH2); dma_init_struct.direction = DMA_PERIPH_TO_MEMORY; dma_init_struct.memory0_addr = (uint32_t)rx_buffer; dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; dma_init_struct.periph_memory_width = DMA_MEMORY_WIDTH_8BIT; dma_init_struct.number = UART1_REC_BUF_LEN; dma_init_struct.periph_addr = USART0_DATA_ADDRESS; dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; dma_init_struct.periph_memory_width = DMA_MEMORY_WIDTH_8BIT; dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; dma_init_struct.circular_mode = DMA_CIRCULAR_MODE_DISABLE; dma_single_data_mode_init(DMA1, DMA_CH2, &dma_init_struct);
dma_channel_subperipheral_select(DMA1, DMA_CH2, DMA_SUBPERI4); dma_channel_enable(DMA1, DMA_CH2); } /******************************************************************* ******************************************************************** * 函数功能:UART0 采用DMA1通道7发送 * ******************************************************************** ********************************************************************/ void UART0_DMA_TX_INIT(void) { dma_single_data_parameter_struct dma_init_struct; rcu_periph_clock_enable(RCU_DMA1); dma_deinit(DMA1, DMA_CH7); dma_init_struct.direction = DMA_MEMORY_TO_PERIPH; dma_init_struct.memory0_addr = (uint32_t)tx_buffer;; dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; dma_init_struct.number = UART1_REC_BUF_LEN; dma_init_struct.periph_addr = USART0_DATA_ADDRESS; dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; dma_init_struct.periph_memory_width = DMA_MEMORY_WIDTH_8BIT; dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; dma_single_data_mode_init(DMA1, DMA_CH7, &dma_init_struct); dma_circulation_disable(DMA1, DMA_CH7); dma_channel_subperipheral_select(DMA1, DMA_CH7, DMA_SUBPERI4); dma_channel_enable(DMA1, DMA_CH7); dma_interrupt_enable(DMA1, DMA_CH7, DMA_CHXCTL_FTFIE);//使用全传输完成中断 nvic_irq_enable(DMA1_Channel7_IRQn, 2, 0); //设置中断优先级 }
/************************************************************ * 函数: 串口0 DMA发送函数 * 说明: 串 * 输入: 无 * 其他: ************************************************************/ void USART0_DMA_SendData(uint8_t *buffer,uint16_t len) { uint8_t wait_uart0_tx_finsh_count=0x00; while(uart0_wait_tx_flag==0x01&&wait_uart0_tx_finsh_count<10) //等待发送完成超时判断 { wait_uart0_tx_finsh_count++; delay_1ms(1); } RS485En_txmode(); dma_channel_disable(DMA1, DMA_CH7); dma_flag_clear(DMA1, DMA_CH7, DMA_FLAG_FTF); memcpy(tx_buffer, buffer, len); //将待发送数据拷贝到发送缓冲区 dma_memory_address_config(DMA1, DMA_CH7,DMA_MEMORY_0,(uint32_t)tx_buffer);//设置要发送数据的内存地址 dma_transfer_number_config(DMA1, DMA_CH7, len); //发送数据长度 dma_channel_enable(DMA1, DMA_CH7); usart_dma_transmit_config(USART0, USART_DENT_ENABLE); uart0_wait_tx_flag=0x01; }
/************************************************************ * 函数: USART0_SendData(uint16_t *buf,uint16_t len) * 说明: 串口发送函数 * 输入: 无 * 输出: 无 * 返回值: 无 * 其他: ************************************************************/ void USART0_SendData(uint16_t *buf,uint16_t len) { uint16_t t; for(t=0;t { while(usart_flag_get(USART0, USART_FLAG_TC) == RESET); usart_data_transmit(USART0,buf[t]); } while(usart_flag_get(USART0, USART_FLAG_TC) == RESET); } /************************************************************ * 函数: 串口接收空闲中断服务程序 * 说明: 串口发送函数 * 输入: 无 * 输出: 无 * 返回值: 无 * 其他: ************************************************************/ void USART0_IRQHandler(void) { uint8_t test_rx_table[UART1_REC_BUF_LEN]; uint8_t temp; uint32_t receive_len; if(RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_IDLE)) { temp = USART_STAT0(USART0); temp = USART_DATA(USART0); temp = temp; receive_len= UART1_REC_BUF_LEN - dma_transfer_number_get(DMA1, DMA_CH2); dma_channel_disable(DMA1, DMA_CH2); dma_flag_clear(DMA1, DMA_CH2, DMA_FLAG_FTF); dma_channel_enable(DMA1, DMA_CH2); //将接收到的数据通过DMA发送出去 memcpy(test_rx_table, rx_buffer, receive_len); //将待发送数据拷贝到发送缓冲区 USART0_DMA_SendData(test_rx_table,receive_len); } } /************************************************************ * 函数: DMA1 CH7发送完成中断服务程序 * 说明: 串口发送函数 * 输入: 无 * 输出: 无 * 返回值: 无 * 其他: ************************************************************/ void DMA1_Channel7_IRQHandler(void) { if(dma_interrupt_flag_get(DMA1, DMA_CH7, DMA_INT_FLAG_FTF)) //获取传输完成标志位 { dma_interrupt_flag_clear(DMA1, DMA_CH7, DMA_FLAG_FTF); //清中断标志位 uart0_tx_flag=0x01; //发送完成标志,启动延时转换RS485接收模式 uart0_wait_tx_flag=0x00; //发送完成,等待标志位清零 } }
|