×
单片机 > 单片机程序设计 > 详情

42.485通信实验

发布时间:2020-06-15 发布时间:
|

一。485接口原理






二。485电路芯片SP3485


一般2,3脚连在一起,当2,3脚为低电平时,使能RO端,当2,3脚为高电平时,使能DI端。

三。电路


采用UART2接口,PA2为USART2_TX,PA3为USART2_RX

PA2接SP3485的4脚DI端

PA3接SP3485的1脚RO端



四。程序

串口2初始化

//初始化IO 串口2
//pclk1:PCLK1时钟频率(Mhz)
//bound:波特率  
void RS485_Init(u32 bound)

    GPIO_InitTypeDef GPIO_InitStructure;
   USART_InitTypeDef USART_InitStructure;
   NVIC_InitTypeDef NVIC_InitStructure;
 
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOG, ENABLE);//使能GPIOA,G时钟
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//使能USART2时钟
 
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;     //PG9端口配置
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;    //推挽输出
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(GPIOG, &GPIO_InitStructure);
 
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA2
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽
    GPIO_Init(GPIOA, &GPIO_InitStructure);
  
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA3
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure); 

  RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,ENABLE);//复位串口2
  RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,DISABLE);//停止复位
  
   #ifdef EN_USART2_RX     //如果使能了接收
  USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
  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(USART2, &USART_InitStructure); ; //初始化串口
  
  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; //使能串口2中断
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //先占优先级2级
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级2级
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
  NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
 
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启中断
  
    USART_Cmd(USART2, ENABLE);                    //使能串口

 #endif

 RS485_TX_EN=0;   //默认为接收模式

}

RS485头文件rs485.h

#ifndef __RS485_H
#define __RS485_H   
#include "sys.h"            
        
extern u8 RS485_RX_BUF[64];   //接收缓冲,最大64个字节
extern u8 RS485_RX_CNT;      //接收到的数据长度

 

//模式控制
#define RS485_TX_EN  PGout(9) //485模式控制.0,接收;1,发送.

//如果想串口中断接收,请不要注释以下宏定义
#define EN_USART2_RX  1   //0,不接收;1,接收.

 

void RS485_Init(u32 bound);  //RS485的初始化函数,初始化串口2
void RS485_Send_Data(u8 *buf,u8 len);  //发送函数
void RS485_Receive_Data(u8 *buf,u8 *len);   //接收函数


#endif   

//RS485发送len个字节.
//buf:发送区首地址
//len:发送的字节数(为了和本代码的接收匹配,这里建议不要超过64个字节)
void RS485_Send_Data(u8 *buf,u8 len)
{
 u8 t;
 RS485_TX_EN=1;   //设置为发送模式
   for(t=0;t
 {    
  while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);  
  USART_SendData(USART2,buf[t]);
 } 
 
 while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);  
 RS485_RX_CNT=0;  
 RS485_TX_EN=0;    //设置为接收模式 
}
//RS485查询接收到的数据
//buf:接收缓存首地址
//len:读到的数据长度
void RS485_Receive_Data(u8 *buf,u8 *len)
{
 u8 rxlen=RS485_RX_CNT;
 u8 i=0;
 *len=0;    //默认为0
 delay_ms(10);  //等待10ms,连续超过10ms没有接收到一个数据,则认为接收结束
 if(rxlen==RS485_RX_CNT&&rxlen)//接收到了数据,且接收完成了
 {
  for(i=0;i
  {
   buf[i]=RS485_RX_BUF[i]; 
  }  
  *len=RS485_RX_CNT; //记录本次数据长度
  RS485_RX_CNT=0;  //清零
 }
}


关键字:485通信  stm32 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
AVR单片机为何要写1作为清0中断标志位