STM32F103C8T6采 DS18B20,通过A7680C 4G模块不断发送短信到手机

STM32F103C8T6采 DS18B20,通过A7680C 4G模块不断发送短信到手机

🎯 实现效果



🎯 传感器用途

DS18B20作为Dallas半导体推出的单总线数字温度传感器,凭借其"单总线通信、无需AD转换、精准度高、布线极简"的核心优势,已广泛应用于工业控制、智能家居、农业养殖、医疗健康、交通运输、嵌入式科研等多个领域,涵盖环境测温、设备监控、温控联动等核心需求,具体细分场景如下:

  1. 工业控制与自动化领域

• 设备状态监测:电机绕组温度监测、配电柜/配电箱内部测温、变频器/PLC模块温度监控

• 工业制程温控:化工反应釜温度采集、冶金设备炉体测温、蒸汽管道温度监测;

• 冷链与仓储:工业冷库、冷链运输车的多点温度监测、药品/化工原料仓储温度追溯。

  1. 智能家居与生活电器领域

• 室温调控:智能空调、地暖系统的温度采集、智能音箱/中控屏的室温显示;

• 家电温控:冰箱/冰柜温度监测、热水器水温控制、烤箱/微波炉温度校准;

• 生活辅助:智能花盆温度监测、恒温酒柜/雪茄柜温度监控、浴室防烫测温。

  1. 农业与养殖领域

• 种植场景:温室大棚多点测温、育苗室温度监控、土壤温度采集;

• 养殖场景:水产养殖池水温监测、畜禽养殖舍温度监测、饲料仓储温度监测。

  1. 医疗健康领域

• 便携式测温:电子体温计、额温枪/耳温枪内部温度校准;

• 设备温控:疫苗冷藏箱/冷藏车温度监测、医用恒温箱、医疗仪器散热监测。

  1. 交通运输与汽车电子领域

• 汽车电子:发动机水温监测、座舱温度采集、动力电池包测温、轮胎温度监测;

• 轨道交通:列车车厢温度监测、制动系统温度监控。

🌟传感器的介绍

DS18B20是一款基于单总线(1-Wire)的数字式温度传感器,采用半导体集成工艺,内部集成了温度敏感元件、A/D转换器、ROM存储器、暂存器等核心模块,无需外部AD转换电路即可直接输出数字温度信号,具有"精准度高、功耗低、布线简单、支持组网"等核心优势

  1. 核心技术特性

• 测温范围宽:-55℃ ~ +125℃,覆盖绝大多数民用、工业场景;其中在-10℃ ~ +85℃的核心区间,测温精度可达±0.5℃,满足高精度测温需求,在-55℃ ~ -10℃和+85℃ ~ +125℃区间,精度可达±1℃

• 通信方式极简:采用单总线通信协议,仅需1根数据线即可实现与主控的双向通信,无需I2C、SPI等多线通信接口,大幅简化布线难度,尤其适合多点组网场景;

• 无需外部元件:正常工作时仅需接入电源、GND和DQ线,无需额外的AD转换模块、放大电路;硬件成本极低;

• 支持多点组网:每个DS18B20都有唯一的64位ROM地址,多个传感器可共用1根DQ线,通过ROM地址区分不同节点,最多可支持数百个传感器组网,适合大面积分布式测温;

• 低功耗设计:工作电流典型值为1mA,待机电流仅为1μA,可适配电池供电的便携式设备,延长续航时间;

• 抗干扰能力强:采用数字信号传输,相较于模拟温度传感器,可有效避免传输过程中的信号衰减、电磁干扰,适合长距离传输;

• 内置保护机制:内部集成CRC校验模块,可对读取的温度数据进行校验,避免数据错误;同时具备过温保护逻辑,可通过指令配置过温报警阈值。

  1. 内部工作原理

DS18B20的核心工作流程的是"温度采集→A/D转换→数字信号输出",内部结构主要包括4个核心模块:

• 温度敏感元件:采用半导体PN结测温原理,PN结的正向压降会随温度变化而线性变化,通过采集该压降信号实现温度感知;

• A/D转换器:将温度敏感元件输出的模拟信号转换为16位数字信号(对应温度值),无需外部AD模块,转换精度由分辨率配置决定;

• ROM存储器:存储唯一的64位ROM地址,用于多点组网时的节点识别,主控可通过指令读取该地址,实现对特定传感器的操作;

• 暂存器:用于存储A/D转换后的温度数据(2字节)、分辨率配置参数(1字节)、过温报警阈值(2字节)、CRC校验码(1字节)等,主控可通过指令读取或写入暂存器数据。

🎯 单片机连接硬件图

• 实物图



🌟驱动思路

步骤1:单总线初始化

单总线初始化是主控与传感器建立通信的第一步,核心是"主控拉低总线→ 传感器回应→ 主控检测回应",时序要求严格:

• 主控(单片机)主动拉低DQ总线,持续时间≥480μs(最小480μs,建议500μs,确保传感器能检测到总线拉低);

• 主控释放总线(将DQ拉高),进入等待状态;

• DS18B20检测到总线拉低后,会在15~60μs内拉低DQ总线,作为回应信号;

• 主控检测DQ引脚电平,若检测到低电平(持续15~60μs),则初始化成功;若未检测到低电平,说明初始化失败;

传感器释放总线后,DQ会自动拉高,等待主控后续指令。

步骤2:单总线写位/写字节

• 单总线的写操作分为"写0"和"写1",每次写位耗时≥60μs,写字节需逐位发送(8位,低位在前):

• 写0时序:主控拉低DQ总线≥1μs(最小1μs)→ 保持低电平≥60μs(确保传感器读取到0)→ 释放总线(拉高DQ);

• 写1时序:主控拉低DQ总线≥1μs(最小1μs)→ 立即释放总线(拉高DQ)→ 保持高电平≥60μs(确保传感器读取到1);

• 写字节逻辑:将待发送的字节拆分为8位(低位在前),逐位调用写位函数,相邻两位的写操作间隔≥1μs。

步骤3:单总线读位/读字节

• 单总线的读操作需主控主动拉低总线触发,然后读取总线电平,每次读位耗时≥60μs,读字节需逐位读取(8位,低位在前):

• 读位时序:主控拉低DQ总线≥1μs(最小1μs)→ 立即释放总线(拉高DQ)→ 等待15μs(确保传感器数据稳定)→ 读取DQ引脚电平(低电平=0,高电平=1)→ 保持总线高电平至60μs结束;

• 读字节逻辑:逐位读取8位数据,将读取到的位依次拼接(低位在前),得到完整字节数据;相邻两位的读操作间隔≥1μs。

步骤4:读取温度的完整指令流程

• 执行单总线初始化,确认初始化成功;

• 发送「跳过ROM指令」(0xCC):无需读取传感器的64位ROM地址,直接对总线上的传感器进行操作;

• 发送「温度转换指令」(0x44):触发DS18B20开始采集温度并进行A/D转换,转换时间与分辨率相关,需等待转换完成;

• 再次执行单总线初始化(转换完成后需重新建立通信);

• 再次发送「跳过ROM指令」(0xCC);

• 发送「读取暂存器指令」(0xBE):指令发送后,可读取传感器暂存器的9字节数据(暂存器地址0~8);

• 读取9字节数据:重点关注第0字节(温度低字节)和第1字节(温度高字节),其余字节为分辨率配置、过温阈值、CRC校验码;

• 解析温度数据:将温度高字节和低字节拼接为16位数据,根据符号位(高字节最高位)处理正负温度,再除以16得到实际温度值。

🎯 单片机程序代码

main.c

c 复制代码
#include "stm32f10x.h"  
#include "string.h"  
#include "stdio.h" 
#include "delay.h"   
#include "bsp_usart.h"
#include "oled.h"
#include "A7680C.h"
#include "bsp_ds18b20.h"

float temp=0.0;
char buff[20];
int cnt=0;
int main(void)
{
    NVIC_PriorityGroupConfig (NVIC_PriorityGroup_2);
    SysTick_Init(72);  //系统时钟初始化 
    usart1_init(115200);//串口1初始化
    printf("USART1 OK!\r\n");
    usart2_init(115200);//串口1初始化
    usart3_init(115200);//串口3初始化    
    OLED_Init();
    A7680C_Init();
    DS18B20_Init();
    OLED_Clear();
    while(1)
    {
        cnt++;
        if(cnt>=200)
        {
            cnt=0;
            temp = DS18B20_GetTemp_SkipRom();
            printf("温度值:%.2f℃\r\n", temp); // 打印温度,保留2位小数
            sprintf(buff,"temp:%.2f", temp);
            OLED_ShowString(0,2,buff);
            A7680C_SendMessage(buff);
        }
        delay_ms(10); // 1秒读取一次                                                          
    }
}

ds18b20.c

c 复制代码
#include "bsp_ds18b20.h"
#include "delay.h"   
 


/* 可以在下面的宏定义中把后面的延时函数替换换SysTick的延时函数,就是想用那个就换成那个的 */

static void                           DS18B20_GPIO_Config                       ( void );
static void                           DS18B20_Mode_IPU                          ( void );
static void                           DS18B20_Mode_Out_PP                       ( void );
static void                           DS18B20_Rst                               ( void );
static uint8_t                        DS18B20_Presence                          ( void );
static uint8_t                        DS18B20_ReadBit                           ( void );
static uint8_t                        DS18B20_ReadByte                          ( void );
static void                           DS18B20_WriteByte                         ( uint8_t dat );
static void                           DS18B20_SkipRom                           ( void );
static void                           DS18B20_MatchRom                          ( void );



 /**
  * @brief  DS18B20 初始化函数
  * @param  无
  * @retval 无
  */
uint8_t DS18B20_Init(void)
{
    DS18B20_GPIO_Config ();
    
    DS18B20_DQ_1;
    
    DS18B20_Rst();
    
    return DS18B20_Presence ();
    
}


/*
 * 函数名:DS18B20_GPIO_Config
 * 描述  :配置DS18B20用到的I/O口
 * 输入  :无
 * 输出  :无
 */
static void DS18B20_GPIO_Config(void)
{        
    /*定义一个GPIO_InitTypeDef类型的结构体*/
    GPIO_InitTypeDef GPIO_InitStructure;
    

    /*开启DS18B20_DQ_GPIO_PORT的外设时钟*/
    DS18B20_DQ_SCK_APBxClock_FUN ( DS18B20_DQ_GPIO_CLK, ENABLE); 

    /*选择要控制的DS18B20_DQ_GPIO_PORT引脚*/                                                               
      GPIO_InitStructure.GPIO_Pin = DS18B20_DQ_GPIO_PIN;    

    /*设置引脚模式为通用推挽输出*/
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   

    /*设置引脚速率为50MHz */   
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 

    /*调用库函数,初始化DS18B20_DQ_GPIO_PORT*/
      GPIO_Init ( DS18B20_DQ_GPIO_PORT , &GPIO_InitStructure );

}

/*
 * 函数名:DS18B20_Mode_IPU
 * 描述  :使DS18B20-DATA引脚变为输入模式
 * 输入  :无
 * 输出  :无
 */
static void DS18B20_Mode_IPU(void)
{
       GPIO_InitTypeDef GPIO_InitStructure;

          /*选择要控制的DS18B20_DQ_GPIO_PORT引脚*/    
      GPIO_InitStructure.GPIO_Pin = DS18B20_DQ_GPIO_PIN;

       /*设置引脚模式为浮空输入模式*/ 
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;    

      /*调用库函数,初始化DS18B20_DQ_GPIO_PORT*/
      GPIO_Init(DS18B20_DQ_GPIO_PORT, &GPIO_InitStructure);
}


/*
 * 函数名:DS18B20_Mode_Out_PP
 * 描述  :使DS18B20-DATA引脚变为输出模式
 * 输入  :无
 * 输出  :无
 */
static void DS18B20_Mode_Out_PP(void)
{
     GPIO_InitTypeDef GPIO_InitStructure;

         /*选择要控制的DS18B20_DQ_GPIO_PORT引脚*/                                                               
      GPIO_InitStructure.GPIO_Pin = DS18B20_DQ_GPIO_PIN;    

    /*设置引脚模式为通用推挽输出*/
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   

    /*设置引脚速率为50MHz */   
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    /*调用库函数,初始化DS18B20_DQ_GPIO_PORT*/
      GPIO_Init(DS18B20_DQ_GPIO_PORT, &GPIO_InitStructure);
}


/*
 *主机给从机发送复位脉冲
 */
static void DS18B20_Rst(void)
{
    /* 主机设置为推挽输出 */
    DS18B20_Mode_Out_PP();
    DS18B20_DQ_0;
    /* 主机至少产生480us的低电平复位信号 */
    delay_us(750);
    /* 主机在产生复位信号后,需将总线拉高 */
    DS18B20_DQ_1;
    /*从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲*/
    delay_us(15);
}


/*
 * 检测从机给主机返回的存在脉冲
 * 0:成功
 * 1:失败
 */
static uint8_t DS18B20_Presence(void)
{
    uint8_t pulse_time = 0;
    
    /* 主机设置为上拉输入 */
    DS18B20_Mode_IPU();
    
    /* 等待存在脉冲的到来,存在脉冲为一个60~240us的低电平信号 
     * 如果存在脉冲没有来则做超时处理,从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲
     */
    while( DS18B20_DQ_IN() && pulse_time<100 )
    {
        pulse_time++;
        delay_us(1);
    }    
    /* 经过100us后,存在脉冲都还没有到来*/
    if( pulse_time >=100 )
        return 1;
    else
        pulse_time = 0;
    
    /* 存在脉冲到来,且存在的时间不能超过240us */
    while( !DS18B20_DQ_IN() && pulse_time<240 )
    {
        pulse_time++;
        delay_us(1);
    }    
    if( pulse_time >=240 )
        return 1;
    else
        return 0;
}


/*
 * 从DS18B20读取一个bit
 */
static uint8_t DS18B20_ReadBit(void)
{
    uint8_t dat;
    
    /* 读0和读1的时间至少要大于60us */    
    DS18B20_Mode_Out_PP();
    /* 读时间的起始:必须由主机产生 >1us <15us 的低电平信号 */
    DS18B20_DQ_0;
    delay_us(10);
    
    /* 设置成输入,释放总线,由外部上拉电阻将总线拉高 */
    DS18B20_Mode_IPU();
    //DHT11_delay_US(2);
    
    if( DS18B20_DQ_IN() == SET )
        dat = 1;
    else
        dat = 0;
    
    /* 这个延时参数请参考时序图 */
    delay_us(45);
    
    return dat;
}


/*
 * 从DS18B20读一个字节,低位先行
 */
static uint8_t DS18B20_ReadByte(void)
{
    uint8_t i, j, dat = 0;    
    
    for(i=0; i<8; i++) 
    {
        j = DS18B20_ReadBit();        
        dat = (dat) | (j<<i);
    }
    
    return dat;
}


/*
 * 写一个字节到DS18B20,低位先行
 */
static void DS18B20_WriteByte(uint8_t dat)
{
    uint8_t i, testb;
    DS18B20_Mode_Out_PP();
    
    for( i=0; i<8; i++ )
    {
        testb = dat&0x01;
        dat = dat>>1;        
        /* 写0和写1的时间至少要大于60us */
        if (testb)
        {            
            DS18B20_DQ_0;
            /* 1us < 这个延时 < 15us */
        delay_us(8);
            
            DS18B20_DQ_1;
            delay_us(58);
        }        
        else
        {            
            DS18B20_DQ_0;
            /* 60us < Tx 0 < 120us */
            delay_us(70);
            
            DS18B20_DQ_1;            
            /* 1us < Trec(恢复时间) < 无穷大*/
            delay_us(2);
        }
    }
}


 /**
  * @brief  跳过匹配 DS18B20 ROM
  * @param  无
  * @retval 无
  */
static void DS18B20_SkipRom ( void )
{
    DS18B20_Rst();       
    
    DS18B20_Presence();     
    
    DS18B20_WriteByte(0XCC);        /* 跳过 ROM */
    
}


 /**
  * @brief  执行匹配 DS18B20 ROM
  * @param  无
  * @retval 无
  */
static void DS18B20_MatchRom ( void )
{
    DS18B20_Rst();       
    
    DS18B20_Presence();     
    
    DS18B20_WriteByte(0X55);        /* 匹配 ROM */
    
}


/*
 * 存储的温度是16 位的带符号扩展的二进制补码形式
 * 当工作在12位分辨率时,其中5个符号位,7个整数位,4个小数位
 *
 *         |---------整数----------|-----小数 分辨率 1/(2^4)=0.0625----|
 * 低字节  | 2^3 | 2^2 | 2^1 | 2^0 | 2^(-1) | 2^(-2) | 2^(-3) | 2^(-4) |
 *
 *
 *         |-----符号位:0->正  1->负-------|-----------整数-----------|
 * 高字节  |  s  |  s  |  s  |  s  |    s   |   2^6  |   2^5  |   2^4  |
 *
 * 
 * 温度 = 符号位 + 整数 + 小数*0.0625
 */
 /**
  * @brief  在跳过匹配 ROM 情况下获取 DS18B20 温度值 
  * @param  无
  * @retval 温度值
  */
float DS18B20_GetTemp_SkipRom ( void )
{
    uint8_t tpmsb, tplsb;
    short s_tem;
    float f_tem;
    
    
    DS18B20_SkipRom ();
    DS18B20_WriteByte(0X44);                /* 开始转换 */
    
    
    DS18B20_SkipRom ();
  DS18B20_WriteByte(0XBE);                /* 读温度值 */
    
    tplsb = DS18B20_ReadByte();         
    tpmsb = DS18B20_ReadByte(); 
    
    
    s_tem = tpmsb<<8;
    s_tem = s_tem | tplsb;
    
    if( s_tem < 0 )        /* 负温度 */
        f_tem = (~s_tem+1) * 0.0625;    
    else
        f_tem = s_tem * 0.0625;
    
    return f_tem;     
    
    
}


 /**
  * @brief  在匹配 ROM 情况下获取 DS18B20 温度值 
  * @param  ds18b20_id:用于存放 DS18B20 序列号的数组的首地址
  * @retval 无
  */
void DS18B20_ReadId ( uint8_t * ds18b20_id )
{
    uint8_t uc;
    
    
    DS18B20_WriteByte(0x33);       //读取序列号
    
    for ( uc = 0; uc < 8; uc ++ )
      ds18b20_id [ uc ] = DS18B20_ReadByte();
    
}


 /**
  * @brief  在匹配 ROM 情况下获取 DS18B20 温度值 
  * @param  ds18b20_id:存放 DS18B20 序列号的数组的首地址
  * @retval 温度值
  */
float DS18B20_GetTemp_MatchRom ( uint8_t * ds18b20_id )
{
    uint8_t tpmsb, tplsb, i;
    short s_tem;
    float f_tem;
    
    
    DS18B20_MatchRom ();            //匹配ROM
    
  for(i=0;i<8;i++)
        DS18B20_WriteByte ( ds18b20_id [ i ] );    
    
    DS18B20_WriteByte(0X44);                /* 开始转换 */

    
    DS18B20_MatchRom ();            //匹配ROM
    
    for(i=0;i<8;i++)
        DS18B20_WriteByte ( ds18b20_id [ i ] );    
    
    DS18B20_WriteByte(0XBE);                /* 读温度值 */
    
    tplsb = DS18B20_ReadByte();         
    tpmsb = DS18B20_ReadByte(); 
    
    
    s_tem = tpmsb<<8;
    s_tem = s_tem | tplsb;
    
    if( s_tem < 0 )        /* 负温度 */
        f_tem = (~s_tem+1) * 0.0625;    
    else
        f_tem = s_tem * 0.0625;
    
    return f_tem;     
    
    
}
/*************************************END OF FILE******************************/

A7680C.c

cpp 复制代码
#include "A7680C.h"
#include "string.h"
#include "bsp_usart.h"
#include "oled.h"
#include "delay.h"

char *strx,*extstrx;

/*****************************************************
清空模块反馈的信息
*****************************************************/
void Clear_Buffer(void)//清空缓存
{
        printf("%s\r\n",buf_uart2.buf);
    buf_uart2.index=0;
    memset(buf_uart2.buf,0,BUFLEN);
}

/*****************************************************
初始化模块 和单片机连接,获取卡号和信号质量
*****************************************************/
void A7680C_Init(void)
{
    //打印初始化信息
    printf("start init A7680C\r\n");
    //发第一个命令ATE1
    USART2_SendStr("ATE1\r\n"); 
    delay_ms(300);
    printf("%s\r\n",buf_uart2.buf);      //打印串口收到的信息
    strx=strstr((const char*)buf_uart2.buf,(const char*)"OK");//返回OK
    Clear_Buffer();    
    while(strx==NULL)
    {
            printf("单片机正在连接模块......\r\n");
            Clear_Buffer();    
            USART2_SendStr("ATE1\r\n"); 
            delay_ms(300);
            strx=strstr((const char*)buf_uart2.buf,(const char*)"OK");//返回OK
    }
    printf("****单片机和模块连接成功*****\r\n");
    OLED_ShowString(0,2,(char *)"              ");
    OLED_ShowString(0,2,(char *)"Connet 4G [OK]");
    USART2_SendStr("ATI\r\n");//获取模块的版本
    delay_ms(300);
    Clear_Buffer();    
    
    USART2_SendStr("AT+CICCID\r\n");//获取卡的序列号 
    delay_ms(300);
    Clear_Buffer();    
    
    USART2_SendStr("AT+CGSN\r\n");//获取模块的imei
    delay_ms(300);
    Clear_Buffer();    
    
    USART2_SendStr("AT+CIMI\r\n");//获取卡号,类似是否存在卡的意思,比较重要。
    delay_ms(300);
    strx=strstr((const char*)buf_uart2.buf,(const char*)"460");//返460,表明识别到卡了
    while(strx==NULL)
    {
            Clear_Buffer();    
            USART2_SendStr("AT+CIMI\r\n");//获取卡号,类似是否存在卡的意思,比较重要。
            delay_ms(300);
            strx=strstr((const char*)buf_uart2.buf,(const char*)"460");//返回OK,说明卡是存在的
    } 
    printf("我的卡号是 : %s \r\n",buf_uart2.buf+8);
    Clear_Buffer();    
    OLED_ShowString(0,2,(char *)"              ");
    OLED_ShowString(0,2,(char *)"SIMCARD [OK]");
    
    USART2_SendStr("AT+CGATT?\r\n");//查询激活状态
    delay_ms(300);
    strx=strstr((const char*)buf_uart2.buf,(const char*)"+CGATT: 1");//返1
    Clear_Buffer();    
    while(strx==NULL)
    {
            Clear_Buffer();    
            USART2_SendStr("AT+CGATT?\r\n");//获取激活状态
            delay_ms(300);
            strx=strstr((const char*)buf_uart2.buf,(const char*)"+CGATT: 1");//返回1,表明注网成功
    }
    OLED_ShowString(0,2,(char *)"              ");
    OLED_ShowString(0,2,(char *)"REGISTER[OK]");

    Clear_Buffer();    
    USART2_SendStr("AT+CSQ\r\n");//查看获取CSQ值
    delay_ms(300);
    strx=strstr((const char*)buf_uart2.buf,(const char*)"+CSQ:");//返回CSQ
    if(strx)
    {
            printf("信号质量是:%s 注意:信号最大值是31 \r\n",buf_uart2.buf+14);      
    }
    Clear_Buffer();    
    OLED_ShowString(0,2,(char *)"              ");
    OLED_ShowString(0,2,(char *)" SINGAL [OK]");
    /*****************************************************/

    USART2_SendStr("AT+CMGF=1\r\n");//将短信模式设置为 text mode
    delay_ms(300);
    strx=strstr((const char*)buf_uart2.buf,(const char*)"OK");//返OK
    Clear_Buffer();    
    while(strx==NULL)
    {
            Clear_Buffer();    
            USART2_SendStr("AT+CMGF=1\r\n");//将短信模式设置为 text mode
            delay_ms(300);
            strx=strstr((const char*)buf_uart2.buf,(const char*)"OK");//返回OK,表明设置成功
    }
    Clear_Buffer();    
}


char ATSTR[128];
void A7680C_SendMessage(char *Data)
{
    Clear_Buffer();    
    sprintf(ATSTR,"AT+CMGS=\"%s\"\r\n",PhoneNumber);
    printf("电话号码: %s \r\n",PhoneNumber);
    USART2_SendStr(ATSTR);//发送短信
    delay_ms(300);
    strx=strstr((const char*)buf_uart2.buf,(const char*)">");
  printf("收到的信息: %s \r\n",buf_uart2.buf);
    Clear_Buffer();
    while(strx==NULL)
    {
            Clear_Buffer();    
            USART2_SendStr(ATSTR);//发送短信
            delay_ms(300);
            strx=strstr((const char*)buf_uart2.buf,(const char*)">");//返回OK,表明设置成功
      printf("收到的信息: %s \r\n",buf_uart2.buf);
    }
    
    Clear_Buffer();
    memset(ATSTR,0,BUFLEN);
    USART2_SendStr(Data);
    delay_ms(300);
    USART2_Send_byte(0x1A);
    strx=strstr((const char*)buf_uart2.buf,(const char*)"OK");
    Clear_Buffer();
    while(strx==NULL)
    {
            Clear_Buffer();    
            USART2_SendStr(ATSTR);//发送短信
            delay_ms(300);
            strx=strstr((const char*)buf_uart2.buf,(const char*)"OK");//返回OK,表明设置成功
      printf("收到的信息: %s \r\n",buf_uart2.buf);
    }
}

🌟代码下载链接

https://download.csdn.net/download/qq_41954594/92516613

相关推荐
zhougl9962 小时前
vue中App.vue和index.html冲突问题
javascript·vue.js·html
止观止2 小时前
告别全局污染:深入理解 ES Modules 模块化与构建工具
javascript·webpack·vite·前端工程化·es modules
echo的PHP开发2 小时前
如何获取苹果手机的 XcodeOrgId
python·智能手机·苹果手机
小刘爱玩单片机2 小时前
【stm32简单外设篇】- LCD1602A
c语言·stm32·单片机·嵌入式硬件
意法半导体STM322 小时前
【官方原创】在H563上使用RTX5 RTOS LAT1584
stm32·单片机·嵌入式硬件·mcu
千寻girling2 小时前
面试官: “ 请你讲一下 package.json 文件 ? ”
前端·javascript·面试
如果你好2 小时前
解决深拷贝循环引用痛点:一篇看懂 WeakMap 实现方案
前端·javascript
han_2 小时前
前端性能优化之性能指标篇
前端·javascript·性能优化
爱生活的苏苏2 小时前
修改默认滚动条样式
开发语言·javascript·ecmascript