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

📄 main.c

📁 用来pdu编解码
💻 C
📖 第 1 页 / 共 3 页
字号:
/**************************************************************************
文件名: main.c
功能  :数据透传
时间  :2005.11.18
程序员:yangxb
NCUtype:MEGA128
GPRStype:IPCOM100   


2007-5-30 20:04 	+ 串口功能打通

				 	+ 将串口缓冲区扩展到2*200字节
				 	
2007-5-31 7:49      + 修改短信协议,支持7bit,8bit编码/解码	

2007-6-16 14:51     + 引入了具有printf功能的输出函数dprintf0,dprintf1

2007-6-16 18:24		+ 实现了部分console命令

2007-6-17 17:44     + 实现了140字节短信发送

2007-6-17 18:49     + 对中心命令和终端相应进行了测试

2007-6-18 1:08		+ 重新设计了console口的命令处理
					+ 实现了data模式和console模式的转换
					
2007-6-20 0:14      + 在响应中加入校验和

2007-6-20 2:16      + 实现了eeprom中参数的读/写

2007-6-21 17:29     + 实现了console中大部分命令,包括查询和设置
**************************************************************************/

#include 	<main.h>

int main (void)
{			
	sysInit();
	
	for(;;)
	{	
		//AD采样
		delay_s(10);
		ADC_Process();
		
//		//终端事件处理
//		tmEventProcess();
//		
//		//处理上行缓冲区数据
//		DealUpData();
//		
//		//处理下行缓冲区数据
//		DealDownData();		
	}
}
/*--------------------------------------------------------------------------
系统初始化    
--------------------------------------------------------------------------*/
void sysInit(void)
{
	ioint();
	varint();
		
	SysPara.Started = 0;		
	RunMsgPrintf("reboot");
	
	delay_s(1);	
	RunMsgPrintf("正在对系统初始化...");

	ParaInit();
	
	//GSM初始化
	while(GsmInit()==0);
	
	//清空缓冲区
	ClearUpBuff();
	ClearDownBuff();
	delay_s(1);
	RunMsgPrintf("系统初始化完成,进入正常工作状态");
	SysPara.Started = 1;	
	
}
/*--------------------------------------------------------------------------
	功能:io初始化    
--------------------------------------------------------------------------*/
void ioint(void)
{		
		DDRC=0xff ;

		UBRR0H=0;		
		UBRR0L=23;//19200,接RS-232
		UCSR0B=(1<<RXEN0)|(1<<RXCIE0)|(1<<TXEN0);
		UBRR1H=0;		
		UBRR1L=3;//115200
		UCSR1B=(1<<RXEN1)|(1<<RXCIE1)|(1<<TXEN1);
		TIMSK=(1<<TOIE0);
		TCCR0=0x07;
		TCNT0=180 ;

		sei();
}

/*--------------------------------------------------------------------------
	功能:变量初始化    
--------------------------------------------------------------------------*/
void varint(void)
{		
		int n ;
		
		UpBuf.BufBegin = 0 ;
		UpBuf.BufEnd = 0 ;
		for(n=0;n<UpBufMax;n++)
		{
			UpBuf.Buff[n].state= writeonly ;			
		}
		DownBuf.BufBegin = 0 ;
		DownBuf.BufEnd = 0 ;
		for(n=0;n<DownBufMax;n++)
		{
			DownBuf.Buff[n].state=writeonly ;	
		}
		SysPara.U0_Mod = U0_WM_DATA;
}

/*-----------------------------------------------------------------------
UART0接收中断服务函数
-----------------------------------------------------------------------*/
SIGNAL(SIG_UART0_RECV)
{
			unsigned char c;
			
			c=UDR0;

			if (UpBuf.Buff[UpBuf.BufEnd].state == writeonly) 
			{
				if(UpBuf.Buff[UpBuf.BufEnd].len<(MAXLEN-1))
				{
					UpBuf.Buff[UpBuf.BufEnd].data[UpBuf.Buff[UpBuf.BufEnd].len++] = c ; 
				}
				else
				{
					UpBuf.Buff[UpBuf.BufEnd].data[MAXLEN-1] = '\0' ; 
				}
				
				//console模式下
				if (SysPara.U0_Mod ==U0_WM_CONSOLE) 
				{
					UARTOnWork0.OnWork = 0;
					//回显
					putChar0(c);
	
					//console口一次输入完毕
					if (c == '\r')
					{
						UpBuf.Buff[UpBuf.BufEnd].data[UpBuf.Buff[UpBuf.BufEnd].len] = '\0' ; 
						UpBuf.Buff[UpBuf.BufEnd].state = readonly ;//可读不可写
			
						//将终止指针后移一项
						if ( UpBuf.BufEnd == (UpBufMax-1) ) 
						{
							UpBuf.BufEnd = 0  ;
						}
						else
						{
							UpBuf.BufEnd++ ;
						}																		
					}
				}
				else//数据模式下,由定时器来判断数据结束
				{
					UARTOnWork0.OnWork = 1 ;
					UARTOnWork0.TimeClick = 1 ;//1*0.01m=10ms										
				}								
			}		
}
/*-----------------------------------------------------------------------
UART1接收中断服务函数
-----------------------------------------------------------------------*/
SIGNAL(SIG_UART1_RECV)
{
	unsigned char c;
	
	c=UDR1;
	if (DownBuf.Buff[DownBuf.BufEnd].state == writeonly) 
	{
			UARTOnWork1.OnWork = 1 ;
			UARTOnWork1.TimeClick = 1 ;//1*0.01m=10ms
			
			if(DownBuf.Buff[DownBuf.BufEnd].len<(MAXLEN-1))
			{
				DownBuf.Buff[DownBuf.BufEnd].data[DownBuf.Buff[DownBuf.BufEnd].len++] = c ; 
			}
	}
}

/*-----------------------------------------------------------------------
TIMER0中断服务函数:判断一包数据接收是否结束,如果结束,则将结束指针后移一位
[note]在中断函数中不要使用具有阻塞性质的程序段
-----------------------------------------------------------------------*/
ISR ( TIMER0_OVF_vect )
{	
	
	TCNT0 = 180 ;
	if (UARTOnWork0.OnWork ==1 )
	{
		if (UARTOnWork0.TimeClick  !=0 )//正在接收数据
		{
			UARTOnWork0.TimeClick-- ;
		}
		else //接收完毕
		{
			UARTOnWork0.OnWork = 0 ;
			UpBuf.Buff[UpBuf.BufEnd].data[UpBuf.Buff[UpBuf.BufEnd].len] = '\0' ; 
			UpBuf.Buff[UpBuf.BufEnd].state = readonly ;//可读不可写

			//将终止指针后移一项
			if ( UpBuf.BufEnd == (UpBufMax-1) ) 
			{
				UpBuf.BufEnd = 0  ;
			}
			else
			{
				UpBuf.BufEnd++ ;
			}			
		}
	}
			
	if (UARTOnWork1.OnWork ==1 )
	{
		if (UARTOnWork1.TimeClick  !=0 )//正在接收数据
		{
			UARTOnWork1.TimeClick-- ;
		}
		else //接收完毕
		{
			UARTOnWork1.OnWork = 0 ;
			DownBuf.Buff[DownBuf.BufEnd].data[DownBuf.Buff[DownBuf.BufEnd].len] = '\0' ; 
			DownBuf.Buff[DownBuf.BufEnd].state = readonly ;//可读不可写
			//将终止指针后移一项
			if ( DownBuf.BufEnd == (DownBufMax-1) ) 
			{
				DownBuf.BufEnd = 0  ;
			}
			else
			{
				DownBuf.BufEnd++ ;
			}
		}
	}	
}
/*-----------------------------------------------------------------------
ADC中断服务函数:
对每一路进行指定次数的转换,转换完毕后,置位转换完成标志
-----------------------------------------------------------------------*/
ISR(ADC_vect)
{	

		ADC_data.AD_Channles[ADC_data.CurrChannel][ADC_data.CurrTimes] = (uint16_t)ADCL;
		ADC_data.AD_Channles[ADC_data.CurrChannel][ADC_data.CurrTimes] = (uint16_t)(ADCH<<8);		
		ADC_data.CurrTimes++;
		
		//转换次数够了,进行下一路
		if (ADC_data.CurrTimes == (ADCONVERTTIMES - 1))
		{
			ADC_data.CurrChannel++;
			
			if (ADC_data.CurrChannel == ADCHANNELMAX)
			{
				//关闭AD,停止转换	
				CloseADC();
				//通知主程序转换完毕
				ADC_data.finished = 1;
			}
			else
			{
				ADMUX = ADC_data.CurrChannel;	
				ADC_data.CurrTimes = 0;
			}						
		}
}
/*-----------------------------------------------------------------------
发送指定字节的数据到串口0
包括'\0'字符
-----------------------------------------------------------------------*/
void WriteUart0(unsigned char *data, int dataLen)
{
	int n ;
	
	for(n=0;n<dataLen;n++)
	{
		while ( !( UCSR0A & (1<<UDRE0)) );
		UDR0 = data[n] ;			
	}
}
/*-----------------------------------------------------------------------
发送指定字节的数据到串口1
包括'\0'字符
-----------------------------------------------------------------------*/
void WriteUart1(unsigned char *data, int dataLen)
{
	int n ;
	
	for(n=0;n<dataLen;n++)
	{
		while ( !( UCSR1A & (1<<UDRE1)) );
		UDR1=data[n] ;			
	}
}
/*-----------------------------------------------------------------------
通过串口1发送一个字符
用于回显
-----------------------------------------------------------------------*/
void putChar1(char c)
{
	while ( !( UCSR1A & (1<<UDRE1)) );UDR1=c;			
}
/*-----------------------------------------------------------------------
通过串口0发送一个字符
用于回显
-----------------------------------------------------------------------*/
void putChar0(char c)
{

	while ( !( UCSR0A & (1<<UDRE0)) );UDR0=c;	
		
}
/*------------------------------------------------------------------------
myprintf0 : 通过串口0发送字符串,串以'\0'结束	
输入:带发送字符串的指针
2007-6-15 23:37 changed by yxb
------------------------------------------------------------------------*/
void myprintf0(char *p)
{
	WriteUart0(p, strlen(p));	
}

/*------------------------------------------------------------------------
myprintf1 : 通过串口1发送字符串,串以'\0'结束
输入:带发送字符串的指针	
2007-6-15 23:37 changed by yxb
-----------------------------------------------------------------------*/
void myprintf1(char *p)
{
	WriteUart1(p, strlen(p));	
}
void RunMsgPrintf(char *info)
{
	if (SysPara.Started == 0)
	{
		dprintf0("\r\n#ZF> %s", info);	
	}
	else
	{
		if (SysPara.U0_Mod ==U0_WM_CONSOLE)
		{
			dprintf0("\r\n#ZF> %s", info);	
		}
	}	
}
/*---------------------------------------------------------------------------
处理上行数据缓冲区中的数据记录
-----------------------------------------------------------------------------*/
void DealUpData(void)
{
	TBuff  Buff ;
	SM_PARAM MySM_PARAM;
	if (ReadUpBuf(&Buff) ==0 )return ;	//从数据缓冲区读取一条数据记录
		
	if (SysPara.U0_Mod ==U0_WM_CONSOLE)
	{
		if (Buff.data[0] =='D')
		{
			//进入数据模式
			myprintf0("\r\nenter into data mode\r\n");
			SysPara.U0_Mod = U0_WM_DATA;
		}
		else
		{
			ExplainConsoleCmd(Buff.data, Buff.len);	
			MySM_PARAM.TP_UDlen = centSimunator(Buff.data, MySM_PARAM.TP_UD);
			if (MySM_PARAM.TP_UDlen > 0)SendSms(&MySM_PARAM);
		}
	}
	else
	{
		if (Buff.data[0] =='C')
		{
			//进入console模式
			
			myprintf0("\r\nenter into console mode\r\n");
			myprintf0("\r\n#ZF> ");
			ClearUpBuff();
			SysPara.U0_Mod = U0_WM_CONSOLE;
		}
		{
			myprintf0(Buff.data);	
		}	
	}
}
/*---------------------------------------------------------------------------
处理下行数据缓冲区中的数据记录
-----------------------------------------------------------------------------*/
void DealDownData(void)
{
	TBuff  Buff ;
	
	Buff.len = ReadDownBuf(Buff.data, MAXLEN);
	if ( Buff.len > 0)
	{
		RunMsgPrintf(Buff.data);
		CheckDownData(&Buff);
	}	
}
/*------------------------------------------------------------------------
功能:从缓冲区取出一条数据
返回: = 0 读取失败 =1 读取成功
输出:读取到的数据
---------------------------------------------------------------------------*/
int ReadUpBuf(TBuff*p)
{
	if (UpBuf.Buff[UpBuf.BufBegin].state == writeonly )//当起始指针所指向的纪录不可读取时,有两种可能
	{                                               //1 串口正在接收数据,但接收尚未结束,数据记录不可读取
		return (0) ;                                 //2 串口没有接收数据,数据记里为空
	}
	
	strcpy((*p).data ,(UpBuf.Buff[UpBuf.BufBegin].data)) ;//从数据缓冲区读取一条记录后,需要修改当前记录为可写不可读[使用变量而非指针]
	(*p).len = UpBuf.Buff[UpBuf.BufBegin].len ;
	UpBuf.Buff[UpBuf.BufBegin].len = 0 ;//清空缓冲区
	UpBuf.Buff[UpBuf.BufBegin].state = writeonly ;//可写不可读
	

	if ( UpBuf.BufBegin ==(UpBufMax-1))//将起始指针后移一位
	{
		UpBuf.BufBegin =0 ;
	}
	else
	{
		UpBuf.BufBegin++ ;	
	}
	if ((*p).len==0)
	{
		return (0) ;	
	}
	return (1) ;


}
/*------------------------------------------------------------------------
功能:从缓冲区取出一条数据
输入:nsrclength=读取的字节数
      PStr=读取到的数据
返回: 读取到的字节数
---------------------------------------------------------------------------*/
int ReadDownBuf(unsigned char *PStr , int nsrclength )
{
	int len;
	if (DownBuf.Buff[DownBuf.BufBegin].state == writeonly )//当起始指针所指向的纪录不可读取时,有两种可能
	{                                               //1 串口正在接收数据,但接收尚未结束,数据记录不可读取
		return (0) ;                                 //2 串口没有接收数据,数据记里为空
	}	

    myCopy( (DownBuf.Buff[DownBuf.BufBegin].data) , PStr , 0 , nsrclength ) ;
	
	len = DownBuf.Buff[DownBuf.BufBegin].len;
	DownBuf.Buff[DownBuf.BufBegin].len = 0 ;//清空缓冲区
	DownBuf.Buff[DownBuf.BufBegin].state = writeonly ;//可写不可读
	
	if ( DownBuf.BufBegin ==(DownBufMax-1))//将起始指针后移一位
	{
		DownBuf.BufBegin =0 ;
	}
	else
	{
		DownBuf.BufBegin++ ;	
	}
	
	return (len) ;


}
/*-----------------------------------------------------------------------
GsmReset		:重新启动gsm
-----------------------------------------------------------------------*/
void GsmReset(void)
{
	PORTC=0 ;
	delay_s(1) ;
	PORTC=0x03;
	delay_ms(800);
	PORTC=0x01;	
	delay_ms(800);	
	PORTC=0x03;		
}
/*-----------------------------------------------------------------------
GprsOff		:关闭Gprs
-----------------------------------------------------------------------*/
void GsmOff(void)
{
	PORTA=0 ;
	delay_s(5);				
}
/*-----------------------------------------------------------------------
功能:GsmInit初始化
返回:=0 初始化失败 =1 初始化成功
-----------------------------------------------------------------------*/
char GsmInit(void)
{	
		int num , kk, flag , len=0 ;
		unsigned char str[60] ;
	
		GsmReset();
		delay_s(5);
		ClearDownBuff () ;

⌨️ 快捷键说明

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