RS485通讯实验

                                          RS485通讯实验

1.硬件:

STM32的串口管教加一个485芯片控制IO:

还需要一个USB 转485转换器,一端接485AB,USB口插PC上用串口助手查看数据。

注意点:以板子为核心,PC12置1为向外发送数据,PC12置0为向内接收数据。

2.代码,效果就是串口3发送5字节数据后收到同样5字节数据的返回:

rs485.h文件:
#ifndef RS485_RS485_H_
#define RS485_RS485_H_

#include "Sys.h"

u8 RS485_RX_CNT;
//接收缓存区
u8 RS485_RX_BUF[64];  	//接收缓冲,最大64个字节.;


void RS485_Send_Data(u8 *buf,u8 len);
void RS485_Receive_Data(u8 *buf,u8 *len);

#endif /* RS485_RS485_H_ */



rs485.c文件:
#include "rs485.h"
#include "Uart.h"
volatile unsigned char RS485_REC_Flag = 0;
//接收缓存区
u8 RS485_RX_BUF[64];  	//接收缓冲,最大64个字节.
//接收到的数据长度
u8 RS485_RX_CNT=0;

//RS485发送len个字节.
//buf:发送区首地址
//len:发送的字节数(为了和本代码的接收匹配,这里建议不要超过64个字节)
void RS485_Send_Data(u8 *buf,u8 len)
{
	u8 t;
	GPIO_SetBits(GPIOC,GPIO_Pin_12);
  	for(t=0;t<len;t++)		//循环发送数据
	{
		while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);
		USART_SendData(USART3,buf[t]);
	}

	while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);
	RS485_RX_CNT=0;
	GPIO_ResetBits(GPIOC,GPIO_Pin_12);
}
//RS485查询接收到的数据
//buf:接收缓存首地址
//len:读到的数据长度
void RS485_Receive_Data(u8 *buf,u8 *len)
{
	u8 rxlen=RS485_RX_CNT;
	u8 i=0;
	u8 lenx = 5;
	*len=0;				//默认为0
	delay_ms(100);		//等待10ms,连续超过10ms没有接收到一个数据,则认为接收结束
	if(rxlen==RS485_RX_CNT&&rxlen)//接收到了数据,且接收完成了
	{
		for(i=0;i<rxlen;i++)
		{
			buf[i]=RS485_RX_BUF[i];
		}
		RS485_Send_Data(buf,lenx);
		*len=RS485_RX_CNT;	//记录本次数据长度
		RS485_RX_CNT=0;		//清零
	}
}


void USART3_IRQHandler(void)
{
	u8 res;
 	if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) //接收到数据
	{

		res =USART_ReceiveData(USART3); 	//读取接收到的数据
		if(RS485_RX_CNT<64)
		{
			RS485_RX_BUF[RS485_RX_CNT]=res;		//记录接收到的值
			RS485_RX_CNT++;						//接收数据增加1
		}
	}
}

Uart.h文件:
#ifndef UART_UART_H_
#define UART_UART_H_

#include "Sys.h"

#define USART_REC_LEN  			200  	//定义最大接收字节数 200

u16 USART_RX_STA;       //接收状态标记
u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.

void uart_init(u32 bound);
void uart3_init(u32 bound);

#endif /* UART_UART_H_ */

Uart.c文件:
#include "Uart.h"
void uart_init(u32 bound)
{

	//USART 初始化设置
	USART_InitTypeDef USART_InitStructure;


	USART_InitStructure.USART_BaudRate = bound;//串口波特率
	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_Rx | USART_Mode_Tx;	//收发模式

	USART_Init(UART5, &USART_InitStructure); //初始化串口1
	USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);//开启串口接受中断
	USART_Cmd(UART5, ENABLE);                    //使能串口1



}

void uart3_init(u32 bound)
{

	//USART 初始化设置
	USART_InitTypeDef USART_InitStructure;

	USART_InitStructure.USART_BaudRate = bound;//串口波特率
	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_Rx | USART_Mode_Tx;	//收发模式

	USART_Init(USART3, &USART_InitStructure); //初始化串口1
	USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启串口接受中断
	USART_Cmd(USART3, ENABLE);                    //使能串口1
	USART_ClearITPendingBit(USART3, USART_IT_TC);//清除中断TC位


}

Sys.h文件:
#ifndef SYS_SYS_H_
#define SYS_SYS_H_

#include <stdio.h>
#include <string.h>
#include "stm32f10x.h"

#define 	True	(1)
#define 	False 	(0)
typedef   uint32_t   u32;///32位


void delay_init(void);
void RCC_Configuration(void);
void GPIO_RemapConfig(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void systemInit(void);
void delay_ms(u16 nms);


#endif /* SYS_SYS_H_ */


Sys.c文件:
#include "Sys.h"
#include "Uart.h"

static u8  fac_us=0;							//us延时倍乘数
static u16 fac_ms=0;							//ms延时倍乘数,在ucos下,代表每个节拍的ms数
//初始化延迟函数
//当使用OS的时候,此函数会初始化OS的时钟节拍
//SYSTICK的时钟固定为HCLK时钟的1/8
//SYSCLK:系统时钟
void delay_init()
{
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);	//选择外部时钟  HCLK/8
	fac_us=SystemCoreClock/8000000;				//为系统时钟的1/8
	fac_ms=(u16)fac_us*1000;					//非OS下,代表每个ms需要的systick时钟数
}

void RCC_Configuration(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOC, ENABLE);	//使能USART1,GPIOA时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);


}

void GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
	GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOA.9

	//USART1_RX	  GPIOA.10初始化
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOA.10

	//USART1_RX	  GPIOA.10初始化
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//浮空输入
	GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOA.10

}

void GPIO_RemapConfig(void)
{
	GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE);
}

void NVIC_Configuration(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2

	//中断优先级NVIC设置
	NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;  //TIM3中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  //先占优先级0级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级3级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器

}

//延时nms
//注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms
//对72M条件下,nms<=1864
void delay_ms(u16 nms)
{
	u32 temp;
	SysTick->LOAD=(u32)nms*fac_ms;				//时间加载(SysTick->LOAD为24bit)
	SysTick->VAL =0x00;							//清空计数器
	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;	//开始倒数
	do
	{
		temp=SysTick->CTRL;
	}while((temp&0x01)&&!(temp&(1<<16)));		//等待时间到达
	SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;	//关闭计数器
	SysTick->VAL =0X00;       					//清空计数器
}

void systemInit(void)
{
	SystemInit();
	delay_init();
	RCC_Configuration();						// RCC配置
	GPIO_Configuration();						// GPIO配置
	GPIO_RemapConfig();							// GPIO重映射
	NVIC_Configuration();						// NVIC配置
	uart3_init(9600);
}




main.c文件:
#include "Sys.h"
#include "Uart.h"
#include "rs485.h"


void getSysClk(void)
{
	RCC_ClocksTypeDef get_rcc_clock;
	RCC_GetClocksFreq(&get_rcc_clock);
}

int main(void)
{
	TimerFlagCounter = 0x00;
	TimerFlag = False;
	USART_RX_STA = 0;
	RS485_RX_CNT = 0;
	u8 rs485buf[5];
	u8 key = 0x05;
	systemInit();
	while(1)
	{
		RS485_Receive_Data(rs485buf,&key);
	}
	return 0;
}





 

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值