打印
[ZLG-ARM]

LPC2200串口终端调试问题

[复制链接]
2537|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
cdd51408|  楼主 | 2008-10-3 15:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
程序编译通过,且单步执行时,串口能进入中断,且中断响应程序执行正确,但一旦全速执行,中断可进,但中断响应程序中,接收数据发生错误,我用的是串口调试助手模拟上位机给串口发送数据。


#include  "config.h" 
#define UART_BPS   9600;    //定义通信波特率
#define LEDCON    0xf0000000;                             
uint8  rcv_buf[8];

uint8 rcv_new;
/*volatile uint8 rcv_new;*/

void DelayNS(uint32 dly)
{
  uint32  i;
  for(;dly>0;dly--)
    {
    for(i=0;i<5000;i++);
    }
}

/*
uint8  UART0_RcvByte(void)

{  uint8 rcv_data;

while((U0LSR&0x01)==0);   //U0RBR为空的话, 一直等待

rcv_data=U0RBR;   //数据保存在串口0的一位寄存器中
return(rcv_data);
}

void UART0_RcvStr(uint8 *s,uint32 n)    //以n个字节为一字符串,n由main函数中给出
{
 for (;n>0;n--)
 {  *s++=UART0_RcvByte();
    }
 } 
 */
 
 void  UART0_SendByte(uint8 data)
 {
   U0THR=data;
   while((U0LSR&0x40)==0);
 }
  void UART0_SendBuf(uint8  *str)
  { while(1) 
   { if(*str=='\0')
   break;
   UART0_SendByte(*str++);
   }
 }
   void UART0_Init(void)


    uint16 Fdiv;

    U0LCR = 0x83;                        // DLAB = 1,可设置波特率
    Fdiv = (Fpclk / 16) / UART_BPS;        // 设置波特率
    U0DLM = Fdiv / 256;                            
    U0DLL = Fdiv % 256;                        
    U0LCR = 0x03;                                     
}                                             // 初始化串口模式


 void __irq IRQ_UART0 (void)
{
    uint8 i,j,k;
    uint8 temp;                    //取得的数据
    uint8 strlen;               //所需数据长度
    uint8 checksum;
    uint8 h1,h2,h3;              //h1,h2半字节校验,h2放高字节累加和校验,h1放低字节累加和校验
    uint8  check_buf[2];
    uint8 *p;
    uint8  SendStr_1[]="OK!\r\n";
    uint8  SendStr_2[]="wrong!\r\n" ;
    uint8  SendStr_3[]="Resend\r\n";
    IO2CLR=0xf0000000;
    /*IO2DIR=0xf0000000;
    IO2CLR=0xa0000000; */       //测试是否进中断用,实验结果表明可进入中断  2008 9.24
                 
    if ((U0IIR & 0x0F) == 0x04);    
        rcv_new = 1;            // 设置接收到新的数据标志
        /*IO2DIR=0xf0000000;
        IO2CLR=0xa0000000;*/    //再次测试串口是否能进入中断,实验结果可行  2008 9 24
    for (i=0; i<8; i++)
    {
        rcv_buf = U0RBR;        // 读取FIFO的数据,并清除中断
            
    }
        if(rcv_buf[0]==0x24)    // 接收到开始字符$
      { 
         checksum=0;
         for(strlen=0;strlen<6;strlen++)     //半字节校验
         {
          checksum=checksum^rcv_buf[strlen+1];         
          h2=checksum&0x0F;
          h1=((checksum>>4)&0x0F);
     
         }
         h3=(h1<<4)^h2;
         if(h3==rcv_buf[7]) //累加和校验通过
      {
         for(j=2;j<7;j++)                //将数据再次返回上位机,进行再次验对
         UART0_SendByte(rcv_buf[j]);
        
        
         rcv_new=0;                      //清楚接收标志位,等待上位机的回应
         U0FCR=U0FCR|0x07;               //复位Rx FIFO 和Tx FIFO
         while((U0LSR&0x01)==0);           //U0RBR 为空的话,一直等待
         rcv_new=1;
         for(k=0;k<2;k++)
        { temp=U0RBR;
         check_buf[k]=temp; }            //将上位机返回的check值,放入buf中,U0RBR中每次只能放一个字节
         p=check_buf;
           
         if (strcmp(p,"OK")==0)
      {   rcv_new=1;                     //接收到验证码,通过上位机的验证
         UART0_SendBuf(SendStr_1);      //返回确认信号,提醒上位机准备开始记录
         rcv_new=0;                     //清楚接收标志位
         U0FCR=U0FCR|0x07;              //复位Rx FIFO 和Tx FIFO 
         switch(rcv_buf[6])             //根据上位机给出的激励电流值大小                    
          
       {
         case 0x31:                     //电流值为1A
         IO1SET=0x200000;    //p1.21
         IO2SET=0xf0000000;
         IO2CLR=0x10000000;
         break;
         case 0x32:                     //电流值为2A
         IO1SET=0x400000;    //p1.22
         IO2SET=0xf0000000;
         IO2CLR=0x20000000;
         break;
         case 0x33:                     //电流值为3A
         IO1SET=0x600000;    //p1.21 p1.22
         IO2SET=0xf0000000;
         IO2CLR=0x30000000;
         break;
   
         case 0x34:                     //电流值为4A
         IO1SET=0x800000;    //p1.23
         IO2SET=0xf0000000;
         IO2CLR=0x40000000;
         break;
   
        case 0x35:                     //电流值为5A
        IO1SET=0xA00000;   //p1.21 p1.23
        IO2SET=0xf0000000;
        IO2CLR=0x50000000;
        break;
   
        case 0x36:                    //电流值为6A
        IO1SET=0xC00000;   //p1.23 p1.22
        IO2SET=0xf0000000;
        IO2CLR=0x60000000;
        break;
   
        case 0x37:                    //电流值为7A
        IO1SET=0xE00000;    //p1.21 p1.22 p1.23
        IO2SET=0xf0000000;
        IO2CLR=0x70000000;
        break;
   
        case 0x38:                   //电流值为8A
        IO1SET=0x1000000;   //p1.24
        IO2SET=0xf0000000;
        IO2CLR=0x80000000;
        break;
         }
        
       }
         else                      //数据验证错误
         UART0_SendBuf(SendStr_3);
         U0FCR=U0FCR|0x07; 
                      
       }
     
     
         
      else                //累加校验不通过
        // UART0_SendByte(h2);      //将0换为rcv_buf[3],作为实验之用,实验结果表明正确,在半字检验未通过时,返回值正确 2008 9 24
         UART0_SendBuf(SendStr_2);  //调整程序,使得返回值更实际  2008 9 25
         U0FCR=U0FCR|0x07;               //复位Rx FIFO 和Tx FIFO
         
       }
       
     else
         UART0_SendBuf(SendStr_3); 
         U0FCR=U0FCR|0x07;           //复位Rx FIFO 和Tx FIFO                                                
        
    VICVectAddr = 0x00;            // 中断处理结束
  }




int  main(void)
{   
   /* rcv_new=0;*/
    PINSEL0 = 0x00000005;                      // 设置I/O连接到UART0
    IO1DIR=0x1ff0000;        //p1.16-p1.24为输出  I/O
    IO2DIR=0xf0000000;     //p2.28-p2.31为输出 LED
    //IO2DIR=LEDCON;                          // 配置LED控制为输出
   
    UART0_Init();
    U0FCR=0x81;                            //触发点为8字节,且使能对于FIFO的访问
    U0IER=0x01;                            //使能RDA中断
    
                                            
    VICIntSelect = 0x00000000;               // 设置所有通道为IRQ中断
    VICVectCntl0 = 0x26;                    // UART0中断通道分配到IRQ slot 0,即优先级最高
    VICVectAddr0 = (uint32)IRQ_UART0;       // 设置UART0向量地址                                      
    VICIntEnable = 0x00000040;              // 使能串口中断
  
                    
  
   while(1);                                // 等待中断      
   return(0);
 }

相关帖子

沙发
rmbzhang| | 2008-10-4 21:15 | 只看该作者

原因可能是:

1.建议你中断服务函数不要太长,处理可以放在主函数中;
2.你的UART数据就收方式只能接收8的整数倍的数据,如果不是那会出错,UART还会产生超时中断

使用特权

评论回复
板凳
armecos| | 2008-10-5 21:48 | 只看该作者

程序写得太不标准规范了,

按照标准步骤写就不会出现这种问题了。
《第六讲 串口操作》
《第三讲 ecos中断操作》

更多内容,详见:
《培训系列“丛书”》
www.armecos.com
-----------------------------------
More details, see:
《"Series Books" of Training》
www.armecos.com

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

7

帖子

0

粉丝