ForumsJobs

LPC2148 UART1使用中断在数据量达到一定数量后停止发送数据

开始于 rtoribio 1 year ago5条回复最新回复1年前59浏览

大家好, 

我已经使用以下命令配置了LPC2148的UART1

速度(9600 / 8bits / N奇偶校验/ 1bit stop)有中断。 

UART1连接到我可以发送和接收的ESP-01 

信息完美。我出现的问题是收到时 

来自ESP-01的一定数量的数据,微控制器 

由于某种原因停止传输信息,我不明白 

原因是。在下面,我离开配置和我所需要的信息 

当从ESP接收到该帧的6倍时,从微控制器接收 

停止。

数据框:

// ----------------------------------------收到数据帧----- ----------------

+ IPD,4,346:HTTP / 1.1 200 OK

日期:星期六,2020年1月4日13:12:46 GMT

服务器:xxxxx / x.x.xx(xxxxxx)

有所不同:接受编码

内容长度:155

连接方式:关闭

内容类型:text / html;字符集= UTF-8

[{“ count”:“ 6”,“ image”:“ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,

 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,“}]

好的

// ------------------------------------------------ -------------------------------------------


码:

// ----------------------------收到的数据结构---------------- --------------------------

typedef struct {

int in;

int out;

char buffer[400];

} p;

p * ptr2,datos_serial2;


// ---------------------------初始化UART1 ------------------- --------------------------

无效uart1_init(void)// 9600 BAUD pclock 48MHZ
{
     PCONP | = 0x00000010; / * PCRTC = 1 * /
     PINSEL0 | = 0x00050000; / *启用RxD1和TxD1 * /
     U1LCR = 0X83; // 8个数据位,1个停止位,禁用奇偶校验和启用DLAB
     U1DLL = 0x38; // MULVAL = 0x5和DIVADDVAL = 14
     U1DLM=1;
     U1LCR = 0X03; //已清除DLAB
     U1IER = 0x00000001; //启用中断
}

// ---------------------------------发送字符------------- ---

无效SendCharUART1(char str){

   U1THR = str;

    while( (U1LSR &0x40)== 0); / *等到THRE位变为1表示传输完成* /

}

// --------------------------------中断启用-------------- ----------------------------------------

无效UART1_Interrupt_EN(void)

{

    // VICIntSelect = 0x00000000; 

     VICVectAddr7 =(无符号)UART1Handler; //向量7

     VICVectCntl7 = 0x00000020 | 7; //选择UART1中断作为IRQ,即向量7

    VICIntEnable |=(1UL<<7);//interrupt ena.

}


// ------------------------------------------中断IRQ ---- ----------------------------------------

void UART1Handler(void)__irq

{

// / / *串行接收中断。 * /

char recieved;

if ((U1IIR & 0x0E) == 0x04) {

     recieved=U1RBR;

     ptr2 = &datos_serial2;

     if(ptr2->in>=399)

          ptr2->in=0;

     ptr2->buffer[ptr2->in++]=recieved;

  }

   VICVectAddr = 0x00;

}

// - - - - - - - - - - - - - - - - - - - - -主要 - - - -------------

int main()

{

uart1_init();

UART1_Interrupt_EN();


而(1){

  sendata_esp01(); //发送数据到ESP01的过程

  delay()

   // -----------------处理接收到的数据的算法------------------ //

   Process_Datareceived();

  // ------------------------------------------------ -------------------------------------- //

  }

}



[-]
回覆者 科奇尼亚2020年1月4日

一个可能的问题是,在您的ISR中,您具有以下优势:

ISR()
{
    if ( ( IRQ_source_reg & 0x0e ) == 0x04 ) { 
        process_receive_char; 
    }
    clear_the_VIC;
}

问题是,当您启用RX IRQ时,您还启用了代码为0x0c的RX超时IRQ(请参见《用户手册》中有关U1IER reg的RBR位的说明)。因此,如果有IRQ进入,您将永远不会清除它,因此只会进入ISR-一旦在VIC上清除IRQ,您就会得到另一个,因为UART仍会声明其请求线。

我并不是说那是问题所在,但是如果您错过了一个角色,那就有可能了。您的ISR仅从FIFO中清除一个字符,只要您从不禁用超过1个字符的IRQ,就可以了,但是如果这样做,则可能会遇到问题,因此值得一看。也许是这样的:

ISR()
{
int temp; 

    temp = IRQ_source_reg & 0x0e;               
    if ( temp == 0x04 || temp == 0x0c ) {
        while ( line_status_reg & 0x01 ) {
            store_receive_char_in_buffer;
        }
    }
    clear_the_VIC;
}                     

实际上,由于您没有启用任何其他中断,因此您甚至不需要检查IIR包含的内容,如果读取了它就足够了,然后转到线路状态reg循环:

ISR()
{
    (void) IQR_source_reg;
    while ( line_status_reg & 0x01 ) {
        ...        
[-]
回覆者 rtoribio2020年1月4日

您提出的内容是正确的,我进行了您建议的更改,但  

问题继续。我必须强调,在连续收到6次后 

数据帧,微控制器专门停止6。

void UART1Handler(void)__irq{
int temp; char recieved;    
temp = U1IIR & 0x0e;                   
if ( temp == 0x04 || temp == 0x0c ) {        
    while ( U1LSR & 0x01 ) {
        recieved=U1RBR;
        ptr2 = &datos_serial2;
        if(ptr2->in>=399)
            ptr2->in=0;
        ptr2->buffer[ptr2->in++]=recieved;            
    }    
}    
VICVectAddr = 0x00;
}
无效SendCharUART1(char str){
    U1THR = str;
    while( (U1LSR &0x40)== 0); / *等到THRE位变为1表示传输完成* /
}


问候,

[-]
回覆者 科奇尼亚2020年1月4日

您是否有一个或多个备用端口引脚可以放置示波器?

您可以在每次进入和离开ISR以及每次进入离开发送例程时切换它们。就像,在进入时将其设置为1,在离开时将其设置为0。然后,当代码停止时,您可以查看它是否被这些例程卡住了。

UART处理程序可能没有问题,但是处理请求并创建响应的其余代码在收到6帧后会卡在某处。

这种切换端口的业务非常痛苦,但是我发现当您没有其他调试方法时,它可以帮助解决非常丑陋的软件错误。此外,它不需要额外的RAM,对时序的影响最小,并且通常来说,它是您所拥有的侵入性最低的调试工具。

[-]
回覆者 rtoribio2020年1月5日

非常感谢,您正确的问题不在发送或接收的UART功能中。我在一个函数中溢出数组。

[-]
回覆者 mr_bandit2020年1月6日

查找此类问题的好方法是编写最简单的程序(在这种情况下),只需读取值并打印出来即可。基本上,隔离输入并确保其有效。

一个核心概念是简化,简化,简化。获得您可以做的最低程序。