如何让RS485实现打印输出功能

[复制链接]
 楼主| zeshoufx 发表于 2020-6-13 17:43 | 显示全部楼层 |阅读模式
一、基于RS232的串口重映射
       RS232是全双工的,基于RS232的串口重映射实现就很简单,官方例程有提供,不再赘述;
  1. int fputc(int ch,FILE *p)
  2. {
  3.         usart_data_transmit(USART0,(u8)ch);
  4.         while(!usart_flag_get(USART0,USART_FLAG_TBE));
  5.         return ch;
  6. }


二、基于RS485的串口打印输出
      大部分的RS485芯片支持半双工通讯模式,与RS232的全双工不同多了一个收发控制,同一时刻最多只能处于收发模式中的一种,
利用编译器下的库实现,包含头文件如图,,因为需要用到va_list 类和“vsnprintf()”函数,需要将“stdarg.h”等头文件添加
674485ee49e97730bf.png

三、程序
(1)、串口初始化
  1. void USART1_Init(u32 bound)
  2. {
  3.         //时钟设置
  4.         rcu_periph_clock_enable(RCU_GPIOA);       
  5.     rcu_periph_clock_enable(RCU_USART1);

  6.         //USARTx_TX
  7.         gpio_init(GPIOA,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_2);

  8.         //USARTx_RX
  9.         gpio_init(GPIOA,GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,GPIO_PIN_3);  
  10.        
  11.         #if RS485_USART1==1
  12.         gpio_init(GPIOA,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_1);
  13.         RS485_USART1_TX_EN=0;
  14.         #endif
  15.        
  16.         //NVIC 配置
  17.         nvic_irq_enable(USART1_IRQn,0,2);         
  18.        
  19.          //USARTx初始化
  20.         usart_baudrate_set(USART1,bound);
  21.     usart_parity_config(USART1,USART_PM_NONE);
  22.     usart_word_length_set(USART1,USART_WL_8BIT);
  23.     usart_stop_bit_set(USART1,USART_STB_1BIT);
  24.     usart_transmit_config(USART1,USART_TRANSMIT_ENABLE);
  25.     usart_receive_config(USART1,USART_RECEIVE_ENABLE);
  26.     usart_hardware_flow_rts_config(USART1,USART_RTS_DISABLE);
  27.     usart_hardware_flow_cts_config(USART1,USART_CTS_DISABLE);
  28.    
  29.         //使能配置
  30.        
  31.         usart_interrupt_enable(USART1,USART_INT_RBNE);
  32.         usart_interrupt_enable(USART1,USART_INT_IDLE);//开启串口空闲IDEL中断
  33.         usart_enable(USART1);                    //使能串口
  34.         USART1_printf("USART1 OK...\r\n");
  35. }
(2)、RS485打印函数
  1. void USART1_printf (char *fmt, ...)
  2. {
  3.         u16 i = 0;
  4.         va_list arg_ptr;
  5.         va_start(arg_ptr, fmt);  
  6.         vsnprintf((char *)USART1_TX_BUF, USART1_MAX_TX_LEN+1, fmt, arg_ptr);
  7.         va_end(arg_ptr);
  8.        
  9.         #if RS485_USART1==1
  10.         RS485_USART1_TX_EN=1;
  11.         #endif
  12.        
  13.         while ((i < USART1_MAX_TX_LEN) && USART1_TX_BUF[i])
  14.         {
  15.                 while (usart_flag_get(USART1, USART_FLAG_TBE) == RESET);
  16.                 usart_data_transmit(USART1, (u8) USART1_TX_BUF[i++]);
  17.                 while (usart_flag_get(USART1, USART_FLAG_TC)  == RESET);
  18.         }
  19.        
  20.         #if RS485_USART1==1
  21.         RS485_USART1_TX_EN=0;
  22.         #endif
  23. }
(3)主函数
  1. int main(void)
  2. {
  3.     sysdelay_set(96);
  4.     led_set();
  5.     USART1_Init(9600);
  6.     while (1)
  7.         {
  8.         led_on(5);
  9.         delay_nms(500);
  10.         USART1_printf("led on\r\n");
  11.         led_off(5);
  12.         delay_nms(500);
  13.         USART1_printf("led off\r\n");
  14.     }
  15. }


四、验证结果
983825ee49fb911268.png

aoyi 发表于 2020-7-6 16:13 | 显示全部楼层
非常感谢楼主分享
drer 发表于 2020-7-6 16:16 | 显示全部楼层
代码很全啊
gwsan 发表于 2020-7-6 16:16 | 显示全部楼层
楼主辛苦了
kxsi 发表于 2020-7-6 16:16 | 显示全部楼层
正好可以拿来用
nawu 发表于 2020-7-6 16:17 | 显示全部楼层
感谢分享代码哈
您需要登录后才可以回帖 登录 | 注册

本版积分规则

67

主题

1989

帖子

15

粉丝
快速回复 在线客服 返回列表 返回顶部