RS232
- 硬件直接对接,程序完全来自于USART
- 由sp3232将TTL电平转化为RS232的标准电平
- 实际应用中需要注意RS232对于2脚和3脚的直连或交叉接,现成的RS232当然不会有这个问题,但是自己DIY的时候要注意防止接反(如图3 图4)
RS485
- 基于usart
- 通过sp3485将数据的收发集成到一根线上,转而由RS485_RE(B口)判断/切换数据的收发模式
RS232和RS485的理论极限使用场景
即短距离传输,中距离传输和远距离传输
程序示例
rs485.c
#include "sys.h"
#include "usart.h"
#include "rs485.h"void RS485_Init(void){ //RS485接口初始化GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = RS485_RE; //选择端口号(0~15或all) GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //选择IO接口工作方式 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO接口速度(2/10/50MHz) GPIO_Init(RS485PORT, &GPIO_InitStructure);GPIO_ResetBits(RS485PORT,RS485_RE); //RE端控制接收/发送状态,RE为1时发送,为0时接收。}/*
RS485总线通信,使用USART3,这是RS485专用的printf函数
调用方法:RS485_printf("123"); //向USART3发送字符123
*/
void RS485_printf (char *fmt, ...){ char buffer[USART3_REC_LEN+1]; // 数据长度u8 i = 0;va_list arg_ptr;GPIO_SetBits(RS485PORT,RS485_RE); //为高电平(发送)//RS485收发选择线 va_start(arg_ptr, fmt); vsnprintf(buffer, USART3_REC_LEN+1, fmt, arg_ptr);while ((i < USART3_REC_LEN) && (i < strlen(buffer))){USART_SendData(USART3, (u8) buffer[i++]);while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET); }va_end(arg_ptr);GPIO_ResetBits(RS485PORT,RS485_RE); //为低电平(接收)//RS485收发选择线
}
可以将上面的程序与
usart_c.usart_printf(char * fmt);
做对比
不能说一模一样,只能说完全一致
RS485_Init()
更是不用多说
RS485的数据接收倒是没有再“套壳”
而是同usart一样
交由主程序
USART_GetFlagStatus 判断后
直接处理
main.c
#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "touch_key.h"
#include "relay.h"
#include "oled0561.h"#include "usart.h"
#include "rs485.h"int main (void){//主程序u8 a;delay_ms(100); //上电时等待其他器件就绪RCC_Configuration(); //系统时钟初始化 TOUCH_KEY_Init();//触摸按键初始化RELAY_Init();//继电器初始化I2C_Configuration();//I2C初始化OLED0561_Init(); //OLED初始化OLED_DISPLAY_8x16_BUFFER(0," YoungTalk "); //显示字符串OLED_DISPLAY_8x16_BUFFER(2," RS485 TEST "); //显示字符串OLED_DISPLAY_8x16_BUFFER(6,"TX: RX: "); //显示字符串USART3_Init(115200);//串口3初始化并启动RS485_Init();//RS485总线初始化,需要跟在USART3初始化下方while(1){if(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_A)){RS485_printf("%c",'A');OLED_DISPLAY_8x16(6,4*8,'A');} //向RS232串口发送字符并在OLED上显示 else if(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_B)){RS485_printf("%c",'B');OLED_DISPLAY_8x16(6,4*8,'B');} //向RS232串口发送字符并在OLED上显示 else if(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_C)){RS485_printf("%c",'C');OLED_DISPLAY_8x16(6,4*8,'C');} //向RS232串口发送字符并在OLED上显示else if(!GPIO_ReadInputDataBit(TOUCH_KEYPORT,TOUCH_KEY_D)){RS485_printf("%c",'D');OLED_DISPLAY_8x16(6,4*8,'D');} //向RS232串口发送字符并在OLED上显示//查询方式接收if(USART_GetFlagStatus(USART3,USART_FLAG_RXNE) != RESET){ //查询串口待处理标志位a =USART_ReceiveData(USART3);//读取接收到的数据OLED_DISPLAY_8x16(6,11*8,a);//在OLED上显示}}
}