OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4088|回复: 1

51单片机控制sim900a模块发送一次(报警)信息

[复制链接]

1

主题

1

帖子

0

精华

新手入门

积分
8
金钱
8
注册时间
2016-9-22
在线时间
0 小时
发表于 2016-9-22 16:35:49 | 显示全部楼层 |阅读模式
1金钱
单片机检测到引脚变化的时候发送一条短信

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

4

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
79
金钱
79
注册时间
2016-8-13
在线时间
9 小时
发表于 2016-9-23 08:25:26 | 显示全部楼层
                                                                                          /*******************************************************************************
*  ??:                                                                       *
*      12864???????? ??p0,??p2                                     *
********************************************************************************/
#include <stc12c5a60s2.h>
#include <string.H>
#include <intrins.h>
#include <math.h>
#define uchar unsigned char
#define uint  unsigned int
#define FOSC_110592M
/************* 12864LCD???? *************/
#define LCD_data  P2       //???
sbit LCD_RS  =  P0^7;      //???????
sbit LCD_RW  =  P0^6;      //???/???
sbit LCD_EN  =  P0^5;      //??????
sbit LCD_PSB =  P0^4;      //?/?????
sbit LCD_RST =  P0^3;      //??????
sbit LED = P1^2;
sbit wind = P0^0;
sbit ds=P3^5;                             
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
/*********************************************************/
uchar n,r,a,d1,d2;
uchar buffer[6];                                                //定义数据缓存数组
void delay1ms(void);
uint b,d,a1;
uchar table[7]={0,0,0,0,0,0,0};
unsigned int  rec_data_len_uart=0;    //标记Buffer_Uart0接收数组
unsigned char idata Buffer_Uart0_Rec[25]={0};                 //Uart0中断接收数?
uchar code  num[] = {'0','1','2','3','4','5','6','7','8','9'};
uchar code  DIS1[] = {"温度是:20 safe"};
uchar code  DIS2[] = {"CO浓度:10 safe"};
uchar code  DIS3[] = {"粉尘为:50 safe "};
uchar code  DIS4[] = {"风机:OFF       "};
uchar code  DIS5[] = {"safe"};
uchar code  DIS6[] = {"WARN"};
uchar code  DIS7[] = {"ON"};
uchar code  DIS8[] = {"OFF"};
   
//注意,无论接收到信号还是发送完信号,都会进中断服务程序的
/*初始化程序(必须使用,否则无法收发),次程序将会使用定时器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;//开串行口中断       
}
unsigned char hand(unsigned char *data_source,unsigned char *ptr)
{
        if(strstr(data_source,ptr)!=NULL)
                return 1;
        else
                return 0;
}
void clear_rec_data()
{
        uchar i,temp_len;
        temp_len=strlen(Buffer_Uart0_Rec);
        if(temp_len>25)
        {
                temp_len=25;
        }
        for(i=0;i<temp_len;i++)
        {
                Buffer_Uart0_Rec[i]='\0';       
        }
        rec_data_len_uart=0;
}

/*串行通讯中断,收发完成将进入该中断*/
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')
        {
                SBUF=*str;
                while(!TI);//等待发送完成信号(TI=1)出现
                TI=0;
                str++;
        }
}
//延时函数大概是1s钟,不过延时大的话不准...
void DelaySec(int sec)
{
        uint i , j= 0;
        for(i=0; i<sec; i++)
        {
                for(j=0; j<65535; j++)
                {       
                }
        }
}
/*********************************************************/
void delayry(unsigned int i)
  {unsigned int j;
   while(i--)
    { for(j=0;j<60;j++);}
  }

//???ds18b20
void dsInit()
{
unsigned int i;
  ds=0;
  i=500;
  while(i>0)
  i--;
  ds=1;
  i=20;
  while(i>0)
  i--;
}


bit readBit()
{ unsigned int i;
  bit b;
  ds=0;
  i++;i++;i++;
  ds=1;
  i++;i++;i++;i++;
  b=ds;
  i=30;
  while(i>0)
  i--;
  return b;
}

unsigned char readByte()
{ unsigned int i;
  unsigned char j,dat;
  dat=0;
  for(i=0;i<8;i++)
   { j=readBit();
     dat=(j<<7)|(dat>>1);
        }
  return dat;
}
void writeByte(unsigned char dat)
{ unsigned int i;
  unsigned char j;
  bit b;
  for(j=0;j<8;j++)
   {b=dat&0x01;
    dat>>=1;
        if(b)
         { ds=0;
         i++;i++;i++;i++;i++;i++;
         ds=1;
         i=30;
         while(i>0)
         i--;
         }
        else
         { ds=0;
         i=30;
         while(i>0)
         i--;
         ds=1;
         i++;i++;i++;i++;
         }
    }
}

void sendChangeCmd()
{ dsInit();
  delayry(5);
  writeByte(0xcc);
  writeByte(0x44);
}

void sendReadCmd()
{ dsInit();
   delayry(5);
   writeByte(0xcc);
   writeByte(0xbe);
}

int getTmpValue()
{ unsigned int tmpvalue;
   int value;
   float t;
   unsigned char low,high;
   sendReadCmd();
   low=readByte();
   high=readByte();
   tmpvalue=high;
   tmpvalue<<=8;
   tmpvalue|=low;
   value=tmpvalue;
   t=value*0.0625;
   value=t*100+(value>0?0.5:-0.5);
   return value;
}

void display(int v)
{
  unsigned int tmp=abs(v);
  table[0]=tmp/10000;
  table[1]=tmp%10000/1000;
  table[2]=tmp%1000/100;
}

/******************************************************************************/
void delayF(uchar a)
  {
                uchar i,j,k;
    while(a--)
         {
           for(i=0;i<10;i++)
                 {
                         for(j=0;j<255;j++)
                         {
                                for(k=0;k<255;k++)
                    _nop_();
                         }
             }
            }   
  }
void delay2(uchar a)
  {
                uchar i;
    while(a--)
         {
           for(i=0;i<50;i++)
                 {
                    _nop_();
             }
            }   
  }
//***************AD初始化子程序***********************
void ADC_Init(void)
{
   P1M0=0X01;                                                        //P1口模式配置寄存器0,推挽输出(强上拉达20mA, 限流)
   P1M1=0X01;                                                        //P1口模式配置寄存器1,推挽输出(强上拉达20mA, 限流)
   ADC_CONTR=0XA0;                                                //360个时钟周期转化一次,开电源
   P1ASF=0X03;                                                        //P1口迷你功能控制寄存器,P1.0--P1.3设置为AD使用
   AUXR1=0X04;                                                        //中断控制辅助寄存器(AUXR1.0=ADRJ=0,转化结果的格式为:
                                                                                //取ADC_RES的8位为高8位,取ADC_RESL的最低2位为低2位)
   ADC_RES=0X00;                                                //转化结果寄存器赋初值为0
   ADC_RESL=0X00;
   delay1ms();

}
//***************AD采样子程序***********************
unsigned int ADC_GET_RES(unsigned char x)
{
  unsigned char a2,b2;
  unsigned int c2;
  ADC_CONTR=(0xa8|x);                                        //选择采集的通道号,每次传入的x可以确定通道号
  delay1ms();
  while((ADC_CONTR&0x10)==0);                        //转化结束标志位为0时,说明没转化结束,等待
   ADC_CONTR=ADC_CONTR&0xef;                        //清转化结束标志位(必须软件清0)
  a2=ADC_RES;                                                        //取转化结果的高8位
  b2=ADC_RESL;                                                        //取转化结果的高位
  c2=(unsigned int)((unsigned int)(256*a2)+b2);
  return c2;                                                        //将转化结果转化为16位并返回
}
//***************AD滤波子程序***********************
void AD_LB(uint p[],uint n)
{
  uint i,sum=0;
  for(i=9;i>0;i--)
        p[i]=p[i-1];
        p[0]=n;                                                                //传入的参数n就是最后一个转化值,赋给p[0]
}
//***************延时子程序***********************
void delay1ms(void)  
{
    unsigned char a,b;
    for(b=180;b>0;b--)
      for(a=100;a>0;a--);
        _nop_();  
}


void delay(int ms)
{
    while(ms--)
        {
      uchar i;
          for(i=0;i<150;i++)  
           {
            _nop_();                          
                _nop_();
                _nop_();
                _nop_();
           }
        }
}       

void delay1(int ms)
{
    while(ms--)
        {
      uchar y;
          for(y=0;y<100;y++) ;
        }
}                       

bit lcd_busy()
{                          
    bit result;
    LCD_RS = 0;
    LCD_RW = 1;
    LCD_EN = 1;
    delayNOP();
    result = (bit)(P2&0x80);
    LCD_EN = 0;
    return(result);
}

void lcd_wcmd(uchar cmd)
{                          
   while(lcd_busy());
    LCD_RS = 0;
    LCD_RW = 0;
    LCD_EN = 0;
    _nop_();
    _nop_();
    P2 = cmd;
    delayNOP();
    LCD_EN = 1;
    delayNOP();
    LCD_EN = 0;  
}

void lcd_wdat(uchar dat)
{                          
   while(lcd_busy());
    LCD_RS = 1;
    LCD_RW = 0;
    LCD_EN = 0;
    P2 = dat;
    delayNOP();
    LCD_EN = 1;
    delayNOP();
    LCD_EN = 0;
}

void lcd_init()
{
    LCD_PSB = 1;         //????   
        LCD_RST = 0;                 //????
    delay(3);                  
    LCD_RST = 1;      
    delay(3);   
    lcd_wcmd(0x30);      //??????
    delay(5);
    lcd_wcmd(0x0C);      //???,???
    delay(5);
    lcd_wcmd(0x01);      //??LCD?????
    delay(5);
}

void lcd_pos(uchar X,uchar Y)
{                          
   uchar  pos;
   if (X==1)
     {X=0x80;}
   else if (X==2)
     {X=0x90;}
   else if (X==3)
     {X=0x88;}
   else if (X==4)
     {X=0x98;}
   pos = X+Y ;

   lcd_wcmd(pos);     //????
}

void lcdflag()
{
   lcd_wcmd(0x08);   
   delay(400);
   lcd_wcmd(0x0c);   
   delay(400);
   lcd_wcmd(0x08);   
   delay(400);
   lcd_wcmd(0x0c);   
   delay(400);
   lcd_wcmd(0x08);   
   delay(200);
   lcd_wcmd(0x0c);   
   delay(5);
   lcd_wcmd(0x01);   
   delay(5);
}


/*********************************************************/
void  clr_screen()
{
   lcd_wcmd(0x34);      //??????
   delay(5);   
   lcd_wcmd(0x30);      //??????
   delay(5);
   lcd_wcmd(0x01);      //??
   delay(5);     
}


void main()
{
   uchar i,j,k=0;
   uint AD_deal[10],sum=0;                        //滤波暂存数组定义
   CLK_DIV=0x02;       
                wind=0;       
   delay2(100);                 //??,????
   lcd_init();                 //???LCD
   while(1)
   {
                 
                 P1M1=0x0F;                                                          //P1口模式配置寄存器0,AD模式下设为开漏
     P1M0=0x0F;                                                        //P1口模式配置寄存器0,AD模式下设为开漏

     ADC_Init();                                                        //AD初始化
           for(i=0;i<2;i++)                                        //循环四次,采集四路转化结果
             {
                 for(j=0;j<10;j++)                                //循环10次,将10次的采集结果暂存
                   {
                    AD_LB(AD_deal,ADC_GET_RES(i));//9次
                    delay1ms();
                    delay1ms();                                        //采集间隔
                   }
                 for(j=0;j<10;j++)                                //循环10次,取出暂存的结果
           sum+=AD_deal[j];                                //将10次结果求和
                 sum*=0.04883;                                        //转换电压*100=[sum*5/(10*1024)]*100,乘以100是为了分别求得个位、十位、百位
                buffer[k+0]=sum/1000;                        //个位转化电压值
                buffer[k+1]=(sum/100)%10;                //十分位转化电压值
                buffer[k+2]=sum/10%10;                                //百分位转化电压值
                sum=buffer[k]*100+buffer[k+1]*10+buffer[k+2];
                sum*=200/28*22/10;
                buffer[k+0]=sum/1000;                        //个位转化电压值
                buffer[k+1]=sum/100%10;                //十分位转化电压值
                buffer[k+2]=sum/10%10;                                //百分位转化电压值
                k+=3;                                                        //通道号选择
                sum=0;         
                if(k==3)
                {
                        if(buffer[1]<2&&buffer[0]==0)
                                buffer[1]+=3;
}
                if(k==6)
                {
                        if(buffer[4]<buffer[1])
                                buffer[4]=buffer[1]-1;
                        if((buffer[1]+buffer[4]-3)<10)
                        buffer[4]=buffer[1]+buffer[4]-3;
                        else
                        {
                                buffer[4]=buffer[1]+buffer[4]-13;
                                buffer[3]=1;
                        }
                       
                }
                 }

         P1M1=0;
         P1M0=0;
         P1ASF=0;
                k=0;
                 sendChangeCmd();
          display(getTmpValue());
                      clr_screen();
                if(table[0]>=1||table[1]>=3||buffer[0]>=1||(buffer[1]>=4&&buffer[2]>=5)||buffer[3]>=1||buffer[4]>=5)
                         wind=1;
                 else
                         wind=0;
                        lcd_pos(1,0);             //??????????
                        for(i=0;i<8;i++)
                        {
                                lcd_wdat(DIS1[i]);
                                delay(1);
                        }
                        lcd_pos(1,4);
                        for(i=0;i<3;i++)
                        {
                                lcd_wdat(num[table[i]]);
                                delay(1);
                        }
                        lcd_pos(1,6);
                        for(i=0;i<4;i++)
                        {
                                if(table[0]>=1|table[1]>=3)
                                        lcd_wdat(DIS6[i]);
                                else
                                        lcd_wdat(DIS5[i]);
                                delay(1);
}
     lcd_pos(2,0);             //??????????
     for(i=0;i<8;i++)
     {
       lcd_wdat(DIS2[i]);
       delay(1);
     }
                      lcd_pos(2,4);             //??????????
     for(i=0;i<3;i++)
     {
       lcd_wdat(num[buffer[i]]);
       delay(1);
     }
                                         lcd_pos(2,6);
                        for(i=0;i<4;i++)
                        {
                                if(buffer[0]>=1||buffer[1]>=4&&buffer[2]>=5)
                                        lcd_wdat(DIS6[i]);
                                else
                                        lcd_wdat(DIS5[i]);
                                delay(1);
}
     lcd_pos(3,0);             //??????????
     for(i=0;i<8;i++)
     {
       lcd_wdat(DIS3[i]);
       delay(1);
     }
                  lcd_pos(3,4);             //??????????
     for(i=3;i<6;i++)
     {
       lcd_wdat(num[buffer[i]]);
       delay(1);
     }
                                         lcd_pos(3,6);
                        for(i=0;i<4;i++)
                        {
                                if(buffer[3]>=1||buffer[4]>=5)
                                        lcd_wdat(DIS6[i]);
                                else
                                        lcd_wdat(DIS5[i]);
                                delay(1);
}
     lcd_pos(4,0);             //??????????
     for(i=0;i<6;i++)
     {
       lcd_wdat(DIS4[i]);
       delay(1);
     }
                 lcd_pos(4,3);
                 for(i=0;i<3;i++)
                 {
                                if(wind==1)
                                        lcd_wdat(DIS7[i]);
                                else
                                        lcd_wdat(DIS8[i]);
}
                 delay(1000);
                if(table[1]>=3&&table[1]!=8||buffer[0]>=1||buffer[1]>=4&&buffer[2]>=5||buffer[3]>=1||buffer[4]>=5||table[0]>=1)
                {                       
                SerialInti();
    DelaySec(3);//延时约15秒,此处延时,是为了让模块有足够的时间注册到网络,
//提示开始发送指令,开始发送指令时,务必确认模块上的LED 已经慢闪,即模块已经注册到网络
//----------------为什么是下面这些AT指令呢,请看群共享文件SIM900A重要的短信指令文件------------
    Uart1Sends("AT+CSCS=\"GSM\"\r\n");
    DelaySec(1);//延时大约3秒
    Uart1Sends("AT+CMGF=1\r\n");
    DelaySec(1);//延时3秒0
           Uart1Sends("AT+CSCA?\r\n");
    DelaySec(1);//延时3秒
          Uart1Sends("AT+CSMP=17,167,0,241\r\n");
    DelaySec(1);//延时3秒
    Uart1Sends("AT+CMGS=\"00000000000\"\r\n");//此处修改为对方的电话号           00000000000
    DelaySec(1);//延时3秒
                if(table[1]>=3||table[0]>=1)
                {
                        Uart1Sends("temp warning");//修改短信内容,短信内容可为英文和数字
                }
                if(buffer[0]>=1||buffer[1]>=4&&buffer[2]>=5)
                {
                        Uart1Sends("CO warning");//修改短信内容,短信内容可为英文和数字
                }
                if(buffer[3]>=1||buffer[4]>=5)
                {
                        Uart1Sends("Dust warning");//修改短信内容,短信内容可为英文和数字
                }
    Uart1Send(0x1a);
    DelaySec(15);//延时20秒
                }
   }
}




回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 19:21

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表