栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

基于STM32的无线抄表系统

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

基于STM32的无线抄表系统

目录

一、项目描述

二、原理图

三、实物

 四、代码

六、论文

七、资料清单


资料下载地址:基于STM32无线抄表系统

一、项目描述

1.通过串口获取电表数据,并在OLED液晶上显示;
2. 通过ESP8266WIFI模块将电表数据上传到云平台和手机APP上

二、原理图

 

三、实物

 

 

手机APP

 

 

云平台 

 

 四、代码

    ESP8266代码

#include "bsp_esp8266.h"
#include "common.h"
#include 
#include 
#include 
#include "bsp_SysTick.h"
#include "test.h"
#include "bsp_usart1.h"



static void                   ESP8266_GPIO_Config                 ( void );
static void                   ESP8266_USART_Config                ( void );
static void                   ESP8266_USART_NVIC_Configuration    ( void );

struct  STRUCT_USARTx_Fram strEsp8266_Fram_Record = { 0 };			//ESP8266接收数据结构体


void ESP8266_Init ( void )
{
    ESP8266_GPIO_Config ();								//ESP8266模块使用到的IO口初始化
    ESP8266_USART_Config ();							//与ESP8266模块连接的串口初始化
    macESP8266_RST_HIGH_LEVEL();					//ESP8266模块 复位脚设置为高电平
    macESP8266_CH_DISABLE();							//片选引脚不选中
}

static void ESP8266_GPIO_Config ( void )
{
    
    GPIO_InitTypeDef GPIO_InitStructure;

    
    macESP8266_CH_PD_APBxClock_FUN ( macESP8266_CH_PD_CLK, ENABLE );
    GPIO_InitStructure.GPIO_Pin = macESP8266_CH_PD_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init ( macESP8266_CH_PD_PORT, & GPIO_InitStructure );

    
    macESP8266_RST_APBxClock_FUN ( macESP8266_RST_CLK, ENABLE );
    GPIO_InitStructure.GPIO_Pin = macESP8266_RST_PIN;
    GPIO_Init ( macESP8266_RST_PORT, & GPIO_InitStructure );
}

static void ESP8266_USART_Config ( void )
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;

    
    macESP8266_USART_APBxClock_FUN ( macESP8266_USART_CLK, ENABLE );
    macESP8266_USART_GPIO_APBxClock_FUN ( macESP8266_USART_GPIO_CLK, ENABLE );

    
    
    GPIO_InitStructure.GPIO_Pin =  macESP8266_USART_TX_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init( macESP8266_USART_TX_PORT, &GPIO_InitStructure );

    
    GPIO_InitStructure.GPIO_Pin = macESP8266_USART_RX_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init( macESP8266_USART_RX_PORT, &GPIO_InitStructure );

    
    USART_InitStructure.USART_BaudRate = macESP8266_USART_BAUD_RATE;
    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;
    USART_Init( macESP8266_USARTx, &USART_InitStructure );

    
    USART_ITConfig ( macESP8266_USARTx, USART_IT_RXNE, ENABLE ); //使能串口接收中断
    USART_ITConfig ( macESP8266_USARTx, USART_IT_IDLE, ENABLE ); //使能串口总线空闲中断

    ESP8266_USART_NVIC_Configuration ();

    USART_Cmd( macESP8266_USARTx, ENABLE );
}

static void ESP8266_USART_NVIC_Configuration ( void )
{
    NVIC_InitTypeDef NVIC_InitStructure;
    
    NVIC_PriorityGroupConfig ( macNVIC_PriorityGroup_x );

    
    NVIC_InitStructure.NVIC_IRQChannel = macESP8266_USART_IRQ;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init( &NVIC_InitStructure );
}

void macESP8266_USART_INT_FUN ( void )
{
//		char * pCh;
//		char cStr [ 100 ] = { 0 };
    uint8_t ucCh;
    if ( USART_GetITStatus ( macESP8266_USARTx, USART_IT_RXNE ) != RESET )					//若串口中有数据进来,存储接收到的数据
    {
        ucCh  = USART_ReceiveData( macESP8266_USARTx );
        if ( strEsp8266_Fram_Record .InfBit .FramLength < ( RX_BUF_MAX_LEN - 1 ) )                       //预留1个字节写结束符
            strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ++ ]  = ucCh;
    }
    //进入空闲中断,说明一组数据接收完成
    if ( USART_GetITStatus( macESP8266_USARTx, USART_IT_IDLE ) == SET )              //数据帧接收完毕
    {
        strEsp8266_Fram_Record .InfBit .FramFinishFlag = 1;													//设置数据接收完成标志
        ucCh = USART_ReceiveData( macESP8266_USARTx );                              //由软件序列清除中断标志位(先读USART_SR,然后读USART_DR)
        USART_ClearITPendingBit( macESP8266_USARTx, USART_IT_IDLE );
        //检测与服务器的连接是否断开  只在Station模式下使用
        ucTcpClosedFlag = strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "CLOSEDrn" ) ? 1 : 0;
    }
		    

}

void ESP8266_Rst ( void )
{
#if 1
    ESP8266_Cmd ( "AT+RST", "OK", "ready", 2500 );
#else
    macESP8266_RST_LOW_LEVEL();
    Delay_ms ( 500 );
    macESP8266_RST_HIGH_LEVEL();
#endif
}

bool ESP8266_Cmd ( char * cmd, char * reply1, char * reply2, u32 waittime )
{
    strEsp8266_Fram_Record .InfBit .FramLength = 0;               //接收缓冲区数据长度清0

    macESP8266_Usart ( "%srn", cmd );														//向模块发送命令
    if ( ( reply1 == 0 ) && ( reply2 == 0 ) )                      //不需要接收数据
        return true;
    Delay_ms ( waittime );                 												//延时  等待接收模块返回的指令
    strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ]  = '';			//接收到的字符串末尾加入 结束符
    macPC_Usart ( "%s", strEsp8266_Fram_Record .Data_RX_BUF );		//调试口打印接收到模块的指令
    if ( ( reply1 != 0 ) && ( reply2 != 0 ) )
        return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply1 ) ||
                 ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply2 ) );
    else if ( reply1 != 0 )
        return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply1 ) );
    else
        return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply2 ) );
}


//void ESP8266_AT_Test ( void )
//{
//	macESP8266_RST_HIGH_LEVEL();
//
//	Delay_ms ( 1000 );
//
//	while ( ! ESP8266_Cmd ( "AT", "OK", NULL, 200 ) ) ESP8266_Rst ();

//}
void ESP8266_AT_Test ( void )
{
    char count = 0;

    macESP8266_RST_HIGH_LEVEL();
    Delay_ms ( 1000 );
    while ( count < 10 )
    {
        if( ESP8266_Cmd ( "AT", "OK", NULL, 500 ) ) return;				//如果接收到模块返回的OK指令,就直接返回
        ESP8266_Rst();																						//否则复位模块,重新发送AT测试指令
        ++ count;
		//Main_Uart2();
    }
}

bool ESP8266_Net_Mode_Choose ( ENUM_Net_ModeTypeDef enumMode )
{
    switch ( enumMode )
    {
    case STA:
        return ESP8266_Cmd ( "AT+CWMODE=1", "OK", "no change", 2500 );
    case AP:
        return ESP8266_Cmd ( "AT+CWMODE=2", "OK", "no change", 2500 );
    case STA_AP:
        return ESP8266_Cmd ( "AT+CWMODE=3", "OK", "no change", 2500 );
    default:
        return false;
    }
}

bool ESP8266_JoinAP ( char * pSSID, char * pPassWord )
{
    char cCmd [120];
    sprintf ( cCmd, "AT+CWJAP="%s","%s"", pSSID, pPassWord );
    return ESP8266_Cmd ( cCmd, "OK", NULL, 5000 );
}

bool ESP8266_BuildAP ( char * pSSID, char * pPassWord, ENUM_AP_PsdMode_TypeDef enunPsdMode )
{
    char cCmd [120];
    sprintf ( cCmd, "AT+CWSAP="%s","%s",1,%d", pSSID, pPassWord, enunPsdMode );//名称、密码、通道号(默认为1)、加密方式
    return ESP8266_Cmd ( cCmd, "OK", 0, 1000 );
}

bool ESP8266_Enable_MultipleId ( FunctionalState enumEnUnvarnishTx )
{
    char cStr [20];
    sprintf ( cStr, "AT+CIPMUX=%d", ( enumEnUnvarnishTx ? 1 : 0 ) );
    return ESP8266_Cmd ( cStr, "OK", 0, 500 );
}

bool ESP8266_Link_Server ( ENUM_NetPro_TypeDef enumE, char * ip, char * ComNum, ENUM_ID_NO_TypeDef id )
{
    char cStr [100] = { 0 }, cCmd [120];
    switch (  enumE )
    {
    case enumTCP:
        sprintf ( cStr, ""%s","%s",%s", "TCP", ip, ComNum );
        break;
    case enumUDP:
        sprintf ( cStr, ""%s","%s",%s", "UDP", ip, ComNum );
        break;
    default:
        break;
    }
    if ( id < 5 )
        sprintf ( cCmd, "AT+CIPSTART=%d,%s", id, cStr );
    else
        sprintf ( cCmd, "AT+CIPSTART=%s", cStr );
    return ESP8266_Cmd ( cCmd, "OK", "ALREAY CONNECT", 4000 );
}

bool ESP8266_StartOrShutServer ( FunctionalState enumMode, char * pPortNum, char * pTimeOver )
{
    char cCmd1 [120], cCmd2 [120];
    if ( enumMode )													//开启服务
    {
        sprintf ( cCmd1, "AT+CIPSERVER=%d,%s", 1, pPortNum );
        sprintf ( cCmd2, "AT+CIPSTO=%s", pTimeOver );
        return ( ESP8266_Cmd ( cCmd1, "OK", 0, 500 ) &&
                 ESP8266_Cmd ( cCmd2, "OK", 0, 500 ) );
    }
    else																		//关闭服务
    {
        sprintf ( cCmd1, "AT+CIPSERVER=%d,%s", 0, pPortNum );
        return ESP8266_Cmd ( cCmd1, "OK", 0, 500 );
    }
}

uint8_t ESP8266_Get_LinkStatus ( void )
{
    if ( ESP8266_Cmd ( "AT+CIPSTATUS", "OK", 0, 500 ) )
    {
        if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "STATUS:2rn" ) )							//获得ip
            return 2;
        else if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "STATUS:3rn" ) )				//建立连接
            return 3;

        else if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "STATUS:4rn" ) )				//失去连接
            return 4;
    }
    return 0;
}

uint8_t ESP8266_Get_IdLinkStatus ( void )
{
    uint8_t ucIdLinkStatus = 0x00;
    if ( ESP8266_Cmd ( "AT+CIPSTATUS", "OK", 0, 500 ) )
    {
        if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+CIPSTATUS:0," ) )
            ucIdLinkStatus |= 0x01;
        else
            ucIdLinkStatus &= ~ 0x01;

        if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+CIPSTATUS:1," ) )
            ucIdLinkStatus |= 0x02;
        else
            ucIdLinkStatus &= ~ 0x02;

        if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+CIPSTATUS:2," ) )
            ucIdLinkStatus |= 0x04;
        else
            ucIdLinkStatus &= ~ 0x04;

        if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+CIPSTATUS:3," ) )
            ucIdLinkStatus |= 0x08;
        else
            ucIdLinkStatus &= ~ 0x08;

        if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+CIPSTATUS:4," ) )
            ucIdLinkStatus |= 0x10;
        else
            ucIdLinkStatus &= ~ 0x10;
    }
    return ucIdLinkStatus;
}

uint8_t ESP8266_Inquire_ApIp ( char * pApIp, uint8_t ucArrayLength )
{
    char uc;
    char * pCh;
    ESP8266_Cmd ( "AT+CIFSR", "OK", 0, 500 );
    pCh = strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "APIP,"" );
    if ( pCh )
        pCh += 6;
    else
        return 0;
    for ( uc = 0; uc < ucArrayLength; uc ++ )
    {
        pApIp [ uc ] = * ( pCh + uc );

        if ( pApIp [ uc ] == '"' )
        {
            pApIp [ uc ] = '';
            break;
        }
    }
    return 1;
}

bool ESP8266_UnvarnishSend ( void )
{
    if ( ! ESP8266_Cmd ( "AT+CIPMODE=1", "OK", 0, 500 ) )
        return false;
    return
        ESP8266_Cmd ( "AT+CIPSEND", "OK", ">", 500 );
}

void ESP8266_ExitUnvarnishSend ( void )
{
    Delay_ms ( 1000 );
    macESP8266_Usart ( "+++" );
    Delay_ms ( 500 );
}

bool ESP8266_SendString ( FunctionalState enumEnUnvarnishTx, char * pStr, u32 ulStrLength, ENUM_ID_NO_TypeDef ucId )
{
    char cStr [20];
    bool bRet = false;
    if ( enumEnUnvarnishTx )
    {
        macESP8266_Usart ( "%s", pStr );
        bRet = true;
    }
    else
    {
        if ( ucId < 5 )
            sprintf ( cStr, "AT+CIPSEND=%d,%d", ucId, ulStrLength + 2 );
        else
            sprintf ( cStr, "AT+CIPSEND=%d", ulStrLength + 2 );

        ESP8266_Cmd ( cStr, "> ", 0, 1000 );
        bRet = ESP8266_Cmd ( pStr, "SEND OK", 0, 1000 );
    }
    return bRet;
}

char * ESP8266_ReceiveString ( FunctionalState enumEnUnvarnishTx )
{
    char * pRecStr = 0;

    strEsp8266_Fram_Record .InfBit .FramLength = 0;
    strEsp8266_Fram_Record .InfBit .FramFinishFlag = 0;

    while ( ! strEsp8266_Fram_Record .InfBit .FramFinishFlag );
    strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ] = '';

    if ( enumEnUnvarnishTx )
        pRecStr = strEsp8266_Fram_Record .Data_RX_BUF;
    else
    {
        if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+IPD" ) )
            pRecStr = strEsp8266_Fram_Record .Data_RX_BUF;
    }
    return pRecStr;
}

uint8_t ESP8266_CWLIF ( char * pStaIp )
{
    uint8_t uc, ucLen;
    char * pCh, * pCh1;
    ESP8266_Cmd ( "AT+CWLIF", "OK", 0, 100 );
    pCh = strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "," );
    if ( pCh )
    {
        pCh1 = strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "AT+CWLIFrrn" ) + 11;
        ucLen = pCh - pCh1;
    }
    else
        return 0;
    for ( uc = 0; uc < ucLen; uc ++ )
        pStaIp [ uc ] = * ( pCh1 + uc );

    pStaIp [ ucLen ] = '';
    return 1;
}

uint8_t ESP8266_CIPAP ( char * pApIp )
{
    char cCmd [ 30 ];
    sprintf ( cCmd, "AT+CIPAP="%s"", pApIp );
    if ( ESP8266_Cmd ( cCmd, "OK", 0, 5000 ) )
        return 1;
    else
        return 0;
}

六、论文

七、资料清单

 

 

 

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/882891.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号