民科小石头 2024-03-11 17:30 采纳率: 36.4%
浏览 44

51单片机向SIM800A发送AT指令,但SIM800A不发送短信是什么原因?

当单片机与电脑通信时,串口助手显示如下:

img

我独自用电脑操作串口助手发送AT指令,SIM800A成功发送短信:

img

但当我单片机与SIM800A通信时,SIM800A没有执行指令。想请教各位专家是什么原因?
接线如下:

img


代码如下:

#include<REGX52.H>
#include<intrins.h>
#include "Delay.h"
#include "LCD1602.h"
#include "ADC0832.h"
#include<stdio.h>
#define FOSC_110592M
#define uchar unsigned char
#define uint unsigned int
unsigned int AD_X;
unsigned int AD_Y;

//ÒÔÏÂÊÇ¿ª»úºó·¢Ë͵½ÊÖ»úµÄÄÚÈÝ£¬·¢Ë͵ĺÅÂëÔÚ³ÌÐòÖÐÐ޸ġ£    
unsigned int  rec_data_len_uart=0;    //±ê¼ÇBuffer_Uart0½ÓÊÕÊý×é
unsigned char idata Buffer_Uart0_Rec[25]={0};         //Uart0ÖжϽÓÊÕÊý×é

//×¢Ò⣬ÎÞÂÛ½ÓÊÕµ½ÐźŻ¹ÊÇ·¢ËÍÍêÐźţ¬¶¼»á½øÖжϷþÎñ³ÌÐòµÄ
/*³õʼ»¯³ÌÐò£¨±ØÐëʹÓ㬷ñÔòÎÞ·¨ÊÕ·¢£©£¬´Î³ÌÐò½«»áʹÓö¨Ê±Æ÷1*/
void SerialInti()//³õʼ»¯³ÌÐò£¨±ØÐëʹÓ㬷ñÔòÎÞ·¨ÊÕ·¢£©
{
    TMOD=0x20;//¶¨Ê±Æ÷1²Ù×÷ģʽ2:8λ×Ô¶¯ÖØÔض¨Ê±Æ÷

#ifdef FOSC_12M           //ÔÚÕâÀï¸ù¾Ý¾§Õñ´óСÉèÖò»Í¬µÄÊýÖµ³õʼ»¯´®¿Ú
    TH1=0xf3;//×°Èë³õÖµ£¬²¨ÌØÂÊ2400
    TL1=0xf3;    
#else     
    TH1=0xfd;//×°Èë³õÖµ£¬²¨ÌØÂÊ9600
    TL1=0xfd;
#endif //end of SOC_12M
    
    TR1=1;//´ò¿ª¶¨Ê±Æ÷
    SM0=0;//ÉèÖô®ÐÐͨѶ¹¤×÷ģʽ£¬£¨10Ϊһ²¿·¢ËÍ£¬²¨ÌØÂʿɱ䣬Óɶ¨Ê±Æ÷1µÄÒç³öÂÊ¿ØÖÆ£©
    SM1=1;//(ͬÉÏ)ÔÚ´ËģʽÏ£¬¶¨Ê±Æ÷Òç³öÒ»´Î¾Í·¢ËÍÒ»¸öλµÄÊý¾Ý
    REN=1;//´®ÐнÓÊÕÔÊÐí루ҪÏÈÉèÖÃsm0sm1ÔÙ¿ª´®ÐÐÔÊÐí£©
    EA=1;//¿ª×ÜÖжÏ
    ES=1;//¿ª´®ÐпÚÖÐ¶Ï    
}

/*´®ÐÐͨѶÖжϣ¬ÊÕ·¢Íê³É½«½øÈë¸ÃÖжÏ*/
void Serial_interrupt() interrupt 4 
{
    unsigned char temp_rec_data_uart0;    
    temp_rec_data_uart0 = SBUF;//¶ÁÈ¡½ÓÊÕÊý¾Ý        
    RI=0;//½ÓÊÕÖжÏÐźÅÇåÁ㣬±íʾ½«¼ÌÐø½ÓÊÕ            
    Buffer_Uart0_Rec[rec_data_len_uart]=temp_rec_data_uart0;    //½ÓÊÕÊý¾Ý
    rec_data_len_uart++;
    if(rec_data_len_uart>24)
    {
        rec_data_len_uart=0;     //´ÓÍ·¿ªÊ¼½ÓÊÕÊý¾Ý
    }    
}
void Uart1Send(uchar c)
{
    SBUF=c;
    while(!TI);//µÈ´ý·¢ËÍÍê³ÉÐźţ¨TI=1£©³öÏÖ
    TI=0;    
}
//´®ÐпÚÁ¬Ðø·¢ËÍcharÐÍÊý×飬Óöµ½ÖÕÖ¹ºÅ/0½«Í£Ö¹
void Uart1Sends(uchar *str)
{
    while(*str!='\0')
    {
        Uart1Send(*str);
        //SBUF=*str;
        //while(!TI);//µÈ´ý·¢ËÍÍê³ÉÐźţ¨TI=1£©³öÏÖ
        //TI=0;
        str++;
    }
}

void main()
{
    LCD_Init();
    SerialInti();
    LCD_ShowString(1,1,"X     Y");
    Delay(10000);
    while(1)
    {
        AD_X=ADC0832(1);
        LCD_ShowNum(2,1,AD_X,3);
    AD_Y=ADC0832(0);
        LCD_ShowNum(2,6,AD_Y,3);
        if((AD_X<=47  ||  AD_X>=126) || (AD_Y>=141 ||  AD_Y<=57))
        {
                //----------------ΪʲôÊÇÏÂÃæÕâЩATÖ¸ÁîÄØ£¬Ç뿴Ⱥ¹²ÏíÎļþSIM900AÖØÒªµÄ¶ÌÐÅÖ¸ÁîÎļþ------------
                Uart1Sends("AT\r\n");
                Delay(2000);//ÑÓʱ´óÔ¼2Ãë
                Uart1Sends("AT+CSCS=\"UCS2\"\r\n");
                Delay(2000);//ÑÓʱ´óÔ¼2Ãë
                Uart1Sends("AT+CMGF=1\r\n");
                Delay(2000);//ÑÓʱ2Ãë
            Uart1Sends("AT+CSCA?\n");
                Delay(2000);//ÑÓʱ2Ãë
            Uart1Sends("AT+CSMP=17,167,0,25\r\n");
                Delay(2000);//ÑÓʱ2Ãë
                Uart1Sends("AT+CMGS=\"00310039003100360037003500340036003700320034\"\r\n");//´Ë´¦ÐÞ¸ÄΪ¶Ô·½µÄµç»°ºÅ£¬µç»°»°µÄUNICON±àÂ룬¿ÉʹÓÃÎÒÃÇÅäÌ×µÄ
                                                                                        //×ÊÁÏ°üÖÐµÄ ÖÐÎÄתUNICON±àÂ빤¾ßÀ´»ñÈ¡¡£Ìرð×¢Ò⣺ÄǸöÈí¼þ
                                                                                        //»ñµÃµÄunicon ±àÂë´ýÓпոñ£¬Êµ¼ÊÖÐҪȥµô£¬·ñÔòÄ£¿é»á±¨´í
                Delay(2000);//ÑÓʱ2Ãë
                Uart1Sends("4F7F7528800553EF80FD64545012FF0C8BF7524D5F800058005800585E2E52A9FF01");//Ð޸ĶÌÐÅÄÚÈÝ,¶ÌÐÅÄÚÈÝ¿ÉΪÖÐÎÄ¡¢Ó¢ÎĺÍÊý×Ö£¬µ«¶¼ÊǶÔÓ¦µÄunicon ±àÂë¡£
                Uart1Send(0x1a);
                Delay(8000);//ÑÓʱ10Ãë
        }
            
        Delay(100);
    }
}

  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-03-11 17:33
    关注

    引自免费微信小程序:皆我百晓生

    从您提供的信息来看,51单片机通过串口向SIM800A模块发送AT指令时无法成功发送短信。首先,请确认以下几点以排查问题:

    1. 硬件连接

      • 检查51单片机与SIM800A模块之间的TX和RX线是否正确连接。通常情况下,单片机的TX引脚应连接到SIM800A的RX引脚,单片机的RX引脚应连接到SIM800A的TX引脚,并确保电源、地线等连接无误。
    2. 波特率设置

      • 根据代码中的初始化设置,波特率为9600,确保SIM800A模块也配置为相同的波特率。
    3. AT指令执行顺序及格式

      • 确保所有的AT指令均被正确执行且接收到相应的“OK”回复,尤其是AT+CMGS命令之后,需要等待“>`字符出现才能发送短信内容。在您的代码中似乎没有检查并等待这个指示符,应当在发送短信内容前加入一个循环来等待" > "符号。
    4. 短信内容编码

      • SMS内容是使用UNICODE编码(UCS2)的,确保在发送前已经将中文或其他非ASCII字符转换为正确的UCS2编码。
    5. 控制字符发送

      • 在发送完短信内容后,最后需发送结束符Ctrl+Z(即0x1A),用于告知SIM800A模块短信内容已发送完毕。您的代码中已经包含了发送结束符的部分,但请确保该字符实际被正确发送出去。

    针对以上第3点,在您的代码中添加处理等待" > "符号的逻辑,修改后的部分可以如下所示:

    void main()
    {
        // ... 其他初始化代码
    
        while(1)
        {
            // ... 读取ADC数据并显示
            
            //----------------- 发送AT指令 -----------------
            
            Uart1Sends("AT\r\n");
            Delay(2000);
            if (CheckResponseForOK()) // 添加检查响应函数
            {
                // 继续发送其他AT指令...
            }
    
            // ... 其他AT指令发送和延时...
    
            Uart1Sends("AT+CMGS=\"00310039003100360037003500340036003700320034\"\r\n");
            Delay(2000);
            if (WaitForPrompt(">")) // 添加等待">"提示符的函数
            {
                Uart1Sends("4F7F7528800553EF80FD64545012FF0C8BF7524D5F800058005800585E2E52A9FF01");
                Uart1Send(0x1a); // 发送结束符
                Delay(8000);
            }
                
            Delay(100);
        }
    }
    
    // 添加函数:检查是否有"OK"响应
    uchar CheckResponseForOK()
    {
        uchar response[5];
        uint timeout = 0;
        while(timeout < 1000) // 设置合理的超时时间
        {
            if (rec_data_len_uart > 0 && Buffer_Uart0_Rec[0] == 'O' && Buffer_Uart0_Rec[1] == 'K')
            {
                rec_data_len_uart = 0; // 清空接收缓冲区
                return 1; // 返回真,表示收到了"OK"
            }
            timeout++;
            Delay(10); // 延时等待下一次中断到来
        }
        return 0; // 返回假,表示超时未收到"OK"
    }
    
    // 添加函数:等待">"提示符
    uchar WaitForPrompt(char prompt)
    {
        uint timeout = 0;
        while(timeout < 5000) // 设置合理的超时时间
        {
            if (rec_data_len_uart > 0 && Buffer_Uart0_Rec[0] == prompt)
            {
                rec_data_len_uart = 0; // 清空接收缓冲区
                return 1; // 返回真,表示收到了指定提示符
            }
            timeout++;
            Delay(10); // 延时等待下一次中断到来
        }
        return 0; // 返回假,表示超时未收到指定提示符
    }
    

    请注意,这里假设了你已经有了一个基本的UART中断驱动的数据接收机制,并且能够正确地将接收到的数据存入Buffer_Uart0_Rec数组中。你需要根据实际情况完善或调整上述代码中的CheckResponseForOK()WaitForPrompt()函数实现。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 3月11日

悬赏问题

  • ¥15 phython如何实现以下功能?查找同一用户名的消费金额合并—
  • ¥15 孟德尔随机化怎样画共定位分析图
  • ¥18 模拟电路问题解答有偿速度
  • ¥15 CST仿真别人的模型结果仿真结果S参数完全不对
  • ¥15 误删注册表文件致win10无法开启
  • ¥15 请问在阿里云服务器中怎么利用数据库制作网站
  • ¥60 ESP32怎么烧录自启动程序
  • ¥50 html2canvas超出滚动条不显示
  • ¥15 java业务性能问题求解(sql,业务设计相关)
  • ¥15 52810 尾椎c三个a 写蓝牙地址