找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1414|回复: 1
打印 上一主题 下一主题
收起左侧

求一段AT89C51单片机控制SIM900A模块发送英文短信的程序,能直接调用到主函数的

[复制链接]
跳转到指定楼层
楼主
ID:716476 发表于 2020-5-23 22:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
100黑币
如题

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:887750 发表于 2021-3-13 13:05 | 只看该作者
/************************************************************
程序说明:
首先要确定模块已经注册到网络
然后正确的硬件连接   P3.0-----STXD或者5VT   P3.1-----SRXD或者5VR   GND---GND(只要保证公地即可,没必要单独接一次)
然后确认你单片机上的晶振,根据晶振修改自己的程序。
推荐先将单片机与电脑相连,确定单片机发送的数据是正确的。如果发送的是乱码,请检查晶振与单片机的串口波特率。
如果通过以上几条还解决不了问题,请看群共享文件 AN0004 。

*************************************************************/
#include <REG51.H>
#include <string.H>
#include <stdio.h>
#include "DHT11.H"

#define uchar unsigned char
#define uint unsigned int
//以下是板子上LED的配置,把Px_x改成自己对应的脚。LED 只是用来提示,非必须。
//以下是你的51单片机的晶振大小


sbit P13=P2^3;
sbit P14=P2^4;
sbit P15=P2^5;

sbit P11=P2^2;

#define FOSC_110592M
//#define FOSC_12M

//以下是GSM模块返回数据
uchar rec_data[50];
uchar rec_num;

uchar S[20];
//注意,无论接收到信号还是发送完信号,都会进中断服务程序的
/*初始化程序(必须使用,否则无法收发),次程序将会使用定时器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;//开串行口中断       
}

/*串行通讯中断,收发完成将进入该中断*///如:+CMTI:"SM",2
void Serial_interrupt() interrupt 4
{

        uchar temp;
        temp=SBUF;
        rec_data[rec_num++]=temp;
        if(rec_num>=50)
                rec_num=0;
        else
                ;
        RI=0;//接收中断信号清零,表示将继续接收

}

//串行口连续发送char型数组,遇到终止号/0将停止
void Uart1Sends(uchar *str)
{
        while(*str!='\0')
        {
                SBUF=*str;
                while(!TI);//等待发送完成信号(TI=1)出现
                TI=0;
                str++;
        }
}
void Uart1BYTE(uchar temp)
{
                SBUF=temp;
                while(!TI);//等待发送完成信号(TI=1)出现
                TI=0;

}


void clear_rec_data()
{
        uchar i;
        for(i=0;i<strlen(rec_data);i++)
        {
                rec_data[i]='0';
       
        }
        rec_num=0;


}
//延时函数大概是1s钟,不过延时大的话不准...
void DelaySec(int sec)
{
        uint i , j= 0;

        for(i=0; i<sec; i++)
        {
                for(j=0; j<65535; j++)
                {       
                }
        }
}

void main()
{
        uchar i = 0;
        SerialInti();
        receive();
        P13=1;
        P14=1;
        P15 = 1;
        if(P11==0)
        {
                receive();
         P13=0;       
        clear_rec_data();
        DelaySec(1);//延时
//以下是发送英文短信短信
        Uart1Sends("AT+CSCS=\"GSM\"\r\n"); //
        DelaySec(1);//延时
        Uart1Sends("AT+CSCA?\r\n"); //短信中心号码
        DelaySec(1);//延时
        Uart1Sends("AT+CMGF=1\r\n");  //方式1
        DelaySec(1);//延时       
        Uart1Sends("AT+CMGS=\"18295376558\"\r\n");  //此处修改短信接收方电话号
        DelaySec(1);//延时
        P14 = 0;
        sprintf(S,"Water level overrun!T:%d-R:%d",RH,TH);//         
        Uart1Sends(S);  //此处修改短信内容
        DelaySec(1);//延时
        Uart1BYTE(0X1A);
        P15=0;
        DelaySec(1);//延时
        DelaySec(1);//延时
        DelaySec(1);//延时
        DelaySec(1);//延时
        }
       
}


#include "DHT11.H"

uint RH, RL, TH, TL;        //湿度(整数),湿度(小数),温度(整数),温度(小数)//
uchar data_byte;

void delay(uchar ms) //延时模块//
{
  uchar i;
  while(ms--)                 
for(i=0;i<100;i++);
}


void delay1()//一个for循环大概需要8个多机器周期一个机器周期为1us晶振为12MHz也就是说本函数延时8us多此延时函数必须德稍微精确一点

{

  uchar i;

  for(i=0;i<1;i++);

}

  
void start()//开始信号

{

  io=1;

  delay1();

  io=0;

  delay(25);// 主机把总线拉低必须大于18ms保证DHT11能检测到起始信号

  io=1;    //发送开始信号结束后拉高电平延时20-40us

  delay1();//以下三个延时函数差不多为24us符合要求

  delay1();

  delay1();

}



uchar receive_byte()//接收一个字节//

{

  uchar i,temp;

  for(i=0;i<8;i++)//接收8bit的数据

  {

        while(!io);//等待50us的低电平开始信号结束

        delay1();//开始信号结束之后延时26us-28us以下三个延时函数

         delay1();

        delay1();

        temp=0;//时间为26us-28us表示接收的为数据'0'

        if(io==1)

         temp=1; //如果26us-28us之后还为高电平则表示接收的数据为'1'

    while(io);//等待数据信号高电平'0'为26us-28us'1'为70us

        data_byte<<=1;//接收的数据为高位在前右移

         data_byte|=temp;

  }

  return data_byte;

}

   

void receive()//接收数据//

{

  uchar T_H,T_L,R_H,R_L,check,num_check,i;

  start();//开始信号//

  io=1;   //主机设为输入判断从机DHT11响应信号

  if(!io)//判断从机是否有低电平响应信号//

  {  
        while(!io);//判断从机发出 80us 的低电平响应信号是否结束//

        while(io);//判断从机发出 80us 的高电平是否结束如结束则主机进入数据接收状态

        R_H=receive_byte();//湿度高位

        R_L=receive_byte();//湿度低位

        T_H=receive_byte();//温度高位

        T_L=receive_byte();//温度低位

        check=receive_byte();//校验位

        io=0; //当最后一bit数据接完毕后从机拉低电平50us//

        for(i=0;i<7;i++)//差不多50us的延时

        delay1();

        io=1;//总线由上拉电阻拉高进入空闲状态

        num_check=R_H+R_L+T_H+T_L;

        if(num_check==check)//判断读到的四个数据之和是否与校验位相同

        {

   RH=R_H;

   RL=R_L;

   TH=T_H;

   TL=T_L;

   check=num_check;

        }

  }

}
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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