STM32单片机ESP8266发送数据到WiFi接收端代码实现

ESP8266支持的一些指令看我另一篇博文:http://blog.csdn.net/qq_17242837/article/details/53931712

首先需要配置STM32的串口发送和接收,在本文中基于原子和网上的一些程序修改,使用DMA传输,减少CPU占用,下面列出所有代码。

注:发送使用的是UDP传输,在我自己的设计中是能正确执行的,程序中的头文件自己编译的时候需要什么自己添加吧,有"usart.h"和"stm32f10x_usart.h",串口1配置了C语言重定向,可以使用printf发送数据,我用于调试,串口2用于与其他器件通讯。

ESP8266程序

头文件:

#ifndef __ESP8266_H
#define	__ESP8266_H

#include "headers.h"

void init_esp8266(void);
u8* ESP8266_send(char* cmd);

#endif /* __ESP8266_H */


C程序:

#include "esp8266.h"

extern u16 USART2_RX_Size;
extern u8 USART2_RX_FLAG;
extern u8 USART2_RX_BUF[USART_REC_LEN];

char* CWMODE = "AT+CWMODE=2\r\n";
char* CIPMUX = "AT+CIPMUX=1\r\n";
/** AT+ CWSAP=<ssid>,<pwd>,<chl>, <ecn>
	*	ssid:WiFi热点名称
	* 	pwd: WiFi热点连接密码
	*	chl: 通道
	* 	ecn: 加密方式,0-OPEN,1-WEP,2-WPA_PSK,3-WPA2_PSK,4-WPA_WPA2_PSK
	*/
char* CWSAP  = "AT+CWSAP=\"WIFI\",\"12345678\",1,0\r\n";
char* CIPSERVER  = "AT+CIPSERVER=1,8080\r\n";
char* CIPSTART   = "AT+CIPSTART=1,\"UDP\",\"192.168.4.2\",8080\r\n";
char  CIPSEND[50]= "AT+CIPSEND=1,12\r\n";
char* CIPSTATUS  = "AT+CIPSTATUS\r\n";
char* CIPCLOSE   = "AT+CIPCLOSE\r\n";


u8 len(char str[])
{
	u8 i = 0;
	while(str[i++]);
	return --i;
}

/** 判断src字符串中是否包含str字符串
	* input:截取部分,需要判断部分
	* return: 不包含返回0,包含返回1
	*/
char haveString(char* str, char* src)
{
	u16 i;
	u16 j;
	u16 length = len(str);
	
	for(i = 0; i < len(src); i++)
	{
		if(src[i] == str[0])
		{
			for(j = 1; j < length; j++)
				if(src[++i] != str[j])
					break;
		}
		if(length == j)
			break;
    else
      j = 0;
	}

	if(length == j)
		return 1;
	else
		return 0;
}

/** brief: 发送指令,直到串口接收到响应返回
	* input: AT+CMD,指令内容
	* @note  在操作系统支持下,可以等待串口接收数据事件返回
	*/
void write(char* str)
{
	SendMulData(str, len(str));
	while(!USART2_RX_FLAG);
	USART2_RX_FLAG = 0;
}

/** brief: 初始化ESP8266
	* in:    无
	* retval:无
	*/
void init_esp8266(void)
{
	printf("----------start esp init-----------\n");
	USART2_RX_FLAG = 0;
	write(CWMODE);
	write(CIPMUX);
	write(CWSAP);
	write(CIPSERVER);
	write(CIPSTART);
	ESP8266_send("ESP start.\r\n");
}

/** brief:发送数据到服务器或上位机
	* in:   需发送数据
	* retval:串口接收到的数据
	*/
u8* ESP8266_send(char* cmd)
{
	u8 wait = 10;
	
	sprintf(CIPSEND, "AT+CIPSEND=1,%d\r\n", len(cmd)-2);
	write(CIPSEND);
	while(!haveString(">", (char*)USART2_RX_BUF) && wait--) Delay_ms(1);
	SendMulData(cmd, len(cmd));
	return USART2_RX_BUF;
}


串口程序

头文件:

#ifndef __USART_H
#define	__USART_H

#include "headers.h"

#define USART_REC_LEN  			256 	//定义最大接收字节数 8

void USART_Config(uint32_t baud,uint32_t uart_num);

void SendMulData(char *data, u16 size);

#endif /* __USART1_H */

C程序:

/***************************************
 * 文件名  :usart1.c
 * 描述    :配置USART1         
 * 实验平台:MINI STM32开发板 基于STM32F103C8T6
 * 硬件连接:------------------------
 *          | PA9  - USART1(Tx)      |
 *          | PA10 - USART1(Rx)      |
 *           ------------------------
 * 库版本  :ST3.0.0  

**********************************************************************************/

#include "usart.h"
#include <stdarg.h>
#include "misc.h"

u8 USART1_RX_FLAG = 0;
u8 USART2_RX_FLAG = 0;
u16 USART1_RX_Size = 0;
u16 USART2_RX_Size = 0;
u8 USART1_RX_BUF[USART_REC_LEN];
u8 USART2_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.

int fputc(int ch, FILE *f)
{
	USART_SendData(USART1, (unsigned char) ch);
	while (!(USART1->SR & USART_FLAG_TXE));
	
	return (ch);
}

void USART_Config(uint32_t baud,uint32_t uart_num)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	DMA_InitTypeDef   DMA_InitStructure;
	NVIC_InitTypeDef  NVIC_InitStructure;

	/* config USART1 clock */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	if( uart_num == 1)
	{
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
		
		/* USART1 GPIO config */
		/* Configure USART1 Tx (PA.09) as alternate function push-pull */
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_Init(GPIOA, &GPIO_InitStructure);    
		/* Configure USART1 Rx (PA.10) as mn floating */
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
		GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	}
	else
	{
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
		/* USART1 GPIO config */
		/* Configure USART1 Tx (PA.2) as alternate function push-pull */
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_Init(GPIOA, &GPIO_InitStructure);    
		/* Configure USART1 Rx (PA.3) as mn floating */
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
		GPIO_Init(GPIOA, &GPIO_InitStructure);
		
	}
	
	

	/* USART1 mode config */
	USART_InitStructure.USART_BaudRate = baud;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	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;
	
	if( uart_num == 1 )
	{
		// UART1 interrupt
		USART_ITConfig(USART1,USART_IT_TC,DISABLE);
		USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);
		USART_ITConfig(USART1,USART_IT_IDLE,ENABLE); 
		NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;  
		
		USART_Init(USART1, &USART_InitStructure); 
		DMA_DeInit(DMA1_Channel5);
		DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART1->DR);
		DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART1_RX_BUF;
	}
	else
	{
		// UART2 interrupt
		USART_ITConfig(USART2,USART_IT_TC,DISABLE);
		USART_ITConfig(USART2,USART_IT_RXNE,DISABLE);
		USART_ITConfig(USART2,USART_IT_IDLE,ENABLE); 
		NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;  
		
		USART_Init(USART2, &USART_InitStructure); 
		DMA_DeInit(DMA1_Channel6);
		DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART2->DR);
		DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_RX_BUF;
	}

	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
	DMA_InitStructure.DMA_BufferSize = USART_REC_LEN;//100
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//  内存自增
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//8位
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//8位
	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
	DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	
	if( uart_num == 1 )
	{
		DMA_Init(DMA1_Channel5, &DMA_InitStructure);
		DMA_Cmd(DMA1_Channel5, ENABLE);
		
		USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);
		USART_Cmd(USART1, ENABLE); 
	}
	else
	{
		DMA_Init(DMA1_Channel6, &DMA_InitStructure);
		DMA_Cmd(DMA1_Channel6, ENABLE);
		
		USART_DMACmd(USART2,USART_DMAReq_Rx,ENABLE);
		USART_Cmd(USART2, ENABLE); 
	}
	   
  
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);          
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;      
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;      
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     
  NVIC_Init(&NVIC_InitStructure); 
}

void uart1_Rstart_dma(void)
{
	static uint16_t last_size1 = 0;
	uint16_t x;
	
	DMA1_Channel5->CCR &= (uint16_t)(~DMA_CCR1_EN);//close dma
	
	DMA1_Channel5->CMAR = (uint32_t)USART1_RX_BUF;
	
	DMA1_Channel5->CNDTR = USART_REC_LEN;
	
	for( x = USART1_RX_Size; x < last_size1; x++)
	{
		USART1_RX_BUF[x] = 0;
	}
	last_size1 = USART1_RX_Size;
	DMA1_Channel5->CCR |= DMA_CCR1_EN;// enable
}

// usart1 interrupt handle    
void USART1_IRQHandler(void)                                 
{  
	uint32_t temp = 0;
	
	if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)  
	{ 
			// 相当于USART_ClearFlag(USART1,USART_IT_IDLE); (函数无效,需软件读取清) 
      temp = USART1->SR;  
      temp = USART1->DR;
				
			USART1_RX_FLAG = 1;
      USART1_RX_Size = USART_REC_LEN - DMA_GetCurrDataCounter(DMA1_Channel5);  
  
		#ifdef debug
			SendMulData((char*)USART1_RX_BUF, USART1_RX_Size);
		#endif
      // DMA reset  
      uart1_Rstart_dma(); 
	} 
	__nop();
} 

void uart2_Rstart_dma(void)
{
	static uint16_t last_size2 = 0;
	uint16_t x;
	
	DMA1_Channel6->CCR &= (uint16_t)(~DMA_CCR1_EN);//close dma
	
	DMA1_Channel6->CMAR = (uint32_t)USART2_RX_BUF;
	
	DMA1_Channel6->CNDTR = USART_REC_LEN;
	
	for( x = USART2_RX_Size; x < last_size2; x++)
	{
		USART2_RX_BUF[x] = 0;
	}
	last_size2 = USART2_RX_Size;
	DMA1_Channel6->CCR |= DMA_CCR1_EN;// enable
}

// usart1 interrupt handle    
void USART2_IRQHandler(void)                                 
{  
	uint32_t temp = 0;
	
	if(USART_GetITStatus(USART2, USART_IT_IDLE) != RESET)  
	{ 
		#ifdef debug
			printf("\n%s\n", USART2_RX_BUF);
		#endif
			// 相当于USART_ClearFlag(USART1,USART_IT_IDLE); (函数无效,需软件读取清) 
      temp = USART2->SR;  
      temp = USART2->DR;
				
			USART2_RX_FLAG = 1;
      USART2_RX_Size = USART_REC_LEN - DMA_GetCurrDataCounter(DMA1_Channel6);  
  
      // DMA reset  
      uart2_Rstart_dma(); 
	} 
	__nop();
} 

void SendMulData(char *data, u16 size)		//最多发送USART_SEND_LEN字节
{
	int i=0;
	for(; i < size; i++)
	{
		USART_SendData(USART2,data[i]);
		while( !USART_GetFlagStatus(USART2, USART_FLAG_TXE) );
	}
}









  • 33
    点赞
  • 278
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值