5495|3

545

帖子

0

TA的资源

一粒金砂(高级)

楼主
 

LM3S8962UART控制MODEM通信之三UART驱动MODEM函数 [复制链接]

LM3S8962UART驱动MODEM底层驱动函数:
LM23S8962开发板和MODEM通过串口连接,但是由于开发板没有提供UART 转RS-232C 的接口芯片 SP3232E,因此需要外扩,正好手头有块自己做的电源板,上面有SP3232E,正好可以用了,这个电源板是我自己做的第一块电路板,用的是LM2576和LT1085开关电源芯片,外接》12V直流电压,可输出12V、5V、3.3V电压,很方便。下面图是开发板、电源板和MODEM的连接图。

MODEM内部结构图

 

UART驱动MODEM整个通信过程是这样子的:利用LM3S8962的UART接收读取MODEM串口数据,同时可以发送各种命令控制MODEM进行不同操作。

当时申请开发板时,要做一个机房监控系统,利用MODEM就可以实现,如当外界MODEM或电话呼叫机房MODEM时,机房MODEM收到振铃RING时,LM3S8962通过UART读取到有RING时,然后通过UART向MODEM发送摘机命令,这样就建立起通信连接,外界电话或MODEM发送一系列的指令,机房内的MODEM就能收到,LM3S8962就根据不同的命令来进行不同测试,并可以把操作结果数据发送给主叫方(前提是双方先定义好通信协议,如主叫发送888#,LM3S8962进行温度读取操作。主叫发送000#,LM3S8962进行湿度读取,并且可以把操作所得到的数据通回发给主叫MODEM)。这里所有的收发数据都是通过DTMF码来实现的,MODEM发送DTMF码的AT指令为AT#VTS={x,y},x表示DTMF码(0~9,A~D,*,#),y表示DTMF码持续时间。比如要向MODEM发送1,2,3,可以这样:AT#VTS={1,01}}#VTS={2,01}#VTS={3,01}。

最新回复

顶。学习、、、  详情 回复 发表于 2010-11-25 09:02
 
点赞 关注

回复
举报

545

帖子

0

TA的资源

一粒金砂(高级)

沙发
 

UART驱动MODEM函数包括以下几个函数:
1、UART初始化函数
2、UART从串口设备读取数据函数
3、UART向串口设备发送数据数据函数
4、MODEM初始化函数
5、MODEM摘机函数
6、MODEM挂机函数
7、向MODEM串口写数据函数
8、从MODEM串口读取数据函数
9、向MODEM发送命令函数。
有了这些驱动,我们就可以很方便的操作MODEM了。
1、UART初始化函数
/************************************************************************************************************
** 功能描述: 初始化UART
** 输   入: bps  : Band Rate
** 输   出: TRUE : 成功
**           FALSE: 失败
************************************************************************************************************/
unsigned char init_uart (unsigned int ulBase,unsigned int  BaudRate, unsigned char  Prio)
{
    if (UART0_BASE == ulBase) {
  memset(&rbuf0,0,sizeof(struct buf_s0));
  memset(&tbuf0,0,sizeof(struct buf_s0));
 } else if (UART1_BASE == ulBase) {
  memset(&rbuf1,0,sizeof(struct buf_s0));
  memset(&tbuf1,0,sizeof(struct buf_s0)); 
 }

    if (BaudRate > 115200) {                                            /*  波特率太高,错误返回       */
        return(FALSE);
    }
 if(ulBase == UART0_BASE)
 {
     SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);                        /*  使能串口0外围设备          */
     SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);                        /*  使能GPIOA                  */
     GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);          /*  设置PA0,PA1为RXD0,TXD0     */
   }
 else if(ulBase == UART1_BASE)
 {
     SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);                        /*  使能串口1外围设备          */
     SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);                        /*  使能GPIOD                  */
     GPIOPinTypeUART(GPIO_PORTD_BASE, GPIO_PIN_2 | GPIO_PIN_3);          /*  设置PD2,PD3为RXD0,TXD0     */
 }

    UARTConfigSet(ulBase, BaudRate, (UART_CONFIG_WLEN_8 |           /*  配置串口0,8位数据,1位起始*/
                                                                        /*  位,1位停止位,用户波特率  */
                                     UART_CONFIG_STOP_ONE |
                                     UART_CONFIG_PAR_NONE) & 0xFFFFFFEF);

    UARTFifoLevelSet(ulBase, UART_FIFO_TX4_8, UART_FIFO_RX6_8);
    UARTIntEnable(ulBase, UART_INT_RX | UART_INT_RT);              /*  使能串口接收中断和接收超时 */
     if(ulBase == UART0_BASE)
 {
     IntEnable(INT_UART0);                                      /*  使能串口0系统中断           */
                                                                   /*  中断                        */
     IntPrioritySet(INT_UART0, Prio);                           /*  设置中断优先级              */
 
 }
 else if(ulBase == UART1_BASE)
 {
     IntEnable(INT_UART1);                                      /*  使能串口1系统中断           */
                                                                   /*  中断                        */
     IntPrioritySet(INT_UART1, Prio);                           /*  设置中断优先级              */
    
 }
 UARTEnable(ulBase);


  return(TRUE);
}
2、UART从串口设备读取数据函数
*********************************************************************************************************
** Function name:           uartRead
** Descriptions:            从串口设备读取数据
** input parameters:        ulBase:      设备号
**                          puiBuf:      保存返回数据的字符串指针地址
**                          uiNum:       读取的数据个数
** Output parameters:       puiBuf:      读到的数据首地址     
** Returned value:          实际读取的数据个数
*********************************************************************************************************/
extern int   read_uart (unsigned int ulBase,unsigned char  *puiBuf,  int uiNum)
{
 int i;
 int c =0;
 int uiReviceNum = 0;
  
 for (i=0;i<uiNum;i++)
 {   
  if(ulBase == UART0_BASE)
   c = get_char_0();
  else if(ulBase == UART1_BASE)
   c = get_char_1();
  if (c != -1)
  {
   puiBuf = (unsigned char)c;
   uiReviceNum ++;
  }
  else
   break;
 }
 
  
 return uiReviceNum; 
}
3、UART向串口设备发送数据数据函数
*********************************************************************************************************
** Function name:           UartSend
** Descriptions:            从串口设备发送数据,等待发送完毕,阻塞
** input parameters:        ulBase:      设备号
**                          Buffer:      发送数据的字符串指针地址
**                          NByte:       发送的数据个数    
** Returned value:         
*********************************************************************************************************/

extern void write_uart (unsigned int ulBase,unsigned char  *Buffer, unsigned short  NByte)
{
 
    if(UART0_BASE == ulBase)
 {
  while (NByte) {
         if ( UARTSpaceAvail(UART0_BASE) ) {
             UARTCharNonBlockingPut(UART0_BASE, *Buffer++);
             NByte--;
         }
     }
     while ( !UARTTraFifoEmp(UART0_BASE) ) {
         ;
     }
  
 }
 else if(UART1_BASE == ulBase)
 {
  while (NByte) {
         if ( UARTSpaceAvail(UART1_BASE) ) {
             UARTCharNonBlockingPut(UART1_BASE, *Buffer++);
             NByte--;
         }
     }
     while ( !UARTTraFifoEmp(UART1_BASE) ) {
         ;
     }
  
 }
}
4、MODEM初始化函数
/*********************************************************************************************************
** 函数名称: init_modem_device
** 功能描述: 初始化Modem,包括连接Modem模块等操作
**           初始化MODEM为语音模式              

(1)发送“AT&D0&S0&R1” ,设置为忽略DTR,DSR,CTS信号;
(2)发送“AT&K0” ,设置为忽略流控;
(3)发送“ATE0X0S0=0” ,将Modem 设置为不回应所收到的指令以及返回结果码的类型,
S0=0表示MODEM不自动摘机并试图连接;

********************************************************************************************************/


int init_modem_device(int mode)
{
 int proc_result = -1;
 
 //初始化Modem使用的串口
 init_uart(MODEM_UART,57600,3);
 
 /***********初始化Modem流程********************/
 //通过发送AT命令,查看Modem是否存在
 proc_result = check_modem_device(20);
 if (0 == proc_result) {
  g_modem_flag = 1;
 } else {
  g_modem_flag = 0;
  proc_result = -1;
  return (proc_result);
 }

 //配置Modem初始工作状态
 //配置不回送AT命令字元
 proc_result = send_at_cmd_to_modem("ATE0\r\n",1000);
 //proc_result = send_at_cmd_to_modem("ATQ0\r\n",1000);
 if (MODEM_RET_OK != proc_result) {
  proc_result = -1;
  return (proc_result);
 }

 //配置不自动应答
 proc_result = send_at_cmd_to_modem("ATS0=0\r\n",1000);
 if (MODEM_RET_OK != proc_result) {
  proc_result = -1;
  return (proc_result);
 }
 
 //停止使用流控
 proc_result = send_at_cmd_to_modem("AT&K0\r\n",1000);
 if (MODEM_RET_OK != proc_result) {
  proc_result = -1;
  return (proc_result);
 }
 
 //设置Modem工作在话音模式下
 proc_result = send_at_cmd_to_modem("AT#CLS=8\r\n",1000);
 if (MODEM_RET_OK != proc_result) {
  proc_result = -1;
  return (proc_result);
 }

 
 return (proc_result);
}
5、MODEM摘机函数
*********************************************************************************************************
** 函数名称: answer_call_for_connect
** 功能描述: 摘机函数
**------------------------------------------------------------------------------------------------------

int answer_call_for_connect(int mode)
{
 int proc_result = -1;

 //等待满足振铃次数后摘机
 proc_result = wait_for_ring_count(0,2);
 proc_result = 0;
 if (0 == proc_result) {
  //满足摘机条件,摘机
  proc_result = send_at_cmd_to_modem("ATA\r\n",1000);//摘机指令ATA
  
   }
        return (proc_result);
}
6、MODEM挂机函数
*********************************************************************************************************
** 函数名称:
** 功能描述: 挂断电话
**-------------------------------------------------------------------------------------------------------
int disconnect_for_modem(int mode)
{
 int proc_result = -1;
 proc_result = send_at_cmd_to_modem("ATH0\r\n",1000);//挂机指令ATH0
 if (MODEM_RET_OK == proc_result) {
  proc_result = 0;
 } 

 return (proc_result);
}
7、向MODEM串口写数据函数
int write_modem(unsigned char *p_buf,int len)
{
 int proc_result = -1;
 
 
 write_uart(MODEM_UART,p_buf,len);
    proc_result = len;

 return (proc_result);

}
8、从MODEM串口读取数据函数

int read_modem(unsigned char *p_buf,int len,int s,int ms)
{
 int proc_result = -1;

 int ms_all,now_read;

 ms_all = s * 1000 + ms;

 now_read = 0;
 while (1) {

  proc_result = read_uart(MODEM_UART,p_buf,len);
  if (0 < proc_result) {
   len -= proc_result;
   now_read += proc_result;
     *p_buf += len;
   if (0 >= len) {
    //已经读取了足够的字节
    break;
   }
  }

  if (ms_all <= 0) {
   //已经超时
   break;
  }

  ms_all -= 50;
 }
 return (now_read);
}
9、向MODEM发送命令函数
int send_at_cmd_to_modem(unsigned char *p_at_cmd,int wait_ms)
{
 int proc_result = -1;
 int i,tx_len;
 char rx_buf[32];
 char tx_buf[64];
 memset(&rx_buf[0],0,32);
 memset(&tx_buf[0],0,64);
 
 tx_len = sprintf(&tx_buf[0],p_at_cmd,strlen(p_at_cmd));
 //发送命令
 write_modem((unsigned char *)&tx_buf[0],tx_len);
 proc_result =  wait_for_modem_back(0,1000,0);
 
 
 #if 0
 tx_len = read_modem((unsigned char *)&rx_buf[0],16,0,wait_ms);
 
 if (0 >= tx_len) {
  proc_result = -1;
  return (proc_result);
 } else {
  //通过比较返回的字符串,回送检查结果
  if (0 != strstr(&rx_buf[0],"OK")) {
   proc_result = MODEM_RET_OK;
   return (proc_result);
  } else if (0 != strstr(&rx_buf[0],"ERROR")) {
   proc_result = MODEM_RET_ERROR;
   return (proc_result);
  }
 }
 #endif
  

 return (proc_result);
}


 

[ 本帖最后由 beyondvv 于 2010-11-23 15:26 编辑 ]
 
 

回复

545

帖子

0

TA的资源

一粒金砂(高级)

板凳
 

 

[ 本帖最后由 beyondvv 于 2010-11-23 15:31 编辑 ]
 
 
 

回复

849

帖子

0

TA的资源

纯净的硅(高级)

4
 
顶。学习、、、
 
个人签名只有想不到,没有做不到。
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表