工控论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 2|回复: 0

STM32F407与STM32F103的基于RS485通信配置

[复制链接]

188

主题

189

帖子

22

积分

初级会员

Rank: 2

工控币
22
发表于 2020-6-5 10:16:33 | 显示全部楼层 |阅读模式
总体思路:
主机:STM32F407
从机:STM32F103
通信协议:RS485

主机-----串口2----RS485--------------------RS485---串口3-----从机


//-------------------------------主机代码:--------------------------------
//****RS485头文件代码:
#ifndef _RS485_H_
#define _RS485_H_

#include "stm32f4xx.h"
#include "string.h"
#include "bitband_cm4.h" // 位带操作头文件
#include <stdio.h>
#include "usart2.h"

#define RS485_RE(x) (PGout(8) = x) //发送与接收控制引脚

void RS485_Init();
void RS485_SendData(char *data,u32 len);
#endif

//****RS485源文件代码:
#include "rs485.h"


/*
函数功能:RS485初始化
函数原型:RS485_Init
函数参数:无
函数返回值:无
//RS485_RE -- PG8
*/
void RS485_Init()
{
        //1.配置时钟
        RCC->AHB1ENR |= (1<<6);//开启PG端口时钟
        //2.配置GPIO
        GPIOG->MODER &= ~(3<<2*8);// 输出模式
        GPIOG->MODER |= 1<<2*8;         
        GPIOG->OTYPER &=~(1<<1*8);// 推挽
        GPIOG->OSPEEDR &=~(3<<2*8);// 2M
        //3.初始化USART3
        USART2_Init(9600);
        RS485_RE(0); //默认为接收模式
}


/*
函数功能:RS485发送len个字节.
函数原型:RS485_SendData
函数参数:buf:发送区首地址   len:发送的字节数
函数返回值:无
*/
void RS485_SendData(char *data,u32 len)
{
        uint8_t i = 0;
        RS485_RE(1);//设置为发送模式
        for(i=0;i<len;i++)
        {
                while((USART2->SR &(1<<6)) == 0);
                USART2->DR = data[i];
        }
        while((USART2->SR &(1<<6)) == 0);
        RS485_RE(0);//设置为接收模式
}


UartBuf_TypeDef U2;
/**********************************************************************
*函数名:USART2_IRQHandler
*功  能:USART2中断服务函数
*参  数:无
*返  回:无
*备  注:无
**********************************************************************/
void USART2_IRQHandler(void)  // 串口1中断服务函数
{
        if(USART2->SR&1<<5)                                 // 读取数据寄存器不为空中断
        {
                U2.RxBuf[U2.RxLen++]=USART2->DR;
        }
        if(USART2->SR&1<<4)                                 // 检测到空闲线路中断
        {

                U2.RxBuf[U2.RxLen]=0;     // 字符串结束标志
                U2.RxLen=0;                                                                // 索引清零
                if(strcmp(U2.RxBuf,"1")==0)
                {
                                LED1=!LED1;                                       

                }
                else if(strcmp(U2.RxBuf,"2")==0)
                {
                                LED2=!LED2;                                       

                }
                else if(strcmp(U2.RxBuf,"3")==0)
                {
                                LED3=!LED3;                                       

                }
                else if(strcmp(U2.RxBuf,"4")==0)
                {
                                LED4=!LED4;                                       
                                BEEP=!BEEP;      
                }
                printf("从机给主机发送数据:%s\r\n",U2.RxBuf);
                USART2->SR;        // 读取清零
                USART2->DR;                                                        
        }
}


//-------------------------------从机代码:--------------------------------
//****RS485头文件代码:
#ifndef _RS485_H_
#define _RS485_H_

#include "stm32f10x.h"
#include "string.h"
#include "bitband_cm3.h" // 位带操作头文件
#include <stdio.h>
#include "usart3.h"

#define RS485_RE(x) (PAout(12) = x)//发送与接收控制引脚

void RS485_Init(void);
void RS485_SendData(char *data,uint32_t lenth);
#endif


//****RS485源文件代码:


#include "systick.h"
#include "rs485.h"

/*
函数功能:RS485初始化
函数原型:RS485_Init
函数参数:
函数返回值:无
//RS485_RE -- PA12
*/
void RS485_Init()
{
        //1.配置时钟
        RCC->APB2ENR |= (1<<2);
        //2.配置GPIO
        GPIOA->CRH &= ~(0xf<<4*(12-8));
        GPIOA->CRH |=  (0x3<<4*(12-8)); // 通用推挽输出模式
        //3.初始化USART3
        USART3_Init(9600);
        RS485_RE(0); //默认为接收模式
}


/*
函数功能:RS485发送len个字节.
函数原型:RS485_SendData
函数参数:buf:发送区首地址   len:发送的字节数
函数返回值:无
*/
void RS485_SendData(char *data,uint32_t lenth)
{
        uint8_t i = 0;
        RS485_RE(1);//设置为发送模式
        for(i=0;i<lenth;i++)
        {
                while((USART3->SR &(1<<6)) == 0);//等待移位数据寄存器为空
                USART3->DR = data[i];//把要发送的数据存放在发送数据寄存器
        }
        while((USART3->SR &(1<<6)) == 0);
        RS485_RE(0);//设置为接收模式
}


char USART3_ReceiveBuf[128];
/**********************************************************************
*函数名:USART3_IRQHandler
*功  能:USART3中断服务函数
*参  数:无
*返  回:无
*备  注:无
**********************************************************************/
void USART3_IRQHandler(void)  // 串口1中断服务函数
{
        static u8 i=0;
        if(USART3->SR&1<<5)                                 // 读取数据寄存器不为空
        {
                USART3_ReceiveBuf[i++]=USART3->DR;
        }
        if(USART3->SR&1<<4)                                 // 检测到空闲线路中断
        {
                USART3_ReceiveBuf[i]=0;                // 字符串结束标志
                if(strcmp(USART3_ReceiveBuf,"1")==0)
                {
                        PCout(5)=!PCout(5);
                }
                i=0;//索引清零
                printf("主机发送了数据:%s\r\n",USART3_ReceiveBuf);
                USART3->SR;        // 读取清零
                USART3->DR;                                                        
        }
}


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

免责声明: 工控技术网(www.eleok.com)所有内容均为网友自行发布,不代表网站立场。如有版权纠纷,请联系本站删除:1370723259@qq.com

QQ|小黑屋|手机版|工控技术网 |网站地图

GMT+8, 2020-7-3 02:49

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表