单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8562|回复: 7
收起左侧

Cortex-M3学习LPC1768 - UART0实验

[复制链接]
xiongxiao 发表于 2015-5-27 19:22 | 显示全部楼层 |阅读模式
本帖最后由 xiongxiao 于 2015-5-27 19:25 编辑

LPC1768含有4 个符合16C550工业标准的异步串口UATR0-UART3,其中UART1具有标准的MODEM接口和RS232。至于RS232的标准是什么样的,这里不在总结了,如果哪位有兴趣可以上网查一下维基百科。RS-485是后期出现的一个传输标准,关于它们的特性,下面列表总结一下:

RS-232特性
RS-485特性
最高速率约为20kb/s
与TTL电平兼容
传输最大距离约为15m
传输距离实际达1200m
共模抑制比能力差
共模抑制比能力强
UATR0/2/3可以工作在UART模式下,也可以工作在IrDA模式下, IrDA是红外数据组织(Infrared Data Association)的简称,目前广泛采用的IrDA红外连接技术就是由该组织提出的。到目前为止,全球采用IrDA技术的设备超过了5000万部。IrDA已经制订出物理介质和 协议层规格,以及2个支持IrDA标准的设备可以相互监测对方并交换数据。 初始的IrDA1.0 标准制订了一个串行,半双工的同步系统,传输速率为2400bps到115200bps,传输范围1 m,传输半角度为15度到30度。最近IrDA扩展了其物理层规格使数据传输率提升到4Mbps。IrDA数据协议由物理层,链路接入层和链路管理层三个基本层协议组成,另外,为满足各层上的应用的需要,IrDA栈支持IrLAP, IrLMP, IrIAS, IrIAP, IrLPT, IrCOMM, IrOBEX和IrLAN等。IrDA的优点是成本低,体积小、功耗低,数据传输干扰小等。关于IrDA的协议与应用这里暂时先不总结,后续学习中会再慢慢涉及到,届时将做深入研究。UATR1具有MODEM接口,能过该接口可以接入电话网络,实现远距离通讯。至于怎么通讯,这里也暂时不总结,因为这一块懒猫也没有深入研究。
关于串口的配置主要涉及到引脚的配置,波特率的配置,帧格式的设置及FIFO设置等。涉及到的寄存器主要有接收缓冲寄存器,它包含即将读取的接收数据。发送保持寄存器,它主要是用来写入发送数据的,中断使能寄存器IER,若是用到中断接收或发送时需配置些寄存器,与之相关联的寄存器还有中断标志寄存器IIR。还有FIFO控制寄存器FCR,它是用来配置先进先出相关的东东的。线控制寄存器LCR,这个寄存器主要就是用来设置帧格式的,与这个寄存器相关联的寄存器是线状态寄存器LSR,用来读取帧格式状态的寄存器。当然还有缓存寄存器SCR,这个与串口操作关系不大。还有自动波特率控制器ACR,配置程序自适应波特率的。还有IrDA控制寄存器,它与红外发送与接收有关。小数分频寄存器FDR,它是波特率配置有关。传输使能寄存器TER,如果这个寄存器的TXEN配置为1,刚只要缓存中有有效数据,就可以通过发送引脚把数据发送出去。还有一个寄存器FIFO等级寄存器FIFOLVL,它是个只读寄存器,用来读取当前FIFO等级状态。此次实验我是用查询方式发送字符到串口,所以很大寄存器没有用到,关于寄存器的详细说明可以参考LPC1768的数据手册,这里就不再照搬手册了。下面简单说一下这次实验电路图,主要是一个 按键,8个LED灯,还有串口0,功能就是按一下按键亮一个灯,等全亮时,再按按键灯全来,然后再按按键时第按一下点亮一个,循环往复,同时哪个灯亮,就发送字符“Led  X  on”,下面是这次实验的电路图:


                                      图 1-1 实验电路图
下面简单说一下这个软件,软件主要分为两大部分,一个是关于串口配置及常用的函数,另一个就是主LED点灯程序,分别在UART.C与MAIN.C两个源文件中,下面把部分代码帖出来,完整部分请参阅附件:
1)、 uart.c源文件
#include "includes.h"
/********************************************************************************
* 函数名称 :uint32_t UARTInit( uint32_t PortNum, uint32_t baudrate )
* 函数功能 : 串口初始化
* 入口参数 : uint32_t PortNum  -- 端口号(0、1)
*            uint32_t baudrate -- 波物率
* 出口参数 : 返回真或假
* 备    注 :如果中断句柄没有建立在向量表中则返回false
*******************************************************************************/
void UARTInit( uint32_t PortNum, uint32_t baudrate )
{
  uint32_t Fdiv;

  if ( PortNum == 0 )
  {
    PINCON->PINSEL0 |= (1 << 4);             /* Pin P0.2 -- TXD0 (Com0) */
    PINCON->PINSEL0 |= (1 << 6);             /* Pin P0.3 -- RXD0 (Com0) */
            UART0->LCR  = 0x83;                       /* 8 bits, 无校验, 1 个停止位 */
    Fdiv = (SystemFrequency/4/ 16) / baudrate;/* 设置波特率 */
    UART0->DLM  = Fdiv / 256;
    UART0->DLL  = Fdiv % 256+1;
    UART0->LCR  = 0x03;                       /* 锁定波特率  */
    UART0->FCR  = 0x07;                       /* 串口先进先出控制寄存器设置*/

  }
  else if ( PortNum == 1 )
  {
               PINCON->PINSEL4 |= (1<<1);                /* Pin P2.0 -- TXD1 (Com1)*/
          PINCON->PINSEL4 |= (1<<3);                /* Pin P2.1 -- RXD1 (Com1)*/
   
               UART1->LCR = 0x83;                                  /* 8 bits, 无校验, 1 个停止位 */
    Fdiv = (SystemFrequency/4/16)/ baudrate ; /* 设置波特, Fpclk: 18MHz */
    UART1->DLM = Fdiv/256;                                                                                             
    UART1->DLL = (Fdiv%256)+1;
               UART1->LCR = 0x03;                                   /* DLAB = 0 */
    UART1->FCR = 0x07;                             /* 使能TX与 RX 并初始化FIFO. */

  }
}

/********************************************************************************
* 函数名称 :void UARTSend( uint32_t portNum, uint8_t *BufferPtr, uint32_t Length )
* 函数功能 : 从串口发送一串数据
* 入口参数 : uint32_t PortNum   -- 端口号(0、1)
*            uint8_t *BufferPtr -- 缓冲指针
*           uint32_t Length    -- 数据长度
* 出口参数 : 无
* 备    注 :无
*******************************************************************************/
void UARTSend( uint32_t portNum, uint8_t *BufferPtr, uint32_t Length )
{
  if ( portNum == 0 )
  {
    while ( Length != 0 )
    {
                 while ( !(UART0->LSR & 0x20) );   /* 检测串口状态,是否包含有效数据 */
                 UART0->THR = *BufferPtr;           /* 输出数据 */
                 BufferPtr++;                       /* 指向下一个数据 */
                 Length--;                          /*  数据长度减1 */
               }
  }
  else
  {
               while ( Length != 0 )
    {
                 while ( !(UART1->LSR & 0x20));    /* 检测串口状态,是否包含有效数据 */
                 UART1->THR = *BufferPtr;                                         /* 输出数据 */
                 BufferPtr++;                                                                                  /* 指向下一个数据 */
                 Length--;                                                                                         /*  数据长度减1 */
    }
  }
  return;
}
/********************************************************************************
* 函数名称 :int UART0_SendByte (int ucData)
* 函数功能 : 串口0发送数据
* 入口参数 : int ucData - 要发送的数据
* 出口参数 : 无
* 备    注 :无
*******************************************************************************/
int UART0_SendByte (int ucData)
{
               while (!(UART0->LSR & 0x20));
    return (UART0->THR = ucData);
}
/********************************************************************************
* 函数名称 :void UART0_SendString (unsigned char *s)
* 函数功能 : 串口0发送字符串
* 入口参数 : unsigned char *s -- 要发送的字符串
* 出口参数 : 无
* 备    注 :无
*******************************************************************************/
void UART0_SendString (unsigned char *s)
{
            while (*s != '\0')
               {
                        UART0_SendByte(*s++);
               }
}
2)、 main.c源文件
  1. /*********************************************************************************
  2. 工程名称:lesson4
  3. 功    能: 学习使用LPC1768的串口通讯                                                      
  4. 编译环境: MDKV4.12                                                   
  5. 时    钟: 外部12Mhz                                                                                           
  6. 日    期: 11/08/19                                                        
  7. 作    者: 懒猫爱飞
  8. 版本  号:V1R0
  9. ---------------------------------------------------------------------------------
  10. 修改内容:NULL
  11. 修改日期:
  12. 修改人员:
  13. ---------------------------------------------------------------------------------
  14.                                                                                                                                                                                                                          
  15. **********************************************************************************/


  16. /*********************************************************************************
  17. 文件名称:mian.c
  18. 功    能: 主要调度函数及应用函数                                                         
  19. 编译环境: MDKV4.12                                                   
  20. 时    钟: 外部12Mhz                                                                                           
  21. 日    期: 11/08/19                                                        
  22. 作    者: 懒猫爱飞
  23. 备    注:NULL
  24. ---------------------------------------------------------------------------------
  25. 修改内容:NULL
  26. 修改日期:XXXX年xx月xx日      xx时xx分
  27. 修改人员:xxx xxx xxx
  28.                                                                                                          
  29. **********************************************************************************/
  30. #include"includes.h"
  31.                                                                             
  32. volatile unsigned long SysTickCnt;                   /* 用于系统时钟计数 */

  33. unsigned char LedOnMeg[] = "Led 1 On!\r\n";
  34. unsigned char LedOffMeg[] = "Led all Off!\r\n";
  35. unsigned char KeyMeg[] = "key push down \r\n";
  36. unsigned char OpenString[][50] = {
  37.                                 "**********************************************\r\n",
  38.                                 "****             --欢迎光临--             ****\r\n",
  39.                                                                 "**** 小野兽的小草窝^_^                    ****\r\n",
  40.                                                                 "**** http://blog*ednchina*com/ytfdhb/     ****\r\n",
  41.                                                                 "**** 我是懒猫爱飞,我的口号是:           ****\r\n",
  42.                                                                 "**** 每天进步一点点,开心多一点^_^        ****\r\n",
  43.                                                                 "**********************************************\r\n"
  44.                                                             };

  45. unsigned int key_sta = 0;              /* 按键状态 */
  46. unsigned int key_pre = 1;                   /* 按键当前状态值 */
  47. unsigned int key_old = 1;                           /* 按键前一个状态值 */
  48. unsigned int led_flag = 0;

  49. unsigned int  StepCnt = 0;        /* 状态计数 */

  50. /********************************************************************************
  51. * 函数名称 :void SysTick_Handler (void)
  52. * 函数功能 : 系统节拍定时器中断函数,每1ms计数一次
  53. * 入口参数 : 无
  54. * 出口参数 : 无
  55. * 备    注 :无
  56. *******************************************************************************/
  57. void SysTick_Handler (void)
  58. {         
  59.   SysTickCnt++;
  60. }

  61. /********************************************************************************
  62. * 函数名称 :void Delay (unsigned long tick)  
  63. * 函数功能 : 毫秒级延时函数
  64. * 入口参数 : unsigned long tick -- 延时时长
  65. * 出口参数 : 无
  66. * 备    注 :无
  67. *******************************************************************************/
  68. void DelayMs (unsigned long tick)
  69. {      
  70.   unsigned long systickcnt;

  71.   systickcnt = SysTickCnt;
  72.   while ((SysTickCnt - systickcnt) < tick);
  73. }
  74. /********************************************************************************
  75. * 函数名称 :void PortInit(void)  
  76. * 函数功能 : 端口初始化
  77. * 入口参数 : 无
  78. * 出口参数 : 无
  79. * 备    注 :无
  80. *******************************************************************************/
  81. void PortInit(void)
  82. {
  83.    GPIO1->FIODIR = 0xB0000000;           /* LEDs on PORT1 defined as Output    */
  84.    GPIO2->FIODIR = 0x0000007C;           /* LEDs on PORT2 defined as Output    */
  85.    LedAllOff();                                                         /* 初始化时熄灭所有的灯 */
  86. }

  87. /********************************************************************************
  88. * 函数名称 :void KeyScan(void)
  89. * 函数功能 : 按键扫描
  90. * 入口参数 : 无
  91. * 出口参数 : 无
  92. * 备    注 :现在只扫描一个按键
  93. *******************************************************************************/
  94. void KeyScan()
  95. {
  96.         key_pre = KEY_EN ;
  97.         if(!KEY_EN )                      /* 如果按键按下 */
  98.         {
  99.                 if(key_old)
  100.                 {
  101.                     if(key_pre == 0)         /* 下降沿有效 */
  102.                     {
  103.                          key_sta = 1;            /* 记录按键状态 */
  104.                     }       
  105.             }
  106.         }
  107.         key_old = key_pre;
  108. }

  109. /********************************************************************************
  110. * 函数名称 :void KeyHandle(void)
  111. * 函数功能 : 按键处理函数
  112. * 入口参数 : 无
  113. * 出口参数 : 无
  114. * 备    注 :无
  115. *******************************************************************************/
  116. void KeyHandle(void)
  117. {
  118.     if(key_sta == 1)
  119.     {
  120.             StepCnt++;                        /* 执行下一步*/
  121.                 if(StepCnt == 9)
  122.                 {
  123.                         UART0_SendString (LedOffMeg); /* 显示LED状态信息 */               
  124.                 }
  125.                  if(StepCnt < 9)
  126.                 {
  127.                         LedOnMeg[4] = StepCnt+0x30;       /* 转换成字符 */
  128.                 UART0_SendString (LedOnMeg);      /* 显示LED状态信息 */                       
  129.                 }
  130.                 key_sta = 0;                         /* 按键状态清零,保证只执行一次 */
  131.         }       
  132. }
  133. void LedHandle()
  134. {
  135.         switch(StepCnt)
  136.         {
  137.                 case 1:Led1On();   /* LED1 点亮*/
  138.                        break;
  139.                 case 2:Led2On();   /* LED2 点亮*/
  140.                        break;
  141.             case 3:Led3On();   /* LED3 点亮*/
  142.                        break;
  143.             case 4:Led4On();   /* LED4 点亮*/
  144.                        break;
  145.                 case 5:Led5On();   /* LED5 点亮*/
  146.                        break;
  147.                 case 6:Led6On();   /* LED6 点亮*/
  148.                        break;
  149.                 case 7:Led7On();   /* LED7 点亮*/
  150.                        break;
  151.                 case 8:Led8On();   /* LED8 点亮*/
  152.                        break;
  153.             case 9:LedAllOff();        /* 熄灭所有的LED灯*/
  154.                        StepCnt = 0;        /* 重新开始 */
  155.                        break;
  156.                 default:break;
  157.         }
  158. }

  159. /********************************************************************************
  160. * 函数名称 :int main(void)
  161. * 函数功能 : 主函数
  162. * 入口参数 : 无
  163. * 出口参数 : 无
  164. * 备    注 :无
  165. *******************************************************************************/
  166. int main(void)
  167. {
  168.     unsigned int i = 0;
  169.         SystemInit();       /* 系统初始化,函数在system_LPC17xx.c文件夹中定义 */
  170.         SysTick_Config(SystemFrequency/1000 - 1);/* 配置节拍定时器中断,每1ms中断一次 */
  171.                                                 
  172.     PortInit();                              /* 端口初始化 */

  173.         UARTInit(0,19200);                             /* 设置串口0波特率 */
  174.         for(i=0;i<7;i++)
  175.         {
  176.                 UARTSend(0,OpenString[i],50);            /* 发送欢迎信息 */
  177.         }
  178. //LedOnMeg[4] = 4+0x30;                    /* 转换成字符 */
  179. //UART0_SendString (KeyMeg);
  180.         while(1)
  181.         {
  182.           KeyScan();   // 按键扫描
  183.           KeyHandle(); // 按键处理
  184.           LedHandle(); // Led处理程序
  185.         }
  186. }




复制代码



程序不是太难,只是简单的实验,各个部分都有详细的注释,这里不在总结,下面是挨靠结果串口调试助手截图:


图 1-2 串口助手截图
好了,先总结到这吧,最近手头上的事有点多,所以写日志的时间就有点紧张,不过,工作归工作,该学习的东东还是要坚持学习的,没有足够的时间,那就见缝插针的学吧。最后再来吼一下懒猫的口号,来鼓励一下自己:每天进步一点点,开心多一点^_^

完整程序源代码工程文件下载地址: SW.rar (188.86 KB, 下载次数: 66)
回复

使用道具 举报

苏荷风 发表于 2015-7-4 16:21 | 显示全部楼层
这个非常有用啊,感谢楼主。
回复

使用道具 举报

骞子 发表于 2015-10-26 21:48 | 显示全部楼层
哈哈 不错不错 学习下
回复

使用道具 举报

菟丝子 发表于 2015-10-28 17:14 | 显示全部楼层
新手真在整这个  
回复

使用道具 举报

m4416202 发表于 2016-2-20 10:08 | 显示全部楼层
多谢楼主,下来看看,多谢多谢
回复

使用道具 举报

马小马 发表于 2016-5-26 21:16 | 显示全部楼层
楼主能不能给我发一份呢?840515756@qq.com
回复

使用道具 举报

w1332433263 发表于 2016-6-22 15:32 | 显示全部楼层
楼主 能不能发给我一份
回复

使用道具 举报

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

本版积分规则

QQ|手机版|小黑屋|单片机论坛 |51hei电子论坛2群 联系QQ:125739409;技术交流QQ群219535678

Powered by 单片机教程网

快速回复 返回顶部 返回列表