魔幻使者Jack 发表于 2015-11-26 09:48:48

NXP的LPC11XX系列,串口中断收发使用

最近在用NXP的LPC1111在做一个光感自动无线开关灯的东西,需要用到串口,因为之前公司有人用过,只做了一些简单的修改,注释,使用时发现了一些关于串口的小问题,先附上串口部分代码:
<p>#include "UART.H"
#include <LPC11xx.h>

static u8 g_UART_Sendcount = 0;
u8 UART_New =0;
u8 g_UART_Sendlen = 0;
u8 g_UART_Rcvlen =0;
u8 UART_SendBuf={0};
u8 UART_RcvBuf={0};

UART_SEND()
{
      while(g_UART_Sendlen > 0)         
      {
                LPC_UART->THR = UART_SendBuf;
                g_UART_Sendlen--;
      }
      LPC_UART->IER = 0x01;                              //只开接收中断
      g_UART_Sendcount = 0;         
}


UART_RCV()
{
      u8 unuseful;
      switch (LPC_UART->IIR & 0x0e)                                                                              //判断状态      
      {   
                case 0x04:                           //010,接收数据可用
                        if(g_UART_Rcvlen < UARTRCVBUFMAX)         
                        {
                              UART_RcvBuf = LPC_UART->RBR;
                              g_UART_Rcvlen++;
                              UART_New=1;
                        }
                        else
                        {
                              unuseful = LPC_UART->RBR;
                              unuseful =0;
                              UART_New=unuseful;
                              g_UART_Rcvlen=unuseful;
                        }
                        break;
                case 0x0C:                  //110,接收超时
                        while(LPC_UART->LSR & 0x01)          //还有字符没有读取   
                        {                        
                              if(g_UART_Rcvlen < UARTRCVBUFMAX)
                              {
                                        UART_RcvBuf = LPC_UART->RBR;
                                        g_UART_Rcvlen++;
                                        UART_New=1;
                              }
                              else
                              {
                                        unuseful = LPC_UART->RBR;                              
                                        unuseful =0;
                                        UART_New=unuseful;
                                        g_UART_Rcvlen=unuseful;
                              }
                        }
                        break;      
                default:
                        unuseful =0;
                        UART_New=unuseful;
                        g_UART_Rcvlen=unuseful;
                break;
      }
}


void UART_Init(void)
{      
      u16 temp;
      NVIC_DisableIRQ(UART_IRQn);             //禁能UART      
      LPC_SYSCON->SYSAHBCLKCTRL |= (1ul << 16);    //使能AHB时钟,否则无法配置ICON
LPC_IOCON->PIO1_6 |= 0x01;            //UART RXD
      LPC_IOCON->PIO1_7 |= 0x01;            //UART TXD
      
LPC_SYSCON->SYSAHBCLKCTRL |= (1ul << 12);// 使能UART时钟      
      LPC_SYSCON->UARTCLKDIV   = 0x01;         // UART时钟不分频
      LPC_UART->LCR= 0x83;                              //长度为8,1位停止位,奇校验   
      
      temp = 48000000/16/UART_BPS;   //设置波特率      
      LPC_UART->DLM= temp / 256;
      LPC_UART->DLL= temp % 256;
      
LPC_UART->LCR= 0x03;    //锁定波特率                           
LPC_UART->FCR= 0x87;   // 使能FIFO,8字节触发                  
LPC_UART->IER= 0x03;                //使能收发中断                                                                                                                                                                                                                                 
      LPC_UART->TER= 0x80;                        //发送使能                                                                                 
      NVIC_EnableIRQ(UART_IRQn);    //使能UART中断         
}


void UART_IRQHandler(void)
{
      int tmp = LPC_UART->LSR;
      if((tmp& 0x20) == 0x20)   //判断是不是发送READY中断
      {
                UART_SEND();
      }
      if((tmp& 0x01) == 0x01)         //判断是不是接收中断
      {
                UART_RCV();
      }
}</p>
一开始使用时是这样的:
      len=sizeof(connect);//connect是一个要发送的数组
      for(i=0;i<len;i++)
      {
                UART_SendBuf=connect;
      }
      g_UART_Sendlen=len;
      LPC_UART->IER |= 0x02;                              //开发送中断
发现使用的时候会出现发送不正常,接收到数据,或者先LPC_UART->THR =0xA5随便发一个数据后就正常了,原因嘛,很明显,修改如下搞定:
      len=sizeof(connect);    //connect是一个要发送的数组
      for(i=0;i<len;i++)
      {
                UART_SendBuf=connect;
      }
      g_UART_Sendlen=len;
      LPC_UART->IER = 0x02;                              //开发送中断
      UART_IRQHandler();

gxm771208 发表于 2015-11-26 14:06:31

整体来说,这个利用串口中断收发数据的架构设计的还是不好,可以自己再优化一下!

linux 发表于 2015-11-26 21:06:08

牛X,这里有Linux高手没?

一不小心爱上 发表于 2019-7-8 10:55:49

      2019年6月18日,上海诚实果品新总部正式落户上海虹桥国际商务区,并举行了新总部剪彩仪式。为提升企业文化,上海市静安区书协副主席朱亚东先生应邀出席,并现场挥毫。
      诚实果品所属上海诚实果篮果品有限公司成立于2014年,是国内水果行业“仓储连锁”模式的开创者和引领者。
https://s2.ax1x.com/2019/07/08/ZDTgHg.jpghttp://player.youku.com/embed/XNDI1ODM4Njc4MA==http://player.youku.com/embed/XNDI1ODM4Njc4MA==
朱亚东先生现场挥毫之一http://player.youku.com/embed/XNDI1ODM5MDE5Ng=='http://player.youku.com/embed/XNDI1ODM5MDE5Ng=='
朱亚东先生现场挥毫之二http://player.youku.com/embed/XNDI1ODM5MTA4OA==http://player.youku.com/embed/XNDI1ODM5MTA4OA==
朱亚东先生现场挥毫之三
https://s2.ax1x.com/2019/07/08/ZDTWNj.jpg
https://s2.ax1x.com/2019/07/08/ZDTREQ.jpg
https://s2.ax1x.com/2019/07/08/ZDTcDS.jpg
https://s2.ax1x.com/2019/07/08/ZDT6u8.jpg
https://s2.ax1x.com/2019/07/08/ZDTf4s.jpg
https://s2.ax1x.com/2019/07/08/ZDT4Cn.jpg
页: [1]
查看完整版本: NXP的LPC11XX系列,串口中断收发使用