Hello,
I am wanting to understand this firmware to know how the measured frequency acquisition works.
Could someone help me?
How can I see the measured frequency at the input of the P1.5 PIN?
Regards,
Follow the link with the source code:
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.
Hello,
I am wanting to understand this firmware to know how the measured frequency acquisition works.
Could someone help me?
How can I see the measured frequency at the input of the P1.5 PIN?
Regards,
Follow the link with the source code:
Hello
I am using a port1 p1.0 interrupt pin to count the flow pulses.
After 5 seconds generated by the basic timer BT (temp ++;) I do the flow measurement:
Q = Pulses / Timer.
float flow = (bottom scale of the meter x pulses x 3600 x 1000) / temp;
3600 x 1000 for unit of m3 / h.
For example: 10.15 Hz equal 36.353 m3/h calculated.
My code: 10.15 Hz equal 25.456 m3/h when measured accurately and does not oscillate.
I realized that it is very slow and inaccurate due to being using the XTAL1 32.768kHz crystal.
Maybe the XTAL2 I can get a better result due to frequency being faster but I tried configuring it by slac118l.zip example and could not get it to work .... I guess I did not know how to configure correctly.
I'm also thinking of counting the pulses at the input of the 74HC590 and using the timer A to precisely time it ... I think milliseconds or microseconds get a better result.
What do colleagues have to tell me?
Hello,
I was able to assemble this code however I am not getting the result waiting! For example: The calculated frequency is different from that shown on the oscilloscope, where it is generated 10Hz is measured 20Hz.
And where it is generated 16.6Hz is measured 513Hz!
Did I do something wrong?
I would also like to know if the timer is set correctly in capture mode?
Is it possible to work in LPM3 mode?
#include <stdio.h> #include <intrinsics.h> #include <stdlib.h> #include <string.h> #include <msp430xG46x.h> volatile unsigned int count, edge1, edge2, period; // Global variables float freq; unsigned char string_freq[10]; volatile unsigned int i; /* defines - testar flag de tx da usci 0 e usci1 */ #define testa_tx_cr() while(!(IFG2 & UTXIFG1)); //************************************************************************************************************// // Definições e Inicialização da Comunicação Serial RS232 do Data Logger // //************************************************************************************************************// void initRS232(void) { P4SEL |= 0x03; // P4.1,0 = USART1 TXD/RXD ME2 |= UTXE1 + URXE1; // Enable USART1 TXD/RXD U1CTL |= CHAR; // 8-bit character U1TCTL |= SSEL0; // UCLK = ACLK U1BR0 = 0x03; // 32k/9600 - 3.41 U1BR1 = 0x00; // U1MCTL = 0x4A; // Modulation U1CTL &= ~SWRST; // Initialize USART state machine IE2 |= URXIE1; // Enable USART1 RX interrupt } //************************************************************************************************************// // Rotina para Transmissão Serial do Data Logger // //************************************************************************************************************// void msg_rs232_cr(unsigned char *string) {// envia uma string via rs232 via UCA0 while (*string != 0) { testa_tx_cr();// testa flag de tx TXBUF1 = *string; *string++; } // while string } void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer FLL_CTL0 |= XCAP14PF; // Configure load caps // Wait for xtal to stabilize do { IFG1 &= ~OFIFG; // Clear OSCFault flag for (i = 0x47FF; i > 0; i--); // Time for flag to set } while ((IFG1 & OFIFG)); // OSCFault flag still set? P1DIR &= ~BIT2; // Set P1.2 -> Input P1SEL |= BIT2; // Set P1.2 -> TA0.1 Capture Mode //P1DIR &= ~BIT0; // Set P1.0 -> Input //P1SEL |= BIT0; // Set P1.0 -> TA0 Capture Mode MSP430FG4618 initRS232(); // Inicializa o RS232 TA0CCTL1 = CAP + CM_1 + CCIE + SCS + CCIS_0; // Capture Mode, Rising Edge, Interrupt // Enable, Synchronize, Source -> CCI0A //TACTL = TASSEL_1 + MC_2 + TAIE + TACLR; // ACLK, cont. mode, TA0CTL |= TASSEL_2 + MC_2 + TACLR; // Clock -> SMCLK, Cont. Mode, Clear Timer while(1) { count = 0; // Initialise count for new capture __bis_SR_register(LPM0_bits + GIE); // Enter LPM0, Enable Interrupt //Exits LPM0 after 2 rising edges are captured if (edge2 > edge1) // Ignore calculation if overflow occured { period = edge2 - edge1; // Calculate Period freq = 1000000L/period; // Calculate Frequency msg_rs232_cr("Frequency: "); // Transmite a string Frequency sprintf(string_freq,"%.2f",freq); msg_rs232_cr(string_freq); msg_rs232_cr(" \r\n"); } __no_operation(); // For inserting breakpoint in debugger } } // Timer_A3 Interrupt Vector (TAIV) handler #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=TIMERA1_VECTOR __interrupt void Timer_A (void) #elif defined(__GNUC__) void __attribute__ ((interrupt(TIMERA1_VECTOR))) Timer_A (void) #else #error Compiler not supported! #endif { switch( TAIV ) { case 2: if (!count) // Check value of count { edge1 = TA0CCR1; // Store timer value of 1st edge count++; // Increment count } else { edge2 = TA0CCR1; // Store timer value of 2nd edge count=0; // Reset count __bic_SR_register_on_exit(LPM0_bits + GIE); // Exit LPM0 on return to main } break; // TACCR1 used case 4: break; // TACCR2 not used case 10: break; // overflow } } /* #pragma vector = TIMER0_A1_VECTOR __interrupt void TIMER0_A1_ISR (void) { switch(__even_in_range(TA0IV,0x0A)) { case TA0IV_NONE: break; // Vector 0: No interrupt case TA0IV_TACCR1: // Vector 2: TACCR1 CCIFG if (!count) // Check value of count { edge1 = TA0CCR1; // Store timer value of 1st edge count++; // Increment count } else { edge2 = TA0CCR1; // Store timer value of 2nd edge count=0; // Reset count __bic_SR_register_on_exit(LPM0_bits + GIE); // Exit LPM0 on return to main } break; case TA0IV_TACCR2: break; // Vector 4: TACCR2 CCIFG case TA0IV_6: break; // Vector 6: Reserved CCIFG case TA0IV_8: break; // Vector 8: Reserved CCIFG case TA0IV_TAIFG: break; // Vector 10: TAIFG default: break; } } */
Thanks for the support Bruce!
Yes I need to measure the flow of a pulsed Hydrometer with a scale of 0.001 m3 / h.
I found this code example on the internet and chose to test it and saw that the lowest measured frequency is 200Hz.
Can you configure it as you said?
/*************************************************************************************/ /* Lab 4C - Frequency measurement */ /* */ /* */ /* */ /* MSP430 Teaching ROM */ /* Produced by: MSP430@UBI Group - www.msp430.ubi.pt */ /* */ /* Exercise: Using the MSP-EXP430FG4618 Development Tool and the */ /* MSP430FG4618 device, perform a frequency measurement */ /* */ /* Instructions: */ /* */ /* Complete the code below: */ /* - Configure Basic Timer1 */ /* - Configure Timer_A */ /* - Configure Timer_B */ /* - Configure P1, P2 and P3 */ /* */ /* */ /* */ /* Copyright Texas Instruments 2009 */ /**********************************************************************************/ #include <msp430xG46x.h> #include "LCD_defs.h" //****************************************************************** // Global data //****************************************************************** unsigned char flag, capture, counter, tick; unsigned int T, T1, T2, freq; //****************************************************************** // Write frequency (Hz) in LCD //****************************************************************** void LCD_freq(void) { unsigned int freq1, freq2, freq3, freq4; freq = 7995392/T; freq1 = freq / 1000; freq2 = freq % 1000; switch (freq1) // switch to write frequency first digit { case 1:P4_A1; break; case 2:P4_A2; break; case 3:P4_A3; break; case 4:P4_A4; break; case 5:P4_A5; break; case 6:P4_A6; break; case 7:P4_A7; break; case 8:P4_A8; break; case 9:P4_A9; break; case 0:P4_A0; break; } freq3 = freq2 % 100; freq2 = freq2 / 100; switch (freq2) // switch to write seconds frequency digit { case 1: P3_A1; break; case 2: P3_A2; break; case 3: P3_A3; break; case 4: P3_A4; break; case 5: P3_A5; break; case 6: P3_A6; break; case 7: P3_A7; break; case 8: P3_A8; break; case 9: P3_A9; break; case 0: P3_A0; } freq4 = freq3 % 10; freq3 = freq3 / 10; switch (freq3) // switch to write seconds frequency digit { case 1: P2_A1; break; case 2: P2_A2; break; case 3: P2_A3; break; case 4: P2_A4; break; case 5: P2_A5; break; case 6: P2_A6; break; case 7: P2_A7; break; case 8: P2_A8; break; case 9: P2_A9; break; case 0: P2_A0; } switch (freq4) // switch to write seconds frequency digit { case 1: P1_A1; break; case 2: P1_A2; break; case 3: P1_A3; break; case 4: P1_A4; break; case 5: P1_A5; break; case 6: P1_A6; break; case 7: P1_A7; break; case 8: P1_A8; break; case 9: P1_A9; break; case 0: P1_A0; } } //****************************************************************** // LCD clean routine //****************************************************************** void LCD_all_off(void) { LCDM2 = 0x00; LCDM3 = 0x00; LCDM4 = 0x00; LCDM5 = 0x00; LCDM6 = 0x00; LCDM7 = 0x00; LCDM8 = 0x00; LCDM9 = 0x00; LCDM10 = 0x00; LCDM11 = 0x00; LCDM12 = 0x00; LCDM13 = 0x00; } //****************************************************************** // Timer A Interrupt Service Routine //****************************************************************** #pragma vector=TIMERA1_VECTOR __interrupt void TimerA1_ISR (void) { switch (TAIV) { case TAIV_TACCR1: if (capture == 0){ T1 = TACCR1; flag = 1; capture = 1; } else { if (flag == 1) { T2 = TACCR1; if (T2 > T1) T = T2-T1; } else{ TAR = 0; } capture = 0; flag = 0; } break; case TAIV_TACCR2: break; case TAIV_TAIFG: tick++; if (tick == 60){ LCD_freq(); tick = 0; } if (flag == 1)flag = 0; break; default: break; } } //***************************************************************** // Basic Timer Interrupt Service Routine. Run with 1 sec period //***************************************************************** #pragma vector=BASICTIMER_VECTOR __interrupt void basic_timer_ISR(void) { unsigned int read_data; // read data from file , frequency in kHz P2OUT^=0x06; // toogle LED1 and LED2 counter++; if (counter == 5){ counter = 0; read_data = 200; TBCCR0 = 7995392/read_data; TBCCR4 = TBCCR0/2; } } //****************************************************************** // Main routine //****************************************************************** void main (void) { //Stop WatchDog WDTCTL = WDTPW | WDTHOLD; // Stop WDT //FLL+ configuration // ACLK - 32.768 kHz FLL_CTL0 |= DCOPLUS + XCAP18PF; // DCO+ set, freq = xtal x D x N+1 SCFI0 |= FN_4; // x2 DCO freq, 8MHz nominal DCO SCFQCTL = 121; // (121+1) x 32768 x 2 = 7.99 MHz // Ports COM0-COM1-COM2-COM3 configuration P5DIR |= 0x1E; // Ports P5.2, P5.3 and P5.4 as outputs P5SEL |= 0x1E; // Ports P5.2, P5.3 and P5.4 as special function (COM1, COM2 and COM3) // S0-S21 ports configuration LCDAPCTL0 = LCDS24 | LCDS20 | LCDS16 | LCDS12 | LCDS8 | LCDS4; // LCDA configuration LCDACTL = LCDFREQ_192 | LCD4MUX | LCDSON | LCDON; // (ACLK = 32768)/192, 4-mux LCD, LCD_A on, Segments on LCDAVCTL0 = LCDCPEN; // Charge pump enable LCDAVCTL1 = VLCD_3_44; // VLCD = 3.44 V LCD_all_off(); // Basic Timer 1 Configuration BTCTL = BTDIV | BT_fCLK2_DIV128; // (ACLK/256)/128 IE2 |= BTIE; // Enable BT interrupt with 1 sec period // TimerB configuration TBCCR0 = 39977; // Output 200 Hz signal with 50% duty cicle TBR = 0; // reset TBR TBCCTL4 = OUTMOD_3; // CCR4 output mode 3 (set/reset) TBCCR4 = TBCCR0/2; TBCTL = TBSSEL_2 | CNTL_0 | TBCLGRP_0 |MC_1 | ID_0; // SMCLK, continuous mode // TimerA configuration TACTL = TASSEL_2 |MC_2 | ID_0 | TAIE; // SMCLK, continuous mode up to 0xffff TACCTL1 = CM1 | CCIS_0 | CAP | CCIE; // Capture on rising edge, Cap mode, cap/com interrupt enable // TACCR1 input signal selected // TA1 (TACCR1) configuration (Port1) P1SEL = 0x04; // P1.2 as special function (TA1) P1DIR = 0x00; // P1.2 as input // LED1 and LED2 configuration (Port2) P2DIR = 0x06; // P2.2 and P2.1 as digital output P2OUT = 0x04; // LED1 on and LED2 off // TB4 configuration (Port3) P3SEL = 0x20; // P3.5 as special function (TB4) P3DIR = 0x20; // P3.5 as output // global data initialition counter = 0; tick = 0; // Interrupts enabled //_BIS_SR(GIE); // all interrupts enable __bis_SR_register(LPM0_bits + GIE); //enter low power mode0 with interrupt enable for(;;); } //***************************************************************** // End of Lab3d_solution.c //*****************************************************************
Thanks Bruce for the tips!
Here is a code that measures frequencies from 1Hz.
Now I need to better evaluate how to measure frequencies smaller than 1Hz.
Thank you all for your patience!
#include <stdio.h> #include <intrinsics.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #include <stdint.h> #include <msp430xG46x.h> #include "LCD16x2_Data_Logger.c" volatile int Temporizador = 0; unsigned char string_vazao[10]; unsigned char flag, capture, counter, tick; unsigned int T, T1, T2; float freq = 0.0; float vazao = 0.0; //************************************************************************************************************// // Definições dos Pinos de Entrada e Saída do MSP430 do Data Logger // //************************************************************************************************************// void initPORTS(void) { P1OUT = 0; // All P1.x reset P1DIR = 0xFF; // All P1.x outputs P2OUT = 0; // All P2.x reset P2DIR = 0xFF; // All P2.x outputs P3OUT = 0; // All P3.x reset P3DIR = 0xFF; // All P3.x outputs P4OUT = 0; // All P4.x reset P4DIR = 0xFF; // All P4.x outputs P5OUT = 0; // All P5.x reset P5DIR = 0xFF; // All P5.x outputs P6OUT = 0; // All P6.x reset P6DIR = 0xFF; // All P6.x outputs P7OUT = 0; // All P7.x reset P7DIR = 0xFF; // All P7.x outputs P8OUT = 0; // All P8.x reset P8DIR = 0xFF; // All P8.x outputs P9OUT = 0; // All P9.x reset P9DIR = 0xFF; // All P9.x outputs P10OUT = 0; // All P10.x reset P10DIR = 0xFF; // All P10.x outputs // TA1 (TACCR1) configuration (Port1) P1SEL = 0x04; // P1.2 as special function (TA1) P1DIR = 0x00; // P1.2 as input // LED1 and LED2 configuration (Port2) P2DIR = 0x07; // P2.2 and P2.1 as digital output P2OUT &=~ 0x04; // LED1 on and LED2 off P5DIR = 0x02; // Define P5.1 como Saída P5OUT &=~ 0x02; // Zera o Pino LED4 P5OUT = !(BIT1); // Desabilita a Conversão de Tensão Step-Up } //************************************************************************************************************// // Definições e Inicialização da Comunicação Serial RS232 do Data Logger // //************************************************************************************************************// void initRS232(void) { P4SEL |= 0x03; // P4.1,0 = USART1 TXD/RXD ME2 |= UTXE1 + URXE1; // Enable USART1 TXD/RXD U1CTL |= CHAR; // 8-bit character U1TCTL |= SSEL0; // UCLK = ACLK U1BR0 = 0x03; // 32k/9600 - 3.41 U1BR1 = 0x00; // U1MCTL = 0x4A; // Modulation U1CTL &= ~SWRST; // Initialize USART state machine IE2 |= URXIE1; // Enable USART1 RX interrupt } //************************************************************************************************************// // Definições e Inicialização do BASIC TIMER para Temporizações do Data Logger // //************************************************************************************************************// void initBT(void) { BTCNT1 = BTCNT2 = 0; BTCTL = BTDIV + BT_fCLK2_DIV128; // Configura o Basic Timer IE2 |= BTIE; // Habilita o Basic Timer } //************************************************************************************************************// // Rotina para Transmissão Serial do Data Logger // //************************************************************************************************************// void msg_rs232_cr(unsigned char *string) {// envia uma string via rs232 via UCA0 while (*string != 0) { testa_tx_cr();// testa flag de tx TXBUF1 = *string; *string++; } // while string } //************************************************************************************************************// // Rotina de Conversão dos Dados do Canal de Pressão Manométrica para Apresentação no Display LCD 16X4 do Data Logger //************************************************************************************************************// void Mostra_Vazao(float Vazao) { sprintf(string_vazao,"%.2f",Vazao); LCDSetPosition(0,1); LCDPrintString("Frequency Meter"); LCDSetPosition(1,2); LCDPrintString("F:"); // Escreve Q: LCDSetPosition(1,6); // Posiciona para Escrita do Valor de Vazão no LCD16x2 LCDPrintString(string_vazao); // Apresenta o Valor da Vazão no LCD16x2 LCDSetPosition(1,13); // Posiciona para Escrita da Unidade de Vazão no LCD16x2 LCDPrintString("Hz"); // Escreve a Unidade de Vazão no LCD16x2 } //****************************************************************** // Write frequency (Hz) in LCD //****************************************************************** void LCD_freq(void) { freq = 32768L/(float)T; } void main (void) { volatile unsigned int j; WDTCTL = WDTPW + WDTHOLD; // Stop WDT // Clock default: MCLK = 32 x ACLK = 1MHz , FLL+ operating FLL_CTL0 |= XCAP14PF; // Configure load caps do { IFG1 &= ~OFIFG; // Clear OSCFault flag for (j = 0x47FF; j > 0; j--); // Time for flag to set } while ((IFG1 & OFIFG)); // OSCFault flag still set? initPORTS(); // Inicializa os PORTS initBT(); // Inicializa o BT initRS232(); // Inicializa o RS232 P5OUT &=~ 0x02; // Habilita o MAX761CPA para Conversão de Tensão InitLCD(); LCDPrintString("Testando..."); __delay_cycles(500000); LCDSetPosition(1,0); LCDPrintString("Display LCD16X2"); __delay_cycles(500000); LCDClear(); // TimerA configuration TACTL = TASSEL_1 |MC_2 | ID_0 | TAIE; // SMCLK, continuous mode up to 0xffff TACCTL1 = CM1 | CCIS_0 | CAP | CCIE; // Capture on rising edge, Cap mode, cap/com interrupt enable // TACCR1 input signal selected do // Rotina Principal { __bis_SR_register(LPM3_bits + GIE); // Entra em LPM3 (Modo de Baixo Consumo) __no_operation (); // Não faz nada } while (1); // Enquanto adjustment for < que 38, garante o LPM3 __bis_SR_register(LPM3_bits + GIE); // Entra em LPM3 (Modo de Baixo Consumo) } // ---------------------------------------------------------------------- // Interrupt service routine for basic timer: start captures on CCI2B // Flag cleared automatically // ---------------------------------------------------------------------- #pragma vector = BASICTIMER_VECTOR __interrupt void BASICTIMER_ISR (void) { /* Temporizador++; if(Temporizador == 5) { Temporizador = 0; // Reseta Temporizador vazao = (freq * 0.001 * 3600); // Converte a Vazão Mostra_Vazao(vazao); // Apresenta a Vazão } */ Mostra_Vazao(freq); // Apresenta a Vazão } //****************************************************************** // Timer A Interrupt Service Routine //****************************************************************** #pragma vector=TIMERA1_VECTOR __interrupt void TimerA1_ISR (void) { switch (TAIV) { case TAIV_TACCR1: if (capture == 0) { T1 = TACCR1; flag = 1; capture = 1; } else { if (flag == 1) { T2 = TACCR1; if (T2 > T1) T = T2-T1; LCD_freq(); } else { TAR = 0; } capture = 0; flag = 0; } break; case TAIV_TACCR2: break; case TAIV_TAIFG: tick++; if (tick == 60) { LCD_freq(); tick = 0; } if (flag == 1) flag = 0; break; default: break; } }
Thank you Bruce! Your instructions were very important to my learning! Code running as I like! Regards, #include <stdio.h> #include <intrinsics.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #include <stdint.h> #include <msp430xG46x.h> #include "LCD16x2_Data_Logger.c" volatile int Temporizador = 0; unsigned char string_freq[10]; unsigned char flag, capture, counter, tick; unsigned int T, T1, T2; float freq = 0.0; //************************************************************************************************************// // Definições dos Pinos de Entrada e Saída do MSP430 do Data Logger // //************************************************************************************************************// void initPORTS(void) { P1OUT = 0; // All P1.x reset P1DIR = 0xFF; // All P1.x outputs P2OUT = 0; // All P2.x reset P2DIR = 0xFF; // All P2.x outputs P3OUT = 0; // All P3.x reset P3DIR = 0xFF; // All P3.x outputs P4OUT = 0; // All P4.x reset P4DIR = 0xFF; // All P4.x outputs P5OUT = 0; // All P5.x reset P5DIR = 0xFF; // All P5.x outputs P6OUT = 0; // All P6.x reset P6DIR = 0xFF; // All P6.x outputs P7OUT = 0; // All P7.x reset P7DIR = 0xFF; // All P7.x outputs P8OUT = 0; // All P8.x reset P8DIR = 0xFF; // All P8.x outputs P9OUT = 0; // All P9.x reset P9DIR = 0xFF; // All P9.x outputs P10OUT = 0; // All P10.x reset P10DIR = 0xFF; // All P10.x outputs // TA1 (TACCR1) configuration (Port1) P1SEL = 0x04; // P1.2 as special function (TA1) P1DIR = 0x00; // P1.2 as input // LED1 and LED2 configuration (Port2) P2DIR = 0x07; // P2.2 and P2.1 as digital output P2OUT &=~ 0x04; // LED1 on and LED2 off P5DIR = 0x02; // Define P5.1 como Saída P5OUT &=~ 0x02; // Zera o Pino LED4 P5OUT = !(BIT1); // Desabilita a Conversão de Tensão Step-Up } //************************************************************************************************************// // Definições e Inicialização da Comunicação Serial RS232 do Data Logger // //************************************************************************************************************// void initRS232(void) { P4SEL |= 0x03; // P4.1,0 = USART1 TXD/RXD ME2 |= UTXE1 + URXE1; // Enable USART1 TXD/RXD U1CTL |= CHAR; // 8-bit character U1TCTL |= SSEL0; // UCLK = ACLK U1BR0 = 0x03; // 32k/9600 - 3.41 U1BR1 = 0x00; // U1MCTL = 0x4A; // Modulation U1CTL &= ~SWRST; // Initialize USART state machine IE2 |= URXIE1; // Enable USART1 RX interrupt } //************************************************************************************************************// // Definições e Inicialização do BASIC TIMER para Temporizações do Data Logger // //************************************************************************************************************// void initBT(void) { BTCNT1 = BTCNT2 = 0; BTCTL = BTDIV + BT_fCLK2_DIV128; // Configura o Basic Timer IE2 |= BTIE; // Habilita o Basic Timer } //************************************************************************************************************// // Rotina para Transmissão Serial do Data Logger // //************************************************************************************************************// void msg_rs232_cr(unsigned char *string) {// envia uma string via rs232 via UCA0 while (*string != 0) { testa_tx_cr();// testa flag de tx TXBUF1 = *string; *string++; } // while string } //************************************************************************************************************// // Rotina de Conversão dos Dados do Canal de Pressão Manométrica para Apresentação no Display LCD 16X4 do Data Logger //************************************************************************************************************// void Mostra_Freq(float Freq) { sprintf(string_freq,"%.2f",Freq); LCDSetPosition(0,2); LCDPrintString("Frequency Meter"); LCDSetPosition(1,2); LCDPrintString("F:"); LCDSetPosition(1,6); LCDPrintString(string_freq); LCDSetPosition(1,13); LCDPrintString("Hz"); } //****************************************************************** // Write frequency (Hz) in LCD //****************************************************************** void LCD_freq(void) { freq = 4096L/(float)T; } void main (void) { volatile unsigned int j; WDTCTL = WDTPW + WDTHOLD; // Stop WDT // Clock default: MCLK = 32 x ACLK = 1MHz , FLL+ operating FLL_CTL0 |= XCAP14PF; // Configure load caps do { IFG1 &= ~OFIFG; // Clear OSCFault flag for (j = 0x47FF; j > 0; j--); // Time for flag to set } while ((IFG1 & OFIFG)); // OSCFault flag still set? initPORTS(); // Inicializa os PORTS initBT(); // Inicializa o BT initRS232(); // Inicializa o RS232 P5OUT &=~ 0x02; // Habilita o MAX761CPA para Conversão de Tensão InitLCD(); LCDPrintString("Testando..."); __delay_cycles(500000); LCDSetPosition(1,0); LCDPrintString("Display LCD16X2"); __delay_cycles(500000); LCDClear(); // TimerA configuration TACTL = TASSEL_1 |MC_2 | ID_3 | TAIE; // SMCLK, continuous mode up to 0xffff TACCTL1 = CM1 | CCIS_0 | CAP | CCIE; // Capture on rising edge, Cap mode, cap/com interrupt enable // TACCR1 input signal selected do // Rotina Principal { __bis_SR_register(LPM3_bits + GIE); // Entra em LPM3 (Modo de Baixo Consumo) __no_operation (); // Não faz nada } while (1); // Enquanto adjustment for < que 38, garante o LPM3 __bis_SR_register(LPM3_bits + GIE); // Entra em LPM3 (Modo de Baixo Consumo) } // ---------------------------------------------------------------------- // Interrupt service routine for basic timer: start captures on CCI2B // Flag cleared automatically // ---------------------------------------------------------------------- #pragma vector = BASICTIMER_VECTOR __interrupt void BASICTIMER_ISR (void) { Mostra_Freq(freq); // Apresenta a Vazão } //****************************************************************** // Timer A Interrupt Service Routine //****************************************************************** #pragma vector=TIMERA1_VECTOR __interrupt void TimerA1_ISR (void) { switch (TAIV) { case TAIV_TACCR1: if (capture == 0) { T1 = TACCR1; flag = 1; capture = 1; } else { if (flag == 1) { T2 = TACCR1; if (T2 > T1) T = T2-T1; LCD_freq(); } else { TAR = 0; } capture = 0; flag = 0; } break; case TAIV_TACCR2: break; case TAIV_TAIFG: tick++; if (tick == 60) { LCD_freq(); tick = 0; } if (flag == 1) flag = 0; break; default: break; } }
**Attention** This is a public forum