?? modem.c
字號:
/****************************************************************************
* 文件名:MODEM.C
* 功能:MODEM驅(qū)動程序。
* 說明:基于LPC2100、LPC2200系列ARM7微控制器的UART1
****************************************************************************/
#define IN_MODEM
#include "config.h"
static volatile uint8 ModemState=NOT_INIT_MODEM; // 定義MODEM狀態(tài)變量
/****************************************************************************
* 名稱:DelayNS()
* 功能:長軟件延時(shí)
* 入口參數(shù):dly 延時(shí)參數(shù),值越大,延時(shí)越久
* 出口參數(shù):無
****************************************************************************/
void DelayNS(uint32 dly)
{ uint32 i;
for(; dly>0; dly--)
for(i=0; i<10000; i++);
}
/****************************************************************************
* 名稱:UART1Init()
* 功能:UART1初始化(MODEM功能)。
* 入口參數(shù):bps 波特率
* 出口參數(shù):無
****************************************************************************/
void UART1Init(uint32 bps)
{
uint16 Fdiv;
PINSEL0 = (PINSEL0 & 0x0000FFFF) | 0x55550000; // 選擇管腳為UART0
U1LCR = 0x80; // 允許訪問分頻因子寄存器
Fdiv = (Fpclk / 16) / bps; // 設(shè)置波特率
U1DLM = Fdiv / 256;
U1DLL = Fdiv % 256;
U1LCR = 0x03; // 禁止訪問分頻因子寄存器
// 且設(shè)置為8,1,n
U1IER = 0x0D; // 允許接收和MODEM中斷
U1FCR = 0x87; // 初始化FIFO
U1MCR = 0x03;
}
/****************************************************************************
* 名稱:ModemWrite()
* 功能:向UART1(MODEM)發(fā)送多字節(jié)數(shù)據(jù)。
* 入口參數(shù):Data 待發(fā)送數(shù)據(jù)指針
* NByte 發(fā)送數(shù)據(jù)字節(jié)個(gè)數(shù)
* 出口參數(shù):返回當(dāng)前MODEM狀態(tài)值
****************************************************************************/
uint8 ModemWrite(char *Data, uint16 NByte)
{
uint8 i;
while (NByte > 0) // 發(fā)送NByte字節(jié)數(shù)據(jù)
{
for (i = 0; i < 8; i++) // 一次發(fā)送8個(gè)字節(jié)(已使能FIFO)
{
U1THR = *Data++;
NByte--;
if (NByte == 0)
{
break;
}
}
while((U1LSR&0x20) == 0); // 等待數(shù)據(jù)發(fā)送完畢
}
return(ModemState);
}
/****************************************************************************
* 名稱:ModemGetch()
* 功能:接收UART1(MODEM)字節(jié)數(shù)據(jù)。
* 入口參數(shù):無
* 出口參數(shù):返回取得的數(shù)據(jù)
****************************************************************************/
uint8 ModemGetch(void)
{
uint8 rt;
while((U1LSR&0x01) == 0)
{ // 沒有收到數(shù)據(jù)
U1IER = U1IER | 0x01; // 允許接收中斷
for(rt=0; rt<200; rt++);
}
rt = U1RBR; // 讀取收到的數(shù)據(jù)
return(rt);
}
/****************************************************************************
* 名稱:ModemCommand()
* 功能:發(fā)送MODEM命令。
* 入口參數(shù):Command AT指令(字符串)
* 出口參數(shù):返回當(dāng)前MODEM狀態(tài)值
****************************************************************************/
uint8 ModemCommand(char *Command)
{
char *cp;
uint8 i, err;
if(ModemState == MODEM_CLOSE)
{
while((U1LSR&0x01) != 0) // 讀取完接收到的數(shù)據(jù)
{
err = U1RBR;
}
cp = Command;
i = 0;
while(*cp++ != 0) // 取得AT指令字符個(gè)數(shù)
{
i++;
}
ModemWrite(Command, i); // 發(fā)送AT指令
ModemWrite("\r", 1); // 發(fā)送命令結(jié)束符
i = ModemGetch();
if((i=='A') || (i=='a')) // 若命令回顯,接字符形式等待回應(yīng)
{
while(1)
{
err = i;
i = ModemGetch();
if((err=='O') || (err=='o'))
if((i=='K') || (i=='k'))
{
i = ModemGetch();
i = ModemGetch();
break;
}
}
}
else // 按數(shù)字形式等待回應(yīng)
{
while(1)
{
if(i == '0')
{
i = ModemGetch();
break;
}
i = ModemGetch();
}
}
}
return(ModemState);
}
/****************************************************************************
* 名稱:ModemDialDown()
* 功能:Modem斷開。
* 入口參數(shù):Number 拔號字符串
* 出口參數(shù):返回當(dāng)前MODEM狀態(tài)值
****************************************************************************/
uint8 ModemDialDown(void)
{
U1MCR = 0x02; // 設(shè)置DTR為0,使MODEM掛機(jī)并返回命令狀態(tài)
DelayNS(1); // MODEM中斷會設(shè)置ModemState為MODEM_CLOSE
U1MCR = 0x03; // 恢復(fù)DTR為1
DelayNS(1);
return(ModemState);
}
/****************************************************************************
* 名稱:ModemDialUp()
* 功能:Modem拔號操作。
* 入口參數(shù):Number 拔號字符串
* 出口參數(shù):返回當(dāng)前MODEM狀態(tài)值
****************************************************************************/
uint8 ModemDialUp(char Number[])
{
char *cp;
uint8 i, err;
if(ModemState == MODEM_CLOSE)
{
while((U1LSR & 0x00000001) != 0) // 讀取完接收到的數(shù)據(jù)
{
err = U1RBR;
}
ModemWrite("ATD", 3); // 發(fā)送拔號命令
i = 0;
cp = Number;
while(*cp++ != 0) // 取得AT指令字符個(gè)數(shù)
{
i++;
}
ModemWrite(Number, i); // 發(fā)送拔號號碼
ModemWrite("\r", 1); // 發(fā)送命令結(jié)束符
U1IER = U1IER | 0x01; // 允許接收中斷
for (i = 0; i < 200; i++)
{
DelayNS(5);
if (ModemState == MODEM_CONNECT)
{
break;
}
}
}
return(ModemState);
}
/****************************************************************************
* 名稱:GetModemState()
* 功能:讀取MODEM狀態(tài)值。
* 入口參數(shù):無
* 出口參數(shù):當(dāng)前MODEM狀態(tài)值
****************************************************************************/
uint8 GetModemState(void)
{
return(ModemState);
}
/****************************************************************************
* 名稱:ModemInit()
* 功能:初始化MODEM。
* 入口參數(shù):bps 串口波特率
* 出口參數(shù):返回當(dāng)前MODEM狀態(tài)值
****************************************************************************/
uint8 ModemInit(uint32 bps)
{
ModemState = MODEM_CLOSE; // 設(shè)置MODEM已關(guān)閉狀態(tài)
UART1Init(bps); // 初始化UART1
if((U1MSR & 0x30) != 0x30) // 判斷DSR、CTS是否有效
{
DelayNS(1);
if((U1MSR & 0x30) != 0x30)
{
ModemState = NOT_FIND_MODEM; // 沒有發(fā)現(xiàn)MODEM
}
}
if(ModemState == MODEM_CLOSE) // 進(jìn)行MODEM初始化
{
ModemCommand("ATE0"); // 關(guān)閉命令回顯
ModemCommand("ATV0"); // 以數(shù)字形式返回結(jié)果碼
ModemCommand("AT&C1"); // 數(shù)據(jù)載波檢測(DCD)選擇有效
ModemCommand("AT&D2"); // 數(shù)據(jù)終端準(zhǔn)備就緒(DTR)選擇,當(dāng)DTR由ON-OFF時(shí),MODEM將掛機(jī),并返回命令狀態(tài)
ModemCommand("AT&R0"); // 請求發(fā)送(RTS)/清除發(fā)送(CTS)選擇,當(dāng)MODEM在線時(shí),CTS跟隨RTS的變化
ModemCommand("AT&S0"); // 數(shù)據(jù)設(shè)備就緒(DSR)選擇,DSR一直有效
ModemCommand("ATS0=2"); // 自動摘機(jī)應(yīng)答設(shè)置,響鈴2次后MODEM自動摘機(jī)
}
return(ModemState);
}
/****************************************************************************
* 名稱:UART1_Exception()
* 功能:UART1中斷服務(wù)程序。
* 入口參數(shù):無
* 出口參數(shù):無
* 說明:
****************************************************************************/
void __irq UART1_Exception(void)
{
uint8 IIR, temp;
while(((IIR=U1IIR) & 0x01) == 0)
{ // 有中斷未處理完
switch (IIR & 0x0e)
{
case 0x00: // Modem狀態(tài)變化中斷
if ((U1MSR & 0x80) != 0)
{
ModemState = MODEM_CONNECT;
}
else
{
ModemState = MODEM_CLOSE;
}
if ((U1MSR & 0x40) != 0)
{
ModemState = MODEM_RING;
}
if ((U1MSR & 0x30) != 0x30)
{
ModemState = NOT_FIND_MODEM;
}
break;
case 0x04: // 接收數(shù)據(jù)可用
U1IER &= (~0x01); // 禁止接收及字符超時(shí)中斷
break;
case 0x06: // 接收線狀態(tài)
temp = U1LSR;
break;
case 0x0c: // 字符超時(shí)指示
U1IER &= (~0x01); // 禁止接收及字符超時(shí)中斷
break;
default:
break;
}
}
VICVectAddr = 0; // 通知中斷控制器中斷結(jié)束
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -