> 文档中心 > gd32f130 G8U6RS485 实现串口接收数据

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