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

📄 cms.c

📁 一个用单片机实现gprs modem发送短信的程序.里面有详细的注释,不可多得的学习程序
💻 C
字号:
#include <stdio.h>
#include <string.h>
#include <intrins.h>
#include <stdlib.h>

#include "REG669.H"
#include "cmsdata.h"

//串口0用于和CMS91通信,串口1用于和PC机进行通信

#define GPRS_OK      0   // 正确
#define GPRS_ERR      1   // 错误
#define GPRS_PWR_ON  1
#define GPRS_PWR_OFF 0



#define GPRS_RECV_CMD_MAX_BUF 1024


char Uart0_RX_buf[GPRS_RECV_CMD_MAX_BUF]; //串口0接收缓冲区
char Uart1_RX_buf[GPRS_RECV_CMD_MAX_BUF]; //串口1接收缓冲区
int  receiver0;           //串口0接收缓冲区中数据的长度
int  receiver1;          //串口1接收缓冲区中数据的长度
int  read0;
int  read1;

void Init_UART0()
{
  	//====设置波特率===================
/*	tmod = 0x20;
	th1  = 0xfd;
	tl1  = 0xfd;
	pcon = 0x00;     
	scon=0x50;   //串口工作在方式1下,10位异步收发,允许接收
	tcon = 0x40; //启动定时器1
	ie=0x90;     //允许串口中断*/

  PCON=0x00;

  S0STAT=0x20;
  S0CON=0x50; /*设置Uart0工作模式为8位可变波特率(模式1)作DSP串口收发*/
  
  TMOD=0x20;  /*设置T1为8位重装定时器(模式2)*/
  
  TH1=0xfd;  /*设置Uart0波特率为9600Hz(时钟11.0592MHz)*/
  TL1=0xfd;

  TCON = 0x40; //启动定时器1

  ES0R=1;            //开放UART0接收中断

}

void Init_UART1()
{
     S1STAT=0X20;    //区分接受和发送中断.S1STAT.5=1
     S1CON=0X00;        //串口控制寄存器清零
     
     REN_1=1;            //允许接收中断
   //  TI_1=1;
     
     SM0_1=0;
     SM1_1=1;            //串口通讯方式为1//S1CON=0x52;
 
     BRGCON=0X00;        //关闭波特率发生器,设置波特率9600
     BRGR1=0X04;
     BRGR0=0X70;
     BRGCON=0X01;        //开启波特率发生器
     
     ES1R=1;            //开放UART1接收中断
   

}

void IntUart0Rx(void) interrupt 6    //串口0接收中断函数
{
    
	Uart0_RX_buf[receiver0++]=S0BUF;
	if(receiver0>=GPRS_RECV_CMD_MAX_BUF)
	    receiver0=0;
		
		RI_0=0;
}

void IntUart1Rx(void) interrupt 10    //串口1接收中断函数
{
    
	Uart1_RX_buf[receiver1++]=S1BUF;
	if(receiver1>=GPRS_RECV_CMD_MAX_BUF)
	    receiver1=0;
		
		RI_1=0;
}

void Uart1SendCrt(unsigned char crt)    //串口1发送函数
{
    S1BUF=crt;
    while(TI_1==0);
    TI_1=0;
}

void Uart0SendCrt(unsigned char crt)    //串口0发送函数
{
    S0BUF=crt;
    while(TI_0==0);
    TI_0=0;
}

void Uart0_SendString(char *pt)         //发送字符串到串口0
{
    while(*pt)
	Uart0SendCrt(*pt++);
}

void Uart1_SendString(char *pt)         //发送字符串到串口1
{
    while(*pt)
	Uart1SendCrt(*pt++);
}

int IntUart0Rx_cmd(char *cmd)          //串口0接收cms91发来的数据
{
  	int loopcnt = 0;
	int ncount = 0;
	
	while(1)
	{	
		if(read0 == receiver0)
		{
			ncount ++;
			if(ncount >= 10000)
			{
				cmd[loopcnt++] = 0;
				return GPRS_ERR;
			}
			continue;
		}
		ncount = 0;
		if( (Uart0_RX_buf[read0] == '\r') || (Uart0_RX_buf[read0] == '\n'))
		{
			cmd[loopcnt ++] = 0;
			read0 ++;
			if(read0 >= GPRS_RECV_CMD_MAX_BUF)
				read0 = 0;
			
			if(strlen(cmd))
			{
				Uart1_SendString("\nRecv <- ");
				Uart1_SendString(cmd);
				Uart1_SendString("\n");
			}
			return GPRS_OK;
		}else
		{
			cmd[loopcnt ++] = Uart0_RX_buf[read0];
			read0 ++;
			if(read0 >= GPRS_RECV_CMD_MAX_BUF)
				read0 = 0;
		}
	}
}

 void delay_1mS(void)
{
   unsigned char i;
   _nop_();
   _nop_();
for(i=248;i>0;i--)
       {

      _nop_();
      _nop_();
       }
}

 void Delay(int time)
{
  unsigned char i;
  for(i=0;i<time;i++)
     delay_1mS();
}

 int gprsSendMessage(const SM_PARAM* pSrc)
{
	 int nPduLength;		// PDU串长度
	 unsigned char nSmscLength;	// SMSC串长度
	 int nResult;		// 
	 char cmd[16];		// 命令串
	 //char temp[16];
	 char pdu[512];		// PDU串
	 char ans[128];		// 应答串

	nPduLength = gprsEncodePdu(pSrc, pdu);	// 根据PDU参数,编码PDU串
	pdu[nPduLength] = 0;

	gprsString2Bytes(pdu, &nSmscLength, 2);	// 取PDU串中的SMSC信息长度
	nSmscLength++;		// 加上长度字节本身

	// 命令中的长度,不包括SMSC信息长度,以数据字节计
	sprintf(cmd, "AT+CMGS=%d\r", nPduLength / 2 - nSmscLength);	// 生成命令

	Uart0_SendString(cmd);	// 先输出命令串

	Delay(500);
	
	nResult = IntUart0Rx_cmd(ans);	// 读应答数据
	nResult = IntUart0Rx_cmd(ans);

	// 根据能否找到"\r\n> "决定成功与否
	if(nResult == GPRS_OK)
	{
		int loopcnt = 40;
		nResult = IntUart0Rx_cmd(ans);
		Uart0_SendString(pdu);  // 得到肯定回答,继续输出PDU串

		pdu[0] = 0x1a; // CTRL + Z = 0x1a
		pdu[1] = 0x0;
		Uart0_SendString(pdu);
		
		while(1)
		{
			Delay(1000);
			IntUart0Rx_cmd(ans);	// 读应答数据

			// 根据能否找到"+CMS ERROR"决定成功与否
			if(strncmp(ans, "+CMS ERROR", 10) == 0)
			{
				Uart1_SendString("发送失败\n");
				return 0;
			}else if (strncmp(ans, "OK", 2) == 0)
			{
				Uart1_SendString("发送成功\n");
				return 1;
			}
			
			if(loopcnt-- == 0)
				return 0;
		}
	}
	Uart1_SendString("发送失败\n");
	IntUart0Rx_cmd(ans);
	IntUart0Rx_cmd(ans);
	return 0;
}

/********************************************************************
// Function name	: gprs_print_msg
// Description	    : 打印短消息
// Return type		: void
// Argument         : SM_PARAM* pMsg
*********************************************************************/
void gprs_print_msg(SM_PARAM* pMsg)
{
	char tmp[100];
	
	Uart1_SendString("\n服务中心:");
	Uart1_SendString(pMsg->SCA);
	Uart1_SendString("\n来自:");
	Uart1_SendString(pMsg->TPA);
	Uart1_SendString("\n时间:");
	sprintf(tmp, "20%c%c年%c%c月%c%c日%c%c时%c%c分%c%c秒", pMsg->TP_SCTS[0], pMsg->TP_SCTS[1], \
	                               pMsg->TP_SCTS[2], pMsg->TP_SCTS[3], \
	                               pMsg->TP_SCTS[4], pMsg->TP_SCTS[5], \
	                               pMsg->TP_SCTS[6], pMsg->TP_SCTS[7], \
	                               pMsg->TP_SCTS[8], pMsg->TP_SCTS[9], \
	                               pMsg->TP_SCTS[10], pMsg->TP_SCTS[11]);
	Uart1_SendString(tmp);
	Uart1_SendString("\n内容:");
	Uart1_SendString(pMsg->TP_UD);
	Uart1_SendString("\n");
}

void gprs_pwr_on_off(int bon)
{
	static status_pwr = GPRS_PWR_OFF;
	
	if(bon == GPRS_PWR_ON)
	{

		AD0 |= 1;
		Delay(20);
		AD0 &= ~1;
		Delay(15000);
		AD0 |= 1;
		
		status_pwr = GPRS_PWR_ON;
	}else
	{

		AD0 |= 1;
		Delay(20);
		AD0 &= ~1;
		Delay(15000);
		AD0 |= 1;
		
		status_pwr = GPRS_PWR_OFF;
	}
}

void SMS()
{
	enum GPRS_SMS_STATUS
	{
		GPRS_SMS_INIT,     // 正在初始化
		GPRS_SMS_IDLE,     // 初始化完毕,等待输入
		GPRS_SMS_GET_NUM,  // 输入号码 
		GPRS_SMS_SEND,     // 呼出
	};
	
	char strcallnum[20];
	char gprs_cmd_send_string[512];
	char gprs_cmd_recv_string[512];
	char strtemp[10];
	int  gprs_recv_msg_code;
//	char ch;
	int  loopcnt;
	int  gprs_sms_status;
	int  bexit = 0;

    char *cmd;
    int loopcnt1 = 0;
	int ncount = 0; 

	strcallnum[0] = 0;

	// 打印提示信息	
	Uart1_SendString("短信功能!\n");
	Uart1_SendString("网络连接中,请等待...\n");
	
	// 系统初始化
	gprs_sms_status = GPRS_SMS_INIT;
//	gprs_init();	
	gprs_pwr_on_off(GPRS_PWR_ON);

////////////////////////////////////////////////////////////////
// GPRS复位	
{
	int loopcnt;
__RESET:
	// 延时一定时间
	Delay(15000);
	
	// 发送AT命令
	Uart0_SendString("\r");
	Uart0_SendString("AT\r");
	for(loopcnt = 0; loopcnt < 30; loopcnt++)
	{
		// 获取结果,如果读取到OK,认为复位成功,否则重新复位
		IntUart0Rx_cmd(gprs_cmd_recv_string);
		if(strstr(gprs_cmd_recv_string, "OK") != 0)
			break;
		Delay(100);
	}
	if(loopcnt == 30)
	{
		Delay(30000);
		gprs_pwr_on_off(GPRS_PWR_ON);
		goto __RESET;
	}
}
///////////////////////////////////////////////////////////////

	Delay(15000);
	Uart0_SendString("\r");	
	Uart0_SendString("ATE0\r");
	
	// switch to pdu mode
	strcpy(gprs_cmd_send_string, "AT+CMGF=0\r");
	Uart0_SendString(gprs_cmd_send_string);

	strcpy(gprs_cmd_send_string, "AT+CNMI=2,1\r");
	Uart0_SendString(gprs_cmd_send_string);
	
	// 进入空闲状态,开启状态机
	gprs_sms_status = GPRS_SMS_IDLE;
	// 显示主界面	
	Uart1_SendString("输入号码,ENTER键发送,Cancel退出\n");
	while(bexit == 0)
	{
	
	  if(read1 == receiver1)
		{
			ncount ++;
			if(ncount >= 10000)
			{
				cmd[loopcnt1++] = 0;
				bexit=1;
			}
			continue;
		}

		ncount = 0;

		switch(Uart1_RX_buf[read1])
		{
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
			case '0':
				if(gprs_sms_status == GPRS_SMS_IDLE || \
				   gprs_sms_status == GPRS_SMS_GET_NUM)
				{
					gprs_sms_status = GPRS_SMS_GET_NUM;
					sprintf(strtemp, "%c", Uart1_RX_buf[read1]);
					Uart1_SendString(strtemp);
					strcat(strcallnum, strtemp);
                    read1 ++;
			        if(read1 >= GPRS_RECV_CMD_MAX_BUF)
				      read1 = 0;
				}
				break;
			case 'E':
				// 退出
				gprs_sms_status = GPRS_SMS_IDLE;
                read1 ++;
			    if(read1 >= GPRS_RECV_CMD_MAX_BUF)
				   read1 = 0;
				bexit = 1;
				break;
			case 'F':
                read1 ++;
			    if(read1 >= GPRS_RECV_CMD_MAX_BUF)
				   read1 = 0;
   
				Uart1_SendString("发送短消息\n");
				gprs_sms_status = GPRS_SMS_SEND;
				// 设置服务中心号码
				strcpy(gprs_cmd_send_string, "AT+CSCA=\"+8613800270500\"\r");
				Uart0_SendString(gprs_cmd_send_string);
				loopcnt = 0;
				do
				{
					IntUart0Rx_cmd(gprs_cmd_recv_string);
					gprs_recv_msg_code = gprs_analyze_msg(gprs_cmd_recv_string);
					
					loopcnt ++;
					if(loopcnt >= 20)
					{
						break;
					}
				}while(gprs_recv_msg_code != AT_RECV_MSG_OK && gprs_recv_msg_code != AT_RECV_MSG_ERROR);
				
				if(gprs_recv_msg_code == AT_RECV_MSG_ERROR)
				{
					Uart1_SendString("服务中心号码设置错误\n");
					bexit = 1;
					break;
				}else
				{
					// 发送短信
					SM_PARAM Src;
				
					strcpy(Src.SCA, "8613800270500");			// 短消息服务中心号码(SMSC地址)
					strcpy(Src.TPA, "86");
					strcat(Src.TPA, strcallnum/*"8613707190506"*/);			// 目标号码或回复号码(TP-DA或TP-RA)
					strcallnum[0] = 0;
					Src.TP_PID = 0;			// 用户信息协议标识(TP-PID)
					Src.TP_DCS = 0;			// 用户信息编码方式(TP-DCS)
					strcpy(Src.TP_SCTS, "04060308421002");		// 服务时间戳字符串(TP_SCTS), 接收时用到
					strcpy(Src.TP_UD, "Hello!");		// 原始用户信息(编码前或解码后的TP-UD)
					
					Uart1_SendString("开始发送\n");
					
					gprsSendMessage(&Src);
					
					Uart1_SendString("发送完毕\n");
				//	TRACE("输入号码,ENTER键发送,Cancel退出\n");
					gprs_sms_status = GPRS_SMS_IDLE;
				}
			break;
         default:break;
		}
		
		IntUart0Rx_cmd(gprs_cmd_recv_string);
		gprs_recv_msg_code = gprs_analyze_msg(gprs_cmd_recv_string);
		if(gprs_recv_msg_code == AT_RECV_MSG_CMTI)
		{
			char *pDest;
			
			// 收到短消息
			Uart1_SendString("收到短消息\n");
			
			// 解析短消息
			pDest = strstr(gprs_cmd_recv_string, ",");
			if(pDest != 0)
			{
			//	SM_PARAM Msg;
				
				pDest++;
				// 阅读短消息
				Uart1_SendString("阅读短消息\n");
				
				// Read Message
				sprintf(gprs_cmd_send_string, "AT+CMGR=%d\r", atoi(pDest));
				Uart0_SendString(gprs_cmd_send_string);
				// receive message
				do
				{
					IntUart0Rx_cmd(gprs_cmd_recv_string);
					gprs_recv_msg_code = gprs_analyze_msg(gprs_cmd_recv_string);
					if(gprs_recv_msg_code == AT_RECV_MSG_CMGR)
					{
						SM_PARAM Msg;
						
						IntUart0Rx_cmd(gprs_cmd_recv_string);
						IntUart0Rx_cmd(gprs_cmd_recv_string);
						gprsDecodePdu(gprs_cmd_recv_string, &Msg);
						
						gprs_print_msg(&Msg);
						break;
					}
				}while(1);
			}
		}
	}
}


main()
{
  receiver0=0;
  receiver1=0;
  read0=0;
  read1=0;

  Init_UART0();
  Init_UART1();

  EA=1;                //使能所有中断

  SMS();
}

⌨️ 快捷键说明

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