IN THE KNOW
Go to bottomPage: 1
TOPIC:
#898
External Interrupt: Z8FS021A 1 Year, 5 Months ago Karma: 1
I am having problems with doing an external interrupt using Z8FS021 Zmotion processors. When my external interrupt is trigger, the MCU seems to locks ups. I am not sure what I am doing wrong, but would appreciate any input anyone would have on how to resolved the issue.

Harware Configuration:

Basic Z8FS021A MCU. I am using PA0, PA1, PA2 for lighting LEDs. PA3 is used connected to MOM switch that when pressed, it goes from GND to 3.2V. I am using a pull down resistor on PA3 to ensure that its at 0V. I am also using Timer0 at 2Hz rate to blink an LED and increment a counter. (that part works).

If you could look at my code. I have put into a single file to make it easier to review.

Appreciate any input.

Don

Code:



/**********************************************************************************************************
**  INTERRUPT DEMO ROUTINE
**
**  Purpose:   To demonstrate using multiple interrupt, external and timer.
** 
**  Hardware:  Using 3 LED connected to PA0, PA1 and PA2.   Use the timer to blink LED3, every 1/2 second
**             and every 10 blinks, toggle LED 2.    For the external GPIO interrupt, toggle LED1 everytime
**             the switch is pressed.  (rising edge using a MOM SW connected to Vcc).  
**
**  Reference: Used examples from Zilog AN0141 and the timer service routine was generated by 
**             http://projectproto.blogspot.com/2010/07/zilog-z8f64xx-timer-calculator.html
**
**  Issues:    When the PA3 is trigger from LOW to HIGH, the MCU locks up.   Not sure why?
***********************************************************************************************************/


#include <ez8.h>


// DEFINES

#define LED_PORT PAOUT // Set the LED using PAOUT

#define LED_BIT1 0x01 // Define LED_BIT1 as 1st Bit of register
#define LED_OFF1 LED_PORT |= LED_BIT1 // LED OFF - Set Bit High to turn LED OFF
#define LED_ON1 LED_PORT &= ~LED_BIT1 // LED ON - Set big low to turn LED ON
#define LED_TOGGLE1 LED_PORT ^=LED_BIT1         // Toggle the LED


#define LED_BIT2 0x02 // Define LED_BIT2 as 2nd Bit of register
#define LED_OFF2 LED_PORT |= LED_BIT2 // LED OFF - Set Bit High to turn LED OFF
#define LED_ON2 LED_PORT &= ~LED_BIT2 // LED ON - Set big low to turn LED ON
#define LED_TOGGLE2 LED_PORT ^=LED_BIT2         // Toggle the LED


#define LED_BIT3 0x04 // Define LED_BIT3 as 3rd Bit of register
#define LED_OFF3 LED_PORT |= LED_BIT3 // LED OFF - Set Bit High to turn LED OFF
#define LED_ON3 LED_PORT &= ~LED_BIT3 // LED ON - Set big low to turn LED ON
#define LED_TOGGLE3 LED_PORT ^=LED_BIT3         // Toggle the LED

#define DO_ME_FOREVER  while(1)                 // Infinite Look -- Having Fun

// GLOBAL VARIABLES

unsigned int count=0;     // Keep track of timer




/**********************************************************************************************************
**  TIMER0_ISR()
**
**  Timer0 Interrupt Service Routine.   Toggle LED 3
**
***********************************************************************************************************/
#pragma interrupt
void TIMER0_ISR(void)
{
//DI(); //disable global interrupt
/* your ISR code here */

     LED_TOGGLE3;
count++;



//IRQ0 &= ~0x20; //clear pending interrupt request
//EI(); //enable global interrupt
}

/**********************************************************************************************************
**  init_TIMER0()
**
**  Timer0 Interrupt Initialization Routine.   Set to 2 hz schedule
**
***********************************************************************************************************/

void init_TIMER0(void)
{

T0CTL1 &= ~0x80; //disable Timer
T0CTL1 |= 0x01; //continuous mode
T0CTL1 |= (7)<<3; //prescaler
T0H = 0x00; //initial value is 1
T0L = 0x01;

//expected interrupt rate = 2.00001Hz
T0RH = 168; //reload value
T0RL = 195;

SET_VECTOR(TIMER0, TIMER0_ISR);// interrupt vector

IRQ0ENH |= 0x20; //enable timer interrupt
//IRQ0ENL |= 0x20; //(enable this to make it high priority interrupt)
T0CTL1 |= 0x80; //enable timer

}


 /**********************************************************************************************************
**  isr_p0ad()
**
**  Interrupt Service routing for PA3
**
***********************************************************************************************************/
#pragma interrupt  
void isr_p0ad(void)                   //Interrupt service routine for Port A bit3
 {
   
 LED_TOGGLE1;
 
 IRQ1 &= ~0x08; //clear pending interrupt request
 
 
 }/*isr_p0ad*/  

 

/**********************************************************************************************************
**  init_p0ad()
**
**  GPIO Initialization Routine for PA3
**
***********************************************************************************************************/

void init_p0ad(void) {


  // Set PA 3 as interupt (Pin 9)

  SET_VECTOR(P4AD, isr_p0ad);    // Set vector for interupt.   I assume I can use any vector.  Is that correct?

  PAADDR  = 0x02;                     //Port A Alternate Function
  PACTL &= 0x00;                      //No Alternate Function

  PAADDR  = 0x01;                    //Port A Data Direction
  PACTL |= 0x08;                     //Port A bit 3 is configured as Input

 
  
  IRQ1ENH &= ~0x08;   // Set IRQ1 Bit for the field I want to interupt
  IRQ1ENL |= 0x08; // Set IRQ1 Lower bit - Low
 
  IRQES |= 0x08;                    //Interrupt is rising edge triggered 
  
  
  
 } /*init_p0ad*/

 
 /**********************************************************************************************************
**  MAIN()
**
**  Main Routine
**
***********************************************************************************************************/

void main(void)
{
DI(); //disable global interrupt



// SETUP THE LED FOR OUTPUT with OPEN DRAIN.
// Setup the Ouput for GPIO for Drain for PA0, PA1 & PA2
PAADDR = 0x03;     //  Out-Control PA1 to Open Drain:    // 00 - No Function, 01 - Data Direction, 02 - Alt Func, 03-Out Control Open Drain, 04 High enabl, 
PACTL |= 0x07;    //  Set Bit 0,1&2 = 7.

// Set the data direction of the GPIO
PAADDR = 0x01;    //  Data Direction    
PACTL  &= ~0x07;  //  Clear lower three bits for output only 


// Turn off Control of PA
PAADDR = 0x00; 



    // Initialize the Interrupts
init_p0ad();    // PA3 initialize interrupt 
init_TIMER0(); //initialize timer 

EI(); //enable global interrupt


    // Turn LED OFF
LED_OFF1;
LED_OFF2;
LED_OFF3;


DO_ME_FOREVER {      // Just a little fun with macros:   This is while(1)


if (count>10) {

LED_TOGGLE2;    // Toggle 2nd Bit
count=0;        // Reset Counter

}
}

}


// End of file




Don Pitchford (User)
Fresh Boarder
Posts: 7
graphgraph
User Offline Click here to see the profile of this user
The administrator has disabled public write access.
 
#899
Re:External Interrupt: Z8FS021A 1 Year, 5 Months ago Karma: 4
Hi Don
From a cursory review of the code, it looks like you are assigning the interrupt routine to P4AD but connected to and defining P3AD.
You might try changing your SETVECTOR macro to:
SETVECTOR(P3AD, isr_p0ad)

Let me know if that solves the problem.
Tom
Tom Ormiston (Admin)
Admin
Posts: 168
graph
User Offline Click here to see the profile of this user
The administrator has disabled public write access.
 
#900
Re:External Interrupt: Z8FS021A 1 Year, 5 Months ago Karma: 1
Tom,

Awesome... I guess I been looking at the same code and it was right in front of me. That did the trick.

Thanks a million.

Don
Don Pitchford (User)
Fresh Boarder
Posts: 7
graphgraph
User Offline Click here to see the profile of this user
The administrator has disabled public write access.
 
Go to topPage: 1
Деревянные дома, дома из сруба