STM32F4xx驱动WIFI串口收发(寄存器版)

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CinzWS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值