最近在用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, ¶m); // 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);
} |