STM32F4xx驱动WIFI串口收发(寄存器版)
1、接线方式
wifi MCU(USART2)
VCC VCC(3.3)注意
GND GND
RX PA2(USART2_TX)
TX PA3(USART2_RX)
2、配置wifi.c
#include "stm32f4xx.h"
#include "string.h"
#include "usart1.h"
#include "usart2.h"
#include "delay.h"
#include "wifi.h"
char str[100];
char str0[]="AT";
char str1[] = "AT+RST";//复位
char str2[] = "AT+CIFSR";//查询本机地址
char str3[] = "AT+CWMODE=2";//设置wifi为2
/*1: 代表是 Station 模式;
2: 代表是 AP 模式;
3: 代表是 AP 兼容 Station 模式。*/
char str4[] = "AT+CWSAP?";//查询当前 AP 的参数。
char str5[] =" AT+CIPMUX=1";//开启多连接
char str6[] = "AT+RESTORE"; //恢复出厂设置
char str7[]="AT+CIPSERVER=1,8080";
void wifi_init(void)
{
int i=5;
LED4_ON;
//发送AT指令
USART2_Sendstring(str0);
// USART2_Receivestring(str);
Delay_ms(500);
// USART1_Sendstring((char *)str);
//发送查询本机地址命令
USART2_Sendstring(str2);
// USART2_Receivestring(str);
Delay_ms(500);
// USART1_Sendstring((char *)str);
//设置wifi为2
USART2_Sendstring(str3);
// USART2_Receivestring(str);
Delay_ms(500);
// USART1_Sendstring((char *)str);
// //WIFI 复位
// USART2_Sendstring(str1);
// while(i--)
// {
// Delay_ms(500);
// }
// //查询当前 AP 的参数。
// USART2_Sendstring(str4);
// while(i--)
// {
// Delay_ms(500);
// }
//开启多连接
USART2_Sendstring(str5);
// USART2_Receivestring(str);
Delay_ms(500);
// USART1_Sendstring((char *)str);
//发送管口
USART2_Sendstring(str7);
// USART2_Receivestring(str);
Delay_ms(500);
// USART1_Sendstring((char *)str);
}
3.声明wifi.h
#ifndef WIFI_H
#define WIFI_H
void wifi_init(void);
#endif
4、配置usart2.c
#include "stm32f4xx.h"
#include "stdio.h"
#include "usart1.h"
#include "usart2.h"
/********************************
函数名:USART2_IOinit
函数参数:无
函数返回值:无
函数功能:实现USART1的初始化
函数描述:
USART2_TX : PA2
USART2_RX : PA3 复用功能
*********************************/
void USART2_IOinit(void)
{
//PA外设使能时钟
RCC->AHB1ENR |=(1<<0);
//PA2端口模式寄存器
GPIOA->MODER &=~(0XF<<4);//清零
GPIOA->MODER |=(0XA<<4);//复用功能
//选择哪种复用功能
GPIOA->AFR[0] &=~(0XFF<<8);//清零
GPIOA->AFR[0] |=(0X77<<8);//复用功能为USART2
}
/********************************
函数名:USART2_init
函数参数:int boand 波特率
函数返回值:无
函数功能:实现串口USART1的接收和发送
函数描述:
*********************************/
void USART2_init(int boand)
{
int over8;//过采样倍数
float USARTDIV;//放入波特率中的数值
int DIV_Mantissa;//正数
int DIV_Fraction;//小数
//USART1对应的管脚的初始化
USART2_IOinit();
//USART2 发送、接收配置
//USART2外设时钟使能
RCC->APB1ENR |=(1<<17);
//发送器使能
USART2->CR1 |=(1<<3);
//接收器使能
USART2->CR1 |=(1<<2);
//不发送断路字符
USART2->CR1 &=~(1<<0);
//不使用奇偶校验
USART2->CR1 &=~(1<<10);
//USART1串口使能
USART2->CR1 |=(1<<13);
/*****波特率配置******/
#ifdef OVER8
//16倍过采样
USART2->CR1 &=~(1<<15);
over8=0;
#else
//8倍过采样
USART2->CR1|=(1<<15);
over8=1;
#endif
USARTDIV=(float)42000000/(8*(2-over8)*boand);//注意各个型号的M4,时钟频率可能不一致
DIV_Mantissa=USARTDIV;
DIV_Fraction=(USARTDIV-DIV_Mantissa)*8*(2-over8);
USART2->BRR=DIV_Mantissa<<4|DIV_Fraction;
}
/****************************
函数名:USART2_Sendbyte
函数参数:
char date :要发送的字符
函数返回值:无
函数功能:实现USART2单字符发送
函数描述:
*****************************/
void USART2_Sendbyte(char date)
{
//等待上次数据发送完
while((USART2->SR &(1<<6))==0)
{
;
}
//发送该次数据
USART2->DR =date;
}
/****************************
函数名:USART2_Receivebyte
函数参数:无
函数返回值:char date :接收到的字符
函数功能:实现USART2单字符接收
函数描述:
*****************************/
char USART2_Receivebyte(void)
{
char date;
//等待接收到数据
while((USART2->SR &(1<<5))==0)
{
;
}
//读出接受到的数据
date =USART2->DR;
return date;
}
/****************************
函数名:USART2_Sendstring
函数参数:
char *str :要发送的字符串的首地址
函数返回值:无
函数功能:实现USART2字符串发送
函数描述:
字符串结束标志 '\0'
*****************************/
void USART2_Sendstring(char *str)
{
while(*str !='\0')//字符串结束标志
{
USART2_Sendbyte(*str);
str++;
}
// USART2_Sendbyte('\r');
// USART2_Sendbyte('\n');
}
/****************************
函数名:USART2_Receivestring
函数参数:char *str :接收到的字符串首地址
函数返回值:无
函数功能:实现USART2字符串接收
函数描述:
自定义接收结束标志
# led_on#
常用 空格 \r \n
*****************************/
void USART2_Receivestring(char *str)
{
char date;
while(1)
{
//接收一个字符
date= USART2_Receivebyte();
//判断是否是结束标志
if( date =='\r'|| date=='\n')
{
// *str =date;
break;
}
else
{
// printf("data=%c\r\n",date);
*str =date;
str++;
}
}
*str='\0';
}
5、声明usart2.h
#ifndef USART2_H
#define USART2_H
//如果采用16倍,定义该宏
//如果采用8倍 ,屏蔽该宏
#define OVER8
void USART2_IOinit(void);
void USART2_init(int boand);
void USART2_Sendbyte(char date);
char USART2_Receivebyte(void);
void USART2_Sendstring(char *str);
void USART2_Receivestring(char *str);
#endif
6、配置usart1.c
#include "usart1.h"
#include "stdio.h"
#include <string.h>
#include <stdio.h>
#include <math.h>
/*****************************
函数名:USART1_init
函数参数:int baud
函数的返回值:无
函数的功能:实现串口一的初始化
函数的描述:
RX-----PA9 接收
******************************/
void USART1_init(int baud)
{
float USARTDIV;
int DIV_M;
int DIV_F;
u8 over;
/**USART1对应IO口PA9 PA10复用功能配置**/
//打开A口时钟
RCC->AHB1ENR|=(1<<0);
//PA9 PA10选择为复用模式
GPIOA->MODER &=~(0xf<<18);//清零
GPIOA->MODER |=(0xa<<18);
//选择为那种复用
GPIOA->AFR[1] &=~(0xff<<4);//清零
GPIOA->AFR[1] |=(0x77<<4);//选择USART1复用功能
/*****USART1串口的配置****/
//打开串口时钟
RCC->APB2ENR |=(1<<4);
//1、串口使能 CR1 13
USART1->CR1 |=(1<<13);
//2、发送使能 CR1 3
USART1->CR1 |=(1<<3);
//3、接收使能 CR1 2
USART1->CR1 |=(1<<2);
//4、断路字符 CR1 0
USART1->CR1 &=~(1<<0);
//5、奇偶校验 CR1 10
USART1->CR1 &=~(1<<10);
//6、波特率 BRR
#ifdef _OVER_ //16倍过采样
USART1->CR1 &=~(1<<15);
over=0;
#else //8倍的过采样
USART1->CR1 |=(1<<15);
over=1;
#endif
USARTDIV=(float) 84000000/(8*(2-over)*baud);
DIV_M=USARTDIV;
DIV_F=(USARTDIV-DIV_M)*8*(2-over);
USART1->BRR=DIV_M<<4|DIV_F;
}
/******************
函数名:USART1_sendbyte
函数参数:u8 data
函数返回值:无
函数的功能:实现串口的一个字符的发送
函数描述:
********************/
void USART1_sendbyte(u8 data)
{
//等待发送完成
while((USART1->SR&(1<<6))==0);
//发送数据
USART1->DR=data;
}
/******************
函数名:USART1_sendbyte
函数参数:u8 data
函数返回值:无
函数的功能:实现串口的一个字符的发送
函数描述:
********************/
u8 USART1_recievebyte()
{
u8 data;
//等待数据的接收
while((USART1->SR&(1<<5))==0);
//读取数据值
data=USART1->DR;
//返回数据
return data;
}
/****************************
函数名:USART1_Sendstring
函数参数:
char *str :要发送的字符串的首地址
函数返回值:无
函数功能:实现USART1字符串发送
函数描述:
字符串结束标志 '\0'
*****************************/
void USART1_Sendstring(char *str)
{
while(*str !='\0')//字符串结束标志
{
USART1_sendbyte(*str);
str++;
}
// USART1_sendbyte('\r');
// USART1_sendbyte('\n');
}
/****************************
函数名:USART1_Receivestring
函数参数:char *str :接收到的字符串首地址
函数返回值:无
函数功能:实现USART1字符串接收
函数描述:
自定义接收结束标志
# led_on#
常用 空格 \r \n
*****************************/
void USART1_Receivestring(char *str)
{
char date;
while(1)
{
//接收一个字符
date= USART1_recievebyte();
//判断是否是结束标志
if(date ==' '|| date =='\r'|| date=='\n')
{
break;
}
else
{
*str =date;
str++;
}
}
*str='\0';
}
#pragma import(__use_no_semihosting_swi) //取消半主机状态
struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;
int fputc(int ch, FILE *f) {
USART1_sendbyte(ch);
return (ch);
}
int ferror(FILE *f) {
/* Your implementation of ferror */
return EOF;
}
void _ttywrch(int ch) {
USART1_sendbyte(ch);
}
7、声明usart1.h
#ifndef _USART1_H
#define _USART1_H
#include "stm32f4xx.h"
//采用16倍过采样定义该宏
//否则采用8倍过采样
#define _OVER_
void USART1_init(int baud);
void USART1_sendbyte(u8 data);
u8 USART1_recievebyte();
void USART1_Sendstring(char *str);
void USART1_Receivestring(char *str);
#endif
8、配置延时函数delay.c
#include "stm32f4xx.h"
#include "delay.h"
/**********************
函数名:Delay_ms
函数参数:int ms 要延时的毫秒数
函数返回值:无
函数功能:实现毫秒级别的延时
函数描述:
一次最大的毫秒延时数:
定时时间 = 时钟周期 *计数值
x (秒) t y
x =y/f
已知 :y最大 2^24 f:21M
x <= 2^24/21000=789ms
**********************/
void Delay_ms(int ms)
{
//选择外部时钟作为定时器时钟源
SysTick->CTRL &=~(1<<2);
//写入计数初值到重装载寄存器
SysTick->LOAD = ms *21000;
SysTick->VAL=0;
//时钟使能,开始递减计数
SysTick->CTRL |=(1<<0);
//等待定时时间到
while((SysTick->CTRL &(1<<16))==0);
//关闭时钟
SysTick->CTRL &=~(1<<0);
}
/**********************
函数名:Delay_us
函数参数:int us 要延时的微秒数
函数返回值:无
函数功能:实现微秒级别的延时
函数描述:
**********************/
void Delay_us(int us)
{
//选择外部时钟作为定时器时钟源
SysTick->CTRL &=~(1<<2);
//写入计数初值到重装载寄存器
SysTick->LOAD = us *21;
SysTick->VAL=0;
//时钟使能,开始递减计数
SysTick->CTRL |=(1<<0);
//等待定时时间到
while((SysTick->CTRL &(1<<16))==0);
//关闭时钟
SysTick->CTRL &=~(1<<0);
}
9、声明延时函数delay.h
#ifndef DELAY_H
#define DELAY_H
void Delay_ms(int ms);
void Delay_us(int us);
#endif
10、主函数main.c
#include "stm32f4xx.h"
#include "stdio.h"
#include "usart1.h"
#include "usart2.h"
#include "delay.h"
#include "wifi.h"
#include "led.h"
/****************************
接线方式:
wifi MCU(USART2)
VCC VCC(3.3)注意
GND GND
RX PA2(USART2_TX)
TX PA3(USART2_RX)
*****************************/
int main()
{
int i=0;
char data[500];
USART1_init(115200);
USART2_init(115200);
wifi_init();
while(1)
{
//串口接收数据
USART2_Receivestring(data);
//串口发送数据
USART1_Sendstring((char *)data);
}
}
整个工程代码上传至:
https://download.csdn.net/download/qq_37619128/83932843