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.

Pattern (or Bit) generator with MSP430

Other Parts Discussed in Thread: MSP430G2553

Hi,

I'd like to have a bit generator such as 1010101010000000000 using msp430g2553.

 I generated PWM signal using code below. This code will generate about 50-kHz signal with 50% duty cycle. 

#include <msp430g2553.h>
unsigned int i=0;


void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT

P1DIR |= BIT2; // P1.2 to output
P1SEL |= BIT2; // P1.2 to TA0.1

CCR0 = 20-1; // PWM Period
CCTL1 = OUTMOD_7; // CCR1 reset/set
CCR1 = 10; // CCR1 PWM duty cycle
TACTL = TASSEL_2 + MC_1; // SMCLK, up mode

}

But this is only 10101010101010101010 not (1010101010000000000) so I tried to use interrupt and added these lines in the main (). 

P1IE |= BIT2; // P1.2 interrupt enabled
P1IES |= BIT2; // P1.2 Hi/lo edge
P1IFG &= ~BIT2; // P1.2 IFG cleared

Also tried to add interrupt service routine such as 

#pragma vector = TIMER0_A0_VECTOR
__interrupt void CCR0_ISR(void) {
for (i=0;i<=9;i++){

if (i <= 4) {
CCTL0= OUTMOD_1;
P1IFG &= ~BIT2;
}
else if(i <= 8) {
CCTL0= OUTMOD_0;
P1IFG &= ~BIT2;

}
else {
CCTL0= OUTMOD_0;
P1IFG &= ~BIT2; //clear IFG
i=0; //reset i so it can only loop between 0~9
}
}

}

My code doesn't work either so can you please help me generating bit sequence 10101010100000000000 and repeating these?

  •  Asking someone to solve what you are not able to do is not a correct learning method!!!! Here none can waste time to do that so to do your job you have to learn C programming in first then load your pattern in an array and scan this array on interrupt to output the sequence you prepared. A better approach can be to store more than 1 bit per array element.

     

  • You are going the wrong way!

    PWM is not really suitable for that. Take a timer and generate an interrupt. This period is the frequency (bitrate) at which your 1s and 0s come out of your MCU.

    In this ISR you have to determine your actual bit of your pattern and set a GPIO high or low, depending on the actual bit.

  • Dennis Eichmann said:

    PWM is not really suitable for that. Take a timer and generate an interrupt. This period is the frequency (bitrate) at which your 1s and 0s come out of your MCU.

     Dennis in some way the original poster was on the correct way repeating a lomng sequence of instruction setting mode_0 mode_1 etc... this is wrong as approach so it can simply scan outbit from an array and decide to set output at 1 or 0 on next timer event. First part of code is PWM but second is "beginner mode" sequence macrocode....

    Dennis Eichmann said:
    In this ISR you have to determine your actual bit of your pattern and set a GPIO high or low, depending on the actual bit.

     This is also wrong so you can add jitter to pattern clock.

     The approach of our poster was ok.

     So set outmode as set bit then decide to set 1 or 0 according to bit value. It need two counter, bit counter to decide when current array element exhaust last bit and an index counter to scan pattern storage array...

     As I wrote take inspiration from software serial example.

  • Daeyeon Kim said:
    My code doesn't work either so can you please help me generating bit sequence 10101010100000000000 and repeating these?

     I hate  do that.. but

    Daeyeon Kim said:

    #pragma vector = TIMER0_A0_VECTOR
    __interrupt void CCR0_ISR(void) {
    for (i=0;i<=9;i++){

     This code repeatedly set outmode on interrupt service.. this is a non sense, remove this instruction and declare a static variable:

    static int i=0;

    Daeyeon Kim said:
    CCTL0= OUTMOD_0;

    P1IFG &= ~BIT2; //clear IFG
    i=0; //reset i so it can only loop between 0~9

     This is internal to for loop so before to test next value i got reste to 0 and for never leave interrupt hanging here.

     On other word a lot of beginner coding errors but some way intuition on how to do ..

     Static declaration inside interrupt routine allocate space on global variable leaving it local, this don't waste time to make space on stack and also remember value from one call to the next one.

     Change last red line with:

     i++; // increment pointer

     if(i>9) i=0; // restart sequence if over last element of array..

     Outmod can be set by element value... SO please grasp array manipulation tecnique and you are ok.

  • OK, had a look at OUTMOD_0 - have never used it. So...sorry for "wrong way"!

    Give it a try.

    Anyway...I would not expect a measurable jitter, but this also depends on the coding technique.

  • @Roberto I didn't mean to ask to fix my code nor provide an answer. This is a part of my code and simplified version. I wanted to show my code what I was trying so you could understand better. I apologize if you feel I urge you give me an answer and also thank you for pointing out which direction I should go. I appreciate your help.

    best

    Daeyeon 

  • Daeyeon Kim said:
    This is a part of my code and simplified version.

     Hi, please don't try to lie yourself, I am teaching too and I am able to see what is a mistake and when someone was not so acquainted with code writing... Everyone of us can do a mistake and sometime I do too.

     Hope this helped you to complete your job and as hint on how to do things better.

     If you get the code I suggested (software usart) you can learn technique of set output precisely when timer compare.

    Daeyeon Kim said:
    I apologize if you feel I urge you give me an answer

     If that was the intention felt, I assure you never wrote an answer again.

     My answer was to direct to solution than have loss of information and confusion.

     Your code as I wrote was near solution but fuzzy in the manner like a beginner who don't well know how to code, sorry if this was an error done by some other way, it is a common beginner error.

     Your code was a non sense due to OUTMODE perform its action on next interrupt due to next compare. The errors on code catched interrupt service on an infinite loop. Setting multiple times OUTMODE has no useful application, just last one take effect and just on next interrupt than never can come without first returning from first catch.

     Another rule never do looping instruction in interrupt service than it is really necessary, interrupt service has to be as short as possible.

  • Dennis Eichmann said:
    Anyway...I would not expect a measurable jitter, but this also depends on the coding technique.

     Hi Dennis, Jitter came from two sources:

     one is code delay in interrupt service, time to serve (fixed if irq forever on, undeterminate if some part disable/enable interrupt) and internal decisional part (pattern/position dependent), both of them appears as fixed phase delay.

     the worst come from other interrupt services that can delay service of pattern generator by unknown value, also if nested can delay a lot service. Try set two pin, one from capture and the other from software, with a scope you can see what happen adding other interrupt sources, just try add a flashing led routine on high speed mode watchdog timer counting down event in more than one loop, this is enough to add visible jitter.

  • Hi Roberto!

    I fully agree with you in all points!I referred to the line:

    I generated PWM signal using code below. This code will generate about 50-kHz signal with 50% duty cycle.

    This did not sound like there is the need to be such accurate as the internal DCO is used which isn't very precise at all. Anyway...to point it out again: Of course you are right.

**Attention** This is a public forum