6803|2

66

帖子

0

TA的资源

纯净的硅(高级)

楼主
 

1343UART例程浅析 [复制链接]

最近一直在研究那个UART的例程,感谢斑竹tiankai001的心得,令我受到不少启发,目前的状态是:例程代码基本看懂,但用起来还不能得心应手,lanyu345的代码我粘到uarttest.c中报了一大堆错,是我没有用好?现把例程代码讲一下(估计大家都已知道了哈)。

UART中共有4个文件:cr_startup_lpc13xx.c、uart.c、uart.h、uarttest.c.主要是后三个。

#define SystemFrequency SystemCoreClock      //定义产生波特率的时钟

volatile uint32_t UARTStatus;                            //定义UART状态变量
volatile uint8_t  UARTTxEmpty = 1;                   //标志缓冲区状态的变量,该变量=1时RBR不为空
volatile uint8_t  UARTBuffer[BUFSIZE];             //接收和发送的数据共用该数组,下文可知,收到数据后存入该数组,马上又从中读出数据发回串口

volatile uint32_t UARTCount = 0;                      //上面数组的元素地址

下面着重讲下串口中断的服务函数

void UART_IRQHandler(void)
{
  uint8_t IIRValue, LSRValue;
  uint8_t Dummy = Dummy;

**********************************************************************************

  IIRValue = LPC_UART->IIR;

  IIRValue >>= 1;   /* skip pending bit in IIR 右移跳过保留位?保留位在4:5啊?*/
  IIRValue &= 0x07;   /* check bit 1~3, interrupt identification */
  if (IIRValue == IIR_RLS)  /* Receive Line Status在uart.h中定义IIR_RLS=0x03 */
  {
    LSRValue = LPC_UART->LSR;
    /* Receive Line Status */
    if (LSRValue & (LSR_OE | LSR_PE | LSR_FE | LSR_RXFE | LSR_BI))  //根据uart.h中的宏定义,LSR_OE | LSR_PE | LSR_FE | LSR_RXFE | LSR_BI=10011110,查询LSR对应位,表明有错误状态激活。
    {
      /* There are errors or break interrupt */
      /* Read LSR will clear the interrupt 读取LSR,中断被清除*/
      UARTStatus = LSRValue;
      Dummy = LPC_UART->RBR; /* Dummy read on RX to clear
        interrupt, then bail out 读取缓冲区,清楚中断*/
      return;
    }

/*这部分用来给串口通信除错*/

*************************************************************
    if (LSRValue & LSR_RDR) /* Receive Data Ready   uart.h中定义RDR=0x01,LSR对应位表明缓冲区包含有效数字 */   
    {
      /* If no error on RLS, normal ready, save into the data buffer. */
      /* Note: read RBR will clear the interrupt */
      UARTBuffer[UARTCount++] = LPC_UART->RBR;         //读取缓冲区变量到数组UARTBuffer,地址变量UARTCount累加1
      if (UARTCount == BUFSIZE)                                        //地址变量UARTCount超出数组预定义长度64时清零。
      {
        UARTCount = 0;  /* buffer overflow */
      } 
    }
  }
  else if (IIRValue == IIR_RDA) /* Receive Data Available    uart.h中定义IIR_RDA)=0x02, IIRValue右移两位再&0x07,查手册IIR处于RDA中断(接收数据可用状态),但反推IIRvalue的值似乎尚有疑问?*/
  {
    /* Receive Data Available */
    UARTBuffer[UARTCount++] = LPC_UART->RBR;
    if (UARTCount == BUFSIZE)
    {
      UARTCount = 0;  /* buffer overflow 读数据同上*/
    }
  }
  else if (IIRValue == IIR_CTI) /* Character timeout indicator   CTI中断表明通讯超时,FCR的7:6位定义通信的最小字节数,当上位机信号不是最小字节数的整数倍时余项字节将触发CTI中断,本例的串口初始化函数void UARTInit(uint32_t baudrate)中已定义最小字节为零,故理论上不会触发CTI */
  {
    /* Character Time-out indicator */
    UARTStatus |= 0x100;  /* Bit 9 as the CTI error */
  }
  else if (IIRValue == IIR_THRE) /* THRE, transmit holding register empty 这部分用来给UARTTxEmpty 赋值,协助发送程序判断fifo是否可用 */
  {
    /* THRE interrupt */
    LSRValue = LPC_UART->LSR;  /* Check status in the LSR to see if
        valid data in U0THR or not */
    if (LSRValue & LSR_THRE)
    {
      UARTTxEmpty = 1;
    }
    else
    {
      UARTTxEmpty = 0;
    }
  }
  return;
}

 

 

 

void UARTSend(uint8_t *BufferPtr, uint32_t Length)
{
 
  while ( Length != 0 )
  {
   /* THRE status, contain valid data */
#if !TX_INTERRUPT
   while ( !(LPC_UART->LSR & LSR_THRE) );
   LPC_UART->THR = *BufferPtr;
#else
   /* Below flag is set inside the interrupt handler when THRE occurs. */
      while ( !(UARTTxEmpty & 0x01) );
   LPC_UART->THR = *BufferPtr;
      UARTTxEmpty = 0; /* not empty in the THR until it shifts out */
#endif
      BufferPtr++;
      Length--;
  }
  return;

 

此帖出自NXP MCU论坛

最新回复

UARTSend可以送自定义的值的啊 但这个uart驱动写得很缩水:第1,没用ringbuff;第2,发送没有buff,在需要高速应用时不合适。 keil的这个例程没花心思,小小BS下  详情 回复 发表于 2010-7-15 10:08
点赞 关注
 

回复
举报

66

帖子

0

TA的资源

纯净的硅(高级)

沙发
 
uart.c中最后的void UARTSend(uint8_t *BufferPtr, uint32_t Length)用来定义发送函数,结合入口函数中的主循环代码  while (1)
  {                                /* Loop forever */
        if ( UARTCount != 0 )
        {
          LPC_UART->IER = IER_THRE | IER_RLS;                        /* Disable RBR */
          UARTSend( (uint8_t *)UARTBuffer, UARTCount );
          UARTCount = 0;
          LPC_UART->IER = IER_THRE | IER_RLS | IER_RBR;        /* Re-enable RBR */
        }
  }
可知主函数发现 UARTCount(串口中断触发UARTCount累加)非零时启动发送函数,发送函数先判断有无接收中断(#if !TX_INTERRUPT),然后通过寄存器LSR和THRE判断fifo是否可用,把UARTBuffer中的数据送出。这里的问题在于TX_INTERRUPT在uart.h中被宏定义为0,但在程序中应该有自己变化的功能啊?否则#if !TX_INTERRUPT后面的两个else就没有用了。
调试中我曾尝试修改UARTSend中的*BufferPtr,和主循环发送程式中的(uint8_t *)UARTBuffer,想让它向上位机发送自定义的其它值,但没有用,无论怎么改1343都只在上位机下传数据时回发一个相同的值,估计是因为执行发送函数时也触发了串口中断。
此帖出自NXP MCU论坛
 
 
 

回复

7

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
UARTSend可以送自定义的值的啊
但这个uart驱动写得很缩水:第1,没用ringbuff;第2,发送没有buff,在需要高速应用时不合适。

keil的这个例程没花心思,小小BS下
此帖出自NXP MCU论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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

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

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

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