Hi,
I am trying to write a code on the launchpad msp430g2553, which would simulate the output of several simple logic gates.
I have connected 2 push buttons as inputs to pins P1.3 and P1.7 and 4 LEDs as outputs to P1.0, P1.4, P1.5, and P1.6.
2 of the LEDs are representing the "truth" and "false" of the truth table and the other 2 are just to indicate that a push button has been pressed (1 for each).
At first I did it with polling with 6 diferrent logic gates in switch cases and it is working just fine.
#include <msp430g2553.h>
#include <stdlib.h>
void main(void) {
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
P1DIR |= 0x71; // Set P1.0, P1.4, P1.5, and P1.6 to output direction, 1 is output
P1OUT &= ~0x71; // Set all the LED off
P1DIR &= ~0x88; // Port 1 P1.3 and P1.7 (push buttons) as input, 0 is input
P1SEL &= ~0x88; // Select Port 1 P1.3 and P1.7 (push buttons), 0 selects
// P1REN |= 0x88; // Enable Port 1 P1.3 (push button) pull-up resistor
srand (time(NULL)); // Initialise random seed
long random= rand() % 6 + 1; // generate random number from 1 to 6
while(1){
if( (P1IN & 0x08) == 0x08) // if Push button at P1.3 is pressed
P1OUT |= 0x40; // Set LED at 1.6 ON when button down
else
P1OUT &= ~0x40; // Set LED at 1.6 OFF
if ((P1IN & 0x80) == 0x80) // if Push button at P1.7 is pressed
P1OUT |= 0x01; // Set LED at 1.0 ON when button down
else
P1OUT &= ~0x01; // Set LED at 1.6 OFF
switch(random){
case 1: //logic "AND"
if ((P1IN & 0x88) == 0x88) //if both push buttons are pressed
{
P1OUT |= 0x10; // Set "TRUE" LED at 1.4 ON
P1OUT &= ~0x20; // Set "FALSE" LED at 1.5 OFF
}
else{
P1OUT |= 0x20; // Set "FALSE" LED at 1.5 ON
P1OUT &= ~0x10; // Set "TRUE" LED at 1.5 OFF
}
break;
case 2: //logic "OR"
if (((P1IN & 0x88) == 0x88) || ((P1IN & 0x80) == 0x80) || ((P1IN & 0x08) == 0x08) )
{
P1OUT |= 0x10;
P1OUT &= ~0x20;
}
else{
P1OUT |= 0x20;
P1OUT &= ~0x10;
}
break;
case 3: //logic "XNOR"
if (((P1IN & 0x88) == 0x88) || ((P1IN & 0x80) == 0x80) || ((P1IN & 0x08) == 0x08) ) {
P1OUT |= 0x20;
P1OUT &= ~0x10;
}
else{
P1OUT |= 0x10;
P1OUT &= ~0x20;
}
break;
case 4: //logic "XOR"
if ((P1IN & 0x88) == 0x88)
{
P1OUT |= 0x20;
P1OUT &= ~0x10;
}
else if ((P1IN & 0x80) == 0x80){
P1OUT |= 0x10;
P1OUT &= ~0x20;
}
else if ((P1IN & 0x08) == 0x08){
P1OUT |= 0x10;
P1OUT &= ~0x20;
}
else{
P1OUT |= 0x20;
P1OUT &= ~0x10;
}
break;
case 5: //logic "NAND" {
if ((P1IN & 0x88) == 0x88)
{
P1OUT |= 0x20;
P1OUT &= ~0x10;
}
else{
P1OUT |= 0x10; // Set green LED off when button up
P1OUT &= ~0x20;
}
break;
case 6: //logic "XNOR"
if ((P1IN & 0x88) == 0x88)
{
P1OUT |= 0x10;
P1OUT &= ~0x20;
}
else if ((P1IN & 0x80) == 0x80){
P1OUT |= 0x20;
P1OUT &= ~0x10;
}
else if ((P1IN & 0x08) == 0x08)
{
P1OUT |= 0x20;
P1OUT &= ~0x10;
}
else{
P1OUT |= 0x10;
P1OUT &= ~0x20;
}
break;
default:
P1OUT &= ~0x71;
}
}
}
But now I am trying to do it with interrupts and I get problems while pressing both buttons at the same time (simulating 2 inputs of ´1´ and ´1´). for pressing one of the buttons I used this code and it works:
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
if(P1IFG & BUTTON){
P1OUT ^= LED1; // P1.6 = toggle
P1IFG &= ~BUTTON; // P1.3 IFG cleared
P1IES ^= BUTTON; // toggle the interrupt edge,
}
But when I want to set the "truth" LED on while pressing both buttons at the same time it does not work
if ((P1IFG & BUTTON1)&&(P1IFG & BUTTON)){
P1OUT ^= LED2;
P1IFG &= ~(BUTTON + BUTTON1);
P1IES ^= (BUTTON + BUTTON1);
}
I have stopped coding when I realized that I got it wrong,so the code is not complete, but eventually I want to code it so it functions exactly as the first polling code.
#include <msp430x20x2.h>
#define LED0 BIT0
#define LED1 BIT6
#define LED2 BIT4
#define BUTTON BIT3
#define BUTTON1 BIT7
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
P1DIR |= (LED0 + LED1 + LED2);
P1OUT &= ~(LED0 + LED1 + LED2);
P1IE |= (BUTTON + BUTTON1); // P1.3 and P1.7 interrupt enabled
P1IFG &= ~(BUTTON + BUTTON1); // P1.3 and P1.7 IFG cleared
__enable_interrupt(); // enable all interrupts
for(;;)
{}
}
// Port 1 interrupt service routine
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
if(P1IFG & BUTTON){
P1OUT ^= LED1; // P1.6 = toggle
P1IFG &= ~BUTTON; // P1.3 IFG cleared
P1IES ^= BUTTON; // toggle the interrupt edge,
// the interrupt vector will be called
// when P1.3 goes from HitoLow as well as
// LowtoHigh
}
if(P1IFG & BUTTON1){
P1OUT ^= LED0; // P1.0 = toggle
P1IFG &= ~BUTTON1; // P1.7 IFG cleared
P1IES ^= BUTTON1; // toggle the interrupt edge,
// the interrupt vector will be called
// when P1.3 goes from HitoLow as well as
// LowtoHigh
}
if ((P1IFG & BUTTON1)&&(P1IFG & BUTTON)){
P1OUT ^= LED2;
P1IFG &= ~(BUTTON + BUTTON1);
P1IES ^= (BUTTON + BUTTON1);
}
}
I am new to msp430 and to microcontrollers and I understand that there is a problem with how I handle the interrupts (the ISR reads only 1 interrupt at a time??) but can't figure out how to fix it.
any help would be much appreciated
Many thanks,
Shahar