打印

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

[复制链接]
4099|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
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 | 只看该作者
好的,我看看。。。

使用特权

评论回复
5
oh_right|  楼主 | 2009-9-18 11:25 | 只看该作者
if(temp==0x76) uart0_index=0x00;//如果接收到0x76的话,uart0_index将归零
我用串口发的固定的测试数据:76 00 39 00 00

使用特权

评论回复
6
oh_right|  楼主 | 2009-9-18 11:27 | 只看该作者
读取接收缓冲时,接收缓冲自动清0,因些不存在丢失数据的问题。

使用特权

评论回复
7
oh_right|  楼主 | 2009-9-18 14:03 | 只看该作者
继续在线等。。。
第一次用ARM做项目。。。。

使用特权

评论回复
8
yangxh2005| | 2009-9-18 15:32 | 只看该作者
U0IER=0x01;  ----------???
检查一下是不是接受中断没有打开!?,如果是产生一次中断,后面的数据再无法触发中断,比较象是没有打开中断!

使用特权

评论回复
9
yangxh2005| | 2009-9-18 15:39 | 只看该作者
还有一个地方需要注意,就是FIFO的使用,一定要搞清楚,使用FIFO时,需要检查相关对应的状态寄存器配置位的状态,不要查错了,否则也会出现这种状况!

使用特权

评论回复
10
oh_right|  楼主 | 2009-9-18 16:07 | 只看该作者
好的。我看看。。。

使用特权

评论回复
11
oh_right|  楼主 | 2009-9-18 16:34 | 只看该作者
现在的情况是:
屏幕掉主程序里的无线手柄接收模块后 就OK。
while(1)
{
    //rf_rcv();//无线接收  
}
到底是什么问题?继续查。。。。。。

使用特权

评论回复
12
yangxh2005| | 2009-9-18 16:51 | 只看该作者
呵呵,不会是操作无线接收模块的驱动时,误操作UART0的参数,如中断?

使用特权

评论回复
13
oh_right|  楼主 | 2009-9-18 17:04 | 只看该作者
无线接收模块的驱动里用到一个变量:Time_counters
这个变量是用定时器中断累加的,但是定时器的中断优先级是小于UART0的优先级的,为什么会影响呢?

使用特权

评论回复
14
mbutterfly| | 2009-9-18 17:17 | 只看该作者
根据各单片机的中断特性,有些中断标志等要手动清零。

使用特权

评论回复
15
oh_right|  楼主 | 2009-9-19 08:13 | 只看该作者
今天继续找问题。。。

使用特权

评论回复
16
oh_right|  楼主 | 2009-9-19 08:31 | 只看该作者
为什么我在主循环中加入一个空函数都不行?
如下:
void receive_rf(void)
{
   ;
}
int main(void)
{
  init_device();
  while(1)
   {
     receive_rf();//空函数
    }
    return 0;
}

加入空函数后,只要中断一来,系统就不知道飞到哪里去了。

使用特权

评论回复
17
oh_right|  楼主 | 2009-9-19 10:11 | 只看该作者
中断一来,系统的UART0中断 UART1中断 外部中断0 其中一个中断产生,系统马上复位。

使用特权

评论回复
18
oh_right|  楼主 | 2009-9-19 21:01 | 只看该作者
很可能是伪中断问题
现在在中断处理程序中用VICIntEnClr = 0xffffffff;禁止中断后系统正常。
谢谢大家的关注!

使用特权

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

本版积分规则

9

主题

28

帖子

0

粉丝