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

📄 gprs data for wavecom q2406b(v2.0).c

📁 以arm和ucos为平台,实现的GPS通信功能,上传的是源代码,可以直接拿来用
💻 C
字号:
/****************************************Copyright (c)**************************************************
                             内蒙古工业大学信息学院GPS车载开发小组
**--------------File Info-------------------------------------------------------------------------------
** File name:			GPRS数传实验程序
** Last modified Date:  2006-1-5
** Last Version:		1.0
** Created by:			孙作雷
** Descriptions:		完成GPRS模块WAVECOME Q2406的拨号连接并自动设定服务器端的IP地址和监听端口,可自动
                        重拨两次,每拨号一次将产生一声峰鸣提示,若三次拨号均未成功建立与服务器端的数传连
                        接,则峰鸣10声报警,需手工重启模块。如成功进入数传状态,则实验板上的8个LED同时闪
                        烁3次,可按KEY1键向服务器端发送预设的字符串"北纬40.506290度,东经11.1405032度",
                        同时可接收上位机发来的0-6的数字字符,每接收到一个字符,峰鸣一次,并将加3后的数值
                        送回上位机全部LED闪烁一次,按KEY2键退出数传状态,并断开与GPRS网络的连接,全部LED
                        闪烁15次。                        
**
********************************************************************************************************/
#include "config.h"
#include<string.h>
#include<ctype.h>
#define   BEEP   (1<<7)
#define   KEY1	 (1<<16)			// P0.16
#define   KEY2	 (1<<17)			// P0.17
/*声明任务*/
void Task_Send(void *mydata) reentrant;//发送任务
void Task_Receive(void *mydata)  reentrant;//接受任务
void Task_KeyBoard(void *mydata)  reentrant;//键盘查询任务
 
OS_STK TaskStk_ Send_GPRSAT[MaxStkSize+1];         
OS_STK TaskStk_KeyBoard[MaxStkSize+1];
 
INT8U  Task_Send_GPRSAT_Prio=1;
 
INT8U  Task_KeyBoard_Prio=2;

/* 定义串口模式设置数据结构 */
typedef struct UartMode
{
	uint8 datab;		// 字长度,5/6/7/8可选
	uint8 stopb;		// 停止位,1/2可选
	uint8 parity;		// 奇偶校验位,0-无校验,1-奇校验,2-偶校验
}UARTMODE;

volatile uint8 D=1,E=0;	// D为进入数传状态标志,E为接收到数传状态建立信号Ok_Info_WaitingForData标志。
const uint32 LEDS=(0xff<<18);
volatile *int Sendstr;
const char *in[10]={
                       "AT#APNSERV=\"CMNET\"\r",
                       "AT+CGATT=1\r",
                       "AT#TCPPORT=\"6800\"\r",
                       "AT#TCPSERV=\"202.207.28.17\"\r",
                       "AT#CONNECTIONSTART\r",
                       "AT#OTCP\r",
                       "北纬40.506290度,东经11.1405032度",
                       "+++",
                       "AT#CONNECTIONSTOP\r",
                       "AT+CGATT=0\r"
                       };

/*
******************************************************************************************
** 函数名称 : DelayNS()
** 函数功能 : 长软件延时。
** 入口参数 : dly		延时控制值,值越大延时越长
** 出口参数 : 无
******************************************************************************************
*/
void  DelayNS(uint32  dly)
{  uint32  i;

   for(; dly>0; dly--) 
      for(i=0; i<50000; i++);
}
/*
******************************************************************************************
** 函数名称 : Beep()
** 函数功能 : 产生形参对应次数的峰鸣
** 入口参数 : n       峰鸣的次数
** 出口参数 : 无
******************************************************************************************
*/
void  Beep (uint8 n)    
{
	for(; n>0; n--)
	{
		IO0CLR =  BEEP;		// 峰鸣
		DelayNS(20);		// 延时
		IO0SET =  BEEP;		// 停止峰鸣
		DelayNS(30);		// 延时
	}
}
/*
*********************************************************************************************************
** 函数名称 :LEDS_Flash()
** 函数功能 :8个LED同时闪烁,闪烁次数由形参决定
** 入口参数 :n	闪烁的次数
** 出口参数 :无
*********************************************************************************************************
*/
void  LEDS_Flash (uint8 n)	
{
    uint8 i = 0;
    while (i<n)
	{
		IO1CLR =  LEDS;		// 控制LEDS亮
		DelayNS(50);		// 延时
		IO1SET =  LEDS;		// 控制LEDS灭
		DelayNS(50);		// 延时
		i++;
	}
}
/*
*********************************************************************************************************
** 函数名称 :UART0_SendByte()
** 函数功能 :向串口0发送1字节数据
** 入口参数 :dat	要发送的数据
** 出口参数 :无
*********************************************************************************************************
*/
void UART0_SendByte (uint8 dat)
{
	U0THR = dat;	              // 要发送的数据
    while ((U0LSR & 0x20) == 0);  // 等待发送完成
}

/*
*********************************************************************************************************
** 函数名称 :UART0_SendStr()
** 函数功能 :向串口发送字符串
** 入口参数 :str	要发送的字符串的首地址指针
** 出口参数 :无
*********************************************************************************************************
*/
void UART0_SendStr(char const *str)
{
   for( ; *str!='\0'; str++) 
      UART0_SendByte (*str);    
}
/*
*********************************************************************************************************
** 函数名称 :Send_GPRSAT()
** 函数功能 :发送GPRS建立数传状态的AT指令
** 入口参数 :无
** 出口参数 :无
*********************************************************************************************************
*/
void Send_GPRSAT(void)           //在发送前4条时,关闭中断,不接收模块返回值,在发送第5条指令前开启中断
{
   uint8 i;
   U0IER = 0x00;
   for(i=0;i<5;i++)
   {
      UART0_SendStr(in[i]);
      DelayNS(500);
   }
  
   DelayNS(500);
   U0IER = 0x05;				 // 允许RBR中断
   UART0_SendStr(in[5]);
   DelayNS(500);
 }
/*
*********************************************************************************************************
** 函数名称 :IRQ_UART0()
** 函数功能 :串口0接收中断服务程序
** 入口参数 :无
** 出口参数 :无
*********************************************************************************************************
*/
void __irq IRQ_UART0 (void)
{
	uint8 k=0,IIR,a;
	while(((IIR=U0IIR)&0x01)==0)//LPC2131串口只有一个中断入口,它跳入中断子程序后要依靠中断标志寄存器的
	                              //相关位查询。
	{
	   
	   switch(IIR & 0x0e)
	   {			   
	      case 0x04:   
	          a = U0RBR;  // 读取RBR中的数据,并清除中断
		      if(D)		   	//查询是否进入数传状态
	          {     
	                if(a=='W')
	                {   
	                    E=1;
	                    LEDS_Flash(4); 
	                }
	                    
	                
	                #ifdef DEBUG         //调试时,将
	                 U0THR = a;	           // 要发送的数据
                     while ((U0LSR & 0x20) == 0); //等待发送完成
                     #endif
                     
	          }
	          else        //以下为进入GPRS数传状态后的接收程序,接收到的数据由上位机通过GPRS无线链路传来
	          {
	               Beep(1);
	               LEDS_Flash(1);
	               
	               U0THR = (a+3);	             // 将服务器端发来的数值做加3处理。
                   while ((U0LSR & 0x20) == 0);  // 等待发送完成  
	               
	          }
	          break;
	      case 0x06:                       //串口错误中断
	          k=U0LSR;                  //任意的一个读取U0LSR都可以清除该中断。
	          k=U0RBR;                 //读出错误数据然后放弃
	          break;
	      default:
	         break;
	    }
	 }
	VICVectAddr = 0x00;			      // 中断处理结束
}
/*
*********************************************************************************************************
** 函数名称 :UART0_Init()
** 函数功能 :串口初始化,设置工作模式和波特率。
** 入口参数 :baud	波特率
**			  set	模式设置(UARTMODE数据结构)
** 出口参数 :1-初始化成功,  0-初始化失败
*********************************************************************************************************
*/
int8 UART0_Init (uint32 baud, UARTMODE set)
{
	uint32 bak;
	
	/* 参数过滤 */
	if ((baud ==0 ) || (baud > 115200))	return (0);
	if ((set.datab <5) || (set.datab > 8))	return (0);
	if ((set.stopb == 0) || (set.stopb > 2)) 	return (0);
	if (set.parity > 4)	return (0);
	
	/* 设置串口波特率 */
	U0LCR = 0x80;						// DLAB = 1	
	bak   = (Fpclk >> 4) / baud;
	U0DLM = bak >> 8;
	U0DLL = bak & 0xFF;
	
	/* 设置串口模式 */
	bak   = set.datab - 5;				// 设置字长
	if (set.stopb == 2)	bak |= 0x04;	// 判断是否为2位停止位
	
	if (set.parity != 0)
	{
		set.parity = set.parity - 1;
		bak |= 0x08;
	}
	bak |= set.parity << 4;				// 设置奇偶校验
	
	U0LCR = bak;
	
	return (1);
}

void Key_Prosses(unsigned char keyvalue)
{
 switch( keyvalue)
  {
   case KEY1:
         while((IO0PIN&KEY1) == 0);//当按键松开下向上位机发送数传数据
		         UART0_SendStr(in[6]);
	 
	
			 break;
   case KEY2:
             while((IO0PIN&KEY2) == 0);
	             U0IER = 0x00;
				 Sendstr=
	            for (i=7;i<10;i++)  
	             {
	                UART0_SendStr(in[i]);
	                DelayNS(200);
	             }
				 OSSemPost(Sem_Send); 
	             LEDS_Flash(15)
		 break;
  }

}
/*
*********************************************************************************************************
** 函数名称 :main()
*********************************************************************************************************
*/
int main (void)
{
	uint8 i,k=5; 
	
	UARTMODE set;                //设置串口的格式

	set.datab  = 8;
	set.stopb  = 1;
	set.parity = 0;
	
	
	PINSEL0 = (PINSEL0&(~0x0f)|0x05)&(~(0x03<<14));	// 设置I/O连接到UART0,P0.7(BEEP)为GPIO功能,其它的管脚功能不变
	PINSEL1 = PINSEL1&(~0x0f);   // 设置KEY1(P0.16)和KEY2(P0.17)为GPIO功能,其它的管脚功能不变
	PINSEL2 = PINSEL2&(~0x08);  // P1.18-P1.25为GPIO功能,其它的管脚功能不变
	IO1DIR |= LEDS;             // P1.18-P1.25为输出
	IO0DIR  = IO0DIR&(~KEY1)&(~KEY2)|BEEP; // 设置BEEP控制口P0.7为输出模式,KEY1(P0.16)和KEY2(P0.17)为输入
	IO0SET  = BEEP;			    // 控制BEEP(P0.7)输出高电平1,不峰鸣
	IO1SET  = LEDS;             // LED全灭
	
	UART0_Init(115200, set);			// 串口初始化
	U0FCR = 0x00;						// 禁能FIFO
	
	IRQEnable();						// 使能IRQ中断
	/* 使能UART0中断 */
	VICIntSelect = 0x00000000;			// 设置所有的通道为IRQ中断
	VICVectCntl0 = 0x20 | 0x06;			// UART0分配到IRQ slot0,即最高优先级
	VICVectAddr0 = (uint32)IRQ_UART0;	// 设置UART0向量地址
	VICIntEnable = 1 << 0x06;			// 使能UART0中断

	
	
	LEDS_Flash(2);                      //程序开始时,LED闪烁提示
      OSInit(); //任务初始化 
     OSTaskCreate(Task_Send_GPRSAT, (void *)0, &TaskStk_Send_GPRSAT[0],Task_Send_GPRSAT_Prio);
	 OSTaskCreate(Task_KeyBoard, (void *)0, &Task_KeyBoard[0],Task_KeyBoard_Prio);
	 OSStart(); //开始多任务调度
	/*for (i=0;i<3;i++)
	{
	   Send_GPRSAT();
	   Beep(1);                       
	   
	   while((E==0)&&(k!=0))            //等待接收到Ok_Info_WaitingForData,k用来避免死循环。
	   {
	       DelayNS(300); 
	       k--;
	   }
	   
	   if(E)break;
	}
	   
	   
	  
    if(E)         
	{
	   D = 0;                           //D清零,进入数传状态
	   while (1)                        //等待按键按下,此处是个死循环
	   {
	      if((IO0PIN&KEY1) == 0)        //如KEY1按下,则向上位机发送一串实验字符
	      {
	          DelayNS(1);            //软件延时,去抖动
	          if((IO0PIN&KEY1) == 0)
	          {
	              while((IO0PIN&KEY1) == 0);//当按键松开下向上位机发送数传数据
	              UART0_SendStr(in[6]); 
	          }
	      }
	      else
	      if((IO0PIN&KEY2) == 0)  //入KEY2按下,则退出数传状态并断开GPRS连接
	      {
	          DelayNS(1);            //软件延时,去抖动
	          if((IO0PIN&KEY2) == 0)
	          {  
	             while((IO0PIN&KEY2) == 0);
	             U0IER = 0x00;
	              
	             for (i=7;i<10;i++)  
	             {
	                UART0_SendStr(in[i]);
	                DelayNS(200);
	             }
	             LEDS_Flash(15); 
	          }
	      }
	   }
	}
	else
	  Beep(10); //三次重拨均未进入数传状态则报警
*/	      
}
/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/
void Task_Send_GPRSAT(void *mydata) reentrant
{
  mydata=mydata;
 for(;;){
       Send_GPRSAT();
	   Beep(1); 
	    while((E==0)&&(k!=0))            //等待接收到Ok_Info_WaitingForData,k用来避免死循环。
	   {
	       DelayNS(300); 
	       k--;
	   }
if(E==1)OSTaskDel(Task_Send_GPRSAT_Prio);
}
 
 
void Task_KeyBoard(void *mydata) reentrant
{
   mydata=mydata;
 for(;;){
      if((IO0PIN==0)&&(E==1)) //如果IO0PIN=0说明有键按下
	  {
	   DelayNS(1);
	   Key_Prosses(key);//键盘处理子程序,根据键值得不同执行的操作
	  } 
	 }                 
}

 

⌨️ 快捷键说明

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