总体思路:
主机: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;
}
}
【必读】版权免责声明
1、本主题所有言论和内容纯属会员个人意见,与本论坛立场无关。2、本站对所发内容真实性、客观性、可用性不做任何保证也不负任何责任,网友之间仅出于学习目的进行交流。3、对提供的数字内容不拥有任何权利,其版权归原著者拥有。请勿将该数字内容进行商业交易、转载等行为,该内容只为学习所提供,使用后发生的一切问题与本站无关。 4、本网站不保证本站提供的下载资源的准确性、安全性和完整性;同时本网站也不承担用户因使用这些下载资源对自己和他人造成任何形式的损失或伤害。 5、本网站所有软件和资料均为网友推荐收集整理而来,仅供学习用途使用,请务必下载后两小时内删除,禁止商用。6、如有侵犯你版权的,请及时联系我们(电子邮箱1370723259@qq.com)指出,本站将立即改正。
|