gd32f130 G8U6RS485 实现串口接收数据
你有没有想过,为什么我们在物联网设备中还需要RS485这种“老古董”通信协议?比如在实现LoRa通信网关时,RS485就像那个默默付出的老管家,虽然不炫酷,但稳如老狗。它的串口初始化代码虽然看起来一堆函数调用,但其实就是给串口“上发条”,设置波特率、校验位、数据位等等,确保数据能准确无误地传输。
问题来了,为什么不用更现代的通信方式,比如I2C或SPI?其实,RS485的优势在于它的长距离传输能力和抗干扰性,尤其在工业环境中,设备之间的距离可能是几百米,这时RS485就能大显身手。而I2C和SPI更适合短距离、高速率的通信,各有各的用武之地。
再进一步,RS485的初始化和中断服务函数如何协同工作?初始化函数负责配置串口的各项参数,而中断服务函数则像是个“快递小哥”,每当接收到数据时,它就会立刻行动,将数据从缓冲区中取出,并判断是否已经接收完整。这种机制确保了数据传输的实时性和可靠性。
所以,别看RS485代码写得繁琐,它背后的逻辑却是简单而实用的。下次你遇到类似的问题,不妨多想想:这个看似过时的技术,是否在某些场景下依然无可替代?
最近在实现lora通信网关的代码,用到了RS485实现串口接收数据,其主要代码及完整代码如下:
RS485串口初始化:
/*串口1初始化*/void rs485_usart_init(){ rcu_periph_clock_enable(RCU_USART1); //使能串口时钟 usart_disable(USART1); usart_baudrate_set(USART1, baudrate); //波特率 usart_parity_config(USART1, parity); //奇偶校验位 usart_word_length_set(USART1, wlen); //数据位 usart_stop_bit_set(USART1, stblen); //停止位 usart_hardware_flow_rts_config(USART1, USART_RTS_DISABLE); //禁用RTS usart_hardware_flow_cts_config(USART1, USART_CTS_DISABLE);//无硬件数据流控制 usart_receive_config(USART1, USART_RECEIVE_ENABLE); //使能接收 usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);//使能发送 usart_enable(USART1); drv_usart_nvic_init(); usart_interrupt_enable(USART1, USART_INT_RBNE);}
定时器初始化
void Timer_init(void){ timer_parameter_struct timer_initpara;/*使能时钟*/ rcu_periph_clock_enable(RCU_TIMER1); timer_deinit(TIMER1); /* TIMER0 configuration */ timer_initpara.prescaler = 99; //分频系数 timer_initpara.alignedmode= TIMER_COUNTER_EDGE; timer_initpara.counterdirection = TIMER_COUNTER_UP; //计数方式 timer_initpara.period = 7199; //重载周期 timer_initpara.clockdivision = TIMER_CKDIV_DIV1; //时钟分频因子 timer_initpara.repetitioncounter = 0; timer_init(TIMER1,&timer_initpara); //初始化 timer_interrupt_enable(TIMER1,TIMER_INT_UP);//允许中断nvic_irq_enable(TIMER1_IRQn , 1, 1); timer_disable(TIMER1);}
串口1中断服务函数
void USART1_IRQHandler(void){ uint32_t res; if( RESET != usart_flag_get(USART1, USART_FLAG_RBNE)) //接收到数据 { res=usart_data_receive(USART1);if ((RS485_RX_STA & (1<<15)) == 0)//接收完的一批数据,还没有被处理,则不再接收其他数据{ if (RS485_RX_STA <rs485_rx_max)//串口1接收缓冲区还没满,还可以接收数据{timer_counter_value_config(TIMER1,0); //计数器清空 if(RS485_RX_STA == 0) //一次接收的开始时USART3_RX_STA = 0;{ timer_enable