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) );
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)