guybarash 0 Posted July 30, 2014 Share Posted July 30, 2014 hi , I've switched to the MSP430-F5529 and i'm trying to measure a PWM, and i'm having a bit of hard time understanding the registers use, i want to use timer TA2 which has (according to the datasheet) : P2.3/TA2.0 P2.4/TA2.1 P2.5/TA2.2 as i'm getting input i'm guessing that p2dir = 0; what is the p2sel should be? TA1CCR0 ? TA1CCTL0? TA1CCTL1? TA1CTL? and can i have a bit of an explanation about these register function? and to which of these pins shpuld the pwm be connected to? thank you. Quote Link to post Share on other sites
roadrunner84 466 Posted July 30, 2014 Share Posted July 30, 2014 I've never worked with PWM input, also most PWM related stuff on the forum is about PWM output! If you want to measure PWM signals, then you can use a timer to capture the timer counter register on a specific edge signal. In your case, you should probably have two edge captures set up; one for the falling edge (first PWM part) and a second for the rising edge (second PWM part, relates to the frequency of the PWM signal) Then you need to reset the timer on the second PWM edge so the next cycle will measure over a single period. I think you can use CCR0 to do the reset behaviour. In such a case, you may even need all three of them. In the msp430 family guide there is a detailed description of the timer behaviour (google for SLAU144J.PDF, or just SLAU144) The pins that relate to the timer inputs are described in the datasheet for your msp430, if you're using the Launchpad G2 you can take a peek on the Energia website, but if you're not using Energia you'll still need to set up PxSEL to select the timer functions for your pins. Quote Link to post Share on other sites
tripwire 139 Posted July 31, 2014 Share Posted July 31, 2014 Table 16 ("TA2 signal connections") on page 33 of the datasheet is a good place to start. The left half of that table shows the inputs for the different module blocks of TA2. For externally connected inputs it gives the corresponding pin numbers for the various package types. In the case of the F5529 this is fairly simple; P2.3-5 are your external inputs to TA2, so the input pins match the output pins. That's not always the case, which is why it's important to check the timer's "signal connections" table in the datasheet. Notice how the table says that the three external inputs are called module input CCI0A, CCI1A and CCI2A. You'll need to know that when you set up TA2CCTL0, TA2CCTL1 or TA2CCTL2 later. Assuming you've connected the input signal to P2.3, you then need to configure that pin to pass the input through to the timer module. Table 50 on page 83 of the datasheet shows what you need to do. In this case, you want to configure P2.3 for the TA2.CCI0A function. That means clearing bit 3 of P2DIR and setting bit 3 of P2SEL. Next you need to set up TA2CCTL0. Set the CAP bit, and set the CCIS bits to 00 to take the input from for CCI0A. You can pick which signal edge(s) trigger a capture with the CM_x bits. Finally you need to set up the timer. For capturing you generally want to use continuous mode so the range of timer values is as big as possible. To measure the frequency and duty cycle you'll need to capture the timer's value on the rising and falling edge of the input signal. You can either use a single capture register set to capture on both edges, or use separate registers for the rising edge and the falling edge. If you use two registers you'll need to connect the input signal to multiple timer input pins, of course. guybarash 1 Quote Link to post Share on other sites
KatiePier 73 Posted July 31, 2014 Share Posted July 31, 2014 Hi @@guybarash, The family user's guide is definitely where you want to look for more details about timer operation and the registers and bits that control these functions, just as @@roadrunner84 recommended. However, the SLAU144 document is for the 2xx family of devices - for the F5529, you will want to look at SLAU208 which is the user's guide for the F5xx/6xx family of devices. For timer A operation this shouldn't really matter as timer A is pretty much the same across families, but there are other modules that differ between the two families (clock system, power management, etc) so this is definitely the better document to look at in your particular case. Regards, Katie guybarash 1 Quote Link to post Share on other sites
roadrunner84 466 Posted August 1, 2014 Share Posted August 1, 2014 ...just as @@roadrunner84 recommended. However, the SLAU144 document is for the 2xx family of devices - for the F5529, you will want to look at SLAU208 which is the user's guide for the F5xx/6xx family of devices. Oops, sorry. I wasn't paying enough attention I guess. SLAU208 it is then KatiePier 1 Quote Link to post Share on other sites
guybarash 0 Posted August 3, 2014 Author Share Posted August 3, 2014 ok, i've got it running with a few modification in order to meet my specifics . but every once in while i'm getting jibbrish instead of a number(ASCII jibrrish), i've attached the printscreen and the code, you maybe know where is the failure? #include <msp430.h> #include <stdint.h> #include <stdlib.h> //global variables volatile char vmsg[81]; //the gps str volatile unsigned int vi = 0; // counter for the interrupt volatile int vvalid = 0; // vmsg is valid iff vvalid =1 volatile uint32_t upd = 0; // Ultrasonic Pulse Duration (500 ns resolution) //UART functions void initUART1() ; // init UART1 (to PC) void initUART2() ; // init UART2 (from gps) void putc(volatile char c); //send a single char void puts(volatile char *s); //send a string char getc(); //Receive single char void print_int(int n); // Print integer void print_u32(uint32_t n, const unsigned dp) ; // print U32 //sensor functions void initcmprTimerA (); //init timer A comparison int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT initUART1(); initUART2(); initcmprTimerA (); __bis_SR_register(GIE); //interrupts enabled // Setup puts("\r\nStart here: \r\n"); upd =0; // end of setup while(1){ // Endless Loop start puts("reading: "); while (upd == 0); //wait reading print_u32(upd,0); upd = 0; // signal "ready" puts("\r\n"); // Endless Loop ending } } void initcmprTimerA () { P2DIR &= ~BIT4 ; // Comparison is done on port 2.4 P2SEL |= BIT4 ; // function in 2.4 is used TA2CTL = TASSEL_2 | MC_2 | ID_3 | TACLR | TAIE; TA2CCTL0 = OUTMOD_4; // Toggle mode TA2CCTL1 = CM_3 | SCS | CAP | CCIE; // Rising and falling, sync, capture, interrupt TA2CCTL2 |= 0; // not in use } void initUART1(){ P4SEL |= BIT4 + BIT5; UCA1CTL1 |= UCSWRST; // **Put state machine in reset** UCA1CTL1 |= UCSSEL_2; // SMCLK UCA1BR0 = 6; // 1MHz 9600 UCA1BR1 = 0; // 1MHz 9600 UCA1MCTL = UCBRS_0 + UCBRF_13 + UCOS16; // Modln UCBRSx=0, UCBRFx=0, UCA1IE |= UCRXIE; // over sampling UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine** } void initUART2() { P3SEL = BIT3+BIT4; UCA0CTL1 |= UCSWRST; // **Put state machine in reset** UCA0CTL1 |= UCSSEL_2; // SMCLK UCA0BR0 = 6; // 1MHz 9600 UCA0BR1 = 0; // 1MHz 9600 UCA0MCTL = UCBRS_0 + UCBRF_13 + UCOS16; // Modln UCBRSx=0, UCBRFx=0, // over sampling UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine** UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt } void putc(char c) { while (!(UCA1IFG & UCTXIFG)); UCA1TXBUF = c; } void puts(volatile char *s) { while(*s) putc(*s++); } char getc() { //Receive char while (!(UCA1IFG & UCRXIFG)); return UCA1RXBUF; } void print_int(int n) // Print integer { int msbflag = 1; // changing msbflag setup to 0 disables '0' in msb, '1' o.w . example for values of msb flag: '1' : +000123 '0': 123 if (n < 0 ) { putc('-'); n = 0 - n; } else {putc('+'); } if ((n == 0 ) && (msbflag == 0) ) { putc('0'); return; } unsigned c; // c = '0'; while(n >= 100000UL) n -= 100000UL, ++c; if( (c!= '0') || (msbflag > 0) ) {msbflag++; putc(c);} // c = '0'; while(n >= 10000) n -= 10000, ++c; if( (c!= '0') || (msbflag > 0) ) {msbflag++; putc(c);} // c = '0'; while(n >= 1000) n -= 1000, ++c; if( (c!= '0') || (msbflag > 0) ) {msbflag++; putc(c);} // c = '0'; while(n >= 100) n -= 100, ++c; if( (c!= '0') || (msbflag > 0) ) {msbflag++; putc(c);} // c = '0'; while(n >= 10) n -= 10, ++c; if( (c!= '0') || (msbflag > 0) ) {msbflag++; putc(c);} // c = '0'; while(n) --n, ++c; if( (c!= '0') || (msbflag > 0) ) {msbflag++; putc(c);} // return; } void print_u32(uint32_t n, const unsigned dp) // Print 32 bit unsigned with optional decimal place // 6 decimal digits (0 -> 999999) { // unsigned c; // c = '0'; while(n >= 100000UL) n -= 100000UL, ++c; putc(c); if(dp == 5) putc('.'); // c = '0'; while(n >= 10000) n -= 10000, ++c; putc(c); if(dp == 4) putc('.'); // c = '0'; while(n >= 1000) n -= 1000, ++c; putc(c); if(dp == 3) putc('.'); // c = '0'; while(n >= 100) n -= 100, ++c; putc(c); if(dp == 2) putc('.'); // c = '0'; while(n >= 10) n -= 10, ++c; putc(c); // if(dp == 1) putc('.'); // c = '0'; while(n) --n, ++c; putc(c); // } // interrupts #pragma vector=USCI_A0_VECTOR __interrupt void USCI_A0_ISR(void) { switch(__even_in_range(UCA0IV,4)) { case 0:break; // Vector 0 - no interrupt case 2: // Vector 2 - RXIFG vvalid = 0; vmsg[vi] = UCA0RXBUF; vi++; if ((vmsg[vi-1] == 10) && (vmsg[vi-2] == 13)) { //end of msg vmsg[vi] = '\0'; vi = 0; vvalid = 1; } /* while (!(UCA1IFG&UCTXIFG)); // USCI_A0 TX buffer ready? UCA1TXBUF = UCA0RXBUF; // TX -> RXed character */ break; case 4:break; // Vector 4 - TXIFG default: break; } } #pragma vector = TIMER2_A1_VECTOR // Timer vectored interrupt __interrupt void timer2_a2_isr(void) // { // static uint32_t rise = 0; // Pulse rise time static uint32_t fall; // Pulse fall time // switch(TA2IV) { // TA0IV must be read to reset interrupt case 0:break; // Vector 0 - no interrupt case 0x02: // 0x02 == CCR1 (capture/compare) if(TA2CCTL1 & CCI) { // - Rising edge rise = TA2CCR1; // Save rise time fall = 0; // Reset fall time } else { // - Falling edge if(rise) { // Make sure rising edge has occurred // Handle possible pending overflow interrupt if((TA2CTL & TAIFG) && (TA2R < 0x1000)) fall += TA2CCR0; // fall += TA2CCR1; // Get fall time, add to overflow time if(!upd) {upd = fall - rise;} // Update time if mainline code is ready for it rise = 0; // Clear rise time to ensure next rising edge is used } // } // break; // case 0x0A: // 0x0A == TAIFG (overflow) fall += TA2CCR0; // Update overflow time break; // } // } // of course, any other comments about the code a re very welcome. 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.