单片机: 基于SIM900A的温度报警通信系统

帮室友做的一个简单的单片机实验: 使用热敏电阻测温,当温度超过34摄氏度之后就会向指定手机拨打报警电话。

硬件要求: STC89C52单片机,SIM900A GSM模块,价格都在60元左右;另外还需要3根杜邦线,一个SIM卡(移动/联通)

仔细查看用户手册,按照下图连线:

单片机: 基于SIM900A的温度报警通信系统_第1张图片

另外我们使用TTL电平,注意以下问题:


单片机: 基于SIM900A的温度报警通信系统_第2张图片

好了,硬件连接完毕。

单片机的代码没啥好说的,以前做过一个温度计的实验,可以参考我的博客  http://blog.csdn.net/nk_test/article/details/50375196

然后再结合上SIM900A就可以了。

#include <reg52.h>

#define uchar unsigned char
#define uint unsigned int


#define  PCF8591 0x90
sbit SCL=P2^0;
sbit SDA=P2^1; 
sbit spk=P1^4;
sbit WEI=P2^7;  //wei
sbit DUAN=P2^6; //duan

unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};// 显示段码值0~9
unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码


//以下是你的51单片机的晶振大小
#define FOSC_110592M
//#define FOSC_12M

//以下是开机后拨打的手机号,改成自己想要打的号码即可。
uchar num[] = "ATD15700085721;\r";

void delay(int z)
{
	while(z--);
}


void Screen(int i,int n)
{

     P0=0;
     DUAN=1;
	 DUAN=0;
     
     P0=dofly_WeiMa[i];
     WEI=1;
	 WEI=0;
    
     P0=dofly_DuanMa[n]; 
     DUAN=1;  
     DUAN=0;

	 delay(250);

}
void Get_out_print(uchar temperatureNum)
{
    if(temperatureNum/100>0)
	{
	   Screen(3,temperatureNum/100);
	   temperatureNum%=100;
	}

	if(temperatureNum/10>0)
	 {
	     Screen(4,temperatureNum/10);
        
	 }
      
	 Screen(5,temperatureNum%10);
	 Screen(7,12); //显示c

}

//注意,无论接收到信号还是发送完信号,都会进中断服务程序的
/*初始化程序(必须使用,否则无法收发),次程序将会使用定时器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 
{
//	a=SBUF;
	P2=SBUF;
	RI=0;//接收中断信号清零,表示将继续接收
//	flag=1;//进入中断的标志符号
}

//串行口连续发送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 delay()   //延时4-5个微秒
{;;}

void delay_1ms(uint z)
{
 uint x,y;
 for(x=z;x>0;x--)
           for(y=110;y>0;y--)
                 ;
}

void start()
{
  SDA=1;
    delay();
  SCL=1;
    delay();
  SDA=0;
    delay();
}

void stop()
{
  SDA=0;
    delay();
  SCL=1;
    delay();
  SDA=1;
    delay();
}


void respons()
{
  uchar i;
  SCL=1;
    delay();
  while((SDA==1)&&(i<250))
           i++;
      SCL=0;
    delay();
}

void init() 
{
  SDA=1;
    delay();
  SCL=1;
    delay();    
}

uchar read_byte()  //总线上读取一个字节
{
    uchar i,k;
    SCL=0;
    delay();
    SDA=1;
    delay();
   for(i=0;i<8;i++)
   {
         SCL=1;
            delay();
          k=(k<<1)|SDA;
             SCL=0;
            delay();
   }
  return k;

}

void write_byte(uchar date)
{
     uchar i,temp;
     temp=date;
     for(i=0;i<8;i++)
     {
         temp=temp<<1;
          SCL=0; 
          delay();
          SDA=CY;
          delay();
          SCL=1;
          delay();            
     }   
     SCL=0;
       delay();
     SDA=1;
       delay();
}



void write_address(uchar control,uchar date)
{
        start();
        write_byte(PCF8591);  //发送地址字节,选择器件     
        respons();
        write_byte(control);  //发送控制字节,选择通道
        respons();
        write_byte(date);    //重新发送地址字节,选择器件
        respons();           //接受数据
        stop();

}

uchar read_address(uchar control)
{
       uchar date;
       start();
       write_byte(PCF8591);
       respons();
       write_byte(control);
       respons();
       start();
       write_byte(PCF8591+1);
       respons();
       date=read_byte();
       stop();
       return date;

}
uchar temperatureNum=0;
int flagg=0;
void main()
{
	uchar i = 0;
	WEI=0;
	DUAN=0;

    TMOD= 0x01;		     
    EA=1;
    ET0=1; 
    TR0=1;              
    init();
	SerialInti();
   while(1)
   {
   	temperatureNum=read_address(0x41);  //确定路
	Get_out_print(151-temperatureNum);

	if(flagg) 
    { 
	
	while(1)
	{
		Uart1Sends(num);

		DelaySec(30);//打通后延时30秒
		Uart1Sends("ATH\r");   //挂断电话

		DelaySec(3);//延时3秒
	}
	}
	}


}

void Timer0_isr(void) interrupt 1 
{
   TH0=0xfe;
   TL0=0;
   if(temperatureNum<118)
 	flagg=1;

}



你可能感兴趣的:(通信,GSM,硬件,单片机,热敏电阻)