Jump to content
EdiFirst

Simple Sequential : Led + Breadboard

Recommended Posts

Hello, Guys!

 

 So, as some already know I 'm  a noob with embedded system and I really I'm  liking of the series MSP430 by TI.

 

I am trying make this code work, but so far  I did not succeed, What  I want is a simple led sequential on the breadboard, the breadboard will be 9 Leds, being 6 on Port 1, e just 3 in the Port 2 for now.

That code work but not syncronized,  I'd want which when end the first "array" of the leds, starts the seconds "arrays" of the leds (port 2, 3 leds), I would like to use someone like struct in C but I don't have know enough yet, the code:

 

 #include <msp430G2553.h>


  void Delay(void);
  void sequencial(void);
  char led1[7] = {BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6};
  char led2[3] = {BIT0, BIT1, BIT2};
  volatile int i = 0;
  volatile int f = 0;
 
  int main(void) {
    
  WDTCTL = WDTPW | WDTHOLD;
  P1DIR = 0xff;
  P2DIR = 0xff;
 
 
        for (;;) {
          sequencial();
              }
  }
    
    void Delay(void) {
        unsigned int dly = 30000;
        while(--dly); {
            
        }
        }
      void sequencial(void){
        i++;
          Delay();
        P1OUT = led1;
       if(i==7) i=0;
           
         P1OUT |= 0x00;
            f++;
              Delay();
             P2OUT = led2[f];
              if(f==3) f=0;
              
             P2OUT |= 0x00;
      }
   

 

The outpouts are working separately not synchronized, How do I make this? Thanks!

Share this post


Link to post
Share on other sites

 

void sequencial(void){
  i++;
  Delay();
  if (i < 7)
  {
    P1OUT = led1[i];
    P2OUT = 0;
  }
  else
  {
    P1OUT = 0;
    P2OUT = led2[i - 7];
  }
  if (i == 7 + 3) i = 0;
}
Like this?

Thank you again Road!

I did not tester yet, but surely will go work.Is amazing as you solve fast the stuffs, i was thinking someone stuff like

this,but Iam very slowly..I was caught in the loop for.

How we can solve that using struct and bitwise/bit operation?

Share this post


Link to post
Share on other sites

What do you mean? You want to use bitwise operations instead of the arrays you're currently using? How do you intend that? Do you want to have a similar function (a moving light) but without using the array?

 

I do suggest moving the Delay(); call to the for loop, so in the future you can call sequential from a timer interrupt instead of using a delay. This is good practice for low power operations. As such, the sequential function would not be blocking anymore and can be put in/called from an ISR.

Share this post


Link to post
Share on other sites

What do you mean? You want to use bitwise operations instead of the arrays you're currently using? How do you intend that? Do you want to have a similar function (a moving light) but without using the array?

 

I do suggest moving the Delay(); call to the for loop, so in the future you can call sequential from a timer interrupt instead of using a delay. This is good practice for low power operations. As such, the sequential function would not be blocking anymore and can be put in/called from an ISR.

So, Roadrunner now I arrived at home, I tested the code and I don't no why de 1

Share this post


Link to post
Share on other sites

Ah, I see. You should move the i++ to after the LED output but before the if() i=0;

Try to follow the flow of the program.

If i is 0, it will first be incremented and then used to look up the LED.

If i is 9, it will first be incremented and then used to look up the LED... hang on, this means that I will look up location 10 - 7, which is 3. led2[3] only has indexes 0, 1 and 2. So this means that after led2[2] is written, I will write an illegal memory value to P2OUT!

So by moving i++ down, I both enable using led1[0] and disable using the illegal memory location led2[3].

void sequencial(void){
  // remove i++ here
  Delay();
  if (i < 7)
  {
    P1OUT = led1[i];
    P2OUT = 0;
  }
  else
  {
    P1OUT = 0;
    P2OUT = led2[i - 7];
  }
  i++; // add i++ here
  if (i == 7 + 3) i = 0;
}

Now, I'm still not really sure what you want to do with the struct. But I assume you want to use bitwise operators to manipulate the value of your LED output.

I will be using a trick here that only works fine wit the value line MSP430. I use the property that it has two and only two ports, which both are half the size of my word size. The ports P1 and P2 are both 8 bits wide, while my word size (unsigned short) is 16 bits wide; twice as wide.

As a result I can use a single number to address both ports. This is not a very clean trick and should not be considered good practice.

unsigned short i;

void sequencial(void){
  i <<= 1; // move i one bit to the left, identical to i = i << 1; also identical to i += i; and i = i + i;
  if (!(i & 0x07FF)) i = 1; // since we only use 3 bits of P2, if none of the lower 8 + 3 = 11 bits is high, reset i to ONE
  if (i & 0xFF)
  {
    P1OUT = i;
    P2OUT = 0;
  }
  else
  {
    P1OUT = 0;
    P2OUT = i >> 8; // use the higher byte of i, done by shifting the value by 8.
  }
  Delay();
}

Note that the MSP430 cpu architecture is designed without a barrel shifter, this means that using a shift operator is expensive if done by any value other than 1. The exceptions are the values 8 and 16, since the first is built in as a byte swap (inside a 16 bit word) and the second a word swap (done in software, takes 3 assignments).

 

Alternatively you could use two separate variables, but it will be a little more difficult:

unsigned char i1, i2;

void sequencial(void){
  i2 <<= 1; // shift counter for P2
  if (i1 & 0x80) i2 |= 1; // and set the lowest bit high if it would be carried from i1
  i1 <<= 1; // sift counter for P2
  if ((i1 == 0) && !(i2 & (BIT1 | BIT2 | BIT3))) // if none of the used 11 bits is high, reset the values
  {
    i1 = 1;
    i2 = 0;
  }
  P1OUT = i1;
  P2OUT = i2;
  Delay();
}

Share this post


Link to post
Share on other sites

Ah, I see. You should move the i++ to after the LED output but before the if() i=0;

Try to follow the flow of the program.

If i is 0, it will first be incremented and then used to look up the LED.

If i is 9, it will first be incremented and then used to look up the LED... hang on, this means that I will look up location 10 - 7, which is 3. led2[3] only has indexes 0, 1 and 2. So this means that after led2[2] is written, I will write an illegal memory value to P2OUT!

So by moving i++ down, I both enable using led1[0] and disable using the illegal memory location led2[3].

 

void sequencial(void){
  // remove i++ here
  Delay();
  if (i < 7)
  {
    P1OUT = led1[i];
    P2OUT = 0;
  }
  else
  {
    P1OUT = 0;
    P2OUT = led2[i - 7];
  }
  i++; // add i++ here
  if (i == 7 + 3) i = 0;
}
Now, I'm still not really sure what you want to do with the struct. But I assume you want to use bitwise operators to manipulate the value of your LED output.

I will be using a trick here that only works fine wit the value line MSP430. I use the property that it has two and only two ports, which both are half the size of my word size. The ports P1 and P2 are both 8 bits wide, while my word size (unsigned short) is 16 bits wide; twice as wide.

As a result I can use a single number to address both ports. This is not a very clean trick and should not be considered good practice.

unsigned short i;

void sequencial(void){
  i <<= 1; // move i one bit to the left, identical to i = i << 1; also identical to i += i; and i = i + i;
  if (!(i & 0x07FF)) i = 1; // since we only use 3 bits of P2, if none of the lower 8 + 3 = 11 bits is high, reset i to ONE
  if (i & 0xFF)
  {
    P1OUT = i;
    P2OUT = 0;
  }
  else
  {
    P1OUT = 0;
    P2OUT = i >> 8; // use the higher byte of i, done by shifting the value by 8.
  }
  Delay();
}
Note that the MSP430 cpu architecture is designed without a barrel shifter, this means that using a shift operator is expensive if done by any value other than 1. The exceptions are the values 8 and 16, since the first is built in as a byte swap (inside a 16 bit word) and the second a word swap (done in software, takes 3 assignments).

 

Alternatively you could use two separate variables, but it will be a little more difficult:

unsigned char i1, i2;

void sequencial(void){
  i2 <<= 1; // shift counter for P2
  if (i1 & 0x80) i2 |= 1; // and set the lowest bit high if it would be carried from i1
  i1 <<= 1; // sift counter for P2
  if ((i1 == 0) && !(i2 & (BIT1 | BIT2 | BIT3))) // if none of the used 11 bits is high, reset the values
  {
    i1 = 1;
    i2 = 0;
  }
  P1OUT = i1;
  P2OUT = i2;
  Delay();
}
Very clearely Roadrunne!

I did solved the "bug" making the i= -1

About your another approaches,was this which I was looking for really,anothers way to solve the issue.

After I'll try make with interrupt and push bottons for change the behavior of the move.:-)

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...