0

I am working with MC9S08AW60 on the Board-DEMO9S08AW60E. I have written the following code to perform Serial Comm, LED sequence and Keyboard Tx-RX.

for(;;)
{  
    int i =0;  
    if(TPM1SC_TOF == 1) 
    {
        // this part shows the percentage of the voltage regulator on Hterm 
        bob = ADC1RL;               /*ADC*/

        if((SCI1S1 & (1<<7)))
        { 
            SCI1D = ((bob*100)/255);
        }

        if(SCI1S1_RDRF == 1 )  /*KEYBOARD RX- lights up a specific LED*/
        {
            bob = SCI1S1;
            if(SCI1D_R7_T7 == 1) PTFD_PTFD7 =1;
            else PTFD_PTFD7 = 0;            
        }

        // the following LED sequence is the PROBLEM-A-      
        /*for (i=1;i<=8;i++) 
        {
            if (i==8) i = 1;       
            if (i==1) PTFD_PTFD0 = 0;else PTFD_PTFD0 = 1;    
            if (i==2) PTFD_PTFD1 = 0;else PTFD_PTFD1 = 1;
            if (i==3) PTFD_PTFD2 = 0;else PTFD_PTFD2 = 1;    
            if (i==4) PTFD_PTFD3 = 0;else PTFD_PTFD3 = 1;    
            if (i==5) PTFD_PTFD4 = 0;else PTFD_PTFD4 = 1;    
            if (i==6) PTFD_PTFD5 = 0;else PTFD_PTFD5 = 1;    
            if (i==7) PTFD_PTFD6 = 0;else PTFD_PTFD6 = 1;
        }*/

        TPM1SC_TOF = 0;
    }
}

Now, board performs the 2 actions really well: the Keyboard RX and Voltage regulator to percentage conversion. But as soon as I bring in the LED sequence part, it stops working on other two.

  1. the logic for TIMER control is check for the overflow flag.

  2. logic for Keyboard Rx is to check for hte RX-Flag.

  3. logic for ADC is to check for the ADC data register.

I don't know how to place this question more accurately. If any ambiguity please let me know.

EDIT: the keboard RX and ADC percentage conversion is happening once per second whereas I want the LED sequence to occur at a rate of 250ms, i.e. once every 250ms, led changes state (1 to 0 and 0 to 1).

Links:

Newer code with respect to Oli Glaser's suggestions

for(;;)
{
    if(TPM1SC_TOF < 1)
    {
        bob = ADC1RL;               /*ADC*/

        if((SCI1S1 & (1<<7)))
        { 
            SCI1D = ((bob*100)/255);
        }

        if(SCI1S1_RDRF == 1 )  /*KEYBOARD RX*/
        {
            bob = SCI1S1;
            if(SCI1D_R7_T7 == 1) PTFD_PTFD7 =1;
            else PTFD_PTFD7 = 0;            
        }

        TPM1C1SC_CH1IE = 0; // channel interrupt flag is reset     
        TPM1SC_TOF = 0; //timer overflow flag is reset
    }
}

void ledseq()
{
    for (i=1;i<=8;i++)
    {
        if (i==8) i = 1;       
        if (i==1) PTFD_PTFD0 = 0;else PTFD_PTFD0 = 1;    
        if (i==2) PTFD_PTFD1 = 0;else PTFD_PTFD1 = 1;
        if (i==3) PTFD_PTFD2 = 0;else PTFD_PTFD2 = 1;    
        if (i==4) PTFD_PTFD3 = 0;else PTFD_PTFD3 = 1;    
        if (i==5) PTFD_PTFD4 = 0;else PTFD_PTFD4 = 1;    
        if (i==6) PTFD_PTFD5 = 0;else PTFD_PTFD5 = 1;    
        if (i==7) PTFD_PTFD6 = 0;else PTFD_PTFD6 = 1;
    }
}

ISR

__interrupt void isrVtpm1ch1(void)
{
    void ledseq();
    /* Write your interrupt code here ... */
}
/* end of isrVtpm1ch1 */
Trygve Laugstøl
  • 1,410
  • 2
  • 19
  • 28
sheetansh
  • 355
  • 1
  • 2
  • 15

1 Answers1

1

I would put the LED code in an interrupt routine and use a timer, if you want an accurate timing with minimal disturbance to the main code.
I don't know anything about the micro you are using, but I assume it has a couple of timers, so use one of these to trigger the interrupt to increment the LED. You can either put the whole code in the routine, or set a flag bit in the interrupt routine that triggers an LED increment function in the main code, which then clears the flag (generally you want to keep your interrupt code as short as possible)

You could also use an interrupt for the UART receive also, so you don't have to continuously poll for a keyboard Rx.

Alternatively, if you want to use the same timer but have different timings, you can have two loops, one fast outer loop and an inner loop that checks for, say, every 4th loop to divide the timing by 4 (then you could have your outer loop running at 250ms, and your inner loop running at 1 second intervals)

Your code check could use the modulus symbol e.g. if(i % 4 == 0), then you can just leave i incrementing with no need to reset it.

Oli Glaser
  • 54,990
  • 3
  • 76
  • 147
  • thanks oli! i will get back to you if i am stuck again. thanks for the idea! – sheetansh Jan 23 '13 at 15:10
  • Mate, i tried this. as you know TIMERs use modulo counters, so i checked the Modulo counter value it takes to reach 250ms, within the timer which is working at 1 sec. BUT it didnt work. was my method rite? – sheetansh Jan 23 '13 at 15:20
  • I meant just a char or int value you check and increment in the loop. I couldn't say about your method without seeing the full code you used. In any case, the interrupt method is a better way to do things, try this and see how you go, if you get stuck post all your code and I'll take a closer look (a link to the datasheet of your micro and dev board would be handy too) – Oli Glaser Jan 23 '13 at 15:25
  • mate, i have never worked with interrupts so this is wat i am facing now. I am using freescale Processor Expert to initialize values and settings for the board and MCU. now whenever i simply initilize or enable the interrupt property of the MCU, BOOM, the other two programmed funcitons also stop working. Note at this point my interrupt code is empty. nothing in there.its only initialised, why is tat?? – sheetansh Jan 23 '13 at 16:12
  • You probably need to clear the interrupt flag in the interrupt routine (unless it's automatically cleared, which some peripherals do), otherwise it will just keep calling the interrupt. – Oli Glaser Jan 23 '13 at 16:15
  • Mate, i just came back to work today, tried as you suggested. please take note of the code in the edits. the code now does a run through, it just fast fowards through the entire code once and stops. irrespective of the TIMER value. for the keyboard rx and ADC function i have set the channel compare value at 65535(1sec) whereas for the led sequence i have set the channel compare value at 16000(250ms). if you are still interested please advise! – sheetansh Jan 25 '13 at 08:41