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

📄 main.c

📁 LPC2000 系列AMR7 微控制器的UART1 具有MODEM 接口功能通过RS232 电平转 换即可与MODEM 连接进行MODEM 通讯控制操作 用LPC2000 系列AMR7 微控制器的
💻 C
字号:
/****************************************************************************
* 文件名:MODEM.C
* 功能:MODEM驱动程序。
* 说明:基于LPC2100、LPC2200系列ARM7微控制器的UART1
****************************************************************************/
#define IN_MODEM
#include "config.h"

static volatile uint8  ModemState=NOT_INIT_MODEM;	// 定义MODEM状态变量


/****************************************************************************
* 名称:DelayNS()
* 功能:长软件延时
* 入口参数:dly		延时参数,值越大,延时越久
* 出口参数:无
****************************************************************************/
void  DelayNS(uint32  dly)
{  uint32  i;

   for(; dly>0; dly--) 
      for(i=0; i<10000; i++);
}


/****************************************************************************
* 名称:UART1Init()
* 功能:UART1初始化(MODEM功能)。
* 入口参数:bps		波特率
* 出口参数:无
****************************************************************************/
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 = 0x0D;                                   // 允许接收和MODEM中断 
    U1FCR = 0x87;                                   // 初始化FIFO 
    U1MCR = 0x03;
}


/****************************************************************************
* 名称:ModemWrite()
* 功能:向UART1(MODEM)发送多字节数据。
* 入口参数:Data		待发送数据指针
*          NByte	发送数据字节个数
* 出口参数:返回当前MODEM状态值
****************************************************************************/
uint8  ModemWrite(char *Data, uint16 NByte)
{
    uint8 i;
    
    while (NByte > 0)								// 发送NByte字节数据
    {
        for (i = 0; i < 8; i++)						// 一次发送8个字节(已使能FIFO)			
        {
            U1THR = *Data++;
            NByte--;
            if (NByte == 0)
            {
                break;
            }
        }
        while((U1LSR&0x20) == 0);					// 等待数据发送完毕
    }
    
    return(ModemState);
} 


/****************************************************************************
* 名称:ModemGetch()
* 功能:接收UART1(MODEM)字节数据。
* 入口参数:无
* 出口参数:返回取得的数据
****************************************************************************/
uint8  ModemGetch(void)
{
    uint8 rt;

    while((U1LSR&0x01) == 0)
    {                                           // 没有收到数据
        U1IER = U1IER | 0x01;                   // 允许接收中断 
        for(rt=0; rt<200; rt++);
    }
    rt = U1RBR;                                 // 读取收到的数据

    return(rt);
} 


/****************************************************************************
* 名称:ModemCommand()
* 功能:发送MODEM命令。
* 入口参数:Command		AT指令(字符串)
* 出口参数:返回当前MODEM状态值
****************************************************************************/
uint8  ModemCommand(char *Command)
{
    char  *cp;
    uint8  i, err;
    
    if(ModemState == MODEM_CLOSE)
    {
        while((U1LSR&0x01) != 0)			// 读取完接收到的数据
        {
            err = U1RBR;
        }
        
        cp = Command;
        i = 0;
        while(*cp++ != 0)					// 取得AT指令字符个数
        {
            i++;
        }
        ModemWrite(Command, i);				// 发送AT指令
        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);
}


/****************************************************************************
* 名称:ModemDialDown()
* 功能:Modem断开。
* 入口参数:Number		拔号字符串
* 出口参数:返回当前MODEM状态值
****************************************************************************/
uint8  ModemDialDown(void)
{
    U1MCR = 0x02;							// 设置DTR为0,使MODEM挂机并返回命令状态
    DelayNS(1);								// MODEM中断会设置ModemState为MODEM_CLOSE
    U1MCR = 0x03;							// 恢复DTR为1
    DelayNS(1);
    										
    return(ModemState);
}

/****************************************************************************
* 名称:ModemDialUp()
* 功能:Modem拔号操作。
* 入口参数:Number		拔号字符串
* 出口参数:返回当前MODEM状态值
****************************************************************************/
uint8  ModemDialUp(char Number[])
{
    char   *cp;
    uint8  i, err;
    
    if(ModemState == MODEM_CLOSE)
    {
        while((U1LSR & 0x00000001) != 0)	// 读取完接收到的数据
        {
            err = U1RBR;
        }
        ModemWrite("ATD", 3);				// 发送拔号命令
        i = 0;
        cp = Number;
        while(*cp++ != 0)					// 取得AT指令字符个数
        {
            i++;
        }
        ModemWrite(Number, i);				// 发送拔号号码
        ModemWrite("\r", 1);				// 发送命令结束符

        U1IER = U1IER | 0x01;             	// 允许接收中断
        for (i = 0; i < 200; i++)
        {
            DelayNS(5);
            if (ModemState == MODEM_CONNECT)
            {
                break;
            }
        }
    }
    
    return(ModemState);
}


/****************************************************************************
* 名称:GetModemState()
* 功能:读取MODEM状态值。
* 入口参数:无
* 出口参数:当前MODEM状态值
****************************************************************************/
uint8  GetModemState(void)
{
    return(ModemState);
}


/****************************************************************************
* 名称:ModemInit()
* 功能:初始化MODEM。
* 入口参数:bps		串口波特率
* 出口参数:返回当前MODEM状态值
****************************************************************************/
uint8  ModemInit(uint32 bps)
{
    ModemState = MODEM_CLOSE;					// 设置MODEM已关闭状态
    UART1Init(bps);								// 初始化UART1

    if((U1MSR & 0x30) != 0x30)					// 判断DSR、CTS是否有效
    {
        DelayNS(1);
        if((U1MSR & 0x30) != 0x30)
        {
            ModemState = NOT_FIND_MODEM;		// 没有发现MODEM
        }
    }
    if(ModemState == MODEM_CLOSE)				// 进行MODEM初始化
    {
        ModemCommand("ATE0");					// 关闭命令回显					
        ModemCommand("ATV0");					// 以数字形式返回结果码
        ModemCommand("AT&C1");					// 数据载波检测(DCD)选择有效
        ModemCommand("AT&D2");					// 数据终端准备就绪(DTR)选择,当DTR由ON-OFF时,MODEM将挂机,并返回命令状态
        ModemCommand("AT&R0");					// 请求发送(RTS)/清除发送(CTS)选择,当MODEM在线时,CTS跟随RTS的变化
        ModemCommand("AT&S0");					// 数据设备就绪(DSR)选择,DSR一直有效
        ModemCommand("ATS0=2");					// 自动摘机应答设置,响铃2次后MODEM自动摘机
    }
    
    return(ModemState);
}


/****************************************************************************
* 名称:UART1_Exception()
* 功能:UART1中断服务程序。
* 入口参数:无
* 出口参数:无
* 说明:
****************************************************************************/
void __irq  UART1_Exception(void)
{
    uint8 IIR, temp;
    
    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 0x04:                                  // 接收数据可用
                U1IER &= (~0x01);                       // 禁止接收及字符超时中断
                break;
                    
            case 0x06:                                  // 接收线状态
                temp = U1LSR;
                break;
                
            case 0x0c:                                  // 字符超时指示
                U1IER &= (~0x01);                       // 禁止接收及字符超时中断
                break;
                
            default:
                break;
        }
    } 
    
    VICVectAddr = 0;      		// 通知中断控制器中断结束
}

⌨️ 快捷键说明

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