1)实验目的
实现STM32和电脑上位机任意字符组合的接收和发送
2)源代码
2-1:RS485.C文件中源代码
主要包括引脚功能配置函数,中断接收函数,发送和数据处理函数
#include “RS485.h”
/**
#define RS485 USART3
ModBus_Tx ModBus_T;
u8 RS485_TX_EN=0,RS485_RX_Over;
/**
函数功能: 初始化配置485通讯GPIO引脚
输入参数: 无
返 回 值: 无
说 明:无
*/
void RS485_GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/初始化RCC_485_Pin 485控制引脚端口时钟/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//RCC_APB2Periph_GPIOB
/初始化RCC_485_RTX 485串口通讯功能端口时钟/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);//RCC_APB1Periph_USART3
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//端口复用功能开启
/初始化控制端口/
GPIO_InitStructure.GPIO_Pin=RS485_EN_Pin;//EN_485
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
GPIO_Init(RS485_EN_Port,&GPIO_InitStructure);
/初始化TX端口/
GPIO_InitStructure.GPIO_Pin=RS485_TX_Pin;//TX
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(RS485_TX_Port,&GPIO_InitStructure);
/初始化RX端口/
GPIO_InitStructure.GPIO_Pin=RS485_RX_Pin;//对应于STM32的USART3_TX
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//推挽复用输出
GPIO_Init(RS485_RX_Port,&GPIO_InitStructure);
}
/**
函数功能: 初始化配置485通讯功能
输入参数: USART_TypeDef* USARTx:USART功能通道;uint32_t BaudRate:波特率
返 回 值: 无
说 明:无
*/
void USART_Configuration(uint32_t BaudRate)
{
USART_InitTypeDef USART_InitStructure;
RS485_GPIO_Configuration();//初始化RS485 GPIO引脚
USART_InitStructure.USART_BaudRate=BaudRate;//系统USART波特率设置
USART_InitStructure.USART_WordLength=USART_WordLength_8b;//字长设置为8位
USART_InitStructure.USART_StopBits=USART_StopBits_1;//在帧结尾传输一个停止位
USART_InitStructure.USART_Parity=USART_Parity_No;//奇偶校验位设置为奇偶使能
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//设置为硬件流控制失能
USART_InitStructure.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;//发送和接受均使能
USART_Init(RS485,&USART_InitStructure);
USART_ITConfig(RS485,USART_IT_RXNE,ENABLE);
USART_Cmd(RS485,ENABLE);
USART_ClearFlag(RS485,USART_FLAG_TC);//清空发送成功标志位
RS485_EN(0);//初始化为接收状态
RS485_TX_EN=0;//接收状态
}
void USART3_IRQHandler(void)
{
u8 res=0;
if(USART_GetITStatus(RS485,USART_IT_RXNE)!=RESET)//检查RS485是否触发接收中断标志位
{
res=USART_ReceiveData(RS485);//将接收到的数据保存到临时变量res中
if(ModBus_T.Rx_Count
ModBus_T.RS485_RX_BUF[ModBus_T.Rx_Count]=res; //将接收到的数据存放到接收缓冲区内
ModBus_T.Rx_Count++;
}
}
}
//RS485发送len个字节.
//buf:发送区首地址
//len:发送的字节数(为了和本代码的接收匹配,这里建议不要超过64个字节)
void RS485_Send_Data(u8 *buf,u8 len)
{
u8 t;
RS485_TX_EN=1; //设置为发送模式
RS485_EN(1);
for(t=0;t
while(USART_GetFlagStatus(RS485, USART_FLAG_TC) == RESET);
USART_SendData(RS485,buf[t]);
}
while(USART_GetFlagStatus(RS485, USART_FLAG_TC) == RESET);
ModBus_T.Rx_Count=0; //清空接收数组计数变量
RS485_TX_EN=0; //设置为接收模式
RS485_EN(0);
RS485_RX_Over=0;//开始下一轮接收
}
//RS485查询接收到的数据
//buf:接收缓存首地址
//返回接收到的字节数
u8 RS485_Receive_Data(u8 *buf)
{
u8 rxlen=ModBus_T.Rx_Count;
u8 i=0;
u8 len=0; //默认为0
delay_ms(10); //等待10ms,连续超过10ms没有接收到一个数据,则认为接收结束
if(rxlen==ModBus_T.Rx_Count&&rxlen)//接收到了数据,且接收完成了
{
for(i=0;i
buf[i]=ModBus_T.RS485_RX_BUF[i];
}
len=ModBus_T.Rx_Count; //记录本次数据长度
ModBus_T.Rx_Count=0; //清零
RS485_RX_Over=1;//接收完成标志位置位
}
return len;
}
2-2 RS485.H中的源代码
#ifndef RS485_H
#define RS485_H
#include “stm32f10x.h”
#include “stm32f10x_usart.h”
#include “SysTick.h”
//#define RCC_485_Pin RCC_APB2Periph_GPIOB
//#define RCC_485_RTX RCC_APB1Periph_USART3
#define RS485_TX_Pin GPIO_Pin_11
#define RS485_TX_Port GPIOB
#define RS485_RX_Pin GPIO_Pin_10
#define RS485_RX_Port GPIOB
#define RS485_EN_Pin GPIO_Pin_12
#define RS485_EN_Port GPIOB
#define RS485_EN(x) x ? GPIO_SetBits(RS485_EN_Port,RS485_EN_Pin):GPIO_ResetBits(RS485_EN_Port,RS485_EN_Pin)
#define RS485_RX_BUF_LEN 64 //宏定义接收缓冲区长度,最大RS485_RX_BUF_LEN个字节
extern u8 RS485_TX_EN; //声明485通讯接收与发送模式切换标志位
//RS485_TX_EN=1;–发送模式
//RS485_TX_EN=0;–接收模式
extern u8 RS485_RX_Over;
typedef struct
{
u8 RS485_RX_BUF[RS485_RX_BUF_LEN];
u8 Rx_Count;
}ModBus_Tx;
void RS485_GPIO_Configuration(void);
void USART_Configuration(uint32_t BaudRate);
void RS485_Send_Data(u8 *buf, u8 len);
u8 RS485_Receive_Data(u8 *buf);
#endif
2-3 main函数
#include
int main()
{
u8 USART_RXLEN;
ModBus_Tx ModBus_T;
SystemInit();//72m
USART_Configuration(9600);//初始化USART 9600 N 8 1
NVIC_RS485_Configuration();
USART_232_Configuration(9600);
NVIC_RS232_Configuration();
while(1)
{
if(!RS485_RX_Over)
{
USART_RXLEN=RS485_Receive_Data(ModBus_T.RS485_RX_BUF);
}
else
RS485_Send_Data(ModBus_T.RS485_RX_BUF,USART_RXLEN);//发送5个字节
}
}