This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

NEED HELP : MSP430 EXPERIMENTS BOARD



Need help with this code...here is the problem I m getting. The code is supposed to display time and adjust hrs and mins by pushbuttons.
Now well I ha Hours and minutes can be adjusted number changesHowever, I m faced with another hurdle now.
As I said the clock is working in real time.So when seconds hit 60 ...mins changes and so on. Now when i adjust the hours or mins.
 The display starts to flicker. i.e for example if time is 16:30:23 and i change it to 18:30:xx.
...then the clock that was running before still keeps on running. Like for instance .. in hour section it shows 18 (adjusted value) and then 16 as well...toggles btw these two numbers.
 And the clock keeps running in realtime in background.
The incremented numbers do not change(if mins hit 60 the number will not change to 17). I hope this makes sense?? Its difficult to explain what exactly is happening.




/*
* main.c
*/
#include <msp430fg4618.h>//Port definitions
#include <intrinsics.h>// For BCD calculation
#include <stdint.h>
#define LCDMEMS 11 //to access the LCD memory
uint8_t * const LCDMem= (uint8_t *) &LCDM3;//pointer to LCDMem which is defined in header file(used an array later)
#define SEG_A BIT0
#define SEG_B BIT1
#define SEG_C BIT2
#define SEG_D BIT3
#define SEG_E BIT4
#define SEG_F BIT5
#define SEG_G BIT6
#define SEG_H BIT7 // define statement.. Each time they appear in the codewill be replaced by subsequent bits

const uint8_t LCDHexChar[] = {
SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_G, //0
SEG_B | SEG_C , //1
SEG_A | SEG_B | SEG_D | SEG_G | SEG_F, //2
SEG_A | SEG_B | SEG_C | SEG_D | SEG_F, //3
SEG_B | SEG_C | SEG_E | SEG_F, //4
SEG_A | SEG_C | SEG_D | SEG_E | SEG_F, //5
SEG_A | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G, //6
SEG_A | SEG_B | SEG_C, //7,
SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F |SEG_G,//8
SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F, //9

};

const uint8_t LCDAMChar = SEG_A | SEG_B | SEG_C | SEG_E | SEG_F | SEG_G;//display characters to indicate AM(A) and PM (p)
const uint8_t LCDPMChar = SEG_A | SEG_B | SEG_E | SEG_F | SEG_G;
const uint8_t LCDBlankChar = 0;

void InitLCD (void); //will be used later(Prototype declared)

void main(void) {
WDTCTL = WDTPW|WDTHOLD; //WATCHDOG TIMER STOP
InitLCD();
TACCR0 = 0x8000; //upper limit for timer count
TACCTL0 = CCIE; //enable compare 0 interrupts
TACTL = MC_1|TASSEL_1|TACLR; //setting up timer A ,no clock division


P1DIR&=~BIT0; //To enable these pins to be used as inputs
P1DIR&=~BIT1;

//Setting bits to be use an I/O interrupt //

P1IE=0x03;// interrupt enable on P1.0 and P1.1
P1OUT = 0x03;//pull up enable on P1.0 and P1.1
P1IFG&=~0X03;
//P1OUT = 0x02;//clear the interrupt flag
//P1IE=0x02;

//P1IES&=~BIT0;


__enable_interrupt();

for (;;) {
__low_power_mode_3(); //Asynchronous clock continues to run
}




}
//INITIALIZING THE LCD DISPLAY
void InitLCD (void)
{
int i;
for (i = 0; i <LCDMEMS; ++i) { //clear LCD memory
LCDMem [i] = 0;
}
//configuring LCD-A controller
P5SEL =BIT4|BIT3|BIT2;//shared pins of port 5 are assigned to backplanes (COM)
LCDAPCTL0 =LCDS4|LCDS8|LCDS12|LCDS16|LCDS20|LCDS24;//Enable LCD segs 4-27 (till 25 used),
LCDAVCTL0 = 0;// no charge pump used
LCDACTL = LCDFREQ_128 |LCD4MUX|LCDSON |LCDON;//Aclk/128 ; 4 mux; segments on;LCD_A on


}

//ISR FOR TIMER//
#pragma vector = TIMERA0_VECTOR
__interrupt void TIMERA0_ISR (void){
//variables need to be static so that they dont change and short as to match with the intrinsic functions for BCD arithmetic
static unsigned short seconds = 0x59; //initial time in BCD 23:59:59
static unsigned short minutes = 0x59;
static unsigned short hours = 0x23;
//Updating time//
seconds = __bcd_add_short(seconds, 0x01);//seconds incremented(intrinsic function used)
if(seconds >= 0x60){
seconds = 0;

minutes = __bcd_add_short(minutes,0x01); //minutes incremented
if(minutes >= 0x60){
minutes = 0; //new hour started
hours = __bcd_add_short(hours,0x01);//hours incremented
if (hours >= 0x24){
hours = 0; //new day
}

}
}
LCDMem[1] = LCDHexChar[seconds & 0x0F]; //Updating all the digits ;segment H is the colon
LCDMem[2] = LCDHexChar[(seconds >> 4) & 0x0F] | SEG_H ;

LCDMem[3] = LCDHexChar[minutes & 0x0F];
LCDMem[4] = LCDHexChar[(minutes >> 4) & 0x0F] | SEG_H;

LCDMem[5] = LCDHexChar[hours & 0x0F];
LCDMem[6] = LCDHexChar[(hours >> 4) & 0x0F] | SEG_H;
LCDMem[11] = LCDHexChar[hours & 0x0F];
}



//TIME ADJUSTMENT //

#pragma vector = PORT1_VECTOR

__interrupt void Port1_ISR(void) //I/O interrupt on port 1
{
static unsigned short minutes=0x59;
static unsigned short hours=0x23;
volatile unsigned int i;

for (i=0x1FFF; i > 0; i--); //DELAY to tackle switch bounce

if ((P1IN & BIT0)==0){
hours = __bcd_add_short(hours,0x01); //when button pressed increment hours
if (hours >= 0x24){
hours = 0;
//P1IFG&=0;
}
//P1IES|=BIT0; // PIES needs to be 1 (for1-0 edge==button pressed)
}

if ((P1IN & BIT1)==0){
minutes = __bcd_add_short(minutes,0x01);//when button pressed increment minutes
if(minutes >= 0x60){
minutes = 0;

}

//P1IES|=BIT1;
}

LCDMem[3] = LCDHexChar[minutes & 0x0F];
LCDMem[4] = LCDHexChar[(minutes >> 4) & 0x0F] | SEG_H;

LCDMem[5] = LCDHexChar[hours & 0x0F];
LCDMem[6] = LCDHexChar[(hours >> 4) & 0x0F] | SEG_H;

}






  • The problem is that you have two different sets of values that can both be written to the display independently so you see the values fighting.

    The simplest solution is to make a single global set of values that both interrupts can access.

    By the way I don't think the __bcd_add_short intrinsic actually adds any benefit in this scenario (possibly even makes the code a bit less efficient) - the following commands would probably suffice:

    if(++secs >= 60)
    {
      secs = 0;
     
      if(++mins >= 60)
      {
     
      ...

      }
    }

    Regards,

    Chris.

**Attention** This is a public forum