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

📄 modem.c

📁 在S3C2440上运行的"电子日历“(支持平年,闰年,星期自动调整). 开发环境是RVDS2.2
💻 C
字号:
/**---------------------版权 (c)----------------------------------------------------------***
***                     作者:颜章健                                                      ***
***                     邮件:jenkinyan@163.com                                           ***
***                                                                                       ***
***---------------------File Info---------------------------------------------------------***
*** 创 建 人:          颜章健                                                            ***
*** 创建日期:          2008-03-08                                                        ***
*** 创建版本:                                                                            ***
*** 文件描述:                                                                            ***
***---------------------------------------------------------------------------------------***
*** 修 订 人:                                                                            ***
*** 修订日期:                                                                            ***
*** 修订版本:                                                                            ***
*** 修订描述:                                                                            ***
***---------------------------------------------------------------------------------------**/
#include 	"config.h"

// 全局变量
PHY_LAYER		PhyLayer;
//static	uint8	EventUp;


/********************************************************************************************
*** 函数名称:	StrToInt
*** 函数描述:	字符串转换成32位整形变量
*** 入    口:	s:字符串
*** 出    口:	转换数值
********************************************************************************************/
/*
static uint32 StrToInt(char *s)
{
	const uint32 tab[10] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
	uint32 val = 0;
	int8   i;	
	uint8  cnt,tmp;
	char   *bak;
	
	bak = s;
	while(*s)	
	{
		tmp = *s++;
        if((tmp < 0x30) || (tmp > 0x39))	return 0;	// 字符无效
		cnt++;
	}
	
	cnt--;
	for(i=cnt; i>=0; i--)
	{
		tmp = (*bak++) - 0x30;
		val = val + tmp * tab[i];
	}
	
	return val;
}*/

/********************************************************************************************
*** 函数名称:	Delay		
*** 函数描述:	软件延时		
*** 入    口:	t:延时参数		
*** 出    口:	无		
********************************************************************************************/
static void		Delay(uint32 t)	{while(--t);}

/********************************************************************************************
*** 函数名称:  ModemLinkOk
*** 函数描述:  检查 MODEM 是否已建立载波连接
*** 入    口:  无
*** 出    口:  1:成功			0:失败	
********************************************************************************************/
uint8	ModemLinkOk(void) 
{
	if(IO0PIN & UART1_DCD)	return 0;	
	else 					return 1;
}

/********************************************************************************************
*** 函数名称:	ModemSetBaud		
*** 函数描述:	设置MODEM 波特率		
*** 入    口:	baud:波特率(单位:bps)		
*** 出    口:	无		
********************************************************************************************/
/*
static	void	Uart1SetBaud(uint32 baud)
{
	uint16	Fdiv;
	uint8 	bak;
	Fdiv  = (Fpclk >> 4) / baud;			// 计算波特率计数器	
	
	bak   = U1LCR;							// 备份	U1LCR
	U1LCR = bak & 0x7f;						// 允许访问分频因子寄存器    
    U1DLM = Fdiv >> 8;						// 设置波特率计数器
	U1DLL = Fdiv & 0xff;					// 设置波特率计数器
    U1LCR = bak;							// 恢复U1LCR
}*/

/********************************************************************************************
*** 函数名称:	Uart1Init		
*** 函数描述:	UART1初始化		
*** 入    口:	baud:波特率(单位:bps)		
*** 出    口:	无		
********************************************************************************************/
void	Uart1Init(uint32 baud)
{
	uint16 Fdiv;
	
	PINSEL0 = (PINSEL0 & (~(0x03<<16  )))|(0x01<<16);	// P0.8  设置为 UART1 TXD
	PINSEL0 = (PINSEL0 & (~(0x03<<18  )))|(0x01<<18);	// P0.9  设置为 UART1 RXD
	PINSEL0 = (PINSEL0 & (~(0x03<<20  )))|(0x00<<20);	// P0.10 设置为 UART1 DTR (GPIO)
	PINSEL0 = (PINSEL0 & (~(0x03<<22  )))|(0x00<<22);	// P0.11 设置为 UART1 DCD (GPIO)
	IO0DIR |= UART1_DTR;					// DTR 设置为输出
	IO0DIR &= (~(UART1_DCD));				// DCD 设置为输入
	IO0SET  = UART1_DTR;					// 数据终端(UART1)准备好
	
	U1LCR = 0x83;							// DLAB=1,允许设置波特率
	Fdiv  = (Fpclk / 16) / baud;			// 设置波特率
	U1DLM = Fdiv / 256;
	U1DLL = Fdiv % 256;
    U1LCR = 0x03;							// 设置为8,1,n 格式
	U1IER = 0x01;							// 仅允许 RBR 中断
    U1FCR = 0xc1;							// 初始化FIFO,触发点为14个字节
}


/********************************************************************************************
*** 函数名称:	ModemWriteByte		
*** 函数描述:	发送单个字节数据		
*** 入    口:	dat:	要发送的数据		
*** 出    口:	无		
********************************************************************************************/
void 	ModemWriteByte(uint8 dat)
{
	U1THR = dat;
	while ((U1LSR & 0x40) == 0);
}


/********************************************************************************************
*** 函数名称:	ModemPutCmd		
*** 函数描述:	发送命令		
*** 入    口:	*command	AT命令		
*** 出    口:	无			
********************************************************************************************/
void	ModemPutCmd(char *command)
{
	while(*command)		ModemWriteByte(*command++);
}

/********************************************************************************************
*** 函数名称:	ModemGetCmd		
*** 函数描述:	检查回显命令中是否包含有指定字符串		
*** 入    口:	*command	AT命令		
*** 出    口:	返回指定字符串所处偏移量		
********************************************************************************************/
uint16	ModemGetCmd(char *command)
{
	uint8 	success = 0;
	char	*cmd;
	uint16	ofs = 0xffff;
	uint16	offset = 0;

	
	if(RxFifo.DatLen == 0)			return	0xffff;
	while(1)
	{
		if(offset > RxFifo.DatLen)	return	0xffff;
		//if(RxFifo.Read(offset) == *command)				// 搜索到字符串第一个字符
		if(ModemFifoRead(offset) == *command)
		{
			ofs = offset;
			cmd = command;
			success = 1;
			while(*cmd)									// 检查整个字符串是否匹配
			{
				if(ofs > RxFifo.DatLen)	return	0xffff;
				//if(RxFifo.Read(ofs++) != *cmd++)		// 字符串不匹配,停止检查
				if(ModemFifoRead(ofs++) != *cmd++)
				{
					success = 0;	
					break;
				}
			}
			if(success == 1)	return	offset;	
		}		
		offset++;										// 继续搜索下一个			
	}	
}

/********************************************************************************************
*** 函数名称:	ModemOpen		
*** 函数描述:	MODEM 拨号		
*** 入    口:	无	
*** 出    口:	1:成功			0:失败		
********************************************************************************************/
uint8	ModemOpen(void)
{
	if(ModemLinkOk())	return 1;
	
	
	ModemPutCmd("AT+CGATT=1\r\n");
	while(ModemGetCmd("OK") > RxFifo.DatLen);	
	//RxFifo.Release(RxFifo.BufLen);
	ModemFifoRelease(RxFifo.BufLen);
	
	ModemPutCmd("AT+CGDCONT=1,IP,CMNET\r\n");	// China Mobile
	//ModemPutCmd("AT+CGDCONT=1,IP,UNIWAP\r\n");	// China Unicom
	while(ModemGetCmd("OK") > RxFifo.DatLen);	
	//RxFifo.Release(RxFifo.BufLen);
	ModemFifoRelease(RxFifo.BufLen);
	
	ModemPutCmd("AT+CGACT=1\r\n");
	while(ModemGetCmd("OK") > RxFifo.DatLen);	
	//RxFifo.Release(RxFifo.BufLen);
	ModemFifoRelease(RxFifo.BufLen);
	
	ModemPutCmd("ATD*99***1#\r\n");
	while(ModemGetCmd("CONNECT") > RxFifo.DatLen);	
	//RxFifo.Release(RxFifo.BufLen);
	ModemFifoRelease(RxFifo.BufLen);
	
	if(ModemLinkOk())	return	1;
	else				return	0;

}

/********************************************************************************************
*** 函数名称:	ModemClose		
*** 函数描述:	MODEM 挂机		
*** 入    口:	无		
*** 出    口:	1:成功			0:失败		
********************************************************************************************/
uint8	ModemClose(void)
{
	IO0CLR = UART1_DTR;		Delay(10000);
	IO0SET = UART1_DTR;		Delay(5000000);
	
	if(ModemLinkOk())		
	{
		return 0;			
	}
	else					
	{
		//RxFifo.Release(RxFifo.BufLen);
		ModemFifoRelease(RxFifo.BufLen);
		return 1;		
	}
}

/********************************************************************************************
*** 函数名称:			
*** 函数描述:			
*** 入    口:			
*** 出    口:			
********************************************************************************************/
/*
uint8	ReadEvent(void)
{
	uint8 Event;
	
	Event = EventUp;
	EventUp = PHYE_NONE;
	return	Event;	
}*/


/********************************************************************************************
*** 函数名称:			
*** 函数描述:			
*** 入    口:			
*** 出    口:			
********************************************************************************************/
uint8	ModemInit(char *baud)
{
	//EventUp = PHYE_NONE;
	
	FifoInit();
	PINSEL0 = (PINSEL0 & (~(0x03<<14  )))|(0x00<<14);	// P0.10 设置为 MC35_IGT (GPIO)
	IO0DIR |= MC35_IGT;
	IO0CLR  = MC35_IGT;	Delay(1000000);
	IO0SET  = MC35_IGT;	Delay(80000000);
	
	// 物理层初始化
	//EventUp = PHYE_NONE;
	//PhyLayer.Event		= ReadEvent;
	/*
	PhyLayer.Pop		= RxFifo.Pop;
	PhyLayer.Read		= RxFifo.Read;
	PhyLayer.Relea		= RxFifo.Release;
	*/
	PhyLayer.Pop		= ModemFifoPop;
	PhyLayer.Read		= ModemFifoRead;
	PhyLayer.Relea		= ModemFifoRelease;
	
	PhyLayer.Open		= ModemOpen;
	PhyLayer.Close		= ModemClose;
	PhyLayer.PutCmd		= ModemPutCmd;
	PhyLayer.GetCmd		= ModemGetCmd;	
	PhyLayer.Write		= ModemWriteByte;
	
	ModemClose();
	Uart1Init(56000);

	//RxFifo.Release(RxFifo.BufLen);			// 清空FIFO
	ModemFifoRelease(RxFifo.BufLen);
	return 1;
}

/********************************************************************************************
*** 函数名称:			
*** 函数描述:			
*** 入    口:			
*** 出    口:			
********************************************************************************************/
void	__irq IRQ_MODEM (void)
{
	uint8 i;

	switch(U1IIR & 0x0f)
	{
		case	0x04:						// FIFO 达到触发点
			for(i=0; i<14; i++)
			{
				ModemFifoPush(U1RBR);
			}
			break;
		case	0x0c:						// FIFO 字符超时
			while(U1LSR & 0x01)
			{
				ModemFifoPush(U1RBR);
			}
			break;
		default:	break;
	}
	
	VICVectAddr = 0x00;	
}

/********************************************************************************************
*** 					文件结束														  ***	
********************************************************************************************/

⌨️ 快捷键说明

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