⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sms.bak

📁 用51单片机收发短消息的源程序,有祥细的注释说明.
💻 BAK
📖 第 1 页 / 共 2 页
字号:
#include <intrins.h>   // 外部函数头文件,只用到了其中的空操作函数_nop_();
#include <At89x52.h>   // AT89C52管脚定义头文件
/////////////////////////////////////
/*采用P1口作控制
// 11.0592的晶体
// RST=20K*/
////////////////////////////////////

// 函数声明
void setup_t1(void);   // 设置波特率
void receive(void);    // 串口接收中断响应函数
void setup_ck(void);   // 设置串口
void show(void);       // 在数码管上显示DATA1,DATA2,DATA3,DATA4的值,调试用

// 下列四个值分别用来显示在数码管上,调试用
// DATA4变化:串口在接收一般字符
// DATA1变化:串口在接收一条新消息到来的标志 +CMTI: "SM",1
// DATA2变化:从新消息到来的标志(放在inbuf中)判断到了"SM"字符,从而可以解析后跟的
//            新消息在SIM卡中的存放位置
// DATA3变化:收到的新消息是合法消息,内容的前6位密码正确
unsigned char data date1=0xa0, date2=0x67 ,date3=0xe6 ,date4=0xaa;

// num2:用来标志收到新到消息标志+CMTI:的字符序号,只有连续收到+CMTI:即num2=6时,
//       才认为确实收到了一条新消息。
// send: 标志是否有新消息到来
//       =0 没有新到消息
//       =1 有新到消息,开始处理新到消息
unsigned char data num2=1, send = 0;

// inbuf: 用来存放从sim卡中读取的消息内容;或者要发送的消息内容
unsigned char data inbuf[50];

//  buff: 用来存放要发送的消息的AT指令头;或者从SIM卡中读取的密码
unsigned char data buff[30];

// type:定义了短消息操作类型
//       =0 空操作
//       =4 收到了合法短消息
//       =5 从sim卡中读取一条短消息
//       =6 从sim卡中删除一条短消息
//       =7 从sim卡的地址本的1位置中读取密码
unsigned char data type = 0;  // send at cmd type

// hasplus86: 接收的短消息内容中,发送方的手机号码是否有+86
//            =0 无+86
//            =1 有+86
unsigned char hasplus86 = 0;

// idx: inbuf缓冲区当前使用字节的计数
char data idx=0;   

// idx2: buff缓冲区当前使用字节的计数
char data idx2=0;  

// offset: 在从sim卡中读取一条短消息时候,只读取发送方的电话
//         号码和内容;中间的时间等其他内容将被忽略掉,offset
//         用来标志在读取中要忽略的字节个数。
char data offset=0;  

#define INBUFF_SIZE 50    // inbuf最大容纳的字节数
#define BUFF_SIZE   30    // buff最大容纳的字节数
#define CLK7219     P1_2  // 数码管显示用管脚
#define DIN7219     P1_1  // 数码管显示用管脚

// 清空缓冲区
void buffzero(unsigned char *pBuff, unsigned char c, unsigned int size)
{
    unsigned char i = 0;
    for(i=0; i<size; i++)
        *(pBuff+i) = c;
}

// 延迟函数
void delay(int c)
{
     int i=0, j=0, k=0;
   	 _nop_();
     if(c > 0)
     {
  	 for(i=0;i<31000;i++);
     { 
         if(c > 1)
         {
         for(j=0;j<31000;j++);
         {
             if(c > 2)   
                for(k=0;k<31000;k++);
         }
         }
     }
     }
}

// 设置波特率
void setup_t1(void)
{
   TMOD=0x20;
   TH1=0xfd;
   TL1=0xfd;
   TR1=1;
   // ET1=0;
}

// 设置串口
void setup_ck(void)
{
   SCON=0x50;
   PCON=0x00;
   EA=1;
   ES=1;
}

// 串口接收中断响应函数
void receive(void) interrupt 4 using 3
{
     ES=0;  // 禁止串口中断
     
     // 向串口发送字符
     if (TI)
     {
         TI=0;
         ES=1;
     }

     // 接收来自串口的字符
     if (RI)
     {
         ES=0;
         RI=0;
         if(0 == send)   // 当前没有处理新消息
         {
            date4=SBUF;  // DATA4变化:串口在接收一般字符
            
            // 握手信号
            // 连续收到字符:+CMTI: 就认为有新到消息
            switch(num2) 
            {
               case 1:
                  num2 = date4=='+' ? ++num2 : 1;
                  break;
               case 2:
                  num2 = date4=='C' ? ++num2 : 1;
                  break;
               case 3:
                  num2 = date4=='M' ? ++num2 : 1;
                  break;
               case 4:
                  num2 = date4=='T' ? ++num2 : 1;
                  break;
               case 5:
                  num2 = date4=='I' ? ++num2 : 1;
                  break;
               case 6:
                  num2 = date4==':' ? ++num2 : 1;
                  if (1 != num2)  // :
                  {
                      send = 1; // 新到消息标志置1
                      num2++;
                      
                      // 清空INBUF,准备将新消息标志+CMTI: "SM",1的后半部分 "SM",1放入
                      buffzero2(inbuf, 0, INBUFF_SIZE);
                      idx = 0;
                  }
                  break;
               default:
                  num2=1;
                  break;
           }
        }else      
        {
           // DATA1变化:串口在接收一条新消息到来的标志 +CMTI: "SM",1
           date1 = SBUF;

           // 根据消息的操作类型将AT指令的返回放入不同的缓冲区中
           switch(type)
           {
           case 7:  // 从地址本中读取密码
                if(idx2 < 0)  // 忽略掉前-idx2个字符,idx2是负数
                    idx2 ++;
                if(idx2 >= 0 && idx2 < BUFF_SIZE)
                    buff[idx2++] = date1;
                break;
           case 5:  // 读取一条消息
           case 6:  // 和删除一条消息,都将返回放入到inbuf中
                if(idx < 0) // 忽略掉前-idx个字符,idx是负数
                    idx ++;    
                    
                // inbuf缓冲区没有溢出       
                if(idx >= 0 && idx < INBUFF_SIZE)
                {
                    // 因为inbuf中只保存新消息的发送方手机号码和消息内容
                    // 用offset来表示要忽略掉的其他不需要的字符
                    if(0 == offset && 0 == idx)
                         offset = 5;  // 忽略掉读取消息AT指令返回的消息头
                    else 
			if(0 == offset && inbuf[0] == '+' && 14 == idx) // has "+86"
			{
				hasplus86 = 1;
                                offset = 28;  // 忽略掉返回的消息体中的时间部分
			}
                    else 
			if(0 == offset && inbuf[0] != '+' && 11 == idx) // not "+86"
			{
				hasplus86 = 0;
                                offset = 28;  // 忽略掉返回的消息体中的时间部分
			}

                    if(offset > 0)
                         offset --;

                    if(0 == offset) 
                    {
                         inbuf[idx++] = date1;
                    }
                }
                break;
           default:
                if(idx < 0)
                    idx ++;           
                if(idx >= 0 && idx < INBUFF_SIZE)
                {
                    inbuf[idx++] = date1;
                }
                break;
           }
        }

     }
         
     // 允许串口中断
     ES=1;
}

// 在数码管上显示一个字节
void  max7219(dat)
{
    unsigned char i = 0;

	//CS7219=1;
	_nop_();
	//CS7219=0;
	_nop_();
	for(i=0;i<8;i++)
	{      CLK7219=0;
		DIN7219=(dat>>(7-i))&0x1;
		_nop_();
		CLK7219=1;
		_nop_();
		CLK7219=0;
	}
	//CS7219=0;
    _nop_();
	//CS7219=1;
}

// 在数码管上显示data1,data2,data3,data4
void show(void)
{
    max7219(date1);
    max7219(date2);
    max7219(date3);
    max7219(date4);
}

// 设置wavcom为接收/发送使用文本格式
// AT指令:AT+CMGF=1<CR>
void setcmgftxt()
{
    SBUF='A';delay(1);
    SBUF='T';delay(1);
    SBUF='+';delay(1);
    SBUF='C';delay(1);
    SBUF='M';delay(1);
    SBUF='G';delay(1);
    SBUF='F';delay(1);
    SBUF='=';delay(1);
    SBUF='1';delay(1);
    SBUF=0x0d;delay(1);
}

// 从SIM卡中读取一条短消息
// AT指令:AT+CMGR=1<CR>
void read_msg(unsigned char imsg)
{
    buffzero(inbuf, 0, INBUFF_SIZE);
    idx = -31;
    offset = 0;
    type = 5;

    SBUF='A';delay(1);
    SBUF='T';delay(1);
    SBUF='+';delay(1);
    SBUF='C';delay(1);
    SBUF='M';delay(1);
    SBUF='G';delay(1);
    SBUF='R';delay(1);
    SBUF='=';delay(1);
    SBUF=imsg;delay(1);
    SBUF = 0x0d;delay(1);
}

// 从SIM卡中删除一条短消息
// AT指令:AT+CMGD=1<CR>
void delete_msg(unsigned char imsg) // delete read msg from sim kard
{
    type = 6;

    SBUF='A';delay(1);
    SBUF='T';delay(1);
    SBUF='+';delay(1);
    SBUF='C';delay(1);
    SBUF='M';delay(1);
    SBUF='G';delay(1);
    SBUF='D';delay(1);
    SBUF='=';delay(1);
    SBUF=imsg;delay(1);
    SBUF = 0x0d;delay(1);
}


// 修改保存在SIM卡地址本位置1中的密码
// AT指令:AT+CPBW=1,"123456",129,"PASS"<CR>
void change_pass()
{    
    SBUF='A';delay(1);
    SBUF='T';delay(1);
    SBUF='+';delay(1);
    SBUF='C';delay(1);
    SBUF='P';delay(1);
    SBUF='B';delay(1);
    SBUF='W';delay(1);
    SBUF='=';delay(1);
    SBUF='1';delay(1);
    SBUF=',';delay(1);
    SBUF='\"';delay(1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -