基于STM32F103C8T6的RS485 MODBUS通信及CRC校验

     在进行RS485 MODBUS收发通信,无固定帧头及帧尾的数据包传输时,两组数据包之间需要有3.5个字符的时间间隔,通过定时器中断延时判定数据包是否传输完成,同时进行CRC校验比对

一、串口通信配置

与常规USART配置基本一致,只是多一个控制发送与接收切换的引脚,下例为USART2的配置,使用GPIOA_PIN_1为控制引脚

Rs485.h

#ifndef __RS485_H
#define __RS485_H

#include <stdio.h>

extern uint8_t  Rs485_TxPacket[];
extern uint8_t  Rs485_RxPacket[];
extern uint8_t  Rs485_pRxPacket;	 
extern uint8_t  Rs485_RxStar;
extern uint8_t  Rs485_RxDataLen; 
extern uint32_t Rs485_RxDlay;
extern uint8_t  Rs485_RxFlag;

void Rs485_Init(void);
void Rs485_SendByte(uint8_t Byte);
void Rs485_SendArray(uint8_t *Array, uint16_t Length);
void Rs485_SendString(char *String);
void Rs485_SendNumber(uint32_t Number, uint8_t Length);
uint8_t Rs485_GetRxFlag(void);

#endif

Rs485.c

#include "stm32f10x.h"                  // Device header
#include <stdio.h>
#include <stdarg.h>

uint8_t  Rs485_TxPacket[32] = {0x01,0x02,0x03,0x04};  //定义发送数据包数组
uint8_t  Rs485_RxPacket[32];				          //定义接收数据包数组
uint8_t  Rs485_RxFlag;					              //定义接收数据包完成标志位
uint8_t  Rs485_pRxPacket = 0;	                      //定义接收数据包位置变量
uint8_t  Rs485_RxStar;                                //定义接收数据包开始
uint8_t  Rs485_RxDataLen = 0;                         //定义接收数据包长度
uint32_t Rs485_RxDlay = 0;                            //定义RS485数据包接收完成判定延时变量


/**
  * 函    数:485串口初始化
  * 参    数:无
  * 返 回 值:无
  */
void Rs485_Init(void)
{
	/*开启时钟*/
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);	//开启USART2的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//开启GPIOA的时钟
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;              //控制数据的接收、发送
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);		//将PA2引脚初始化为复用推挽输出(USART2  TX)
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);		//将PA3引脚初始化为上拉输入(USART2  RX)
	
	/*USART2初始化*/
	USART_InitTypeDef USART2_InitStructure;					                            //定义结构体变量
	USART2_InitStructure.USART_BaudRate = 9600;				                            //波特率9600
	USART2_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;	//硬件流控制,不需要
	USART2_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;	                //模式,发送模式和接收模式均选择
	USART2_InitStructure.USART_Parity = USART_Parity_No;		                        //奇偶校验,不需要
	USART2_InitStructure.USART_StopBits = USART_StopBits_1;                          	//停止位,选择1位
	USART2_InitStructure.USART_WordLength = USART_WordLength_8b;		                //字长,选择8位
	USART_Init(USART2, &USART2_InitStructure);				
	
	/*中断输出配置*/
	USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);		       //开启串口接收数据的中断
	
	/*NVIC中断分组*/
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);			   //配置NVIC为分组2
	
	/*NVIC配置*/
	NVIC_InitTypeDef NVIC_InitStructure;					   //定义结构体变量
	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;		   //选择配置NVIC的USART1线
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			   //指定NVIC线路使能
	NVIC_InitStructure.NVIC_IRQChannelPreemptionP
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值