我能够使用定时器和UART生成的中断,就像我希望在单独使用它们时能够使用它们的方式一样(也就是说,定时器能够在单独使用时激活中断子程序,并且UART在自己使用时能够激活中断子程序),但似乎在UART产生中断后(表明写缓冲区被清除),然后定时器中断停止工作;如果我同时使UART和定时器产生中断,定时器不会在一两个周期后将程序发送到中断子程序中。我有应该使用 UART 定期发送消息的代码 - 每当计时器倒计时达到零时从循环缓冲区发送消息:
/*
* Main.c
*
*
*
* clock: 12 megahertz
*/
#include "io_lib.h"
#include "configuregpio.h"
#include "my_uart_library.h"
/* Debug mode definition -- changed 'NO interrupt' to 4 instead of 0 */
#define WITH_TIMER_INT 0x01
#define WITH_UART_INT 0x02
#define WITHOUT_INT 0x04
#define DEBUG_MODE 3 /* 0 Error - should not use */
/* 1 Debugging with Timer Interrupt */
/* 2 Debugging with UART Interrupt */
/* 3 Debugging with Timer & UART Interrupt */
/* 4 Debugging without all interrupt */
/* 2.1 Timer Operating Counter - utilized either by interrupt or polling */
volatile unsigned int timercounter = 0;
unsigned int previouscounter = 0;
/* 2.2 Timer Operating Counter - utilized only at polling */
unsigned int timervalue;
/* 3. Pending Interrupt Status - RxRDY, TxRDY, Timer interrupt */
/* - similar reason, two variables are defined for polling and interrupt use */
unsigned int irqStatusP; /* Polling or normal routine use */
unsigned int irqStatusI; /* interrupt use only */
/*** 5.x Following variables are defined as temporary purpose. Normally they are not utilized */
unsigned int firstDigit, secondDigit, thirdDigit;
unsigned int tempBCD;
static char frameNo = 0;//0-99
static char counter = 0;
static int i = 0;
static char frameNumber[2];
char frameNoString[50] = "Minor cycle ";
unsigned char x;
unsigned int datax;
/**** end of 5.x ** *******************************/
/* 6. Interrupt Service Routine for 8051 CPU's IRQ0 */
void INT0_IRQHandler(void) __interrupt (0) __using (1) //Changing "using" parameter will produce offset in
//irq handler addresses because a "different register" bank will be used.
{
//disable all interrupts while this is being handled
irqStatusI = inport8 (IRQ_Status);
#if DEBUG_MODE & WITH_UART_INT
#endif
#if (DEBUG_MODE & WITH_TIMER_INT)
if ( (irqStatusI & IRQ_SRC2) != 0 ) /* IRQ Source 2 (Timer) has interrupted */
{
//incriment timer counter. This will make it not equal to previous timer counter in main.
timercounter ++;
outport16(GPIO_OUT, timercounter);
ClearTimerInterrupt();
}
#endif
}
// Main code
int main(void)
{
/* for debugging, initialize the Tx/Rx Buffer */
timercounter=0;
// configure GPIO
configuregpio();
//Turn on every LED bit. to test the GPIO
outport8(GPIO_OUT, 0x0);
outport16(GPIO_OUT, 0x0);
/* To make sure of no interrupt before initiating UART/TIMER, */
/* all of the possible interrupt sources are cleared */
/* a. clear all possible pending interrupt at the interrupt controller */
outport16(FIQ_CLEAR, 0xFFFF);
outport16(IRQ_CLEAR, 0xFFFF);
/* b. clear possible pending interrupt at the timer */
ClearTimerInterrupt();
/* c. clear possible pending interrupt at the UART */
inport8(StatusRegister); /* reading status register of UART */
/* Configure UART */
configure_uart();
//we need to read status register at the end of configuration.
//tx ready signal may automatically generate. To remove it we need to read uart status register once.
//timer configure
Set100msTimer(); /* setup timer 100 milli-second *///when timer is off interrupt 2 when on 6
ClearTimerInterrupt(); /* added to prevent 'false' interrupt by the Timer */
EnableTimer();
ClearTimerInterrupt(); /* added to prevent 'false' interrupt by the Timer */
/* Before Initializing Interrupt Controller, clear them */
outport16(FIQ_CLEAR, 0xFFFF);
outport16(IRQ_CLEAR, 0xFFFF);
//This is enabling IRQ sources of the interrupt controller.
// IRQ Source 0 : RxRDY
// IRQ Source 1 : TxRDY
// IRQ Source 2 : Timer
/* Combine those three macros whenever want to intiate their own interrupt */
#if DEBUG_MODE == (WITH_TIMER_INT | WITH_UART_INT)
outport16(IRQ_Enable_Reg, ( /*IRQ_SRC0 | */IRQ_SRC1 |IRQ_SRC2 )); // all interrupt
#endif
#if (DEBUG_MODE & WITH_TIMER_INT) | (DEBUG_MODE & WITH_UART_INT)
/* enable 8051 interrupt */
set8051_interrupt_type();
enable8051_interrupts();
#endif
while (1)
{
/* for debugging, following strings have added to the Tx Buffer to transmit */
if (timercounter != previouscounter)
{
previouscounter = timercounter;
}
} /* end of while (1) */
}