www.pudn.com > arm_Modem.rar > modem.c


/****************************************Copyright (c)************************************************** 
**                               广州周立功单片机发展有限公司 
**                                     研    究    所 
**                                        产品一部  
** 
**                                 http://www.zlgmcu.com 
** 
**--------------文件信息-------------------------------------------------------------------------------- 
**文   件   名: uart0.c 
**创   建   人: 陈明计 
**最后修改日期: 2003年7月4日 
**描        述: μCOS-II下LPC2114的UART1底层驱动(MODEM操作) 
**               
**--------------历史版本信息---------------------------------------------------------------------------- 
** 创建人: 陈明计 
** 版  本: v1.0 
** 日 期: 2003年7月4日 
** 描 述: 原始版本 
** 
**------------------------------------------------------------------------------------------------------ 
** 修改人: 
** 版  本: 
** 日 期: 
** 描 述: 
** 
**--------------当前版本修订------------------------------------------------------------------------------ 
** 修改人:  
** 日 期:  
** 描 述:  
** 
**------------------------------------------------------------------------------------------------------ 
********************************************************************************************************/ 
 
#define IN_MODEM 
#include "config.h" 
static OS_EVENT *ModemSem, *Uart1Send, *Uart1Get; 
static uint8 ModemState; 
 
/********************************************************************************************************* 
** 函数名称: UART1Init 
** 功能描述: 初始化UART0  
** 输 入: bps:波特率 
** 
** 输 出:TRUE  :成功 
**        FALSE:失败 
** 全局变量: Uart0Sem 
** 调用模块: OSSemCreate 
** 
** 作 者: 陈明计 
** 日 期: 2003年7月4日 
**------------------------------------------------------------------------------------------------------- 
** 修改人:  
** 日 期:  
**------------------------------------------------------------------------------------------------------- 
** 修改人: 陈明计 
** 日 期:  
**------------------------------------------------------------------------------------------------------ 
********************************************************************************************************/ 
        void UART1Init(uint32 bps) 
{ 
    uint16 Fdiv; 
     
    PINSEL0 = (PINSEL0 & 0x0000ffff) | 0x55550000;  /* 选择管脚为UART0 */ 
 
    U1LCR = 0x80;                                   /* 允许访问分频因子寄存器 */ 
    Fdiv = (Fpclk / 16) / bps;                      /* 设置波特率 */ 
    U1DLM = Fdiv / 256;							 
	U1DLL = Fdiv % 256;						 
    U1LCR = 0x03;                                   /* 禁止访问分频因子寄存器 */ 
                                                    /* 且设置为8,1,n */ 
	U1IER = 0x0f;                                   /* 允许接收和发送中断 */ 
    U1FCR = 0x87;                                   /* 初始化FIFO */ 
    U1MCR = 0x03; 
    Uart1Send = OSSemCreate(1); 
    Uart1Get = OSSemCreate(0); 
 
} 
 
/********************************************************************************************************* 
** 函数名称: GetModemState 
** 功能描述: 发送多个字节数据 
** 输 入: Data:发送数据存储位置 
**        NByte:发送数据个数 
** 输 出:无 
** 全局变量: 无 
** 调用模块: UART0Putch 
** 
** 作 者: 陈明计 
** 日 期: 2003年7月4日 
**------------------------------------------------------------------------------------------------------- 
** 修改人: 
** 日 期: 
**------------------------------------------------------------------------------------------------------ 
********************************************************************************************************/ 
        uint8 GetModemState(void) 
{ 
    return ModemState; 
}  
 
/********************************************************************************************************* 
** 函数名称: ModemWrite 
** 功能描述: 发送多个字节数据 
** 输 入: Data:发送数据存储位置 
**        NByte:发送数据个数 
** 输 出:无 
** 全局变量: 无 
** 调用模块: UART0Putch 
** 
** 作 者: 陈明计 
** 日 期: 2003年7月4日 
**------------------------------------------------------------------------------------------------------- 
** 修改人: 
** 日 期: 
**------------------------------------------------------------------------------------------------------ 
********************************************************************************************************/ 
        uint8 ModemWrite(char *Data, uint16 NByte) 
{ 
    uint8 err,i; 
     
    OSSemPend(ModemSem, 0, &err); 
    while (NByte > 0) 
    { 
        OSSemPend(Uart1Send, 0, &err); 
        for (i = 0; i < 8; i++) 
        { 
            U1THR = *Data++; 
            NByte--; 
            if (NByte == 0) 
            { 
                break; 
            } 
        } 
    } 
    OSSemPost(ModemSem); 
    return ModemState; 
}  
 
/********************************************************************************************************* 
** 函数名称: UART0Getch 
** 功能描述: 接收一个字节 
** 输 入: 无 
** 输 出: 接收到的数据 
** 全局变量: 无 
** 调用模块: 无 
** 
** 作 者: 陈明计 
** 日 期: 2003年7月4日 
**------------------------------------------------------------------------------------------------------- 
** 修改人: 
** 日 期: 
**------------------------------------------------------------------------------------------------------ 
********************************************************************************************************/ 
        uint8 ModemGetch(void) 
{ 
    uint8 rt; 
 
    OS_ENTER_CRITICAL(); 
    while ((U1LSR & 0x00000001) == 0) 
    {                                           /* 没有收到数据 */ 
        U1IER = U1IER | 0x01;                   /* 允许接收中断 */ 
        OSSemPend(Uart1Get, 0, &rt); 
    } 
    rt = U1RBR;                                 /* 读取收到的数据 */ 
    OS_EXIT_CRITICAL(); 
 
    return rt; 
}  
/********************************************************************************************************* 
** 函数名称: ModemDialUp 
** 功能描述: Modem拔号操作 
** 输 入:  
** 
** 输 出: 
** 
** 全局变量: 
** 调用模块: 
** 
** 作 者: 陈明计 
** 日 期: 2003年7月4日 
**------------------------------------------------------------------------------------------------------- 
** 修改人:  
** 日 期:  
**------------------------------------------------------------------------------------------------------- 
********************************************************************************************************/ 
        uint8 ModemDialUp(char Number[]) 
{ 
    char *cp; 
    uint8 i; 
    uint8 err; 
     
    if (ModemState == MODEM_CLOSE) 
    { 
        while ((U1LSR & 0x00000001) != 0) 
        { 
            err = U1RBR; 
        } 
        ModemWrite("ATD", 3); 
        i = 0; 
        cp = Number; 
        while (*cp++ != 0) 
        { 
            i++; 
        } 
        ModemWrite(Number, i); 
        ModemWrite("\r", 1); 
 
        U1IER = U1IER | 0x01;                   /* 允许接收中断 */ 
        for (i = 0; i < 120; i++) 
        { 
            OSTimeDly(OS_TICKS_PER_SEC); 
            if (ModemState == MODEM_CONNECT) 
            { 
                break; 
            } 
        } 
    } 
    return ModemState; 
} 
/********************************************************************************************************* 
** 函数名称: ModemDialDown 
** 功能描述: Modem断开。 
** 输 入:  
** 
** 输 出: 
** 
** 全局变量: 
** 调用模块: 
** 
** 作 者: 陈明计 
** 日 期: 2003年7月4日 
**------------------------------------------------------------------------------------------------------- 
** 修改人:  
** 日 期:  
**------------------------------------------------------------------------------------------------------- 
********************************************************************************************************/ 
        uint8 ModemDialDown(void) 
{ 
    U1MCR = 0x02; 
    OSTimeDly(OS_TICKS_PER_SEC / 10); 
    U1MCR = 0x03; 
    OSTimeDly(OS_TICKS_PER_SEC / 10); 
    return ModemState; 
} 
 
/********************************************************************************************************* 
** 函数名称: ModemCommand 
** 功能描述: 发送Modem命令。 
** 输 入:  
** 
** 输 出: 
** 
** 全局变量: 
** 调用模块: 
** 
** 作 者: 陈明计 
** 日 期: 2003年7月4日 
**------------------------------------------------------------------------------------------------------- 
** 修改人:  
** 日 期:  
**------------------------------------------------------------------------------------------------------- 
********************************************************************************************************/ 
        uint8 ModemCommand(char *Command) 
{ 
    char *cp; 
    uint8 i,err; 
     
    if (ModemState == MODEM_CLOSE) 
    { 
        while ((U1LSR & 0x00000001) != 0) 
        { 
            err = U1RBR; 
        } 
         
        cp = Command; 
        i = 0; 
        while(*cp++ != 0) 
        { 
            i++; 
        } 
        ModemWrite(Command, i); 
        ModemWrite("\r", 1); 
        i = ModemGetch(); 
        if (i == 'A' || i == 'a') 
        { 
            while (1) 
            { 
                err = i; 
                i = ModemGetch(); 
                if (err == 'O' || err == 'o') 
                if (i == 'K' || i == 'k') 
                { 
                    i = ModemGetch(); 
                    i = ModemGetch(); 
                    break; 
                } 
            } 
        } 
        else 
        { 
            while (1) 
            { 
                if (i == '0') 
                {    
                    i = ModemGetch(); 
                    break; 
                } 
                i = ModemGetch(); 
            } 
        } 
    } 
    return ModemState; 
} 
 
/********************************************************************************************************* 
** 函数名称: ModemInit 
** 功能描述: 初始化Modem  
** 输 入:  
** 
** 输 出: 
** 
** 全局变量: 
** 调用模块: 
** 
** 作 者: 陈明计 
** 日 期: 2003年7月4日 
**------------------------------------------------------------------------------------------------------- 
** 修改人:  
** 日 期:  
**------------------------------------------------------------------------------------------------------- 
********************************************************************************************************/ 
        uint8 ModemInit(uint32 bps) 
{ 
    ModemState = MODEM_CLOSE; 
    UART1Init(bps); 
    ModemSem = OSSemCreate(1); 
    if (ModemSem != NULL) 
    { 
        if ((U1MSR & 0x30) != 0x30) 
        { 
            OSTimeDly(OS_TICKS_PER_SEC); 
            if ((U1MSR & 0x30) != 0x30) 
            { 
                ModemState = NOT_FIND_MODEM; 
            } 
        } 
        if (ModemState == MODEM_CLOSE) 
        { 
            ModemCommand("ATE0"); 
            ModemCommand("ATV0"); 
            ModemCommand("AT&C1"); 
            ModemCommand("AT&D2"); 
            ModemCommand("AT&R0"); 
            ModemCommand("AT&S0"); 
            ModemCommand("ATS0=2"); 
        } 
    } 
    else 
    { 
        ModemState = NOT_INIT_MODEM; 
    } 
    return ModemState; 
} 
 
/********************************************************************************************************* 
** 函数名称: UART1_Exception 
** 功能描述: UART1中断服务程序 
** 输 入: 无 
** 
** 输 出: 无 
**          
** 全局变量: 无 
** 调用模块: OSSemPost 
** 
** 作 者: 陈明计 
** 日 期: 2003年7月4日 
**------------------------------------------------------------------------------------------------------- 
** 修改人: 
** 日 期: 
**------------------------------------------------------------------------------------------------------ 
********************************************************************************************************/ 
        void UART1_Exception(void) 
{ 
    uint8 IIR, temp; 
     
    OS_ENTER_CRITICAL(); 
    while(((IIR = U1IIR) & 0x01) == 0) 
    {                                                   /* 有中断未处理完 */ 
        switch (IIR & 0x0e) 
        { 
            case 0x00:                                  /* Modem状态变化 中断    */ 
                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 0x02:                                  /* THRE中断    */ 
                OSSemPost(Uart1Send); 
                break; 
            case 0x04:                                  /* 接收数据可用 */ 
                OSSemPost(Uart1Get); 
                U1IER &= (~0x01);                       /* 禁止接收及字符超时中断 */ 
                break; 
            case 0x06:                                  /* 接收线状态   */ 
                temp = U1LSR; 
                break; 
            case 0x0c:                                  /* 字符超时指示 */ 
                OSSemPost(Uart1Get); 
                U1IER &= (~0x01);                       /* 禁止接收及字符超时中断 */ 
                break; 
            default : 
                break; 
        } 
    }  
    VICVectAddr = 0;            // 通知中断控制器中断结束 
    OS_EXIT_CRITICAL(); 
} 
 
/********************************************************************************************************* 
**                            End Of File 
********************************************************************************************************/