打印
[ZLG-ARM]

串口程序的问题

[复制链接]
1851|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sunbean|  楼主 | 2007-10-10 21:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我是新手,想问一个问题,我编写了一个简单的串口程序,是使用中断方式,使用的是ARM LPC2210
程序如下:
int  main(void)
{   
    uint32 ADValue;
    
    run=0;
    InitPWM();
    Init_UART0();
    Init_int();
    Init_ADC();
    
    while(1)
    {
      if(recv_flag==1)
      {

        recv_flag=0;
        ChangePWM(speed);
        Send_UART0(speed);
        if(speed>0&&speed<5)
        {

            run=1;
//            DelayNS(10);
        }
        else if(speed==0)
        {
            run=0;
        }
        
      }
      
      if(run==1)
      {
        ADValue=ADC_Value();

        if(ADValue<=15)
        {
            ChangePWM(0);
            run=0;

            
        }
      } 
      DelayNS(10); 
    
    }

    return(0);
}


void Init_UART0(void)
{
    uint16 Fdiv;
    PINSEL0 |= 0x00000005;            // 设置I/O连接到UART0
    U0LCR=0x83;
    Fdiv=(Fpclk/16)/UART_BPS;
    U0DLM=Fdiv/256;
    U0DLL=Fdiv%256;
    U0LCR=0x03;
    U0IER=0x01;
}

void Send_UART0(uint8 send_data)
{
    U0THR=send_data;
    while((U0LSR&0x40)==0);
}

void Init_int()
{
    IRQEnable();
    VICIntSelect=0x00000000;
    VICVectCntl0=0x20|6;
    VICVectAddr0=(uint32)IRQ_UART0;
    VICIntEnable=1<<6;
    recv_flag=0;
}

void __irq IRQ_UART0(void)
{
    if((U0IIR&0x0f)==0x04)                  //判断是否有中断表示,并且清楚中断表示
    {
        recv_flag=1;
        speed=U0RBR;                        //读取数据
    }

    VICVectAddr=0;
}


如果在中断服务程序中使用if((U0IIR&0x0f)==0x04),好像程序就不会从中断服务程序中跳出,有时候也会跑飞,如果使用if((U0IIR&0x04)==0x04)好像就没有什么问题,想请问各位老师,这是什么问题?谢谢!

相关帖子

沙发
sunbean|  楼主 | 2007-10-11 19:30 | 只看该作者

串口问题

自己顶一下,各位老师,有谁知道吗?

使用特权

评论回复
板凳
liujigan| | 2007-10-11 19:47 | 只看该作者

看一下优先级吧

==比 & 优先级要高,不加括号当然要先计算优先级高的了。

使用特权

评论回复
地板
wj77317| | 2007-10-11 20:19 | 只看该作者

区别一下F和4

if((U0IIR&0x0f)==0x04),
if((U0IIR&0x04)==0x04)
1111 和 0100 其他位影响到结果的。与0X04就是只看那一位,而0X0F看的是4位啊。

使用特权

评论回复
5
zhulijun1| | 2007-10-12 08:26 | 只看该作者

一孔之见

你先读U0IIR再if如
byte data;
data = U0IIR;
这样下面
if((data&0x0f)==0x04){
...
}

if((data&0x04)==0x04){
...
}
结杲一样

使用特权

评论回复
6
yzzhangliy| | 2007-10-12 08:40 | 只看该作者

仅供参考!

void __irq IRQ_Uart0(void)                            //UART0中断服务程序
{
    #if(UART0)
    {
        uint8    byte;
        while(((byte=U0IIR)&0x01)==0)                //当中断标志寄存器U0IIR的b0=0表示还有未处理的中断
        {
            switch(byte&0x0E)
            {
                case 0x02:    //发送中断
//                                if(uart0_txd_count<uart0_txd_len)
                              {
                                  U0THR=0x55;//uart0_txd_point++;            //向发送器保持寄存器写一个字节数据
//                                  uart0_txd_count++;
                              }
//                            else uart0_txd_count=0;
                            break;
                case 0x04:    //接收中断
//                            if(!uart0_rxd_count)uart0_rxd_flag=1;
//                            else uart0_rxd_timer=0;
                              test_byte0=U0RBR;
//                              uart0_rxd_buf[uart0_rxd_count++]=U0RBR;            //读UART0接收数据缓存寄存器
                              uart0_rxd_len=uart0_rxd_count=0;
                              break;
                  case 0x06:    //接收线状态
                              break;
                  case 0x0C:    //接收字符超时
//                              U0IER=U0IER&(~0x01);                            //禁止接收和字符超时中断
                            break;
                default    :
                            break;
            }
        }
        VICVectAddr=0x00;
    }
    #endif
}

使用特权

评论回复
7
zhulijun1| | 2007-10-12 08:50 | 只看该作者

再谈

如发生CTI中断的话,肯定就一直中断,因为你没有处理

使用特权

评论回复
8
yzzhangliy| | 2007-10-12 08:55 | 只看该作者

仅供参考!

void Init_Uart0(void)
{
    #if(UART0)
    {
        uint16    Fdiv0,parity0;
        Fdiv0=parity0=0;
        PINSEL0=PINSEL0|(Uart0_Pin_Set<<Uart0_Pin_Sel);            //设置P0.0和P0.1为TXD0和RXD0
        U0LCR=0x80;                            //线控制寄存器,b7=1允许设置波特率
        Fdiv0=(Fpclk1/16)/Uart0_baud;        //波特率时钟必须是波特率的16倍
        U0DLM=Fdiv0/256;                    //除数锁存MSB寄存器
        U0DLL=Fdiv0%256;                    //除数锁存LSB寄存器,与U0DLM一起存放波特率时钟的VPB时钟16位分频值
        Fdiv0=Uart0_datab-5;                //设置数据位
        if(Uart0_stopb==2)Fdiv0=Fdiv0|0x04;    //判断是否是2个停止位
        parity0=0;
        if(Uart0_parity!=0)                    //如果有校验
        {
            parity0=Uart0_parity-1;
            Fdiv0=Fdiv0|0x08;                //允许校验
        }
        Fdiv0=Fdiv0|(parity0<<4);            //设置奇偶校验
        U0LCR=Fdiv0;
        U0FCR=0x01;                            //FIFO控制寄存器,b0=1使能FIFO,b7b6=00使接收FIFO在收到1个字节的时候就激活中断
        U0IER=0x03;                            //中断允许寄存器,b0=1收中断允许,b1=1发中断允许
        VICVectCntl3=Enable_Uart0|Int_uart0;//向量控制寄存器1,b5=1向量IRQ使能,0x06是UART0中断通道号,UART0的优先级是3
        VICVectAddr3=(uint32)IRQ_Uart0;        //向量地址寄存器,存放UART0中断服务程序入口地址
        VICIntEnable=VICIntEnable|(1<<Int_uart0);//中断允许寄存器,每一位对应一个中断源,0x06允许UART0中断,写入0无效
    }
    #endif
}

使用特权

评论回复
9
sunbean|  楼主 | 2007-10-16 18:41 | 只看该作者

了解了,谢谢

谢谢各位,我自己再试一试

使用特权

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

本版积分规则

1

主题

3

帖子

1

粉丝