打印
[LPC]

ARM7 LPC2132串口中断问题

[复制链接]
2883|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
庄吉|  楼主 | 2013-11-6 21:00 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
周立功的例程,设置出发点为8个字节,串口发送8个字节时,一切都会正常,发送9个字节时,测试了两种情况,第一种是能连续接受,但都不正确,如果再次发送8个字节又可以正常,第二种是发送3次都乱码,3次后,就接收不了了,再次发送8个字节也一样接收不了。令我不解的是:两个程序的区别,我好无解,求大神。程序如下:
#include <LPC213x.H>typedef unsigned int uint32;
typedef unsigned short int uint16;
typedef unsigned char uint8;
uint8 rcv_buf[8];
uint8 rcv_new;
#define Fpclk  11059200
void DelayNS(uint32 dly)        //延时函数
{
        uint32 i;
        for(;dly>0;dly--)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
        for(i=0;i<50000;i++);
}
void PLL_Init()                                 //PLL初始化
{
  PLLCON = 1;          //使能PLL
  PLLCFG=0x63;         //P=2,M=4                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
  PLLFEED = 0xaa;
  PLLFEED = 0x55;                        //更改生效
  while((PLLSTAT & (1 << 10)) == 0);  //等待PLL锁定
  PLLCON = 3;
  PLLFEED= 0xaa;
  PLLFEED = 0x55;       
}
typedef struct  UartMode         //定义串口模式设置数据结构
{                                                                                                                                                                                                                 
        uint8 datab;
        uint8 stopb;
        uint8 parity;
}
UARTMODE;/////////**************重点*********************/
void __irq IRQ_UART1(void)                   //接受中断
{               
        uint8 i;                 
        if(0x04==(U1IIR&0x0F))        //接受数据可用
        {
        rcv_new=1;                   //接受标志位。
        }                         
        for(i=0;i<8;i++)
        {
                rcv_buf=U1RBR;        //读取数据
        }                                                                                                              
        VICVectAddr=0x00;                //清中断
}  /////////**************重点**********************/
void  SendByte(uint8 data)
{
        U1THR=data;
        while((U1LSR&0x40)==0);
}
void ISendBuf(void)
{
        uint8 i;
        for(i=0;i<8;i++)
        SendByte(rcv_buf);       
}
uint8 UART1_Ini(uint32 baud,UARTMODE set)
{
        uint32 bak;                                                                           //参数过滤
        if((0==baud)||(baud>115200)) return(0);
        if((set.datab<5)||(set.datab>8)) return(0);
        if((0==set.stopb)||(set.stopb>2)) return(0);
        if(set.parity>4) return(0);
        U1LCR=0x80;                                                                           //设置串口波特率
        bak=(Fpclk>>4)/baud;
        U1DLM=bak>>8;
        U1DLL=bak&0xFF;       
        bak=set.datab-5;                                                                 //设置串口模式
        if(2==set.stopb)
        bak|=0x04;
        if(0!=set.parity)
        {set.parity=set.parity-1;bak|=0x08;}
        bak|=set.parity<<4;
        U1LCR=bak;
        return(1);
}
void IRQEnable(void)
{
    int temp;
    __asm
        {
              MRS temp,CPSR
              BIC temp,temp,#0x80
              MSR CPSR_c,temp
        }
}  
int main(void)
{
        UARTMODE uart1_set;
        PINSEL0=0x00050000;
        rcv_new=0;
        uart1_set.datab=8;
        uart1_set.stopb=1;
        uart1_set.parity=0;
        UART1_Ini(115200,uart1_set);
        PLL_Init();
        U1FCR=0x81;                                                         //设置触发点为8个字节
        U1IER=0x01;
    IRQEnable();
        VICIntSelect=0x00000000;                                //设置中断允许
        VICVectCntl0=0x27;
        VICVectAddr0=(uint32)IRQ_UART1;
        VICIntEnable=0x00000080;
        while(1)
        {
                if(rcv_new==1)
                {
                        ISendBuf();
                        rcv_new=0;                                       
                }
        }       
         return(0);
}





相关帖子

沙发
你好陌生人| | 2013-11-7 08:28 | 只看该作者
这个例程我用到过,干嘛非要八个字节触发啊,自己改一下,把接收的收据全部存在一个数组里面 ,这样你你不管来多少个字符,都可以全部正确的发送回来

使用特权

评论回复
板凳
庄吉|  楼主 | 2013-11-7 09:46 | 只看该作者
你好陌生人 发表于 2013-11-7 08:28
这个例程我用到过,干嘛非要八个字节触发啊,自己改一下,把接收的收据全部存在一个数组里面 ,这样你你不 ...

void __irq IRQ_UART1(void)                   //接受中断
{               
        uint8 i;                 
        if(0x04==(U1IIR&0x0F))        //接受数据可用
        {
        rcv_new=1;                   //接受标志位。
        }                        
        for(i=0;i<8;i++)
        {
                rcv_buf=U1RBR;        //读取数据
        }                                                                                                               
        VICVectAddr=0x00;                //清中断
}  /////////**************重点**********************/




void __irq IRQ_UART1(void)                   //接受中断
{               
        uint8 i;                 
        if(0x04==(U1IIR&0x0F))        //接受数据可用
        {
        rcv_new=1;                   //接受标志位。                     
        for(i=0;i<8;i++)
        {
                rcv_buf=U1RBR;        //读取数据
        }
        }                                                                                                                 
        VICVectAddr=0x00;                //清中断
}  /////////**************重点**********************/


令我不解的是,我看不出区别在哪里。搞技术的都喜欢钻牛角尖,你懂的:lol

使用特权

评论回复
地板
庄吉|  楼主 | 2013-11-7 15:09 | 只看该作者
你好陌生人 发表于 2013-11-7 08:28
这个例程我用到过,干嘛非要八个字节触发啊,自己改一下,把接收的收据全部存在一个数组里面 ,这样你你不 ...

如果改成发送什么就返回什么的话,那触发点设为多少个字节啊

使用特权

评论回复
5
庄吉|  楼主 | 2013-11-7 15:37 | 只看该作者
你好陌生人 发表于 2013-11-7 08:28
这个例程我用到过,干嘛非要八个字节触发啊,自己改一下,把接收的收据全部存在一个数组里面 ,这样你你不 ...

按照你的意思我把程序改了,发送什么就回复什么。可以也还有只有达到设置好的触发点8个字节才会正常。其他有时候乱码  程序如下:
#include <LPC213x.H>
typedef unsigned int uint32;
typedef unsigned short int uint16;
typedef unsigned char uint8;
uint8 rcv_buf[32];
uint8 rcv_new,recevie_count;
#define Fpclk  11059200
void DelayNS(uint32 dly)        //延时函数
{
        uint32 i;
        for(;dly>0;dly--)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
        for(i=0;i<50000;i++);
}
void PLL_Init()                                 //PLL初始化
{
  PLLCON = 1;          //使能PLL
  PLLCFG=0x63;         //P=2,M=4                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
  PLLFEED = 0xaa;
  PLLFEED = 0x55;                        //更改生效
  while((PLLSTAT & (1 << 10)) == 0);  //等待PLL锁定
  PLLCON = 3;
  PLLFEED= 0xaa;
  PLLFEED = 0x55;       
}
typedef struct  UartMode         //定义串口模式设置数据结构
{                                                                                                                                                                                                                 
        uint8 datab;
        uint8 stopb;
        uint8 parity;
}
UARTMODE;




void __irq IRQ_UART1(void)                   //接受中断
{                                 
        if(0x04==(U1IIR&0x0F))        //接受数据可用
        {
        rcv_new=1;                   //接受标志位。
        }                         
        while(0x01==(U1LSR&0x01))
        {
                rcv_buf[recevie_count]=U1RBR;        //读取数据
                recevie_count++;
        }                                                                                                              
        VICVectAddr=0x00;                //清中断
}

void  SendByte(uint8 data)
{
        U1THR=data;
        while((U1LSR&0x40)==0);
}

void ISendBuf(void)
{
        uint8 i;
        for(i=0;i<recevie_count;i++)
        {
        SendByte(rcv_buf);       
        }
}

uint8 UART1_Ini(uint32 baud,UARTMODE set)
{
        uint32 bak;                                                                           //参数过滤
        if((0==baud)||(baud>115200)) return(0);
        if((set.datab<5)||(set.datab>8)) return(0);
        if((0==set.stopb)||(set.stopb>2)) return(0);
        if(set.parity>4) return(0);

        U1LCR=0x80;                                                                           //设置串口波特率
        bak=(Fpclk>>4)/baud;
        U1DLM=bak>>8;
        U1DLL=bak&0xFF;
       
        bak=set.datab-5;                                                                 //设置串口模式
        if(2==set.stopb)
        bak|=0x04;
        if(0!=set.parity)
        {set.parity=set.parity-1;bak|=0x08;}
        bak|=set.parity<<4;
        U1LCR=bak;
        return(1);

}
void IRQEnable(void)

{
    int temp;
    __asm
        {
              MRS temp,CPSR
              BIC temp,temp,#0x80
              MSR CPSR_c,temp
        }
}  

int main(void)
{
        UARTMODE uart1_set;
        PINSEL0=0x00050000;
        rcv_new=0;
        recevie_count=0;
        uart1_set.datab=8;
        uart1_set.stopb=1;
        uart1_set.parity=0;
        UART1_Ini(115200,uart1_set);
        PLL_Init();
        U1FCR=0x81;                                                         //设置触发点为8个字节
        U1IER=0x01;
    IRQEnable();
        VICIntSelect=0x00000000;                                //设置中断允许
        VICVectCntl0=0x27;
        VICVectAddr0=(uint32)IRQ_UART1;

        VICIntEnable=0x00000080;
        while(1)
        {
                if(rcv_new==1)
                {
                        ISendBuf();
                        rcv_new=0;
                        recevie_count=0;                                       
                }
        }
       
         return(0);
}

使用特权

评论回复
6
你好陌生人| | 2013-11-13 22:00 | 只看该作者
庄吉 发表于 2013-11-7 15:37
按照你的意思我把程序改了,发送什么就回复什么。可以也还有只有达到设置好的触发点8个字节才会正常。其 ...

U1FCR=0x81;
把这句话删除掉,这句话是八个字节触发的

使用特权

评论回复
7
你好陌生人| | 2013-11-13 22:02 | 只看该作者
庄吉 发表于 2013-11-7 15:37
按照你的意思我把程序改了,发送什么就回复什么。可以也还有只有达到设置好的触发点8个字节才会正常。其 ...

你看一下 U1FCR这个寄存器的定义,里面有设置几个字节触发的,改一下就好了

使用特权

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

本版积分规则

4

主题

25

帖子

0

粉丝