#include "usart.h" /* \arg COM_EC800: EC800 \arg COM_485: 485 \arg COM_232: 232 */ static rcu_periph_enum COM_CLK[COMn] = {COM_EC800_CLK, COM_485_CLK, COM_232_CLK}; static uint32_t COM_TX_PIN[COMn] = {COM_EC800_TX_PIN, COM_485_TX_PIN, COM_232_TX_PIN}; static uint32_t COM_RX_PIN[COMn] = {COM_EC800_RX_PIN, COM_485_RX_PIN, COM_232_RX_PIN}; static uint32_t COM_GPIO_PORT[COMn] = {COM_EC800_GPIO_PORT, COM_485_GPIO_PORT, COM_232_GPIO_PORT}; static rcu_periph_enum COM_GPIO_CLK[COMn] = {COM_EC800_GPIO_CLK, COM_485_GPIO_CLK, COM_232_GPIO_CLK}; static uint32_t COM_IT_HANDLER[COMn] = {COM_EC800_IT_HANDLER, COM_485_IT_HANDLER, COM_232_IT_HANDLER}; static uint32_t COM_BAUDTATE[COMn]={COM_EC800_BAUDRATE,COM_485_BAUDRATE,COM_232_BAUDRATE}; uint8_t UART0_RX_BUF[UART0_RX_LEN]; uint8_t UART0_RX_STAT = 0; uint8_t UART0_RX_MQTT_SUB_STAT=0; //mqttt订阅信息标志位 uint32_t UART0_RX_NUM = 0; usart_data_buf_t usart1_rx_buf; //清除dma buffer内数据 void Clear_DMA_Buffer(void) { UART0_RX_NUM=0; memset(UART0_RX_BUF,0,UART0_RX_LEN); } /*! \brief configure 485 DE gpio \param[out] none \retval none */ void gd_485_DE_pin_init(void) { /* enable the 485 DE pin clock */ rcu_periph_clock_enable(RCU_GPIOA); /* configure 485 DE GPIO port */ gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8); GPIO_BC(GPIOA) = GPIO_PIN_8; } /*! \brief turn 485 to tx \param[out] none \retval none */ void gd_485_DE_tx(void) { GPIO_BOP(GPIOA) = GPIO_PIN_8; } /*! \brief turn 485 to rx \param[out] none \retval none */ void gd_485_DE_rx(void) { GPIO_BC(GPIOA) = GPIO_PIN_8; } /*! \brief configure COM port \param[in] com: COM on the board \arg COM_EC800: EC800 \arg COM_485: 485 \arg COM_232: 232 \param[out] none \retval none */ void gd_com_init(uint32_t com) { uint32_t com_id = 0U; if(COM_EC800 == com) { com_id = 0U; } else if(COM_485 == com) { com_id=1U; } else if(COM_232 == com) { com_id = 2U; //重映射usart2端口 rcu_periph_clock_enable(RCU_AF); gpio_pin_remap_config(GPIO_USART2_FULL_REMAP, ENABLE); } //nvic_irq_enable(COM_IT_HANDLER[com_id], 0, 0); /* enable GPIO clock */ rcu_periph_clock_enable(COM_GPIO_CLK[com_id]); /* enable USART clock */ rcu_periph_clock_enable(COM_CLK[com_id]); /* connect port to USARTx_Tx */ gpio_init(COM_GPIO_PORT[com_id], GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, COM_TX_PIN[com_id]); /* connect port to USARTx_Rx */ gpio_init(COM_GPIO_PORT[com_id], GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, COM_RX_PIN[com_id]); /* USART configure */ usart_deinit(com); usart_baudrate_set(com, COM_BAUDTATE[com_id]); usart_word_length_set(com, USART_WL_8BIT); usart_stop_bit_set(com, USART_STB_1BIT); usart_parity_config(com, USART_PM_NONE); usart_hardware_flow_rts_config(com, USART_RTS_DISABLE); usart_hardware_flow_cts_config(com, USART_CTS_DISABLE); usart_receive_config(com, USART_RECEIVE_ENABLE); usart_transmit_config(com, USART_TRANSMIT_ENABLE); usart_enable(com); // usart_interrupt_enable(com, USART_INT_TBE); usart_interrupt_enable(com, USART_INT_RBNE); //开启接受终端 usart_interrupt_enable(com, USART_INT_IDLE); //开启空闲终端,也叫帧终端 } /*! \brief COM port to send buff \param[in] com: COM on the board \arg COM_485 \param[out] none \retval none */ void gd_com_485_send(uint8_t *message,uint16_t size){ uint16_t i=0; gd_485_DE_tx(); uint8_t data; for (i = 0; i < size; i++) { data = message[i]; usart_data_transmit(COM_485, data); while (RESET == usart_flag_get(COM_485, USART_FLAG_TC)); } gd_485_DE_rx(); } void gd_com_232_send(uint8_t *message,uint16_t size){ uint16_t i=0; for (i = 0; i < size; i++){ usart_data_transmit(COM_232, *(message + i)); while (RESET == usart_flag_get(COM_232, USART_FLAG_TC)); } } void gd_com_232_Receive(void) { uint8_t value; if(RESET != usart_interrupt_flag_get(COM_232, USART_INT_FLAG_RBNE)) { /* receive data */ value = (uint8_t)usart_data_receive(COM_232); usart_interrupt_flag_clear(COM_232,USART_INT_FLAG_ERR_FERR); } } /*! \brief configure EC800M pin \param[out] none \retval none */ void gd_EC800M_pin_init(void) { /* enable the EC800M power pin clock */ rcu_periph_clock_enable(EC800M_PER_GPIO_CLK); /* configure EC800M GPIO port */ gpio_init(EC800M_PER_GPIO_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, EC800M_PER_PIN); GPIO_BC(EC800M_PER_GPIO_PORT) = EC800M_PER_PIN; /* enable the EC800M reset pin clock */ rcu_periph_clock_enable(EC800M_RST_GPIO_CLK); /* configure EC800M GPIO port */ gpio_init(EC800M_RST_GPIO_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, EC800M_RST_PIN); GPIO_BC(EC800M_RST_GPIO_PORT) = EC800M_RST_PIN; } void gd_pull_EC800M_pwr_up(void) { GPIO_BOP(EC800M_PER_GPIO_PORT) = EC800M_PER_PIN; } void gd_pull_EC800M_pwr_down(void) { GPIO_BC(EC800M_PER_GPIO_PORT) = EC800M_PER_PIN; } void gd_pull_EC800M_rst_up(void) { GPIO_BOP(EC800M_RST_GPIO_PORT) = EC800M_RST_PIN; } void gd_pull_EC800M_rst_down(void) { GPIO_BC(EC800M_RST_GPIO_PORT) = EC800M_RST_PIN; } //////////////////////////////////////////////////////////////////// void dma_config(void) { dma_parameter_struct dma_init_struct; rcu_periph_clock_enable(RCU_DMA0); dma_deinit(DMA0, DMA_CH4); dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY; dma_init_struct.memory_addr = (uint32_t)UART0_RX_BUF; dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; dma_init_struct.number = UART0_RX_LEN; dma_init_struct.periph_addr = (uint32_t)(&USART_DATA(USART0));// ((uint32_t)0x40013804); dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; dma_init(DMA0, DMA_CH4, &dma_init_struct); dma_circulation_disable(DMA0, DMA_CH4); dma_memory_to_memory_disable(DMA0, DMA_CH4); usart_dma_transmit_config(USART0, USART_DENT_ENABLE|USART_DENR_ENABLE); //nvic_irq_enable(DMA0_Channel4_IRQn, 2, 2); dma_interrupt_enable(DMA0, DMA_CH4, DMA_INT_FTF|DMA_INT_HTF|DMA_INT_ERR); dma_channel_enable(DMA0, DMA_CH4); } //手动控制dma搬运的数据地址和大小,在使用完成后需要恢复到默认的dma配置 void dma_config_change(char *dmaBuffer,uint32_t bufferSize) { dma_parameter_struct dma_init_struct; rcu_periph_clock_enable(RCU_DMA0); dma_deinit(DMA0, DMA_CH4); dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY; dma_init_struct.memory_addr = (uint32_t)dmaBuffer; dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; dma_init_struct.number = bufferSize; dma_init_struct.periph_addr = (uint32_t)(&USART_DATA(USART0));// ((uint32_t)0x40013804); dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; dma_init(DMA0, DMA_CH4, &dma_init_struct); dma_circulation_disable(DMA0, DMA_CH4); dma_memory_to_memory_disable(DMA0, DMA_CH4); usart_dma_transmit_config(USART0, USART_DENT_ENABLE|USART_DENR_ENABLE); //nvic_irq_enable(DMA0_Channel4_IRQn, 2, 2); dma_interrupt_enable(DMA0, DMA_CH4, DMA_INT_FTF|DMA_INT_ERR); dma_channel_enable(DMA0, DMA_CH4); } /* * 函数名:void config_485_port(uint32_t com,uint32_t baudrate, uint8_t databits, uint8_t stopbits, uint8_t parity, uint8_t flowcontrol) * 输入参数:com 串口,baudrate,databits,stopbits,parity,flowcontol 串口的配置参数 * 输出参数:无 * 返回值:无 * 函数作用:配置485串口参数 */ void config_485_port(uint32_t com,uint32_t baudrate, uint8_t databits, uint8_t stopbits, uint8_t parity) { uint32_t com_id = 0U; uint8_t wordLength; if(parity!=0) { wordLength=databits+1; }else wordLength=databits; if(COM_485 == com){ com_id=1U; // nvic_irq_enable(COM_IT_HANDLER[com_id], 0, 0); /* enable GPIO clock */ rcu_periph_clock_enable(COM_GPIO_CLK[com_id]); /* enable USART clock */ rcu_periph_clock_enable(COM_CLK[com_id]); /* connect port to USARTx_Tx */ gpio_init(COM_GPIO_PORT[com_id], GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, COM_TX_PIN[com_id]); /* connect port to USARTx_Rx */ gpio_init(COM_GPIO_PORT[com_id], GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, COM_RX_PIN[com_id]); //usart_deinit(com); usart_baudrate_set(com, baudrate); usart_word_length_set(com, (wordLength == 9) ? USART_WL_9BIT : USART_WL_8BIT); usart_stop_bit_set(com, (stopbits == 2) ? USART_STB_2BIT : USART_STB_1BIT); usart_parity_config(com, parity == 1 ? (USART_PM_ODD) : (parity == 2 ? USART_PM_EVEN : USART_PM_NONE)); usart_hardware_flow_rts_config(com, USART_RTS_DISABLE); usart_hardware_flow_cts_config(com, USART_CTS_DISABLE); usart_receive_config(com, USART_RECEIVE_ENABLE); usart_transmit_config(com, USART_TRANSMIT_ENABLE); /* 使能串口 */ usart_enable(com); usart_interrupt_enable(com, USART_INT_RBNE); usart_interrupt_enable(com, USART_INT_IDLE); //nvic_irq_enable(USART1_IRQn, 1, 0); //解决485第一个帧数据第一个字节丢失问题 usart_flag_clear(COM_485,USART_FLAG_TC); } } void nvic_config(void) { nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); // 设置抢占优先级和子优先级的位数为 2 nvic_irq_enable(USART0_IRQn, 0, 0); nvic_irq_enable(USART1_IRQn, 1, 0); nvic_irq_enable(USART2_IRQn, 2, 0); nvic_irq_enable(DMA0_Channel4_IRQn, 2, 1); }