单片机gsm模块编程_gps模块与gsm模块和单片机通信 - CSDN
  • 51单片机控制GSM模块TC35i发短信,打电话的完整C程序!
  • 自己改的AT89S51单片机控制GSM模块(M22)发送短信程序,在Keil上编译没错,但还未试过烧入片内运行。。 大家看看,这个程序可行否? 还有什么错误的地方? 希望搞过GSM的朋友多提点意见,让程序完善起来! (偶弄...

    自己改的AT89S51单片机控制GSM模块(M22)发送短信程序,在Keil上编译没错,但还未试过烧入片内运行。。  
    大家看看,这个程序可行否?   还有什么错误的地方?  
    希望搞过GSM的朋友多提点意见,让程序完善起来!
    (偶弄GSM也一段时间啦,希望有兴趣的朋友加我QQ:30651279多多交流)

    /***********************************************************
    文件名称:main.c
    作         者:xiaoyi46       QQ:30651279
    说         明:控制发送SMS信息的C51程序[GSM模块(M22)通过串口与单片机相连]
    ***********************************************************/

    #include   <reg51.h>
    #define   uint   unsigned   int
    #define   uchar   unsigned   char

    //**********函数定义**********//
    void   main(void);   //主函数
    void   Ini_UART(void);   //串口初始化
    void   Delay(void);   //延时
    void   CMGF(void);   //设置发送数据为TXET格式
    void   CMGS(void);   //设置目的手机号码
    void   SEND(void);   //发送字符串


    /***********************************************************
    函数名称:main
    函数功能:主函数                                 入口参数:无         出口参数:无
    ***********************************************************/
    void   main(void)
    {
            Ini_UART();   //串口初始化

            CMGF();     //设置发送数据为TXET格式
            Delay();

            CMGS();     //设置目的手机号码
            Delay();

            SEND();
            Delay();
    }


    /***********************************************************
    函数名称:Ini_UART
    函数功能:串口初始化设置                 入口参数:无         出口参数:无
    ***********************************************************/
    void   Ini_UART(void)
    {
            SCON   =   0x50;   //UART方式1:8位UART;   REN=1:允许接收
            PCON   =   0x00;   //SMOD=0:波特率不加倍

            TMOD   =   0x20;   //T1方式2,用于UART波特率

            TH1     =   0xFD;
            TL1     =   0xFD;   //UART波特率设置:9600
            TR1     =   1;
    }


    /***********************************************************
    函数名称:Delay1ms
    函数功能:延时                                   入口参数:无           出口参数:无
    ***********************************************************/
    void   Delay(void)
    {      
            uint   i,j;

            for   (i=0;   i <10;   i++)
            {
                for(j=0;   j <1000;   j++);
            }
    }


    /***********************************************************
    函数名称:CMGF
    函数功能:设置发送数据为TXET格式       入口参数:无     出口参数:无
    ***********************************************************/
    void   CMGF(void)
    {
        uchar   i   =   0;
        uchar   code   mode[]= "AT+CMGF=1/r ";     //   /r即   <CR>   回车

        while(   mode[i]   !=   '/0 ');
            {
                SBUF   =   mode[i];
                while(TI   ==   0);
                TI   =   0;
                i++;
            }
    }


    /***********************************************************
    函数名称:CMGS
    函数功能:设置目的SIM卡号码                 入口参数:无     出口参数:无
    ***********************************************************/
    void   CMGS(void)
    {
        uchar   i   =   0;
        uchar   code   phone[]= "AT+CMGS=/ "13821947411/ "/r ";     //   / "即“

        while(   phone[i]   !=   '/0 ');  
            {
                SBUF   =   phone[i];  
                while(TI   ==   0);
                TI   =   0;
                i++;
            }        
    }


    /***********************************************************
    函数名称:SEND
    函数功能:将GPS数据送入SBUF                 入口参数:无     出口参数:无
    ***********************************************************/
    void   SEND(void)
    {
        uchar   i   =   0;
        uchar   code   sms[]   =   "Hello/x01a ";//sms为欲发送的字符串数组,/x01a即Ctrl+Z

        while(   sms[i]   !=   '/0 ');
            {
                SBUF   =   sms[i];
                while(TI   ==   0);
                TI   =   0;
                i++;  
            }
    }

    展开全文
  • 详细介绍单片机控制GSM模块工作的软件实现过程,对怎样用单片机控制GSM模块收发短信进行探讨,也对程序设计的主体思想作了较为细致的分析。 关键词:单片机 短信收发 软件设计 GSM(Global System for Mobile ...

    摘要:借助系统模型,阐明GSM模块收发短信的基本概念以及串口控制SMS的基本原理。详细介绍单片机控制GSM模块工作的软件实现过程,对怎样用单片机控制GSM模块收发短信进行探讨,也对程序设计的主体思想作了较为细致的分析。

    关键词:单片机 短信收发 软件设计

    GSM(Global System for Mobile communication)系统是目前基于时分多址技术的移动通信体制中,比较成熟完善,且应用最广泛的一种系统。目前已建成的覆盖全国的GSM数字蜂窝移动通信网,是我国公众移动通信网的主要方式。基于GSM的短信信息服务,是一种在移动网络上传送简短信息的无线应用,是一种信息在移动网络上存储和转寄的过程。由于公众GSM网络在全球范围内实现了联网和漫游,建议上述系统不需再组建专用通信网络,所以具有实时传输数据功能的短信应用将得到迅速普及。笔者开发设计的基于GSM网络的温度数据采集与无线传输系统正是借助该网络平台,利用短信息业务实现数据的自动双向传递。系统模型图如图1所示。

    本系统由数据采集部分、数据接收和发送部分、终端处理部分三个模块组成。数据采集模块将采集到的温度数据存入存储器中。数据收发模块采用双单片机共用E2RPOM的方式,单片机2控制数据从存储器转存入E2PROM中;单片机1负责将数据从E2PROM中读出,并经GSM模块2借助GSM网络将数据发送出去。单片机1不仅控制数据的发送,也控制数据的接收。在这里,E2PROM是温度数据临时存储和上传的中转站。终端处理模块负责将接收到的数据交给计算机处理,并将处理后的结果存放到数据库中,以供查询。当终端处理模块需要向GSM模块2发送控制命令时,GSM模块2接收过程正好与上述过程相反,从而实现数据的自动双向传递。

    系统中,三个模块相互独立,彼此又相互依赖,共同完成数据的传输。数据收发模块在系统中起着承上启下的作用,是系统的核心模块。该模块以双单片机为核心,以RS232通信接口,在物理层上实现与GSM模块的连接。由于篇幅的限制,本文主要介绍单片机控制这一模块工作的软件实现过程,旨在对怎样用单片机控制GSM模块收发短信息进行探讨。

    1 GSM模块MZ28

    MZ28是中兴通讯推出的GSM无线双频调制解调器,主要为语音传输、短信发送和数据业务提供无线接口。MZ28集成了完整的射频电路和GSM的基带处理器,特别适合于迅速开发基于GSM无线网络的无线应用产品。带有人机接口(MMI)界面的应用产品内部与MZ28的通信可通过标准的串行接口(RS232)进行。MZ28使用简单的20-PIN ZIP插座与用户自己的应用系统相连,此ZIP连接方式提供开发所需的数据通信、音频和电源等接口信号。MZ28可以作为无线引擎,嵌入到用户自己的产品当中,用户可以用单片机或其它CPU的UART口,使用相应的AT命令,对模块进行控制,达到使其产品可以轻松进入GSM网络的目的。

    2 串口控制SMS的工作原理

    单片机与GSM模块一般采用串行异步通信接口,通信速度可设定,通常为19200bps。采用这种RSM232电缆方式进行连接时,数据传输的可靠性较好。RS232接口方式连接,通过串行接口集成电路和电平转换电路与GSM模块连接,电路比较简单,所涉及的芯片包括单片机89C52和电平转换芯片MAX232,是非常常见的接口电路。需要说明的是,该接口通过I2C总线扩展了一个E2PROM存储器芯片AT24C64,它的主要作用是存储数据,而且断电信息也不会丢失,这些特性正是存储数据所必须的。

    GSM的短信息业务SMS利用信令信道传输,这是GSM通信网所特有的。它不用拨号建立连接,把要发的信息加上目的数据发送到短信息服务中心,经短信服务中心完成存储后再发送给最终的信宿。所以当目的GSM终端没开机时信息不会丢失。每个短信的信息量限制为160字节。

    现在市场上大多数手机均支持GSM07.05规定的AT指令集。该指令集是ETSI(欧洲通信技术委员会)发布的,其中包含了对SMS的控制。利用GSM手机的串行接口,单片机向手机收发一系列的AT命令,就能达到控制GSM模块收发SMS的目的。必须注意的是,用单片机实现时,编程必须注意它发送指令与接收到的响应都是字符的ASCII码。用单片机控制GSM模块收发短信息所涉及以的AT指令如表1所列。

    表1 AT指令

    AT指令

    功 能 描 述

    AT+OFF 关机并重新启动
    AT+CSDH=0 在TEXT模式下在返回值中不显示详细的头信息
    ATE0 关闭回显
    AT+CMGF=1 选择短信格式为TEXT模式
    AT+CMGS 发送短信息
    AT+CMGR 读取短信息
    AT+CMGD=0 删除全部短信息

    3 软件实现

    3.1 上位机模块和下位机模块半双工通信协议的实现

    3.1.1 应答和重发

    上位机模块和下位模块的通信双方遵照半双工通信方式进行,即数据传送是双向的。但是,任何时刻只能由其中的一方发送数据,另一方接收数据,因为E2PROM的读出和写入不能同时进行。为了避免一方在发送信息帧时(这里的信息帧指的是下位机模块发送的数据帧和上位机模块发送的命令帧,下同),另一方也会发送数据,必须把信道变成半双工方式。尽管这样效率可能不如全双工方式,但通过此举牺牲效率可以换取模块工作性能的稳定。双方采取的顺序是:发→收到应答后→再发。

    按照整个系统的设计思路,上位机模块(即图1中的GSM模块1,下同)发送的帧包括命令帧、确认帧和非确认帧;下位机模块(即图1中的GSM模块2,下同)发送的帧包括数据帧、确认帧和非确认帧。其中确认帧和非确认帧是发送数据后等待对方发送的应答帧,以此作为继续发送下一帧和重新发送上一帧的依据。命令帧和数据帧是信息帧,当一方先发送完信息帧,如果收方接收到对方的信息帧,而又没有信息帧需要发送,那么情况就比较简单,收方将根据信息帧的正确与否决定发送确认帧还是非确认帧,以使对方决定是继续发送还是重新发送;如果此刻收方也有信息帧需要发送,那么收方将不立即发送应答帧,而是立即发送本方的信息帧给对方,并等待对方对此帧的应的应答帧,在收到对方的应答帧后,收方将依据应答帧的内容(即确认帧或者是非确认帧,下同)决定是继续发送下一信息帧,还是重新发送原来的信息帧。如果由于链路本身不可靠等因素造成应答帧的丢失,收方将在一定时间内因为没有收到应答帧而延时重发原来的信息帧。在收到对方的应答帧后,收方将继续发送下一信息帧,并等待对方的应答帧,如此反复,直到收方全部发送完信息帧。在本方收到对方最后一个应答帧后,表明本方全部的信息帧发送完毕。然后收方将发送对方仍然等待的应答帧,通知对方收到的信息帧正确与否。

    图2

    3.1.2 延时重发

    在双方通信过程中,有两个时间t1和t2,分别表示重新发送信息帧的最大延时。t1表示一方发送完信息帧到收到对方应答帧的时间,如果等待应答帧的时间超过了t1,则发方会重新发送原来的信息帧;当收方接收到对方发送的信息帧,如果收方此时有需要发送的信息帧,则收方此记得不发送应答帧,而是发送信息帧给对方。也就是说,利用对方等待收方应答帧的时间t1内,收方插入发送本文的信息帧,同样本方的发送也存在一个延时重发的问题。在规定的时间内,如果没有收到对方应答帧,收方也同样需要重发原来的信息帧,这个规定的时间就是t2。显然由于收方是利用间隙时间发送本方信息帧,所以t2<t1。

    图2以下位机模块先发数据帧为例,阐述双方通信的具体实现过程。

    需要说明的是,由于版面的限制,图2所示的通信过程没有涉及到发送非确认帧的情况,如果收方发送非常认帧,发方的发送过程跟发送数据帧是一样的,只不过这种情况下需要重发同一帧号的数据帧。如果上位机模块先发命令帧,双方通信的实现过程跟图2类似,所不同的是数据帧此时变成命令帧,命令帧变成数据帧。在延时的时间上,无论是下位机发送数据帧还是上位机发送命令帧,t2的大小都应该是一样的,都是利用时间间隔t2发送收方信息帧,延时的时间是相同的。然而,对于t1而方,情况就有所不同。因为下位机模块先发送数据帧时,利用t1的间隔时间上位机模块发送的命令帧可靠较少,因此当下位机模块先发送数据帧时所定义的t1应该小于当上位机模块先发送命令帧时,所定义的t1。这是因为当上位机模块先发送命令帧时,利用t1的间隔时间下位机模块发送的数据帧可能比较多。

    3.2 帧格式

    GSM模块通过异步通信接口实现对SMS的控制共有三种接入协议:Block Mode;基于AT指令的Text Mode;基于AT指令PDU Mode。本系统发送和接收的数据都是基于数字的温度数据和命令字,为了保证系统的适用性,SMS的收发采用TEXT模式。TEXT模式是基于字符的,更具体地说是基于ASCII码的一种结构模式。在该模式下,模块发送和接收的信息帧格式如下:

    帧头 帧序号 数据 校验子

    信息帧包括数据帧和命令帧。

    帧头表示数据帧的标记,是由固定的字符“WQ”构成。

    帧序号表示数据帧的序号,由两个字节组成。帧序号表示下位机模块发送的递增数据帧序号和上位机模块发送的命令帧序号。为了简化帧结构,命令帧的序号统一为00H。

    数据字段的长度为154字节,最多发送77个字符(采用TEXT模式,不能发送汉字)。

    检验子为数据字段所有字节累加和的初码(原码取反加1),由一个字节组成。

    除了信息帧外,双向传递的还有应答帧,它包括确认帧和非确认帧。确认帧是双方反馈给发方的应答帧,表示收方已经正确接收到了发方发送的信息帧。确认帧格式仅包括两个字段,且两个字段的内容都是固定的,即帧头“WQ”和数据字段“ACK”,确认帧格式如下。

    WQ ACK

    非确认帧是收方给发方的应答帧,表示收方收到的是无效的信息帧,其格式与应答帧格式类似,帧格式如下。

    WQ NACK

    3.3 E2PROM空间的分配

    采用8KB的E2PROM,按照每77个字节为一个块进行划分,共106块,如图3所示。

    第00、01块留作系统使用,第02块~第105块是数据块,用作存放数据。

    3.4 收发端与采集端的握手协议

    收发端与采集端共用一个存储器,即双CPU对同一个E2PROM进行操作。实现方案是分别使两个微处理器的一个I/O脚相连,两个CPU采用查询方式对此I/O端进行查询。如果某时候收发端查询到本地I/O端为高电平,则单片机1拥有此存储器的操作权,可以对E2PROM进行读写操作。如果采集端查询到本地I/O端为高电平,则单片机2拥有此存储器的操作权,可以对它进行写操作。一方操作完毕后将I2C总线置为高电平,表明本端已经释放I2C总线,E2PROM目前处于可用状态。

    3.5 程序的设计

    3.5.1 主函数的设计思路

    开机上电后,程序在主函数中运行,单片机和GSM模块分别进行初始化。单片机的初始化包括设置串口工作方式、波特率,并初始化变量参数和标志位。GSM模块初始化包括重新启动、关闭回显、设置在TEXT模式下的返回值中不显示详细的头信息、选择短信格式为TEXT模式、开发串口中断准备接收数据。

    3.5.2 GSM返回参数的处理—SHELL函数

    SHELL函数是进入时钟中断程序时被调用时,该函数是对GSM模块返回参数进行处理的函数。根据系统设计的要求,需要对GSM模块进行下列操作:呼叫对方模块号码、发送数据、阅读短信、删除短信。基于以上操作指令,如果操作成功GSM模块会分别返回不同的参数:>、+CMGS、+CMGR、OK。根据接收到的不同参数,下位机模块将转向不同的操作步骤,判断并改变标志位的值。比如,如果某时刻接收到>,这表明呼叫对方模块号码获得成功,接下来需要发送数据。这时SHELL函数将检查发送不同数据所代表的标志位f_sending、f_ack、f_nack,从而决定需要发送何种类型的数据。

    3.5.3 短信数据的处理—ExecData函数

    进入时钟中断调用SHELL函数时,如果接收到了返回的参数+CMTI,表明上位机模块向下位机模块发送了短信数据,可能是命令帧,也可能是确认帧或者非确认帧。在这种情况下,SHELL函数需要对短信内容进行分析,并根据短信的内容进行不同的处理,负责完成以上功能的就是ExecData函数,它是被SHELL函数调用的,用来分析并处理短信数据。

    结语

    通过以上的分析不难发现,整个程序错综复杂,函数之间相互牵扯。标志位在程序的实现过程中扮演着非常重要的角色,正是依靠这些标志位,程序才能很好地实现各个功能之间的切换,而标志位的值是通过OSM模块返回的参数修改的。因此程序的实现过程应该是阅读参数→修改标志位→发送指令。

    主函数、时钟中断和串口中断程序、SHELL函数、ExecData函数贯穿整个程序的主线和核心部分,对它们的分析可以理解程序的主体思想,这也正是笔者着重介绍的原因所在。然而这些函数和中断程序的实现,还需要依靠其它函数的配合,比如基于I2C总线的E2PROM操作函数、字符串操作函数以及串口发送函数等,由于篇幅所限,在此不再介绍。GSM网络本身是不完全可靠的,可能会发生帧发送错误、帧丢失的现象。但是由于重发、延时重发机制的存在,程序可以最大程度避免上述情况的发生。在实际应用过程中,模块运行正常,性能稳定,实时性好。

    展开全文
  • 本设计由DS18B20温度传感器+MQ-2烟雾传感器+HC-SR501人体红外模块+SIM800C GSM模块+LCD1602显示屏组成。

    1、具体介绍

    本设计由DS18B20温度传感器+MQ-2烟雾传感器+HC-SR501人体红外模块+SIM800C GSM模块+LCD1602显示屏组成。

    功能介绍:

    (1)可检测环境温度、烟雾浓雾和人体信号并通过显示屏显示;

    (2)可通过按键设置报警值,当检测值超过报警值时进行报警;

    (3)报警可通过LED+蜂鸣器现场报警,显示屏显示报警内容;还可通过GSM模块实现远程报警,短息可显示不同报警内容。

    2、实物图:

    3、电路图:

    4、部分代码

    #include<reg52.h>
    #include<intrins.h>
    #include "sim800.h"	
    #define uchar unsigned char
    #define uint  unsigned int
    #define K_MG_MV    120/66 
    typedef unsigned char  U8;       /* defined for unsigned 8-bits integer variable 	  无符号8位整型变量  */
    typedef unsigned int   U16;      /* defined for unsigned 16-bits integer variable 	  无符号16位整型变量 */
    
    /********测试GSM是否启动**********/
    int test_boot;
    /********测试GSM是否注册网络**********/
    int test_net_register;
    /********GSM串口接收数据缓存**********/
    unsigned char idata GSM_receive[60];
    /********GSM串口接收计数器**********/
    unsigned char  GSMDATA_count;
    unsigned char *content_temp =  "Warning: over temperature\r\n";
    unsigned char *content_smoke = "Warning: excessive smoke concentration\r\n";
    unsigned char *content_body =  "Warning: body entry\r\n";
    
    unsigned char str_yw[12];//烟雾值
    unsigned char T_baojing = 30;  //温度报警值
    unsigned int  C_baojing = 500; //烟雾浓度报警值
    
    unsigned char T_buff[3];  //报警缓存
    unsigned char H_buff[3];
    unsigned char C_buff[4];
    
    bit  sf_flag=0; //设防标志
    unsigned char moshi=0;
    unsigned char data1;
    long Value;
    
    sbit bADcs=P3^4;
    sbit bADcl=P3^6;
    sbit bADda=P3^5;
    
    sbit  sf_led = P1^3;//   设防指示灯
    sbit  shefang= P1^4;//   设防按键
    sbit  shezhi = P1^5; //  设置
    sbit  jia    = P1^6; //	 加
    sbit  jian   = P1^7; //  减	
    sbit  BUZZER = P2^0; //  LED蜂鸣器
    sbit  Infra	 = P3^2; //  人体红外模块
    
    
    unsigned char IntToString(unsigned char *str, int dat);
    extern bit Start18B20();
    extern bit Get18B20Temp(int *temp);				//	  ;;;;;、‘       
    extern void InitLcd1602();
    extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
    float intT, decT;  //温度值的整数和小数部分
    
     
    long kssj()   //开始收集
     {
       unsigned char i;
    
         bADcs = 0;//当ADC0832未工作时其CS输入端应为高电平,此时芯片禁用.
    	 bADcl=0;
    	 bADda=1;
    	 bADcl=1;
    	 bADcl=0;//i down
    	 bADda=1;
    	 bADcl=1;
    	 bADcl=0;	//   2 down
    	 bADda=0;
    	 bADcl=1;
    	 bADcl=0;	//   3 down
    	 bADda=1;
    	 bADcl=1;
    	 bADcl=0;	//   4 down
    
    	 for(i=8;i>0;i--)
    	 	{
    		
    	 	data1<<=1;
    	 	bADcl=0;
    		bADcl=1;
    		if(bADda==1) data1|=0x01;
    		   	bADda=1;
    	 	}
    		 bADcs=1;
    	 	
           Value=data1*1.0/256*500;
    	   
    	   Value=Value*K_MG_MV;
    	   Value=Value-5;
    	   if(Value<0)Value=0;
    	   return Value;
     }
    
    
    void Key_set_scan()
    {
      	
    	if(shezhi==0)
    	{
    	   Delay_Ms(10);
    		if(shezhi==0)
    		{  
    		   while(!shezhi);
    		   InitLcd1602();     //初始化液晶
    		   moshi++;
    		   if(moshi >= 3)moshi = 0;
    		   if(moshi == 0)
    		   {
    		     LcdShowStr(0, 0,"T:   C");
                 LcdShowStr(7, 0,"C:    PPM");
    		   }
    		   else if(moshi == 1)
    		   {
    		      LcdShowStr(0, 1,"Set_T:   C");
    		   }
    		   else if(moshi == 2)
    		   {
    		   	   LcdShowStr(0, 1,"Set_C:    PPM");
    		   }		   	
    		}
    	}
    	
    	if(jia==0)
    	{
    	   Delay_Ms(10);
    		if(jia==0)
    		{ 	 
    		    while(!jia);
    			if(moshi==1)
    			{
    			 T_baojing++ ;
    			 if( T_baojing>=99 )T_baojing =99;
    			}
    			if(moshi==2)
    			{
    			 C_baojing++ ;
    			 if( C_baojing>=999 )C_baojing =999;
    			}		
    		 }
    	 }
    	 if(jian == 0)
    	 {
    	    Delay_Ms(10);
    	    if(jian == 0)
    	    {
    		    while(!jian);
    	        if(moshi==1)
    			{
    			 T_baojing-- ;
    			 if( T_baojing<=0 )T_baojing =0;
    			}
    			if(moshi==2)
    			{
    			 C_baojing-- ;
    			 if( C_baojing<=0 )C_baojing =0;
    			}
    	   }
    	 }
    	 if(shefang == 0)
    	 {
    	   Delay_Ms(10);
    	   if(shefang == 0)
    	   { 
    	     while(!shefang);
    		 sf_flag =~ sf_flag;
    		 if(sf_flag == 1) //开启设防		    
    			sf_led = 0;
    		 else 			 //关闭设防
    		 { 
    		    sf_led = 1;
    		    BUZZER = 1;
    		 }
    
    	   }
    	 }
    		 
    }
    void wendu()
    { 
      bit res;
      int temp;  //读取到的当前温度值
      
      unsigned char len;
      unsigned char str_wd[5];   //温度缓冲区
                Get18B20Temp(&temp);  //读取当前温度
                res = Get18B20Temp(&temp);  //读取当前温度
                if (res)                    //读取成功时,刷新当前温度显示
                {		
    			    intT = temp >> 4;          //分离出温度值整数部分
                    decT = temp & 0xF;         //分离出温度值小数部分
                    len = IntToString(str_wd, intT); //整数部分转换为字符串
                    str_wd[len++] = '.';             //添加小数点
                    decT = (decT*10) / 16;        //二进制的小数部分转换为1位十进制位
                    str_wd[len++] = decT + '0';   //十进制小数位再转换为ASCII字符
                    str_wd[len] = '\0';              //添加字符串结束符
                    LcdShowStr(2, 0, str_wd);        //显示到液晶屏上
    			 }
        		Start18B20();
    }
    /************主函数****************/
    void main()
    { 
      unsigned char i;
      sf_flag = 0;
      Uart_Init();
      InitLcd1602();     //初始化液晶
      Start18B20();
      
      LcdShowStr(0,0,"  System init   ");
      LcdShowStr(0,1,"  please wait   ");
      for(i = 0;i < 15;i++)//等待网络稳定
    	{
    		Delay_Ms(1000);
    	}
       InitLcd1602();  
      LcdShowStr(0, 0,"T:   C");
      LcdShowStr(7, 0,"C:    PPM");
    //		//测试是否已经开机,同时自适应波特率
    //	while(test_boot==No)
    //	{
    //		Send_String("AT\r\n");	
    //		Delay_Ms(100);
    //	}
    //		test_boot=No;
    //
    //	//测试是否注册到网络
    //	while(test_net_register==No)
    //	{
    //		Send_String("AT+CREG?\r\n");	 
    //		Delay_Ms(100);	
    //	}
    //	test_net_register=No;
    	Receive_message();      //配置成接受短信模式
     
     
      while(1)
     {
      Key_set_scan();//按键扫描
     if(moshi == 0)	  //设置模式切换
     {
       kssj();   //开始收集 ,电压采集检测烟雾浓度
       Value =  Value-100;//烟雾浓度校准
       IntToString(str_yw,Value); //转换成字符串
       LcdShowStr(9, 0, str_yw); //烟雾浓度显示到液晶屏上
       wendu();	 //温度检测并显示
       if(sf_flag == 1) //当开启设防时
       {
          if(Value>=C_baojing||intT>T_baojing||Infra==1)   //有触发报警
         { 
       	   BUZZER = 0;
    	   Delay_Ms(1000);
    	   LcdShowStr(0, 1,"                ");												     
           if(intT > T_baojing)
           { 			  /*1234567890123456*/
            LcdShowStr(0,1,"temp");
       	    Send_message(content_temp);	  //发温度超标短信
           }  else  LcdShowStr(0, 1,"    ");	
           if(Value >= C_baojing)     
           { 				/*1234567890123456*/
             LcdShowStr(5,1,"smoke");  
       	     Send_message(content_smoke);	  //发烟雾浓度超标短信
           }  else  LcdShowStr(5, 1,"     ");
           if(Infra == 1)        
           { 			    /*1234567890123456*/
             LcdShowStr(11, 1,"body");  
       	     Send_message(content_body);	  //发人体进入短信
           }  else  LcdShowStr(11,1,"    ");
    
          }
         else 	//没有触发报警
           {
    	      BUZZER = 1;	 /*1234567890123456*/
    	      LcdShowStr(0, 1," System normal  ");
           }
    	 }
       }
       else if(moshi == 1)	//设置温度上限模式
       {	
       T_buff[0] = T_baojing/10+0x30;
       T_buff[1] = T_baojing%10+0x30;
       T_buff[2] = '\0';
       LcdShowStr(6, 1,T_buff);
       }
       else if(moshi == 2)	 //设置烟雾浓度上限模式
       {
       C_buff[0] = C_baojing/100+0x30;
       C_buff[1] = C_baojing%100/10+0x30;
       C_buff[2] = C_baojing%10+0x30;
       C_buff[4] = '\0';
       LcdShowStr(6, 1,C_buff);
       }
    				                                                                           
     }
    }
    /* 整型数转换为字符串,str-字符串指针,dat-待转换数,返回值-字符串长度 */
    unsigned char IntToString(unsigned char *str, int dat)
    {
        signed char i = 0;
        unsigned char len = 0;
        unsigned char buf[6];
        
        if (dat < 0)  //如果为负数,首先
    	
        {
            dat = -dat;
            *str++ = '-';
            len++;
        }
        do {          //先转换为低位在前的十进制数组
            buf[i++] = dat % 10;
            dat /= 10;
        } while (dat > 0);
        len += i;     //i最后的值就是有效字符的个数
        while (i-- > 0)   //将数组值转换为ASCII码反向拷贝到接收指针上
        {
            *str++ = buf[i] + '0';
        }
    
        *str = '\0';  //添加字符串结束符
        
        return len;   //返回字符串长度
    }
    /*****************************************************************************
    串口中断
    /****************************************************************************/
    void uart(void) interrupt 4
    {
    unsigned char UART_data;
    	if(RI)
    	{
    		UART_data=SBUF;
    		if(UART_data=='\n')
    		{
    			if(GSM_receive[0]=='O'&&GSM_receive[1]=='K')
    			{
    			 	test_boot=Yes;
    			}
    		    //else
    			//	test_boot=No;
    		    if(GSM_receive[0]=='+'&&GSM_receive[1]=='C'&&GSM_receive[2]=='R'&&GSM_receive[3]=='E'&&GSM_receive[4]=='G')
    		    {
    		 	   if(GSM_receive[7]=='1'||GSM_receive[9]=='1'||GSM_receive[9]=='5')
    			   {
    			 	test_net_register=Yes;
    			   }
    		    }		   
    		    //	else
    		    //  test_net_register=No;
    
    			if((GSM_receive[0]=='O')&&(GSM_receive[1]=='K'))	  //大写OK
    		      {	 
    			   // sf_flag = 0;
    			    //sf_led = 1;
    		        //BUZZER = 1;
    			  }
    			if((GSM_receive[0]=='C')&&(GSM_receive[1]=='L')&&(GSM_receive[2]=='O')&&(GSM_receive[3]=='S')&&(GSM_receive[4]=='E'))
    		      {	
    			//  CZ = 1;LcdShowStr(5, 1,"Close"); 
    			  }						
    			  GSMDATA_count=0;
    		  }
    		else
    		{
    			GSM_receive[GSMDATA_count]=UART_data;
    			GSMDATA_count++;
    		}
    	}
    	RI=0;
    }
    
    

     

    展开全文
  • 单片机模块编程

    2010-08-27 02:53:00
    由于经验不足,很少做单片机的系统,最初编写GSM模块,再编写其他模块,每个模块多调试完毕后,才开始主控函数的编写,编写的过程中,还不断修改原来模块的代码,不久后又觉得这样的设计不合理,继续改吧,改到何年...

    最近做一个基于GSM的智能家居远程控制系统,花了好多天来完成了pcb板的制作到硬件调试完毕,感觉和那些乱七八糟的元件打交道也别有一番乐趣,硬件昨晚了就开始我的软件编写。由于经验不足,很少做单片机的系统,最初编写GSM模块,再编写其他模块,每个模块多调试完毕后,才开始主控函数的编写,编写的过程中,还不断修改原来模块的代码,不久后又觉得这样的设计不合理,继续改吧,改到何年何月?这个系统刚开始没设计好模块之间的接口,搞得乱七八糟的。后来居然还在一个模块中嵌入另一个模块的细节,还好写了一些后意识到了这个问题的严重性,这样下去的话,不用多久,我所有的代码都乱七八糟了。决心模块与模块之间必须独立出来,一个模块不要混合另一个模块的内容,模块只留下公共接口给外部调用处理,特殊需要时才放到main.c中写,比如我这个系统几个模块都有中断,而中断处理函数中又必须调用其他模块的东西,那我就干脆把模块的中断放到main.c中,而在模块文件中只留下一个函数的副本,当然是注释掉的了。这样我以后查看模块的时候,知道这个函数放到哪里去做什么了。模块之间有条理地界限分明,是很利于日后维护与二次开发的。代码修改的过程中,由于最初的设计不合理,难免会有很大的改动,所以在你完成了一个比较重要的一个部分后,或者说你觉得它是一个进步的时候,立即备份一个,并给予一个编号,比如我就喜欢用beta***的编号表示,呵呵。否则当你做错了一大步后就没得后悔了哦。。。这些天进度还是客观的,很快就可以完成这个设计了。到时候发到博客与大家分享一下吧。决心这个设计完成后就把单片机撇在一边,开始ARM的学习。

    总的来说,经验或者教训,就这么几个:

    1.三思而后行,先思考各个模块的接口等具体细节,再完成具体模块的各个部分的实现。函数接口很重要,在你开始写模块的代码前,你就需要写好各个函数的声明与功能。然后具体实现它。

    2.模块化,模块之间不要发生不明不白的关系,最好不要发生。实在需要就在主函数的那个文件里写吧。刚开始要一个模块一个地独立编写调试,然后再整合真个系统。

    3.不是硬件底层的东西,先在界面比较好的环境中实现后,在移植到工程中。这样能加速调试过程。

    4..边编写边维护,完成一个重要功能后,立即做好备份,这个是你的里程碑。也有可能是还魂丹。

    以上皆是这次设计的一些心得,有对的也有错的,不停改进,不断提高,实现自我价值,加油

    展开全文
  • 51单片机控制GSM模块TC35的方法介绍一种 采用GSM的短信功能,可以使某些控制达到“零距离"。由于短信息的费用低廉,可以取代传统的无线遥控。现在详细介绍一种采用单片机(MCS51系列)控制TC35(廉价的GSM模块)发送、接收...
  • 浅谈GSM/GPRS模块软硬件设计(基于有方M660+模块单片机)   GSM/GPRS芯片是手机中负责收发短信、拨打电话以及访问GPRS网络的核心。有方M660+为深圳有方公司生产的一款超小封装的GSM/GPRS工业无线模块,可以提供高...
  • 前言 各位朋友们好!在这一系列的文章中,我将会尽力去实现灵感(标题)。通过用户信息可以看到,我是一个小白,所以我想把灵感以及实现的过程大胆写出来,欢迎各位朋友指出疏漏和不足...由于单片机还在路上,于是我...
  • 有方M660+为深圳有方公司生产的一款超小封装的GSM/GPRS工业无线模块,可以提供高品质的语音、短信、数据业务等功能,在各种工业和民用领域得到广泛的应用。 有方M660+ GPRS模块的硬件设计 硬件设计参考附件《M660+...
  • 使用AT89C51单片机控制SMI800Cgsm模块发送中文短信。使用STM32发送短信敬请等待。。。 在这里插入代码片
  • GPRS模块,是具有GPRS数据传输功能的GSM模块。GPRS模块就是一个精简版的手机,集成GSM通信的主要功能于一块电路板上,具有发送短消息、通话、数据传输等功能。GPRS模块相当于手机的核心部分,如果增加键盘和屏幕就是...
  • 如果说一个单片机芯片具有哪些功能(比如带串口和定时器功能),则单片机内部肯定具有这些功能的电路或者器件,他们在单片机内部连接到单片机引脚上。当需要使用这些功能(比如串口和定时器)或者实现一些比较复杂的...
  • Linux-C实现GPRS模块发送短信“GSM模块,是将GSM射频芯片、基带处理芯片、存储器、功放器件等集成在一块线路板上,具有独立的操作系统、GSM射频处理、基带处理并提供标准接口的功能模块。GSM模块根据其提供的数据...
  • 本系列文章由ex_net(张建波)... ...  市面上的短信猫,大多是TC35i、Tc35的模块。下面的程序主要是针对西门子的TC35系列的GSM模块GSM模块的通讯采用AT指令。上位机(PC、单片机、ARM等)通过串口与GSM模块连接。
  • [日期:2006-1-28] 来源:www.21icbbs.com 通信技术版 作者:飞雪季节 [字体:大 中 小] (本文可以自由转载,但必须注明出处) 适合人群:首次接触G网模块人员 凡是利用GSM模块二次开发的,不管是用来做公话,...
  • STM32单片机SIM800CGSM电话短信GPRS网络可编程模块SDK二次开发 板载STM32F103RCT6单片机,板载LDO,板载SIM800C,有SDK,有基础技术支持,可深度定制。 通过我们提供的SDK,客户可自行开发电话、短信、GPRS等相关应用...
  • 最近参加一次校内电子比赛,有个题目就是让做用单片机GSM的结合实现远程控制,这里的控制是控制两盏220V的灯泡,要求实现单片机的短信的收发。比赛已经完了,这次比赛有学习到不少新东西,写写总结体会(软件方面...
  • 这部分一直再看,资料都已经整理好了,但是一直没有汇总。接下来就详细的看一下,GSM这部分是怎么实现的。
1 2 3 4 5 ... 20
收藏数 768
精华内容 307
关键字:

单片机gsm模块编程