Hi, I'm trying to work with interrupts and having some difficulty. I made a simple program (not shown) that declares pin 1.7 as an interrupt pin and then makes a pulse counter. When I tap that pin with a 3V supply, the program performs the ISR and then returns to the pulse counter, as it should. However, when I use that same interrupt pin initialization in a program that also uses I2C (below), a very strange thing happens- the program never gets to the while(1) loop and instead seems to get to the line __bis_SR_register(GIE) and then goes back to the beginning of the program and creates this sort of pseudo while loop. Removing the GIE line allows the program to run as normal, but of course interrupts are not enabled. Any suggestions are appreciated. Thanks
#include <msp430x26x.h>
#include <stdlib.h> //Processor specific definitions
#include <stdio.h>
#include "hardware.h"
unsigned char SADDR, RADDR, TXData, TXData2 = 0x00, temp = 0x00, DRDY;
int j=0, averages[3][3], Sensor_Data[3][3], telemetry = 0x00, Sorted_Data[3][10];
unsigned char RXData[3][6][10];
void I2C_Setup_B1()
{
UCB1CTL1 |= UCSWRST; // Enable SoftWare reset
UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC; // Mode: Master, I2C, synchronous
UCB1CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB1BR0 = 2; // fSCL = SMCLK/2 = ~200kHz
UCB1BR1 = 0;
UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UC1IE |= UCB1TXIE; // Enable TX interrupt
UC1IE |= UCB1RXIE; // Enable RX interrupt
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P1IE |= 0x80; // P1.7 Enable Interrupt
P1IES &= ~0x80; // P1.7 Lo to Hi edge
P1IFG &= ~0x80; // P1.7 IFG cleared
P3SEL |= 0x06; // Assign I2C pins to USCI_B0
P5SEL |= 0x06; // Assign I2C pins to USCI_B0
P5DIR &= ~0x20; // P5.5 is input: DRDY1
P3DIR |= 0x01; // P3.0 is an output test pin
P3OUT &= ~0x01; // Set it low
P3DIR |= 0x08; // P3.3 is an output test pin
P3OUT &= ~0x08; // Set it low
I2C_Setup_B1();
SADDR = 0x00F;
initialize1(SADDR); // Initialize sensor 1
force1(SADDR); // Force Mode for sensor 1
__bis_SR_register(GIE); // General Interrupt Enabled
while (1)
{
SADDR = 0x00F;
RADDR = 0x10; // DataX register address
DRDY = 0x20;
P3OUT |= 0x08;
read1_6(SADDR, RADDR, DRDY, j); // Read sensor 1, put X,Y,Z data in jth col of RXData[0]
P3OUT &= ~0x08;
force1(SADDR); // Force Mode for sensor 1
}
}
//////////////////////////////Functions/////////////////////////////////
#pragma vector = PORT1_VECTOR
__interrupt void Port_1(void)
{
P3OUT |= 0x01;
P3OUT &= ~0x01;
P3OUT |= 0x01;
P3OUT &= ~0x01;
telemetry = 0x01;
P1IFG &= ~0x80; // P1.7 IFG cleared
// __bic_SR_register_on_exit(GIE);
}
void initialize1(unsigned char SADDR)
{
UCB1I2CSA = SADDR; // Slave Address is 00Fh
RADDR = 0x1D; // Sensor's CNTL3 register address
TXData = 0x80; // Soft Reset command
transmit1_1(RADDR, TXData);
RADDR = 0x1B; // Change to CNTL1 register address
TXData = 0x82; // Set Active Mode
transmit1_1(RADDR, TXData);
RADDR = 0x1C; // Change to CNTL2 register address
TXData = 0x0C; // Enable Ready signal
transmit1_1(RADDR, TXData);
RADDR = 0x5C; // Change to CNTL4 register address
TXData = 0xA0; // High-speed measurement mode
TXData2 = 0x7E;
transmit1_2(RADDR, TXData, TXData2);
}
void force1(unsigned char SADDR)
{
UCB1I2CSA = SADDR; // Slave Address is 00Fh
RADDR = 0x1D; // Change to CNTL3 register address
TXData = 0x40; // Force = 1
transmit1_1(RADDR, TXData);
}
void transmit1_1(unsigned char RADDR, unsigned char TXData)
{
UCB1CTL1 |= UCTR; // Transmitter Mode
UCB1CTL1 |= UCTXSTT; // I2C start sequence
while (temp == 0x00)
temp = (UC1IFG & UCB1TXIFG);
UCB1TXBUF = RADDR; // Load TX buffer w/Register ADDR
temp = 0x00;
while (temp == 0x00)
temp = (UC1IFG & UCB1TXIFG);
UCB1TXBUF = TXData; // Load TX buffer w/Reset commmand
temp = 0x00;
while (temp == 0x00)
temp = (UC1IFG & UCB1TXIFG);
UCB1CTL1 |= UCTXSTP; // I2C stop condition
temp = 0x00;
}
void transmit1_2(unsigned char RADDR, unsigned char TXData, unsigned char TXData2)
{
UCB1CTL1 |= UCTR; // Transmitter Mode
UCB1CTL1 |= UCTXSTT; // I2C start sequence
while (temp == 0x00)
temp = (UC1IFG & UCB1TXIFG);
UCB1TXBUF = RADDR; // Load TX buffer w/Register ADDR
temp = 0x00;
while (temp == 0x00)
temp = (UC1IFG & UCB1TXIFG);
UCB1TXBUF = TXData; // Load TX buffer w/Reset commmand
temp = 0x00;
while (temp == 0x00)
temp = (UC1IFG & UCB1TXIFG);
UCB1TXBUF = TXData2; // Load TX buffer w/Reset commmand
temp = 0x00;
while (temp == 0x00)
temp = (UC1IFG & UCB1TXIFG);
UCB1CTL1 |= UCTXSTP; // I2C stop condition
temp = 0x00;
}
void read1_6(unsigned char SADDR, unsigned char RADDR, unsigned char DRDY, int j)
{
UCB1I2CSA = SADDR; // Slave Address
while ((P5IN&DRDY)==0); // Wait for DRDY from sensor 1
UCB1CTL1 |= UCTR; // Transmitter Mode
UCB1CTL1 |= UCTXSTT; // I2C start sequence
while (temp == 0x00)
temp = (UC1IFG & UCB1TXIFG); // Wait for TX Interrupt flag
UCB1TXBUF = RADDR; // Load TX buffer w/Register ADDR
temp = 0x00;
while (temp == 0x00)
temp = (UC1IFG & UCB1TXIFG); // Wait for TX Interrupt flag
UCB1CTL1 |= UCTXSTP; // I2C stop condition
temp = 0x00;
//Receiver Mode
UCB1CTL1 &= ~UCTR; // Master is a receiver
UCB1CTL1 |= UCTXSTT; // Restart
for (int i=0;i<4;i++)
{
while (temp == 0x00)
temp = (UC1IFG & UCB1RXIFG); // Wait for RX Interrupt flag
RXData[0][i][j] = UCB1RXBUF;
temp = 0x00;
}
while (temp == 0x00)
temp = (UC1IFG & UCB1RXIFG); // Wait for RX Interrupt flag
RXData[0][4][j] = UCB1RXBUF;
UCB1CTL1 |= UCTXSTP; // I2C stop condition
temp = 0x00;
while (temp == 0x00)
temp = (UC1IFG & UCB1RXIFG); // Wait for RX Interrupt flag
RXData[0][5][j] = UCB1RXBUF;
temp = 0x00;
}
