stm32f103实现rs485通讯

串口初始化,软件上,485多一个控制引脚,为1发送,为0接收。 初始化为接收状态。

#include "stm32f10x.h"
#include <stdio.h>
#include "uart.h"
#include "Delay.h"
#include "sys.h"

/*****************************************************
串口2初始化485
*******************************************************/
void usart2_init(uint32_t baud) 
{
	//PA1控制,PA2发,PA3收
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 
 
    // 配置USART2 tx引脚
	GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;   // UART2 TX,PA2引脚
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   // 复用推挽输出模式
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    // 配置USART2 rx引脚    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;   // UART2 RX,PA3引脚
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;   // 上拉模式
    GPIO_Init(GPIOA, &GPIO_InitStructure);
	//配置读写引脚
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;	//PA1
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
    // 配置UART2
    USART_InitTypeDef USART_InitStructure;	
    USART_InitStructure.USART_BaudRate = baud;  // 波特率
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;   // 数据位长度为8位
    USART_InitStructure.USART_StopBits = USART_StopBits_1;   // 停止位为1位
    USART_InitStructure.USART_Parity = USART_Parity_No;   // 无奇偶校验
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;   // 无硬件流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;   // 支持接收和发送模式
    USART_Init(USART2, &USART_InitStructure);
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启串口接收中断

	//NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	//配置串口1的中断优先级
    NVIC_InitTypeDef NVIC_InitStructure;	
	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
    // 使能UART2
    USART_Cmd(USART2, ENABLE);
}

/*****************************************************
/串口5初始化485
*******************************************************/
void usart5_init(uint32_t baud) 
{
	//PB3控制,PD2收,PC12发
	
	// 使能USART4时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);
	//打开复用时钟:
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD| RCC_APB2Periph_GPIOB| RCC_APB2Periph_AFIO, ENABLE);
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); 
    // 配置USART4 tx引脚
	GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;   // UART5 RX,PC12引脚
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   // 复用推挽输出模式
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
     //配置USART5 rx引脚   
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;   // UART5 TX,PD2引脚
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;   // 上拉模式
    GPIO_Init(GPIOD, &GPIO_InitStructure);
	//配置读写引脚	
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;   // UART5 PB3引脚
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   //推挽输出模式
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    // 配置UART5
    USART_InitTypeDef USART_InitStructure;	
    USART_InitStructure.USART_BaudRate = baud;  // 波特率
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;   // 数据位长度为8位
    USART_InitStructure.USART_StopBits = USART_StopBits_1;   // 停止位为1位
    USART_InitStructure.USART_Parity = USART_Parity_No;   // 无奇偶校验
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;   // 无硬件流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;   // 支持接收和发送模式
    USART_Init(UART5, &USART_InitStructure);
	USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);//开启串口接收中断
	
	//配置串口1的中断优先级
    NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
    // 使能UART5
    USART_Cmd(UART5, ENABLE);
}

定义发送和接收引脚,也可以不定义,直接具体引脚。

/***************************************************************
*  Set_Usart2_Flag: usart2的标志位,控制发送和接收
*  Set_Usart3_Flag: usart3的标志位,控制发送和接收
***************************************************************/
void Set_Usart2_Flag(uint8_t Flag)
{
	if(Flag){
		//发送模式
		GPIO_SetBits(GPIOA, GPIO_Pin_1);

	}else{
		//接收模式
		GPIO_ResetBits(GPIOA, GPIO_Pin_1);}
}

void Set_Usart5_Flag(uint8_t Flag)
{
	if(Flag){
		//发送模式
		GPIO_SetBits(GPIOB, GPIO_Pin_3);
		
	}else{
		//接收模式
		GPIO_ResetBits(GPIOB, GPIO_Pin_3);}

485发送数据,控制引脚置1,发送完毕置0

注意: 默认是接收状态。


/*********************************************************
/串口2发送字符串、数组 ///
**********************************************************/
void uart2_send_str(char *pstr) 
{
	char *p = pstr;
	
	//发送模式
    Set_Usart2_Flag(1);
	
	while(*p!='\0')
	{
		//发送数据
		USART_SendData(USART2,*p);
		while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);	
		p++;
	}
    // 等待发送完成
    while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);	
    //切换回接收模式
    Set_Usart2_Flag(0);
}
/***************************************************************/
void uart2_send_arry(uint8_t *buf,uint8_t len)
{
	uint8_t t;
	//发送模式
    Set_Usart2_Flag(1);
	
  	for(t=0;t<len;t++)		//循环发送数据
	{		   
		while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);	  
		USART_SendData(USART2,buf[t]);
	}	 	
     // 等待发送完成
    while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);
    Set_Usart2_Flag(0);			//设置为接收模式	
}

/*********************************************************
/串口5发送字符串、数组 ///
**********************************************************/
void uart5_send_str(char *pstr) 
{
	char *p = pstr;
	
	//发送模式
    Set_Usart5_Flag(1);
	
	while(*p!='\0')
	{
		//发送数据
		USART_SendData(UART5,*p);	
		while(USART_GetFlagStatus(UART5,USART_FLAG_TXE)==RESET);	
		p++;
	}
	
	    // 等待发送完成
    while (USART_GetFlagStatus(UART5, USART_FLAG_TC) == RESET);
    //切换回接收模式
    Set_Usart5_Flag(0);
}
/***************************************************************/
void uart5_send_arry(uint8_t *buf,uint8_t len)
{
	uint8_t t;
	//发送模式
    Set_Usart5_Flag(1);
  	for(t=0;t<len;t++)		//循环发送数据
	{		   
		while(USART_GetFlagStatus(UART5, USART_FLAG_TXE) == RESET);	  
		USART_SendData(UART5,buf[t]);
	}	 	
     // 等待发送完成
    while (USART_GetFlagStatus(UART5, USART_FLAG_TC) == RESET);
    Set_Usart5_Flag(0);			//设置为接收模式	
}

printf 重定义:usart2

(记得勾选上 MicroLIB。在调用:<math.h>,<stdlib.h>,<stdio.h>,<string.h>等文件时,比标准所需的RAM和FLASH空间都大大减小,因为MicroLIB做了深度优化)
在这里插入图片描述


/**********printf打印输出*************/
int fputc(int ch,FILE *f) {
	
	USART_SendData(USART2,ch);
	while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
	USART_ClearFlag(USART2,USART_FLAG_TXE);
	
	return ch;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值