怎么中断一次就不再中断了?(LPC2132)

[复制链接]
 楼主| oh_right 发表于 2009-9-18 11:02 | 显示全部楼层 |阅读模式
谢谢你关注本贴。
我想问一下,我现在用LPC2131做项目。用到串口0中断,
但我不明白的是,串口0怎么中断一次就不再发生第二次中断了呢?
代码如下:
初始化:
/*
*********************************************************************************************************
** 函数名称 :uart_init()
** 函数功能 :串口初始化,设置为8位数据位,1位停止位,无奇偶校验
** 入口参数 :无
** 出口参数 :无
*********************************************************************************************************
*/
void uart_init (void)
{
uint16 Fdiv;

//串口0波特率设为38400
U0LCR = 0x83;      // DLAB=1,允许设置波特率
Fdiv  = (Fpclk / 16) / UART0_BPS; // 设置波特率
U0DLM = Fdiv / 256;
U0DLL = Fdiv % 256;
U0LCR = 0x03;      //3表示发送字符长度为8

//串口1设为115200
U1LCR = 0x83;      /* DLAB=1,允许设置波特率 */
Fdiv  = (Fpclk / 16) / UART1_BPS; /* 设置波特率    */
U1DLM = Fdiv / 256;
U1DLL = Fdiv % 256;
U1LCR = 0x03;
//设置管脚连接
PINSEL0 |= 0x00050005;    // 设置I/O连接到UART0和UART1

//设置UART0中断
    U0FCR=0x01 ;                        //使能FIFO,触发点为1字节        
    U0IER=0x01;                         //fifo int  mode int     
    VICIntSelect  = 0x00000000;         // 设置所有通道为IRQ中断   
    VICVectCntl1  = 0x26;               // UART0中断通道分配到IRQ slot 1,即优先级次最高   
    VICVectAddr1  = (uint32)IRQ_UART0;  // 设置UART0向量地址  
VICIntEnable |= 1 << 0x06;      // 使能uart0中断,写入0是无效的   
   
//设置UART1中断
    U1FCR=0x01 ;                        //使能FIFO,触发点为1字节        
    U1IER=0x01;                         //fifo int  mode int     
    VICIntSelect  = 0x00000000;         // 设置所有通道为IRQ中断   
    VICVectCntl3  = 0x27;               // UART1中断通道分配到IRQ slot 3,即优先级次最高   
    VICVectAddr3  = (uint32)IRQ_UART1;  // 设置UART0向量地址  
                           
VICIntEnable |= 1 << 0x07;      // 使能uart1中断,写入0是无效的
}
中断程序:
/*
*********************************************************************************************************
** 函数名称 :uart_init()
** 函数功能 :串口0的中断函数
** 入口参数 :无
** 出口参数 :无
*********************************************************************************************************
*/
uint8 uart0_buf[5],uart0_index=0x00;
void __irq IRQ_UART0(void)
{
uint8 temp;

    IRQDisable();               //先关闭中断,防止自身嵌套和其它中断影响
    if((U0IIR & 0x0F) == 0x04)
{
    temp = U0RBR;            // 读取FIFO的数据,并清除中断
    if(temp==0x76) uart0_index=0x00;
    if(uart0_index<5)uart0_buf[uart0_index++] = temp;   
       if((uart0_buf[0]==0x76)&&(uart0_buf[1]==0x00)&&(uart0_buf[2]==0x39)&&(uart0_buf[3]==0x00)&&(uart0_buf[4]==0x00))
       {
          handle_success();
          reset_uart0();
       }
}
VICVectAddr = 0x00;   // 向量中断向量地址寄存器  
IRQEnable();                //重新开启中断
}
/*
*********************************************************************************************************
** 函数名称 :reset_uart0()
** 函数功能 :复位串口0相关参数
** 入口参数 :无
** 出口参数 :无
*********************************************************************************************************
*/
void reset_uart0(void)
{
    uint8 i;
    for(i=0x00;i<5;i++) uart0_buf[i++] = 0xff;
    uart0_index=0x00;
}
各位能否指点一下?谢谢!
 楼主| oh_right 发表于 2009-9-18 11:09 | 显示全部楼层
在线等。。。
谢谢
xinzha 发表于 2009-9-18 11:20 | 显示全部楼层
if((uart0_buf[0]==0x76)&&(uart0_buf[1]==0x00)&&(uart0_buf[2]==0x39)&&(uart0_buf[3]==0x00)&&(uart0_buf[4]==0x00))

如果你前五个数据不是你想要的序列,那么uart0_index将永远不能归零,而且不会再去读新的数据,程序逻辑有问题,并且要检查你的芯片是否为读取自清中断,如果不是,要手动清中断。
 楼主| oh_right 发表于 2009-9-18 11:22 | 显示全部楼层
好的,我看看。。。
 楼主| oh_right 发表于 2009-9-18 11:25 | 显示全部楼层
if(temp==0x76) uart0_index=0x00;//如果接收到0x76的话,uart0_index将归零
我用串口发的固定的测试数据:76 00 39 00 00
 楼主| oh_right 发表于 2009-9-18 11:27 | 显示全部楼层
读取接收缓冲时,接收缓冲自动清0,因些不存在丢失数据的问题。
 楼主| oh_right 发表于 2009-9-18 14:03 | 显示全部楼层
继续在线等。。。
第一次用ARM做项目。。。。
yangxh2005 发表于 2009-9-18 15:32 | 显示全部楼层
U0IER=0x01;  ----------???
检查一下是不是接受中断没有打开!?,如果是产生一次中断,后面的数据再无法触发中断,比较象是没有打开中断!
yangxh2005 发表于 2009-9-18 15:39 | 显示全部楼层
还有一个地方需要注意,就是FIFO的使用,一定要搞清楚,使用FIFO时,需要检查相关对应的状态寄存器配置位的状态,不要查错了,否则也会出现这种状况!
 楼主| oh_right 发表于 2009-9-18 16:07 | 显示全部楼层
好的。我看看。。。
 楼主| oh_right 发表于 2009-9-18 16:34 | 显示全部楼层
现在的情况是:
屏幕掉主程序里的无线手柄接收模块后 就OK。
while(1)
{
    //rf_rcv();//无线接收  
}
到底是什么问题?继续查。。。。。。
yangxh2005 发表于 2009-9-18 16:51 | 显示全部楼层
呵呵,不会是操作无线接收模块的驱动时,误操作UART0的参数,如中断?
 楼主| oh_right 发表于 2009-9-18 17:04 | 显示全部楼层
无线接收模块的驱动里用到一个变量:Time_counters
这个变量是用定时器中断累加的,但是定时器的中断优先级是小于UART0的优先级的,为什么会影响呢?
mbutterfly 发表于 2009-9-18 17:17 | 显示全部楼层
根据各单片机的中断特性,有些中断标志等要手动清零。
 楼主| oh_right 发表于 2009-9-19 08:13 | 显示全部楼层
今天继续找问题。。。
 楼主| oh_right 发表于 2009-9-19 08:31 | 显示全部楼层
为什么我在主循环中加入一个空函数都不行?
如下:
void receive_rf(void)
{
   ;
}
int main(void)
{
  init_device();
  while(1)
   {
     receive_rf();//空函数
    }
    return 0;
}

加入空函数后,只要中断一来,系统就不知道飞到哪里去了。
 楼主| oh_right 发表于 2009-9-19 10:11 | 显示全部楼层
中断一来,系统的UART0中断 UART1中断 外部中断0 其中一个中断产生,系统马上复位。
 楼主| oh_right 发表于 2009-9-19 21:01 | 显示全部楼层
很可能是伪中断问题
现在在中断处理程序中用VICIntEnClr = 0xffffffff;禁止中断后系统正常。
谢谢大家的关注!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

9

主题

28

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部