ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

STM32基于固件库学习笔记串口的收发功能+WiFi基础配置

2019-09-24 19:06:41  阅读:289  来源: 互联网

标签:USART WiFi RXNE STM32 ucaRxBuf 串口 GPIO USART1


串口设置的一般步骤

1) 串口时钟使能,GPIO 时钟使能
  注:串口是挂载在 APB2 下面的外设还需要需要挂载复用时钟使能

//挂载时钟(复用PA) 串口时钟使能,GPIO 时钟使能,复用时钟使能  
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);

2) 串口复位

//系统刚开始配置外设的时候,都会先执行复位该外设的操作。
void USART_DeInit(USART_TypeDef* USARTx);//串口复位

3) GPIO 端口模式设置
 注意:RXT、TXT输入输出方向不同。

  GPIO_InitTypeDef GPIO_InitTypeDef_RXDPA10;
  GPIO_InitTypeDef GPIO_InitTypeDef_TXDPA9;
//PA9 TXD初始化
  GPIO_InitTypeDef_TXDPA9.GPIO_Pin = GPIO_Pin_9;//PA9 TXD
  GPIO_InitTypeDef_TXDPA9.GPIO_Mode = GPIO_Mode_AF_PP;////复用推挽输出
  GPIO_InitTypeDef_TXDPA9.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA,&GPIO_InitTypeDef_TXDPA9);
//PA10 TXD初始化
  GPIO_InitTypeDef_RXDPA10.GPIO_Pin = GPIO_Pin_10;//PA10 RXD
  GPIO_InitTypeDef_RXDPA10.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOA,&GPIO_InitTypeDef_RXDPA10);

4) 串口参数初始化

//初始化函数
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
//第一个入口参数是指定初始化的串口标号
//第二个入口参数是一个 USART_InitTypeDef 类型的结构体指针

//USART初始化配置
  USART_InitTypeDef  USART_InitTypeDef_USART1;
  USART_InitTypeDef_USART1.USART_BaudRate = 115200;//波特率
  USART_InitTypeDef_USART1.USART_WordLength = USART_WordLength_8b;//发送数据长度
  USART_InitTypeDef_USART1.USART_StopBits = USART_StopBits_1; //一个停止位   
  USART_InitTypeDef_USART1.USART_Parity = USART_Parity_No; //无奇偶校验位     
  USART_InitTypeDef_USART1.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
  USART_InitTypeDef_USART1.USART_Mode = USART_Mode_Tx| USART_Mode_Rx ;//发送+接收模式 
  USART_Init(USART1,&USART_InitTypeDef_USART1);

5) 开启中断并且初始化 NVIC(如果需要使用中断才需要这个步骤)

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置NVIC中断分组2(mcu复位默认2组): 2位抢占优先级,2位响应优先级
  NVIC_InitTypeDef  NVIC_InitTypeDef_USART1;
  NVIC_InitTypeDef_USART1.NVIC_IRQChannel = USART1_IRQn;// “USART1_IRQn”在固件库“stm32f10x.h”文件可以查看
  NVIC_InitTypeDef_USART1.NVIC_IRQChannelPreemptionPriority = 0X00; //抢占优先级 3
  NVIC_InitTypeDef_USART1.NVIC_IRQChannelSubPriority = 0X00; //子优先级 3
  NVIC_InitTypeDef_USART1.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道使能
  NVIC_Init(&NVIC_InitTypeDef_USART1);
//开启中断
  USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //开启串口接受中断

6) 使能串口

USART_Cmd(USART1, ENABLE);//使能串口

7) 编写中断处理函数

//串口中断服务程序“USART1_IRQHandler”在固件库给好了的名字
void USART1_IRQHandler()
{ 
  if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) != RESET)//判断中断标志位
  {       
     ucaRxBuf[usRxCount++] =USART_ReceiveData(USART1); //保存接收到的  
  } 
  USART_ClearFlag(USART1,USART_FLAG_RXNE); 
}
/*固件库“stm32f10x_usart.h”所给定的标志位
  USART_FLAG_CTS/*CTS标志位*/ 
  USART_FLAG_LBD/*LIN中断检测标志位*/
  USART_FLAG_TXE/*发送数据寄存器空标志位*/
  USART_FLAG_TC/*发送完成标志位*/
  USART_FLAG_RXNE/*接收数据寄存器非空标志位*/ 
  USART_FLAG_IDLE/*空闲总线标志位*/
  USART_FLAG_ORE/*溢出错误标志位*/
  USART_FLAG_NE/*噪声错误标志位*/
  USART_FLAG_FE/*帧错误标志位*/
  USART_FLAG_PE/*奇偶错误标志位*/ 
*/

数据的发送与接收

STM32 的发送与接收是通过数据寄存器 USART_DR 来实现的,这是一个双寄存器,包含了 TDR 和 RDR。当向该寄存器写数据的时候,串口就会自动发送,当收到数据的时候,也是存在该寄存器内。

//固件库的发送数据函数
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
//固件库的发送数据函数
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);

字符串的发送函数

  1. 固件库给定的收函数只可以接收发送单个字,下面有两个发送字符串的函数
  void Usart_SendByte(uint8_t ch)
{
  /* 发送一个字节数据到USART1 */
  USART_SendData(USART1,ch);
  /* 等待发送完毕 */
  while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);	//判断读寄存器是否非空(RXNE)
  //判断发送是否完成(TC)USART_GetFlagStatus(USART1, USART_FLAG_TC);
}
//发送给定长度的字符串
void Usart_SendStr_length(uint8_t *str,uint32_t strlen)
{
  unsigned int k=0;
  do 
  {
    Usart_SendByte(*(str + k));
    k++;
  } while(k < strlen);
}
//发送字符串
void Usart_SendString(uint8_t *str)
{
	unsigned int k=0;
  do 
  {
    Usart_SendByte(*(str + k));
    k++;
  } while(*(str + k)!='\0');
}
  1. 简单的字符串发送函数
#include "stdio.h"
////加入以下代码,支持 printf 函数,而不需要选择 use MicroLIB
//#if 1
//#pragma import(__use_no_semihosting)
////标准库需要的支持函数
//struct __FILE
//{ 
//  int handle;
//};
//FILE __stdout;
//  //定义_sys_exit()以避免使用半主机模式
//_sys_exit(int x)
// {
//  x = x;
// }
//重定义 fputc 函数
int fputc(int ch, FILE *f)
{
  while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
  USART_SendData(USART1,(uint8_t)ch);
  return ch;
}
//比如:
char temp[]={"Hello Word !"};
 printf("HIGH:%c us\r\n",temp); 

字符串的接收函数

其实很简单,只需要用一个char数组把接收的字保存下来。要注意此时的数组空间大小。

char ucaRxBuf[256];
char usRxCount=0;
ucaRxBuf[usRxCount++] =USART_ReceiveData(USART1); //保存接收到的  

WIFI_ESP8266_初始化配置

void wifi_init()
{
  delay_ms(200); 
  do{  
       memset(ucaRxBuf,0,256);
       usRxCount=0;     
       USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);//关闭中断
       Usart_SendString("AT+RST\r\n");
       USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);////开启串口接受中断   
       delay_ms(200);
  }while(!strstr(ucaRxBuf,"READY")); 
  do{ 
      memset(ucaRxBuf,0,256);
      usRxCount=0;
      USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);//关闭中断
      Usart_SendString("AT+CWMODE=3\r\n"); 
      USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);////开启串口接受中断
      delay_ms(200);
  }while(!strstr(ucaRxBuf,"OK"));   
   do{  
       memset(ucaRxBuf,0,256);
       usRxCount=0;     
       USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);//关闭中断
       Usart_SendString("AT+RST\r\n");
       USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);////开启串口接受中断   
       delay_ms(200);
  }while(!strstr(ucaRxBuf,"READY"));
  
  do{
      memset(ucaRxBuf,0,256);
      usRxCount=0;
      USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);//关闭中断
      Usart_SendString("AT+CWSAP_DEF=\"nihaohao\",\"123358zxc\",5,0\r\n");
      USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);////开启串口接受中断
          
      delay_ms(200);
  }while(!strstr(ucaRxBuf,te_ok));

  do{
     memset(ucaRxBuf,0,256);
     usRxCount=0;
     USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);//关闭中断
     Usart_SendString("AT+CIPMUX=1\r\n"); 
     USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);////开启串口接受中断     
     delay_ms(200);
  }while(!strstr(ucaRxBuf,te_ok));
  
  do{   
     memset(ucaRxBuf,0,256);
     usRxCount=0;
     USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);//关闭中断
     Usart_SendString("AT+CIPSERVER=1,8080\r\n");
     USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);////开启串口接受中断     
     delay_ms(200);     
  }while(!strstr(ucaRxBuf,te_ok));
     memset(ucaRxBuf,0,256);
     usRxCount=0;  
}

全代码

#include "stm32f10x.h"
#include "string.h"
char Rxflag=0;
char ucaRxBuf[256];
char usRxCount=0;
char te_ok[10]="OK\0";

void Usart_Init()
{ 
  GPIO_InitTypeDef GPIO_ITDef1;
  GPIO_InitTypeDef GPIO_ITDef;
  USART_InitTypeDef  USART_ITDef;
  NVIC_InitTypeDef NVIC_ITDef_Usart1;
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置NVIC中断分组2:2位抢占优先级,2位响应优先级
//挂载时钟(复用PA) 串口时钟使能,GPIO 时钟使能,复用时钟使能
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);
//PA9 TXD初始化
  GPIO_ITDef.GPIO_Pin = GPIO_Pin_9;//PA9 TXD
  GPIO_ITDef.GPIO_Mode = GPIO_Mode_AF_PP;////复用推挽输出
  GPIO_ITDef.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA,&GPIO_ITDef);
//PA10 TXD初始化
  GPIO_ITDef1.GPIO_Pin = GPIO_Pin_10;//PA10 RXD
  GPIO_ITDef1.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOA,&GPIO_ITDef1);
  
//USART初始化
  USART_ITDef.USART_BaudRate = 115200;//波特率
  USART_ITDef.USART_WordLength = USART_WordLength_8b;//发送数据长度
  USART_ITDef.USART_StopBits = USART_StopBits_1; //一个停止位   
  USART_ITDef.USART_Parity = USART_Parity_No; //无奇偶校验位     
  USART_ITDef.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
  USART_ITDef.USART_Mode = USART_Mode_Tx| USART_Mode_Rx ;//发送模式 
  USART_Init(USART1,&USART_ITDef);
  
 
  NVIC_ITDef_Usart1.NVIC_IRQChannel = USART1_IRQn;
  NVIC_ITDef_Usart1.NVIC_IRQChannelPreemptionPriority = 0X00; //抢占优先级 3
  NVIC_ITDef_Usart1.NVIC_IRQChannelSubPriority = 0X00; //子优先级 3
  NVIC_ITDef_Usart1.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道使能
  NVIC_Init(&NVIC_ITDef_Usart1);
  
//开启中断
  USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //开启串口接受中断
  
  USART_Cmd(USART1, ENABLE);//使能串口
}
void Usart_SendByte(uint8_t ch)
{
  /* 发送一个字节数据到USART1 */
  USART_SendData(USART1,ch);
  /* 等待发送完毕 */
  while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);	//判断读寄存器是否非空(RXNE)
  //判断发送是否完成(TC)USART_GetFlagStatus(USART1, USART_FLAG_TC);
}
void Usart_SendStr_length(uint8_t *str,uint32_t strlen)
{
  unsigned int k=0;
  do 
  {
    Usart_SendByte(*(str + k));
    k++;
  } while(k < strlen);
}
void Usart_SendString(uint8_t *str)
{
	unsigned int k=0;
  do 
  {
    Usart_SendByte(*(str + k));
    k++;
  } while(*(str + k)!='\0');
}

void delay_ms(u16 time)
{    
   u16 i = 0;  
   while(time--)
   {
      i = 12000;  
      while(i--);    
   }
}

void wifi_init()
{
  delay_ms(200); 
  do{  
       memset(ucaRxBuf,0,256);
       usRxCount=0;     
       USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);//关闭中断
       Usart_SendString("AT+RST\r\n");
       USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);////开启串口接受中断   
       delay_ms(200);
  }while(!strstr(ucaRxBuf,"READY"));
  
  do{ 
      memset(ucaRxBuf,0,256);
      usRxCount=0;
      USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);//关闭中断
      Usart_SendString("AT+CWMODE=3\r\n"); 
      USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);////开启串口接受中断
      delay_ms(200);
  }while(!strstr(ucaRxBuf,"OK"));
   
   do{  
       memset(ucaRxBuf,0,256);
       usRxCount=0;     
       USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);//关闭中断
       Usart_SendString("AT+RST\r\n");
       USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);////开启串口接受中断   
       delay_ms(200);
  }while(!strstr(ucaRxBuf,"READY"));
  
  do{
      memset(ucaRxBuf,0,256);
      usRxCount=0;
      USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);//关闭中断
      Usart_SendString("AT+CWSAP_DEF=\"nihaohao\",\"123358zxc\",5,0\r\n");
      USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);////开启串口接受中断
          
      delay_ms(200);
  }while(!strstr(ucaRxBuf,te_ok));

  do{
     memset(ucaRxBuf,0,256);
     usRxCount=0;
     USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);//关闭中断
     Usart_SendString("AT+CIPMUX=1\r\n"); 
     USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);////开启串口接受中断     
     delay_ms(200);
  }while(!strstr(ucaRxBuf,te_ok));
  
  do{   
     memset(ucaRxBuf,0,256);
     usRxCount=0;
     USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);//关闭中断
     Usart_SendString("AT+CIPSERVER=1,8080\r\n");
     USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);////开启串口接受中断     
     delay_ms(200);     
  }while(!strstr(ucaRxBuf,te_ok));
     memset(ucaRxBuf,0,256);
     usRxCount=0;  
//  do{         
//      memset(ucaRxBuf,0,256);
//      usRxCount=0; 
//      delay_ms(20000); 
//    }while(!strstr(ucaRxBuf,"CONN")); 
}

int main(void)
{   
  Usart_Init();
  Usart_SendString("这是一个串口中断接收+WIFI实验\n");
  Usart_SendString("输入数据并以回车键结束\n");
  memset(ucaRxBuf,0,256);
  usRxCount=0;
  wifi_init();
  while(1)
  {
    ;
//    if(strstr(ucaRxBuf,te_ok))//接收到的数据包含
//    {
//      memset(ucaRxBuf,0,256);
//      usRxCount=0;
//      Usart_SendString("nihao");           
//    }
  }
}
//串口中断服务程序
void USART1_IRQHandler()
{ 
  if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) != RESET)//接收中断
  {       
    ucaRxBuf[usRxCount++] =USART_ReceiveData(USART1); //保存接收到的  
  } 
  USART_ClearFlag(USART1,USART_FLAG_RXNE); 
}

相关文件

链接:ESP8266模块官方指导文件 提取码:9u2o
STM32 V3.5固件库函数调用说明(中文版)
STM32F10x_StdPeriph_Lib_V3.5.0(官方固件库)

标签:USART,WiFi,RXNE,STM32,ucaRxBuf,串口,GPIO,USART1
来源: https://blog.csdn.net/weixin_43993734/article/details/101228790

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有