帮室友做的一个简单的单片机实验: 使用热敏电阻测温,当温度超过34摄氏度之后就会向指定手机拨打报警电话。
硬件要求: STC89C52单片机,SIM900A GSM模块,价格都在60元左右;另外还需要3根杜邦线,一个SIM卡(移动/联通)
仔细查看用户手册,按照下图连线:
另外我们使用TTL电平,注意以下问题:
好了,硬件连接完毕。
单片机的代码没啥好说的,以前做过一个温度计的实验,可以参考我的博客 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;
}
原文:http://blog.csdn.net/nk_test/article/details/50458291