modem.c
上传用户:zddz2006
上传日期:2020-12-03
资源大小:261k
文件大小:14k
源码类别:

中间件编程

开发平台:

Visual C++

  1. /****************************************Copyright (c)**************************************************
  2. **                               广州周立功单片机发展有限公司
  3. **                                     研    究    所
  4. **                                        产品一部 
  5. **
  6. **                                 http://www.zlgmcu.com
  7. **
  8. **--------------文件信息--------------------------------------------------------------------------------
  9. **文   件   名: uart0.c
  10. **创   建   人: 陈明计
  11. **最后修改日期: 2003年7月4日
  12. **描        述: μCOS-II下LPC2000的Modem底层驱动 
  13. **              
  14. **--------------历史版本信息----------------------------------------------------------------------------
  15. ** 创建人: 陈明计
  16. ** 版  本: v1.0
  17. ** 日 期: 2004年2月25日
  18. ** 描 述: 原始版本
  19. **
  20. **------------------------------------------------------------------------------------------------------
  21. ** 修改人:
  22. ** 版  本:
  23. ** 日 期:
  24. ** 描 述:
  25. **
  26. **--------------当前版本修订------------------------------------------------------------------------------
  27. ** 修改人: 
  28. ** 日 期: 
  29. ** 描 述: 
  30. **
  31. **------------------------------------------------------------------------------------------------------
  32. ********************************************************************************************************/
  33. #define IN_MODEM
  34. #include "config.h"
  35. static OS_EVENT *ModemSem, *Uart1Send, *Uart1Get;
  36. static uint8 ModemState;
  37. /*********************************************************************************************************
  38. ** 函数名称: UART1Init
  39. ** 功能描述: 初始化UART0 
  40. ** 输 入: bps:波特率
  41. **
  42. ** 输 出:TRUE  :成功
  43. **        FALSE:失败
  44. ** 全局变量: Uart0Sem
  45. ** 调用模块: OSSemCreate
  46. **
  47. ** 作 者: 陈明计
  48. ** 日 期: 2004年2月25日
  49. **-------------------------------------------------------------------------------------------------------
  50. ** 修改人: 
  51. ** 日 期: 
  52. **-------------------------------------------------------------------------------------------------------
  53. ** 修改人: 陈明计
  54. ** 日 期: 
  55. **------------------------------------------------------------------------------------------------------
  56. ********************************************************************************************************/
  57.         void UART1Init(uint32 bps)
  58. {
  59.     uint16 Fdiv;
  60.     
  61.     PINSEL0 = (PINSEL0 & 0x0000ffff) | 0x55550000;  /* 选择管脚为UART0 */
  62.     U1LCR = 0x80;                                   /* 允许访问分频因子寄存器 */
  63.     Fdiv = (Fpclk / 16) / bps;                      /* 设置波特率 */
  64.     U1DLM = Fdiv / 256;
  65. U1DLL = Fdiv % 256;
  66.     U1LCR = 0x03;                                   /* 禁止访问分频因子寄存器 */
  67.                                                     /* 且设置为8,1,n */
  68. U1IER = 0x0f;                                   /* 允许接收和发送中断 */
  69.     U1FCR = 0x87;                                   /* 初始化FIFO */
  70.     U1MCR = 0x03;
  71.     Uart1Send = OSSemCreate(1);
  72.     Uart1Get = OSSemCreate(0);
  73. }
  74. /*********************************************************************************************************
  75. ** 函数名称: GetModemState
  76. ** 功能描述: 获取MODEM状态
  77. ** 输 入: 无
  78. **        
  79. ** 输 出: MODEM状态
  80. ** 全局变量: 无
  81. ** 调用模块: 无
  82. **
  83. ** 作 者: 陈明计
  84. ** 日 期: 2004年2月25日
  85. **-------------------------------------------------------------------------------------------------------
  86. ** 修改人:
  87. ** 日 期:
  88. **------------------------------------------------------------------------------------------------------
  89. ********************************************************************************************************/
  90.         uint8 GetModemState(void)
  91. {
  92.     return ModemState;
  93. /*********************************************************************************************************
  94. ** 函数名称: ModemWrite
  95. ** 功能描述: 发送多个字节数据
  96. ** 输 入: Data:发送数据存储位置
  97. **        NByte:发送数据个数
  98. ** 输 出:无
  99. ** 全局变量: 无
  100. ** 调用模块: UART0Putch
  101. **
  102. ** 作 者: 陈明计
  103. ** 日 期: 2004年2月25日
  104. **-------------------------------------------------------------------------------------------------------
  105. ** 修改人:
  106. ** 日 期:
  107. **------------------------------------------------------------------------------------------------------
  108. ********************************************************************************************************/
  109.         uint8 ModemWrite(char *Data, uint16 NByte)
  110. {
  111.     uint8 err,i;
  112.     
  113.     OSSemPend(ModemSem, 0, &err);
  114.     while (NByte > 0)
  115.     {
  116.         OSSemPend(Uart1Send, 0, &err);
  117.         for (i = 0; i < 8; i++)
  118.         {
  119.             U1THR = *Data++;
  120.             NByte--;
  121.             if (NByte == 0)
  122.             {
  123.                 break;
  124.             }
  125.         }
  126.     }
  127.     OSSemPost(ModemSem);
  128.     return ModemState;
  129. /*********************************************************************************************************
  130. ** 函数名称: UART0Getch
  131. ** 功能描述: 接收一个字节
  132. ** 输 入: 无
  133. ** 输 出: 接收到的数据
  134. ** 全局变量: 无
  135. ** 调用模块: 无
  136. **
  137. ** 作 者: 陈明计
  138. ** 日 期: 2004年2月25日
  139. **-------------------------------------------------------------------------------------------------------
  140. ** 修改人:
  141. ** 日 期:
  142. **------------------------------------------------------------------------------------------------------
  143. ********************************************************************************************************/
  144.         uint8 ModemGetch(void)
  145. {
  146.     uint8 rt;
  147.     OS_ENTER_CRITICAL();
  148.     while ((U1LSR & 0x00000001) == 0)
  149.     {                                           /* 没有收到数据 */
  150.         U1IER = U1IER | 0x01;                   /* 允许接收中断 */
  151.         OSSemPend(Uart1Get, 0, &rt);
  152.     }
  153.     rt = U1RBR;                                 /* 读取收到的数据 */
  154.     OS_EXIT_CRITICAL();
  155.     return rt;
  156. /*********************************************************************************************************
  157. ** 函数名称: ModemDialUp
  158. ** 功能描述: 通过modem拨号 
  159. ** 输 入: 电话号码
  160. **
  161. ** 输 出: modem状态
  162. **
  163. ** 全局变量: ModemState
  164. ** 调用模块: ModemWrite,OSTimeDly
  165. **
  166. ** 作 者: 陈明计
  167. ** 日 期: 2004年2月25日
  168. **-------------------------------------------------------------------------------------------------------
  169. ** 修改人: 
  170. ** 日 期: 
  171. **-------------------------------------------------------------------------------------------------------
  172. ********************************************************************************************************/
  173.         uint8 ModemDialUp(char Number[])
  174. {
  175.     char *cp;
  176.     uint8 i;
  177.     uint8 err;
  178.     
  179.     if (ModemState == MODEM_CLOSE)
  180.     {
  181.         while ((U1LSR & 0x00000001) != 0)
  182.         {
  183.             err = U1RBR;
  184.         }
  185.         ModemWrite("ATD", 3);
  186.         i = 0;
  187.         cp = Number;
  188.         while (*cp++ != 0)
  189.         {
  190.             i++;
  191.         }
  192.         ModemWrite(Number, i);
  193.         ModemWrite("rn", 2);
  194.         U1IER = U1IER | 0x01;                   /* 允许接收中断 */
  195.         for (i = 0; i < 120; i++)
  196.         {
  197.             OSTimeDly(OS_TICKS_PER_SEC);
  198.             if (ModemState == MODEM_CONNECT)
  199.             {
  200.                 break;
  201.             }
  202.         }
  203.     }
  204.     return ModemState;
  205. }
  206. /*********************************************************************************************************
  207. ** 函数名称: ModemDialDown
  208. ** 功能描述: 挂断modem 
  209. ** 输 入: 无
  210. **
  211. ** 输 出: modem状态
  212. **
  213. ** 全局变量: ModemState
  214. ** 调用模块: OSTimeDly
  215. **
  216. ** 作 者: 陈明计
  217. ** 日 期: 2004年2月25日
  218. **-------------------------------------------------------------------------------------------------------
  219. ** 修改人: 
  220. ** 日 期: 
  221. **-------------------------------------------------------------------------------------------------------
  222. ********************************************************************************************************/
  223.         uint8 ModemDialDown(void)
  224. {
  225.     U1MCR = 0x02;
  226.     OSTimeDly(OS_TICKS_PER_SEC / 10);
  227.     U1MCR = 0x03;
  228.     OSTimeDly(OS_TICKS_PER_SEC / 10);
  229.     return ModemState;
  230. }
  231. /*********************************************************************************************************
  232. ** 函数名称: ModemCommand
  233. ** 功能描述: 向modem发送命令 
  234. ** 输 入: 命令字符串
  235. **
  236. ** 输 出: modem状态
  237. **
  238. ** 全局变量: ModemState
  239. ** 调用模块: ModemWrite,ModemGetch,
  240. **
  241. ** 作 者: 陈明计
  242. ** 日 期: 2004年2月25日
  243. **-------------------------------------------------------------------------------------------------------
  244. ** 修改人: 
  245. ** 日 期: 
  246. **-------------------------------------------------------------------------------------------------------
  247. ********************************************************************************************************/
  248.         uint8 ModemCommand(char *Command)
  249. {
  250.     char *cp;
  251.     uint8 i,err;
  252.     
  253.     if (ModemState == MODEM_CLOSE)
  254.     {
  255.         while ((U1LSR & 0x00000001) != 0)
  256.         {
  257.             err = U1RBR;
  258.         }
  259.         
  260.         cp = Command;
  261.         i = 0;
  262.         while(*cp++ != 0)
  263.         {
  264.             i++;
  265.         }
  266.         ModemWrite(Command, i);
  267.         ModemWrite("rn", 2);
  268.         i = ModemGetch();
  269.         if (i == 'A' || i == 'a')
  270.         {
  271.             while (1)
  272.             {
  273.                 err = i;
  274.                 i = ModemGetch();
  275.                 if (err == 'O' || err == 'o')
  276.                 if (i == 'K' || i == 'k')
  277.                 {
  278.                     i = ModemGetch();
  279.                     i = ModemGetch();
  280.                     break;
  281.                 }
  282.             }
  283.         }
  284.         else
  285.         {
  286.             while (1)
  287.             {
  288.                 if (i == '0')
  289.                 {
  290.                     break;
  291.                 }
  292.                 i = ModemGetch();
  293.                 i = ModemGetch();
  294.             }
  295.         }
  296.     }
  297.     return ModemState;
  298. }
  299. /*********************************************************************************************************
  300. ** 函数名称: ModemInit
  301. ** 功能描述: 初始化Modem 
  302. ** 输 入: 波特率
  303. **
  304. ** 输 出: modem状态
  305. **
  306. ** 全局变量: ModemState
  307. ** 调用模块: UART1Init,OSTimeDly,ModemCommand,
  308. **
  309. ** 作 者: 陈明计
  310. ** 日 期: 2004年2月25日
  311. **-------------------------------------------------------------------------------------------------------
  312. ** 修改人: 
  313. ** 日 期: 
  314. **-------------------------------------------------------------------------------------------------------
  315. ********************************************************************************************************/
  316.         uint8 ModemInit(uint32 bps)
  317. {
  318.     ModemState = MODEM_CLOSE;
  319.     UART1Init(bps);
  320.     ModemSem = OSSemCreate(1);
  321.     if (ModemSem != NULL)
  322.     {
  323.         if ((U1MSR & 0x30) != 0x30)
  324.         {
  325.             OSTimeDly(OS_TICKS_PER_SEC);
  326.             if ((U1MSR & 0x30) != 0x30)
  327.             {
  328.                 ModemState = NOT_FIND_MODEM;
  329.             }
  330.         }
  331.         if (ModemState == MODEM_CLOSE)
  332.         {
  333.             ModemCommand("ATE0");
  334.             ModemCommand("ATV0");
  335.             ModemCommand("AT&C1");
  336.             ModemCommand("AT&D2");
  337.             ModemCommand("AT&R0");
  338.             ModemCommand("AT&S0");
  339.             ModemCommand("ATS0=2");
  340.         }
  341.     }
  342.     else
  343.     {
  344.         ModemState = NOT_INIT_MODEM;
  345.     }
  346.     return ModemState;
  347. }
  348. /*********************************************************************************************************
  349. ** 函数名称: UART1_Exception
  350. ** 功能描述: UART1中断服务程序
  351. ** 输 入: 无
  352. **
  353. ** 输 出: 无
  354. **         
  355. ** 全局变量: ModemState
  356. ** 调用模块: OSSemPost
  357. **
  358. ** 作 者: 陈明计
  359. ** 日 期: 2004年2月25日
  360. **-------------------------------------------------------------------------------------------------------
  361. ** 修改人:
  362. ** 日 期:
  363. **------------------------------------------------------------------------------------------------------
  364. ********************************************************************************************************/
  365.         void UART1_Exception(void)
  366. {
  367.     uint8 IIR, temp;
  368.     
  369.     OS_ENTER_CRITICAL();
  370.     while(((IIR = U1IIR) & 0x01) == 0)
  371.     {                                                   /* 有中断未处理完 */
  372.         switch (IIR & 0x0e)
  373.         {
  374.             case 0x00:                                  /* Modem状态变化 中断    */
  375.                 if ((U1MSR & 0x80) != 0)
  376.                 {
  377.                     ModemState = MODEM_CONNECT;
  378.                 }
  379.                 else
  380.                 {
  381.                     ModemState = MODEM_CLOSE;
  382.                 }
  383.                 if ((U1MSR & 0x40) != 0)
  384.                 {
  385.                     ModemState = MODEM_RING;
  386.                 }
  387.                 if ((U1MSR & 0x30) != 0x30)
  388.                 {
  389.                     ModemState = NOT_FIND_MODEM;
  390.                 }
  391.                 break;
  392.             case 0x02:                                  /* THRE中断    */
  393.                 OSSemPost(Uart1Send);
  394.                 break;
  395.             case 0x04:                                  /* 接收数据可用 */
  396.                 OSSemPost(Uart1Get);
  397.                 U1IER &= (~0x01);                       /* 禁止接收及字符超时中断 */
  398.                 break;
  399.             case 0x06:                                  /* 接收线状态   */
  400.                 temp = U1LSR;
  401.                 break;
  402.             case 0x0c:                                  /* 字符超时指示 */
  403.                 OSSemPost(Uart1Get);
  404.                 U1IER &= (~0x01);                       /* 禁止接收及字符超时中断 */
  405.                 break;
  406.             default :
  407.                 break;
  408.         }
  409.     } 
  410.     VICVectAddr = 0;            // 通知中断控制器中断结束
  411.     OS_EXIT_CRITICAL();
  412. }
  413. /*********************************************************************************************************
  414. **                            End Of File
  415. ********************************************************************************************************/