STM32
直播中

李宛蔓

7年用户 975经验值
私信 关注
[问答]

如何利用STM32+ESP8266去实现远程控制LED呢

如何利用STM32+ESP8266去实现远程控制LED呢?有哪些基本步骤?

回帖(1)

高峰

2021-12-8 15:24:01
一、硬件连接

[tr]ESP8266STM32[/tr]
3V33.3
GNDGND
RXPB10
TXPB11
然后STM32f103C8T6核心板自带了一个LED接的是PB13引脚。

这里值得一提的是,刚开始我把ESP8266的3V3引脚接到了USB转TTL的3V3上,用串口调试助手没反应,后来发现是供电的问题,换到STLINK的3.3V上就好了。

二、云平台

想要实现远程控制,需要一个数据转发的过程,所以,我们需要云平台来给我们转发数据。
将手机以及其他设备(如ESP8266)接入云平台后,它们之间就可以进行远程通信了。
获取IP地址和端口号,这个IP和端口号在后面的软件配置里需要用到
点进去之后是这样的





三、软件配置

1、LED的配置


//LED初始化
void LED_Init(void)
{
        GPIO_InitTypeDef  GPIO_InitStructure;


        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);         //使能PC端口时钟


        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;                                 //LED0-->PB.5 端口配置
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
        GPIO_Init(GPIOC, &GPIO_InitStructure);                                         //根据设定参数初始化GPIOC13
       
        GPIO_SetBits(GPIOC,GPIO_Pin_13);                                                 //PC13 输出高
}


2、串口3的配置
因为我们需要串口1来调试代码,所以用STM32的串口3也就是PB10、PB11与ESP8266连接,下面是串口3的配置代码以接收中断服务函数。


//串口接收缓存区        
u8 USART3_RX_BUF[USART3_MAX_RECV_LEN];                                 //接收缓冲,最大USART3_MAX_RECV_LEN个字节.
u8  USART3_TX_BUF[USART3_MAX_SEND_LEN];                         //发送缓冲,最大USART3_MAX_SEND_LEN字节


//接收到的数据状态
//[15]:0,没有接收到数据;1,接收到了一批数据.
//[14:0]:接收到的数据长度
vu16 USART3_RX_STA=0;


//串口3接收中断服务函数
void USART3_IRQHandler(void)
{
        u8 res;       
        if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)//接收到数据
        {               
                res =USART_ReceiveData(USART3);       
                USART_SendData(DEBUG_USARTx,res);    //这里是把ESP8266发送到串口3的消息发送到电脑端串口调试助手,便于调试
   
                if(res != 'A')                     //以‘A’为结束位,收到‘A’表示一次接收消息完成
                        {
                                if((USART3_RX_STA&(1<<15))==0)//接收完的一批数据,还没有被处理,则不再接收其他数据
                                {
                                                USART3_RX_BUF[USART3_RX_STA++]=res;        //记录接收到的值         
                                }
                                else
                                {
                                        USART3_RX_STA|=1<<15;                                //没有收到结束符‘A’,收到的字节数>=0x80,强制标记接收完成
                                }       
                        }               
                        else
                        {
                                USART3_RX_STA|=1<<15;                                //接收消息完成
                        }       
        }                               
}




//初始化IO 串口3
//pclk1:PCLK1时钟频率(Mhz)
//bound:波特率          
void usart3_init(u32 bound)
{  
        NVIC_InitTypeDef NVIC_InitStructure;
        GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;


        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);        // GPIOB时钟
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); //串口3时钟使能


        USART_DeInit(USART3);  //复位串口3
                 //USART3_TX   
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB10
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽输出
  GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PB10
   
    //USART3_RX          
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOB, &GPIO_InitStructure);  //初始化PB11
       
        USART_InitStructure.USART_BaudRate = bound;//波特率一般设置为9600;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
        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;        //收发模式
  
        USART_Init(USART3, &USART_InitStructure); //初始化串口        3
  
        USART_Cmd(USART3, ENABLE);                    //使能串口
       
        //使能接收中断
  USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启中断   
       
        //设置中断优先级
        NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2 ;//抢占优先级3
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                //子优先级3
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
        NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器


        USART3_RX_STA=0;                //清零
}


//串口3,printf 函数
//确保一次发送数据不超过USART3_MAX_SEND_LEN字节
void u3_printf(char* fmt,...)  
{  
        u16 i,j;
        va_list ap;
        va_start(ap,fmt);
        vsprintf((char*)USART3_TX_BUF,fmt,ap);
        va_end(ap);
        i=strlen((const char*)USART3_TX_BUF);                //此次发送数据的长度
        for(j=0;j         {
          while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕   
                USART_SendData(USART3,USART3_TX_BUF[j]);
        }
}


3、ESP8266的配置
这里需要注意的是,因为要发送 " ,所以要加上转义字符


这里的IP地址与端口号填我们在云平台获取的,每发送一条命令都需要延时等待一下,可以按情况更改


char a[]="AT+CWMODE=1";
char b[]="AT+RST";
char c[]="AT+CWJAP="WIFI名称","WIFI密码"";               
char d[]="AT+CIPMUX=1";
char e[]="AT+CIPSTART=0,"TCP","IP地址",端口号";




void esp8266_start_trans(void)
{
        //设置工作模式 1:station模式   2:AP模式  3:兼容 AP+station模式
        esp8266_send_cmd1((u8 *)a);
        delay_ms(1000);
        delay_ms(1000);
       
        //重启
        esp8266_send_cmd1((u8 *)b);
  delay_ms(1000);
        delay_ms(1000);
        delay_ms(1000);
        delay_ms(1000);


        //连接WIFI
        esp8266_send_cmd1((u8 *)c);
  delay_ms(1000);
        delay_ms(1000);
        delay_ms(1000);
        delay_ms(1000);
        delay_ms(1000);
        delay_ms(1000);
        delay_ms(1000);
        delay_ms(1000);


       
        esp8266_send_cmd1((u8 *)d);
  delay_ms(1000);
        delay_ms(1000);


        //连接TCP服务端
        esp8266_send_cmd1((u8 *)e);
        delay_ms(1000);
        delay_ms(1000);
        delay_ms(1000);




       


}


void esp8266_send_cmd1(u8 *cmd)
{
  u3_printf("%srn",cmd);        //发送命令,需要加换行符
}


4、main函数
收到"on"开灯,收到"off"灭灯


int main(void)
{       
  USART_Config();
        delay_init();
        LED_Init();
       
        usart3_init(115200);


        esp8266_start_trans();       
       
        printf("初始化完成n");
       
        USART3_RX_STA=0;
  while(1)
        {       


    if(USART3_RX_STA&0x8000)   //如果消息接收完成,则处理
                {
                        if(strstr((const char*)USART3_RX_BUF,"on"))  //这里是看接收到的消息中有没有自己设置的命令“on”,strstr()函数不会用的可以搜一下
                                {
                                        GPIO_ResetBits(GPIOC,GPIO_Pin_13);
                                }
                        if(strstr((const char*)USART3_RX_BUF,"off"))
                        {
                                GPIO_SetBits(GPIOC,GPIO_Pin_13);
                        }
                        USART3_RX_STA=0;    //消息处理完成,开始重新接收
                        memset(USART3_RX_BUF,0,600);         //将接收区清0
                }


        }       
}


四、测试

打开电脑串口调试助手,用手机或电脑网络调试助手连接云平台,发送命令,记得加上结束符’A’,现象如下,同时LED的亮灭情况也随命令变化
手机端我用的是自己写的APP

电脑串口调试助手




LED的变化我就不贴出来了
最后把我的工程文件以及APP分享出来,需要的自取,链接:
好了,到这里就结束了,下次分享一下我写手机端TCP调试助手的过程。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分