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.

Trying to make a pulse counter output results to four multiplexed seven segment displays

Other Parts Discussed in Thread: MSP430G2553

I am a beginner with the MSP 430 and not sure where to begin.  I am making a circuit board and have made a schematic using a msp430g2553, a bcd to seven segment driver, and four seven segment led displays.  I made the schematic on eagle 6.5 and I have attached the file.

1447.project_schematic.sch

 

I'm using a square wave signal from a bnc connector into the msp430.

I connected outputs 1.4, 1.5, 1.6, and 1.7 from the msp430 to the bcd driver inputs.

I connected outputs 1.0, 1.1, 1.2, and 1.3 from the msp430 to transistors to turn the displays on and off.

 

Not sure how to output the counter results to the bcd driver and multiplex the signal across the displays.  Any pointers are very appreciated.

 

  • I think you need to do the following:

    (a) Use a Timer/Counter to count the pulses. (BTW, why BNC? How fast are the pulses? What voltage level?)

    (b) Convert the above count from binary to bcd digits.

    (c) Present one of the bcd digits at P1.4, 5, 6, 7 and assert one of P1.0, 1, 2, 3 that correspond to the digit (deassert other three). 

    (d) Repeat (c) above for all 4 digits.

  • Counting the pulses from a high voltage wave form generator.  Ranging from 600 to 1000 pulses per second.  The voltage level is 600V.  I believe the voltage level coming out of the bnc is 5V.

  • I'm using a MSP430g2553 and I'm looking at the datasheet.  It says Timer0/1_A3 is a 16-bit timer/counter.

     

    What's the C code to initialize Timer 0 or Timer 1 to be a counter?

  • I cannot read Eagle files thus I do not know how your schematics look like. The MSP430G2553 should not be connected directly to anything that goes above its Vcc (~3V) or below its Gnd. If the voltage out of your BNC is about 5V, a series 10k resistor will protect the MSP430G2553.

    You need to connect that to P1.0 to use Timer0; or to P3.7 to use Timer1. You have already used P1.0 for something else, and P3.7 is not available in 20-pin package of MSP430G2553.

    You need to either reroute your P1.0 to LED driver connection, or count the pulses in a different way. The sample code below uses P2.2 interrupt to count.

    #include <msp430.h>
    #define PULSE BIT2
    long int counter;
    void main(void) {
        WDTCTL = WDTPW | WDTHOLD;
        // ... initialize LED display ...
        P2IE |= PULSE;
        P2IFG &= PULSE;
        while (1) {
          // ... display current count on LED...
        }
    }

    #pragma vector=PORT2_VECTOR
    __interrupt void P2_ISR(void) {
        P2IFG = 0;
        if (counter++ > 999999999) counter = 0;
    }


  • I'd implement this using DMA.

    Set up the timer to give a tick each time the multiplex output shall change (so for 1kHz multiplexing frequency, a timer interrupt every ms).

    Set up the DMA to repeatedly copy a sequence of four bytes from memory to P1OUT register, one transfer each timer interrupt.

    Then construct the four combinations of BCD segment and line output settings in this memory location (e.g. in an array of chars). That's all. Alter the array properly to change the display, the DMA will constantly update the display to maintain the multiplexing.

    You probably can't go below LPM0 in this constellation, since the DMA requires MCLK. But well, with a multiplexed LED display, power saving a few µA surely isn't an issue.

  • Here's a .png of the schematic

     

    You can ignore the current sensor for now.  I will use that and program for that later.

  • OK, I got the multiplexing figured out.  Now I just need to set up an interrupt on pin 1.0 to count the pulses.  Here's what I have so far, shortened up a bit:

     

    int main() {

    BCSCTL1 = CALBC1_16MHZ;    // Set range

    DCOCTL = CALDCO_16MHZ;    // Set DCO step and modulation

    WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

    P1DIR = ~BIT0;

    P1IES =BIT0;

    int counter=0;

    __enable_interrupt();

     

    for (; ; ) {

    A bunch of code for multiplexing the counter number ..........

    ..

    ..

    A bunch of code for multiplexing..........

    }

    return 0;

    }

    #pragma vector = PORT1_VECTOR

    __interrupt void pulseCounter (void) {

    counter++;

    }

     

     

    It gives me the error that identifier "counter" is not defined.  Not sure if I set this up right.  But the pulse is going to pin 1.0 and I want it to count the pulses when the pin goes from low to high.  Any suggestions?

  • counter is declared and defined inside main, so it is a local variable of main and not know outside main.
    You need to declare it globally, so it is also known inside your ISR. And you should declare it volatile, as it is used in main and an ISR an the compiler should not make optimizations on it.

**Attention** This is a public forum