本帖最后由 缥缈九哥 于 2012-9-14 12:20 编辑
菜鸟学习NUC140。买了块开发板,其中一个例程如下:
#include <stdio.h>
#include "NUC1xx.h"
#include "DrvGPIO.h"
#include "DrvUART.h"
#include "DrvSYS.h"
void GPABCallback(uint32_t u32GpaStatus, uint32_t u32GpbStatus)
{
printf("GPAB Interrupt! GPA:0x%04x GPB:0x%04x\n", u32GpaStatus, u32GpbStatus);
/* Toggle LED */
outpw((uint32_t)&GPIOA->DOUT, inpw((uint32_t)&GPIOA->;PIN) ^ (1 << 7));
}
void GPCDECallback(uint32_t u32GpcStatus, uint32_t u32GpdStatus, uint32_t u32GpeStatus)
{
printf("GPCDE Interrupt! GPC:0x%04x GPD:0x%04x GPE:0x%04x\n", u32GpcStatus, u32GpdStatus, u32GpeStatus);
/* Toggle LED (GPA7) */
outpw((uint32_t)&GPIOA->DOUT, inpw((uint32_t)&GPIOA->;PIN) ^ (1 << 7));
}
void EINT0Callback(void)
{
printf("EINT0 Interrupt!\n");
/* Toggle LED (GPA7) */
outpw((uint32_t)&GPIOA->DOUT, inpw((uint32_t)&GPIOA->;PIN) ^ (1 << 7));
}
void EINT1Callback(void)
{
printf("EINT1 Interrupt!\n");
/* Toggle LED (GPA7) */
outpw((uint32_t)&GPIOA->DOUT, inpw((uint32_t)&GPIOA->;PIN) ^ (1 << 7));
}
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++)
;
}
/*---------------------------------------------------------------------------------------------------------*/
/* MAIN function */
/*---------------------------------------------------------------------------------------------------------*/
int main (void)
{
STR_UART_T param;
UNLOCKREG();
SYSCLK->;PWRCON.XTL12M_EN = 1;
/* Waiting for 12M Xtal stalble */
DrvSYS_Delay(5000);
DrvGPIO_InitFunction(FUNC_UART0);
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 GPB13, GPC0, GPB14 and GPB15 are used to test key interrupt\n and control LED (GPA7)\n");
/* Configure GPA7 for LED control */
DrvGPIO_Open(GPA, 7, IO_OUTPUT);
/* Configure general GPIO interrupt */
DrvGPIO_Open(GPB, 13, IO_INPUT);
/* The Quasi-bidirection mode could be used as input with pull up enable */
DrvGPIO_Open(GPC, 0, IO_QUASI);
DrvGPIO_SetIntCallback(GPABCallback, GPCDECallback);
DrvGPIO_EnableInt(GPB, 13, IO_RISING, MODE_EDGE); /* IO_FALLING means low level trigger if it is in level trigger mode */
DrvGPIO_EnableInt(GPC, 0, IO_FALLING, MODE_LEVEL);
DrvGPIO_SetDebounceTime(3, DBCLKSRC_HCLK); .
DrvGPIO_EnableDebounce(GPB, 13);
DrvGPIO_EnableDebounce(GPC, 0);
/* Configure external interrupt */
DrvGPIO_EnableEINT0(IO_FALLING, MODE_EDGE, EINT0Callback);
DrvGPIO_EnableEINT1(IO_BOTH_EDGE, MODE_EDGE, EINT1Callback);
/* Waiting for interrupts */
printf(" GPIO Input/Output test ................................ ");
DrvGPIO_Open(GPA,1, IO_OUTPUT);
DrvGPIO_Open(GPA,2, IO_OUTPUT);
DrvGPIO_Open(GPA,3, IO_OUTPUT);
while(1)
{
DrvGPIO_SetBit(GPA,1);
DrvGPIO_SetBit(GPA,2);
DrvGPIO_SetBit(GPA,3);
Delay1ms(2000);
DrvGPIO_ClrBit(GPA,1);
DrvGPIO_ClrBit(GPA,2);
DrvGPIO_ClrBit(GPA,3);
Delay1ms(2000);
}
}
原理图是GPA1 GPA2 GPA3 分别接的3个led, GPB15接一个按键。GPA7什么都没接,没有什么LED灯,(估计是另外板子的例程)GPB13 和GPC0也什么都没接。见附件电路图。
现在程序运行时,结果如下:
+-------------------------------------------------------------------+
| GPIO Driver Sample Code |
+-------------------------------------------------------------------+
GPB13, GPC0, GPB14 and GPB15 are used to test key interrupt
and control LED (GPA7)
EINT1 Interrupt!EINT1 Interrupt!EINT1 Interrupt!EINT1 Interrupt!EINT1 Interrupt!(程序已开始运行就不停输出EINT1 Interrupt!EINT1 Interrupt!
EINT1 Interrupt!
第一次按键时,屏幕上的EINT1 Interrupt!停住,
3个LED灯闪烁,并出现“GPIO Input/Output test ................................ ”)
GPIO Input/Output test ................................
当放手后LED灯不再闪烁,继续出现EINT1 Interrupt!EINT1 Interrupt!EINT1 Interrupt!
以后每次按键或弹起的时候EINT1 Interrupt!又停止了,灯又开始闪烁,但不会出现GPIO Input/Output test ................................ 这句话。偶尔极少数时候按键或弹起的时候又会出现GPAB Interrupt! GPA:0x0000 GPB:0x2000这句话。为什么会是这个结果呀?
其中 DrvGPIO_SetIntCallback函数定义如下:
void DrvGPIO_SetIntCallback(GPIO_GPAB_CALLBACK pfGPABCallback, GPIO_GPCDE_CALLBACK pfGPCDECallback)
{
_pfGPABCallback = (void (*)(uint32_t, uint32_t))pfGPABCallback;
_pfGPCDECallback = (void (*)(uint32_t, uint32_t, uint32_t))pfGPCDECallback;
}
现在有如下几个问题:
1.DrvGPIO_SetIntCallback 函数还有GPABCallback函数到底是干嘛用的呢?
按照我读程序的理解,程序从main函数开始执行。在执行了DrvGPIO_SetIntCallback(GPABCallback, GPCDECallback);这句话之后就应该去执行void GPABCallback和void GPDCECallback这两个回调函数,就应该在屏幕上输出GPAB Interrupt! GPA:0x%04x GPB:0x%04x\n 然后输出GPCDE Interrupt! GPC:0x%04x GPD:0x%04x GPE:0x%04x\n。可是为什么程序中都没有输出呢?这个DrvGPIO_SetIntCallback 函数还有GPABCallback函数到底是干嘛用的呢?
2.然后执行到DrvGPIO_EnableEINT1(IO_BOTH_EDGE, MODE_EDGE, EINT1Callback);这句话时,使能了EINT1的中断。之后程序就停在那里了吗?为什么不继续往下执行printf(" GPIO Input/Output test ................................ "); 这句以及后面的while(1)中的灯闪烁的程序呢?
3.按照我的理解使能EINT1的中断后,要按键触发才会执行中断程序EINT1Callback输出EINT1 Interrupt呀?为什么没按键的时候程序一运行就一直不停输出EINT1 Interrupt呢?
4.灯闪烁这个程序不是应该写在EINT1Callback这个中断程序中吗?当进入中断的时候灯才闪烁,执行完中断程序后又继续执行原来的程序,然后灯停止闪烁。不是应该这样吗?
这些问题困扰我好多天了,一直没搞懂,希望高手帮忙。说说程序执行的过程。解答下以上几个问题。不甚感激。 |