📄 modem.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 + -