打印
[Cortex-M0技术交流]

M0 GPIO多次中断问题

[复制链接]
2582|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
shudaixiongabc|  楼主 | 2012-5-15 17:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近在用NUC140的板子模拟接收数据采样的程序。我用GPA1结合timer0置低置高发送0,1的波形,GPA5结合timer1对GPA1发送的波形进行采样。为使采样不会有比特累计误差,我每次采样50次就用GPA5中断捕获一次数据沿,然后再进行下一个50次的采样。我程序的做法是在GPA5中断里打开timer1,然后关闭GPA5中断。timer1中断采样50次之后在timer1里打开GPA中断。现在的问题是,在timer1里一使能GPA中断NVIC_EnableIRQ(GPAB_IRQn);后GPA5还没有捕获到数据沿就进入中断了?(我另外用了GPA2引脚和示波器来检测采样情况)难道GPIO中断只能进行一次?不能每隔一段时间捕获一次数据沿吗?有人说是因为M0的中断状态不会自己丢失,
TRM文档5.2.5讲
When an interrupt is disabled, interrupt assertion will cause the interrupt to become
Pending,所以pending状态可以通过ICPR手动清除掉,可是我清了还是不行,一使能GPAB中断,沿都还没来,就进入GPAB中断函数了。 这个问题困扰了我好多天了,求大神赐教啊!谢谢!
#include <stdio.h>
#include "NUC1xx.h"
#include "DrvGPIO.h"
#include "DrvUART.h"
#include "DrvSYS.h"
int8_t data[800]={1,1,0,0, 0,1,1,0, 0,0,0,0, 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1, 0,0,0,1,1,0,1,1,0,0,0,1,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,  0,1,0,0, 0,1,1,0, 0,0,0,0, 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1, 0,0,0,1,1,0,1,1,0,0,0,1,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,  0,1,0,0, 0,1,1,0, 0,0,0,0, 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1, 0,0,0,1,1,0,1,1,0,0,0,1,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,  0,1,0,0, 0,1,1,0, 0,0,0,0, 0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1, 0,0,0,1,1,0,1,1,0,0,0,1,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,0,1,0,1,1,0,0,1,0,1,1,0,0,1,0,1,1,0,0,1,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0};
unsigned int  num=0;
unsigned int zz=0,jj=0,kk=1;
unsigned char a[1000];
GPIO_T * tGPIO;
volatile uint32_t u32Reg;
unsigned int  iBit=5;
void GPABCallback(uint32_t u32GpaStatus, uint32_t u32GpbStatus)
{
  tGPIO->DOUT |= (1 <<2);
    a[zz]=(inpw(u32Reg)>>5) & 0x1;
  
    tGPIO->DOUT &= ~(1 <<2);
    /* Step 5. Enable Timer1 module */
TIMER1->TCSR.CEN = 1;  //Enable Timer1
  TIMER1->TCSR.TDR_EN=1;  // Enable TDR function
     NVIC_DisableIRQ(GPAB_IRQn);
   NVIC->ICPR[0] = (1 << ((uint32_t)(GPAB_IRQn) & 0x1F));      
     jj++;
  zz=jj*50;
}
void Delay1ms(int delay1msdata)
{
int i,j,k;
for(i=0;i<delay1msdata;i++)
  for(j=0;j<75;j++)
   for(k=0;k<10;k++)
    ;
}
void TMR0_IRQHandler(void) // Timer0 interrupt subroutine
{
  TIMER0->TISR.TIF =1;
if(data[num])  
tGPIO->DOUT |= (1 <<1);
else
tGPIO->DOUT &= ~(1 <<1);
  num++;
  if(num==801)
   {
   NVIC_DisableIRQ(TMR0_IRQn); //Disable Timer0 interrupt
   outpw(&TIMER0->TCSR ,0 );
   tGPIO->DOUT &= ~(1 <<1);
  }
}
void TMR1_IRQHandler(void) // Timer1 interrupt subroutine
{
uint32_t u32GpaStatus, u32GpbStatus;
  TIMER1->TISR.TIF =1;
tGPIO->DOUT |= (1 <<2);
tGPIO->DOUT &= ~(1 <<2);
a[kk]=(inpw(u32Reg)>>5) & 0x1;
  kk++;
   
if((kk%50)==0)
  
  {
   NVIC->ICPR[0] = (1 << ((uint32_t)(GPAB_IRQn) & 0x1F));      
   NVIC_EnableIRQ(GPAB_IRQn);
     TIMER1->TCSR.CEN = 0;
  TIMER1->TCSR.CRST = 1;  //Reset up counter
  kk++;
  
  }
  
}
/*---------------------------------------------------------------------------------------------------------*/
/* MAIN function                                                                                          */
/*---------------------------------------------------------------------------------------------------------*/   
int main (void)
{

STR_UART_T param;
UNLOCKREG();,
                                    
    SYSCLK->PWRCON.XTL12M_EN = 1;   
    DrvSYS_Delay(10000);
DrvGPIO_InitFunction(FUNC_UART0);//Initialize the GPIO pins as the multi-function pins,GPB_MFP0-1-2-3置位 GPIO使能UART功能


    param.u32BaudRate        = 115200;
    param.u8cDataBits        = DRVUART_DATABITS_8;//8位数据位
    param.u8cStopBits        = DRVUART_STOPBITS_1;//1位停止位
    param.u8cParity          = DRVUART_PARITY_NONE; //校验位
    param.u8cRxTriggerLevel  = DRVUART_FIFO_1BYTES;// FIFO存储深度 1 字节
    param.u8TimeOut          = 0; //   FIFO超时设定
    DrvUART_Open(UART_PORT0, &param);  // The function is used to initialize UART. It consists of baud-rate, parity, data-bits,     */
              // stop-bits, rx-trigger-level and timeout interval settings.
   
printf("\n\n");
    printf("+-------------------------------------------------------------------+\n");
    printf("|                      GPIO Driver Sample Code                      |\n");
    printf("+-------------------------------------------------------------------+\n");
/*---------------------------------------------------------------------------------------------------------*/
/* GPIO Interrupt Test                                                                                     */
/*---------------------------------------------------------------------------------------------------------*/   
   
    printf("\n  GPA1 send pkt,GPA5 receive pkt. are used to test key interrupt\n  and control LED (GPA3)\n");   
DrvGPIO_Open(GPA,1, IO_OUTPUT);
DrvGPIO_Open(GPA,2, IO_OUTPUT);
DrvGPIO_Open(GPA,5, IO_INPUT);
DrvGPIO_ClrBit(GPA,1);
DrvGPIO_ClrBit(GPA,2);
DrvGPIO_ClrBit(GPA,5);
   tGPIO = (GPIO_T *)(uint32_t)GPIOA ;  
   u32Reg = (uint32_t)&GPIOA->PIN;
   
    DrvGPIO_SetIntCallback(GPABCallback, GPCDECallback);
    DrvGPIO_EnableInt(GPA, 5, IO_BOTH_EDGE, MODE_EDGE); //使能指定端口的指定比特的中断功能

    DrvGPIO_SetDebounceTime(3, DBCLKSRC_HCLK); //Set the interrupt debounce sampling timing and the debounce counter clock source.   
    DrvGPIO_EnableDebounce(GPA, 5);  //使能特定的GPIO输入引脚的去抖动函数
  
       /* Waiting for interrupts */
    printf("  GPA1  begins to send data ");
Delay1ms(25000);
/*---------------------------------------------------------------------------------------------------------*/
//初始化Timer1接收
/*---------------------------------------------------------------------------------------------------------*/
  NVIC_DisableIRQ(TMR1_IRQn); //Disable Timer1 interrupt
outpw(&TIMER1->TCSR ,0 ); //Disable Timer1                              
/* Step 1. Enable and Select Timer clock source */         
SYSCLK->CLKSEL1.TMR1_S = 4; //Select 22Mhz for Timer0 clock source
    SYSCLK->APBCLK.TMR1_EN =1; //Enable Timer0 clock source
/* Step 2. Select Operation mode */
TIMER1->TCSR.MODE=1;  //Select periodic mode for operation mode
/* Step 3. Select Time out period = (Period of timer clock input) * (8-bit Prescale + 1) * (24-bit TCMP)*/
  // Set Prescale [0~255]
TIMER1->TCSR.PRESCALE=0;
  // Set TCMPR [0~16777215]
TIMER1->TCMPR = 10000;       // (1/22118400)*(0+1)*(2765)= 125.01usec or 7999.42Hz
/* Step 4. Enable interrupt */
TIMER1->TCSR.IE = 1;
TIMER1->TISR.TIF = 1;  //Write 1 to clear for safty  
NVIC_EnableIRQ(TMR1_IRQn); //Enable Timer0 Interrupt

  TIMER1->TCSR.CRST = 1;  //Reset up counter
//TIMER1->TCSR.CEN = 1;  //Enable Timer1
// TIMER1->TCSR.TDR_EN=1;  // Enable TDR function
/*---------------------------------------------------------------------------------------------------------*/
//初始化Timer0发送
/*---------------------------------------------------------------------------------------------------------*/
  NVIC_DisableIRQ(TMR0_IRQn); //Disable Timer0 interrupt
outpw(&TIMER0->TCSR ,0 ); //Disable Timer0                              
/* Step 1. Enable and Select Timer clock source */         
SYSCLK->CLKSEL1.TMR0_S = 4; //Select 22Mhz for Timer0 clock source
    SYSCLK->APBCLK.TMR0_EN =1; //Enable Timer0 clock source
/* Step 2. Select Operation mode */
TIMER0->TCSR.MODE=1;  //Select periodic mode for operation mode
/* Step 3. Select Time out period = (Period of timer clock input) * (8-bit Prescale + 1) * (24-bit TCMP)*/
//TIMER0->TCSR.PRESCALE=0; // Set Prescale [0~255]
TIMER0->TCSR.PRESCALE=0;
//TIMER0->TCMPR = 2765;  // Set TCMPR [0~16777215]
TIMER0->TCMPR = 10000;       // (1/22118400)*(0+1)*(2765)= 125.01usec or 7999.42Hz
/* Step 4. Enable interrupt */
TIMER0->TCSR.IE = 1;
TIMER0->TISR.TIF = 1;  //Write 1 to clear for safty  
NVIC_EnableIRQ(TMR0_IRQn); //Enable Timer0 Interrupt
/* Step 5. Enable Timer module */
TIMER0->TCSR.CRST = 1;  //Reset up counter
TIMER0->TCSR.CEN = 1;  //Enable Timer0
   TIMER0->TCSR.TDR_EN=1;  // Enable TDR function
    while(1)
{
  
  if(kk==801)
  {
   NVIC_DisableIRQ(TMR1_IRQn); //Disable Timer1 interrupt
   outpw(&TIMER1->TCSR ,0 );
   break;
  }
}
for(kk=0;kk<800;kk++)
{
  printf("\nrecived%d=%d\n",kk,a[kk]);
  //printf("\n");
}
while(1);

}

相关帖子

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

本版积分规则

0

主题

8

帖子

1

粉丝