stm32---RS485初始化

来源:互联网 发布:传奇霸业显示网络异常 编辑:程序博客网 时间:2024/05/16 06:23


u8 RS485_RX_BUF[64];   //接收缓冲,最大64个字节.
u8 RS485_RX_CNT=0;      //接收到的数据长度   

/*
函数:RS485_Init
功能:串口初始化配置
参数:Baud:波特率
备注:GPIO/USART/NVIC初始化,开启串口中断,使能串口中断(中断处理函数)
步骤:
   1---GPIO/USART1/NVIC初始化结构体定义
   2---开启串口USART,GPIO端口时钟
   3---复位串口
   4---USART2_TX/USART2_RX  串口接受/发送端口配置寄存器结构体参数配置
   5---NVIC 中断控制器配置
   6---USART2 初始化设置
   7---开启中断
   8---使能中断
*/ 
void RS485_Init(u32 bound)
{   
    //GPIO/USART1/NVIC初始化结构体
 
    GPIO_InitTypeDef GPIO_InitStructure;
   USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
 
   //开启串口USART,GPIO端口时钟
 
   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);               //停止复位
  
  //USART_DeInit(USART2); //复位串口  :方式相同(USART_DeInit(USART2)函数调用以上两个函数)
   
    //USART 初始化设置
 
  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);                       //初始化串口
  
    //Usart2 NVIC 中断控制器配置

  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);                                       //使能串口

    RS485_TX_EN=0;                                   //默认为接收模式
}
/*
函数:RS485_Send_Data
功能:RS485发送len个字节
参数:buf:发送区首地址,len:发送的字节数(为了和本代码的接收匹配,这里建议不要超过64个字节)
备注:
步骤:
*/
void RS485_Send_Data(u8 *buf,u8 len)
{
   u8 t;
   RS485_TX_EN=1;                         //设置为发送模式
 
   for(t=0;t<len;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_Receive_Data
功能: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<rxlen;i++)
  {
   buf[i]=RS485_RX_BUF[i]; 
  }  
  *len=RS485_RX_CNT;                       //记录本次数据长度
  RS485_RX_CNT=0;                         //计数清零
 }
}
/*
函数:USART2_IRQHandler
功能:中断处理函数
参数:
备注:
步骤:
*/ 
void USART2_IRQHandler(void)
{
 u8 res;    
 
  if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收到数据
 { 
     
  res =USART_ReceiveData(USART2);                    //读取接收到的数据
  if(RS485_RX_CNT<64)
  {
   RS485_RX_BUF[RS485_RX_CNT]=res;                  //记录接收到的值
   RS485_RX_CNT++;                              //接收数据增加1
  }
 }             
}

0 0
原创粉丝点击