AGlass0fMilk 5 Posted July 12, 2011 Share Posted July 12, 2011 I am trying to make a frequency counter in order to experiment with the MSP430G2553. But as a beginner to microcontrollers (although not programming), it is proving harder than I thought (an operating system certainly hides a lot!) This project is supposed to be able to measure quite low frequencies (at most ~1.5kH) and I need to sample multiple frequencies at a time. From my understanding of the research I've currently done, one possible (quick) formula to measure a frequency is to start a counter at the rising edge of a frequency, and then stop it at the next rising edge of a frequency, take the value and then find the reciprocal (1/counter_value) or sample the frequency like this for multiple cycles and then find the average. I also believe that one possible way to do this is to use the Timer_A peripheral of the MSP430G2553 in capture mode, which I understand to have 3 channels for capture (which means I can determine 3 different frequencies with one chip simultaneously?). But where I am having trouble is the actual programming aspect of this project as I am new to microcontrollers and I am quickly realizing that there is a lot more to programming embedded systems than desktop computers! I have a couple of questions: Are my described methods correct/efficient/accurate? If not, what is the best formula for determining a frequency real-time (it must be done as fast as possible) Is my assumption that 3 frequencies (channels) may be analyzed by Timer_A at once correct? Or are there more/less channels available? How do I set up the Timer_A to be sourced by an external 32kH watch crystal? (Apparently Internal DCOs are notoriously inaccurate) I know I should look at the User Guide/Datasheet, but there's a lot of information in there and it is a skill itself to be able to navigate and pick out the information you need quickly, so can you point me towards certain sections/examples to help me set this up? Quote Link to post Share on other sites
jsolarski 94 Posted July 12, 2011 Share Posted July 12, 2011 Timer A setup --this is for the 2452/53 the bare minimum settings --no ISR TACTL |= TASSEL_1; //sets Timer A to ACLK TACCTL0 |= MC_1 + CAP; //sets up Capture/compare register for Capture on rising edge and enable capture TACCTL1 |= MC_1 + CAP; TACCTL2 |= MC_1 + CAP; in TACCTLx register there is a setting to tell it what pin or internal connection to activate the Capture function. CCISx 00 CCCIxA 01 CCIxB 10 grnd 11 vcc This setting allows you to use either an external pin or SW to use the capture function , I would definitely read CH12 in SLA144x.pdf Family user guide, x= version letter Your approach to the whole thing should work correctly, and you may be able to find some examples from iDave, he has been working on the "TAOS light to frequency IC" but dont know if he has posted any code bluehash 1 Quote Link to post Share on other sites
AGlass0fMilk 5 Posted July 12, 2011 Author Share Posted July 12, 2011 It appears that the MSP430G2553 actually has two 16-bit Timers (Timer0_A and Timer1_A)! Which I believe means I have 6 Capture/Compare channels, which is a good number for my project. The only problem is that the TACCRO1 and TACCRO2 are grouped into the TAIV interrupt vector but it probably won't be that big of a problem. EDIT: It also appears that there is no external input pin for TA0CCTL2 so I may only be able to have 5 inputs Quote Link to post Share on other sites
jsolarski 94 Posted July 13, 2011 Share Posted July 13, 2011 if you wanted more you could use SW to switch activate the capture Quote Link to post Share on other sites
AGlass0fMilk 5 Posted July 13, 2011 Author Share Posted July 13, 2011 I have been reading the datasheet and family user guide and have found out more about the MSP430G2553's two Timer_As. For my project, I want interrupts enabled so I have written some extra code. I have also looked at demos that are designed do to things similar to what I am trying to do, but my code isn't working. There's a lot to initialize that I don't fully understand yet so bear with me. I am testing my code with a 555 timer that is set to emit around 500Hz, but nothing happens when I apply the output to P2.0 (the pin I am testing with) Here's the code: #include void main(void) { volatile unsigned int i; WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer for (i=0; i<20000; i++) // Delay for crystal stabilization { } //TA0CTL |= TASSEL_1 + TAIE; //sets Timer A to ACLK - 32768Hz Watch Crystal with Interrupts TA1CTL |= TASSEL_1 + TAIE; P1DIR |= BIT0 + BIT6; //P1.0 and P1.6 Outputs (Red/Green LEDs) P1OUT &= ~BIT0; //Red LED off P1OUT |= BIT6; //Green LED on P2DIR &= ~BIT0; //P2.0 Input //Set P2.0 to Primary Peripheral function P2SEL |= BIT0; //Sets up Capture/Compare register for Capture on rising edge and enable capture TA1CCTL0 |= CM_1 + SCS + CCIS_0 + CAP + CCIE; //Timer1_A : CCI0A - Capture on P2.0 //CC Register: TA1CCR0 _BIS_SR(LPM0_bits + GIE); // Enter LPM0 w/ interrupt } //Timer_A1 TACCR0 Interrupt Vector Handler Routine #pragma vector=TIMER1_A0_VECTOR __interrupt void Timer1A0(void) { P1OUT |= BIT0; //Turn on Red LED } But when I apply the output of the 555 timer circuit onto P2.0, the Red LED does not turn on, so what could be going wrong? What is there still to set? Sorry that the code is kinda messy. Quote Link to post Share on other sites
nobody 47 Posted July 13, 2011 Share Posted July 13, 2011 One error is in line: TA1CTL |= TASSEL_1 + TAIE; Your timer not running. Edited line: TA1CTL |= TASSEL_1 + TAIE + MC_2; /* Timer A mode control: 2 - Continous up */ And into interrupt routine maybe try this (you can see all captures, not only the first ...): P1OUT ^= BIT0; // Toggle Red LED using exclusive-OR jsolarski 1 Quote Link to post Share on other sites
AGlass0fMilk 5 Posted July 13, 2011 Author Share Posted July 13, 2011 Thank you very much! I guess I missed that setting But the capture/ISR works, I'll post back if I have anymore questions. Quote Link to post Share on other sites
AGlass0fMilk 5 Posted July 26, 2011 Author Share Posted July 26, 2011 I have been experimenting with MSP430G2553 for a while now, I have the hardware UART sending the measured frequencies to my computer through the USB and I have successfully measured PWM'd signals accurately. I have been reading the user guides for both the family and the specific chip I have, and I came across the fact that you can set P1 and P2 interrupts to go off on rising edges, much like the Capture/Compare function of Timer_A. But since I need more than 5 capture ports (which is how many my device supports externally) I was thinking: What is the difference between having the Capture/Compare module interrupt on the rising edge and take the value of Timer_A's counter and having P1 or P2 interrupt on the rising edge and take the value of Timer_A's counter? Other than the fact that the C/C module is specifically designed for that purpose, would it be the same? This would allow me to use 1 Microcontroller in the circuit instead of 2, which is much more elegant and desirable. Quote Link to post Share on other sites
oPossum 1,083 Posted July 27, 2011 Share Posted July 27, 2011 It takes some time to respond to an interrupt, so the value you read from the timer will always be a bit off. There are many things that affect interrupt latency, so it is not possible to compensate for it accurately. The timer capture will save the timer value when a pin changes state and then optionally trigger an interrupt. The interrupt latency does not matter because the timer value has been saved in the capture register. Quote Link to post Share on other sites
aaguilar4 0 Posted July 27, 2011 Share Posted July 27, 2011 Depending on your clock speed and the response time required it might not matter at all. If, for example, you are keeping track of time in seconds and want to know on which second the input changed, then it certainly doesn't matter if you use TimerA capture or Pin change interrupts. However, for most applications you want to get as accurate a reading as possible, for which the capture registers are ideal. To give you an example, the interrupt latency in a recent PIC project I was working on was 11 clock cycles (depending on certain parameters this could go up significantly). Accounting for interrupt latency is important if you are interested in accuracy at 1/Fosc kind of scale. (If you use a 1MHz clock for example, you might wanna watch out for latency if you care about microsecond accuracy) So basically you want to watch out for interrupt latency, but keep in mind that it won't unbearably long! Hope this helps! 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.