4894|7

58

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

AT91SAM7S64 串口中断只能触发一次 [复制链接]

各位大侠,我在用AT91SAM7S64做串口接收中断程序,我只能触发一次中断。我在调试时发现,中断结束后,仍可以返回到主函数调用中断的地方,但是无法再执行中断。
以下是中断初始化,中断处理函数,以及主函数,请各位大虾赐教,小弟不胜感激。
下面是串口程序文件uart.c
#include "..\..\main\main.h"

AT91PS_PIO                pPIOA;        // 并行I/O控制器
AT91PS_DBGU                pDBGU;        // 调试单元
AT91PS_UDP                pUDP;        // USB器件端口(UDP)
AT91PS_USART        pCOM0;        // 通用同步/异步收发器(USART)
AT91PS_USART        pCOM1;        // 通用同步/异步收发器(USART)

void uart0_init(void)
{
        pCOM0 = AT91C_BASE_US0;
        pPIOA = AT91C_BASE_PIOA;
       
        // 1. 分配PIO 为USART 模式(外设A), 并禁止RXD0/TXD0为通用I/O 模式          
        // Define RXD and TXD as peripheral
        // Configure PIO controllers to periph mode
        AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA,                        // PIO controller base address
                                                (USART_RXD0 |USART_TXD0),        // Peripheral A
                                                0 );                                                 // Peripheral B

        // 2. 使能USART0  时钟控制器输出
        AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC,1 << AT91C_ID_US0 ) ;


        // 3. Usart Configure
        AT91F_US_Configure(pCOM0,
                                           Main_Clock>>4,
                                           AT91C_US_ASYNC_MODE,
                                           USART0_Baud,0);

        // 5. 使能USART 接收控制寄存器
        USART0_RxEN();
        USART0_TxEN();

        // 6. Enable USART IT error and RXRDY
        AT91F_US_EnableIt(pCOM0,
                                                AT91C_US_RXRDY);
                                //                |AT91C_US_TXRDY);
       
        // 7. open Usart 0 interrupt
        AT91F_AIC_ConfigureIt (AT91C_BASE_AIC,
                                                        AT91C_ID_US0,
                                                        AT91C_AIC_PRIOR_HIGHEST,
                                                        AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL,
                                                        uart0_irq);
                                          
    AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_US0);

}

void uart0_sendbyte(INT8U dat)
{
        USART0_RxDIS();                                        // 禁止USART 接收控制寄存器
        USART0_TxEN();                                        // 使能USART 发送控制寄存器

        AT91C_BASE_US0->US_THR = dat;
        while(!(AT91C_BASE_US0->US_CSR& AT91C_US_TXEMPTY));
       
        USART0_TxDIS();                                        // 禁止USART 发送控制寄存器
        USART0_RxEN();                                        // 使能USART 接收控制寄存器
}

void uart0_irq(void)  
  {
        INT8U data;
       
        //AT91C_BASE_AIC->AIC_IDCR = 0x1 << AT91C_ID_US0 ;                         关中断
        pCOM0 = AT91C_BASE_US0;
        if(pCOM0->US_CSR&AT91C_US_RXRDY)       // RXRDY
        {
                data = AT91F_US_GetChar(pCOM0);
       
                uart0_sendbyte(data);
               
                /*uart0_sendbyte('r');
        uart0_sendbyte('e');
        uart0_sendbyte('c');
        uart0_sendbyte('e');
        uart0_sendbyte('i');
        uart0_sendbyte('v');
        uart0_sendbyte('e');
                  */
     }
       
        pCOM0->US_CR = AT91C_US_RSTSTA;
        //AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_US0 ;
    *AT91C_AIC_EOICR = 0x00;
        //uart0_sendbyte('r');
       
  }





以下是主函数main.c
#include "main.h"

INT32U j;
void delay_nus(INT32U i)
{
        while(i--);
}



void delay_nms(INT32U i)
{
        INT32U t1;
        INT32U t2;
               
        for(t2=0;t2<=i;t2++)
        {
                for(t1=0;t1<=1000;t1++);
        }
}
void system_init(void)
{
  uart0_init();
  
  }


int main(void)
{
  INT8U data;
  ////dat = 's';
  //INT8U i;

  system_init();
  uart0_sendbyte('s');
  uart0_sendbyte('t');
  uart0_sendbyte('a');
  uart0_sendbyte('r');
  uart0_sendbyte('t');
  while(1)
  {j++;
  }   
}

最新回复

终于做出来了,上面出现的那种情况,原因在于uart0_irq();函数的前面应加中断的标记符__irq,不然处理器就会把它当成一般函数处理,特别感谢上面两位兄台指点迷津,在此敬谢。  详情 回复 发表于 2009-9-26 12:40
点赞 关注

回复
举报

80

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
串口中断的标志位需要手动清零才能接收到下一次中断
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
谢谢,但是你说的中断标志位在那个寄存中啊,是AIC_ICCR中断清除命令寄存器吗,我在uart0_irq()函数
*AT91C_AIC_EOICR = 0x00;语句前加了AT91C_BASE_AIC->AIC_ICCR = 1< 能说的具体一些吗,急!!!
 
 
 

回复

53

帖子

0

TA的资源

一粒金砂(初级)

4
 
串口中断的标志位手动清零的方法是读中断状态寄存器吗,我在中断初始化中加了关闭看门狗的函数
AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS; //关看门狗
在中断子程序uart0_irq();中加了两条语句,读中断状态寄存器
i = *AT91C_PIOA_ISR;   
j = *AT91C_AIC_ISR;
但还是只能触发一次中断,到底怎么做呀,请求高手指点!!!!!!
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

5
 
你的中断处理函数完了以后得再清一下标志位才行。
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

6
 
引用 4 楼 beyondma 的回复:
你的中断处理函数完了以后得再清一下标志位才行。
我刚试过,把
i = *AT91C_PIOA_ISR;  
j = *AT91C_AIC_ISR;
这两句加在*AT91C_AIC_EOICR = 0x00;的前面或后面都不行,还是只能触发一次中断,请多多指教!
 
 
 

回复

62

帖子

0

TA的资源

一粒金砂(初级)

7
 
各位大侠,我在调试的时候发现,并不是因为未清标志位接收不到下一次中断,是一旦进入了串口中断,cpsr的值为0x000000092,即irq disable,处于irq模式,R14_irq中存有正确的返回值,中断程序结束后返回到主程序调用中断处继续执行,但是,cpsr中的值仍为0x00000092,也就是说,虽然程序返回到主函数,但还是处于irq中断模式,不知道是什么原因,恳请各位高手赐教。
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

8
 
终于做出来了,上面出现的那种情况,原因在于uart0_irq();函数的前面应加中断的标记符__irq,不然处理器就会把它当成一般函数处理,特别感谢上面两位兄台指点迷津,在此敬谢。
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表