EdiFirst 0 Posted July 14, 2013 Share Posted July 14, 2013 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! Quote Link to post Share on other sites
EdiFirst 0 Posted July 15, 2013 Author Share Posted July 15, 2013 Someone please? Quote Link to post Share on other sites
roadrunner84 466 Posted July 15, 2013 Share Posted July 15, 2013 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? EdiFirst 1 Quote Link to post Share on other sites
EdiFirst 0 Posted July 15, 2013 Author Share Posted July 15, 2013 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? Quote Link to post Share on other sites
roadrunner84 466 Posted July 15, 2013 Share Posted July 15, 2013 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. Quote Link to post Share on other sites
EdiFirst 0 Posted July 15, 2013 Author Share Posted July 15, 2013 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 Quote Link to post Share on other sites
roadrunner84 466 Posted July 16, 2013 Share Posted July 16, 2013 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(); } EdiFirst and GeekDoc 2 Quote Link to post Share on other sites
EdiFirst 0 Posted July 16, 2013 Author Share Posted July 16, 2013 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.:-) Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.