MSP430FG439系列的单片机的OA不工作,无法实现低频信号的放大,这是怎么回事?大神帮帮忙,解释一下,这是为什么???
灰小子:
可能没配置好。建议上传下你的代码和电路图
KANG YANG1:
回复 灰小子:
//*****************************************************************************// MSP430FG439-Heart Rate Monitor Demo//// Description; Uses one Instrumentation Amplifier INA321 and the three// internal opamps of the MSP430FG439//// LSD ZHANGCHONG // MAY 2006// Built with IAR Embedded Workbench Version: 3.20A//*****************************************************************************
//*****************************************************************************#include <msp430xG43x.h>#include "math.h"//defines#define PB_2_0 (1 << 0) // Push Button on P2.0#define PB_2_1 (1 << 1) // Push Button on P2.1#define c 0x01 // LSD 048 LCD SEGMENT DISPLAY#define f 0x02#define e 0x04#define h 0x08#define a 0x10#define b 0x20#define g 0x40#define d 0x80
// variables declarationstatic char beats;int Datain, Dataout, Dataout_pulse, pulseperiod, counter, heartrate;// Lowpass FIR filter coefficients for 17 taps to filter > 30Hzstatic const int coeffslp[9] = { 5225, 5175, 7255, 9453, 11595, 13507, 15016, 15983, 16315 };// Highpass FIR filter coefficients for 17 taps to filter < 2Hzstatic const int coeffshp[9] = { -763, -1267, -1091, -1867, -1969, -2507, -2619, -2911, 29908 };// Character generator definition for displayconst char char_gen[] = { a+b+c+d+e+f, // 0 Displays "0" b+c, // 1 Displays "1" a+b+d+e+g, // 2 Displays "2" a+b+c+d+g, // 3 Displays "3" b+c+f+g, // 4 Displays "4" a+c+d+f+g, // 5 Displays "5" a+c+d+e+f+g, // 6 Displays "6" a+b+c, // 7 Displays "7" a+b+c+d+e+f+g, // 8 Displays "8" a+b+c+d+f+g, // 9 Displays "9"};// undefines#undef a#undef b#undef c#undef d#undef e#undef f#undef g#undef h// function prototypesvoid Init(void); // Initializes device for the applicationvoid ClearLCD(void); // Clears the LCD memoryint filterlp(int); // 17 tap lowpass FIR filterint filterhp(int); // 17 tap highpass FIR filterlong mul16(register int x, register int y); // 16-bit signed multiplicationint itobcd(int i); // 16-bit hex to bcd conversion// main functionvoid main(void){ Init (); // Initialize device for the application while(1) {LPM0; // Enter LPM0 needed for UART TX completion Dataout = filterlp(Datain); // Lowpass FIR filter for filtering out 60Hz Dataout_pulse = filterhp(Dataout)-128; // Highpass FIR filter to filter muscle artifacts Dataout = Dataout >> 6; // Scale Dataout to use scope program if(Dataout>255) // Set boundary 255 max Dataout=255; // if(Dataout<0) // Set boundary 0 min Dataout=0; // // DAC12_0DAT = Dataout; // For scope display TXBUF0 = Dataout; // Transmit via UART0 for Scope display counter++; // Debounce counter pulseperiod++; // Pulse period counter if (Dataout_pulse > 48) // Check if above threshold { //LCDM10 |= 0x0f; // Heart beat detected enable "^" on LCD LCDMEM[1]=0X61; // LSD048 LCD MARK DISP LCDMEM[2]=0X46; // LSD048 LCD MARK DISP counter = 0;} // Reset debounce counter if (counter == 128) // Allow 128 sample debounce time {//LCDM10 = 0x00; // Disable "^" on LCD for blinking effect LCDMEM[1]=0X00; // LSD048 LCD MARK DISP LCDMEM[2]=0X00; // LSD048 LCD MARK DISP beats++; if (beats == 3) {beats = 0; // heartrate = itobcd(30720/pulseperiod); // Calculate beat to beat heart rate per min heartrate = itobcd(92160/pulseperiod); // Calculate 3 beat average heart rate per min pulseperiod = 0; // Reset pulse period for next measurement LCDMEM[6] = char_gen[heartrate & 0x0f]; // Display current heart rate unitsn 0 LCDMEM[5] = char_gen[(heartrate & 0xf0) >> 4]; // tens 1 LCDMEM[4] = char_gen[(heartrate & 0xf00) >> 8];}} // hundreds 2 }}//main// Initialization functionvoid Init( void ){ FLL_CTL0 |= XCAP18PF; // Set load capacitance for xtal WDTCTL = WDTPW | WDTHOLD; // Disable the Watchdog while ( LFOF & FLL_CTL0); // wait for watch crystal to stabilize SCFQCTL = 63; // 32 x 32768 x 2 = 2.097152MHz BTCTL = BT_fLCD_DIV128; // Set LCD frame freq = ACLK/128// Initialize and enable LCD peripheral ClearLCD(); // Clear LCD memory LCDCTL = LCDSG0_3 + LCD4MUX + LCDON ; // 4mux LCD, segs0-23 enabled// Initialize and enable GPIO ports P1OUT = 0x00 + BIT3; // Clear P1OUT register, INA turned ON P1DIR = 0x3f; // Unused pins as outputs, Comparator pins as inputs P2OUT = 0x00; // Clear P2OUT register P2DIR = 0xff; // Unused pins as outputs P2DIR = ~(PB_2_0+PB_2_1); // P2.0 and P2.1 push buttons P2IES = 0x00; // Interrupt edge low to high transition P2IFG = 0x00; // Clear pending P2 interrupts P2IE = PB_2_0 | PB_2_1; // Enable intterupts for push buttons P3OUT = 0x00; // Clear P3OUT register P3DIR = 0xff; // Unused pins as outputs P4OUT = 0x00; // Clear P4OUT register P4DIR = 0xff; // Unused pins as outputs P5OUT = 0x00; // Clear P5OUT register P5DIR = 0xff; // Unused pins as outputs P5SEL = 0xfc; // Set Rxx and COM pins for LCD P6OUT = 0x00; // Clear P6OUT register P6SEL = 0xff; // P6 = Analog// Initialize and enable UART P2SEL|=BIT4; // P2.4 = TXD UCTL0 |= SWRST; // UART SWRST = 1 ME1 |= UTXE0; // Enable UART0 TXD UCTL0 |= CHAR; // 8-bit char, SWRST=1 UTCTL0 |= SSEL1; // UCLK = SMCLK UBR00 = 18; // 115200 from 2.097152MHz UBR10 = 0; UMCTL0 = 0x2c; // Modulation = 0.2044 UCTL0 &= ~SWRST; // UART SWRST = 0, enable UART// Initialize and enable ADC12 ADC12CTL0 = ADC12ON + SHT0_4 + REFON + REF2_5V; // ADC12 ON, Reference = 2.5V for DAC0 ADC12CTL1 = SHP + SHS_1 + CONSEQ_2; // Use sampling timer, TA1 trigger ADC12MCTL0 = INCH_1 + SREF_1; // Vref, channel = 1 = OA0 Out ADC12IE = BIT0; // Enable interrupt for ADC12 MEM0 ADC12CTL0 |= ENC; // Enable conversions// Initialize and enable Timer_A TACTL = TASSEL0 + MC_1 + TACLR; // ACLK, Clear TAR, Up Mode TACCTL1 = OUTMOD_2; // Set / Reset TACCR0 = 63; // 512 samples per second TACCR1 = 15; //// Initialize and enable DAC12x DAC12_0CTL = DAC12OPS + DAC12CALON + DAC12IR + DAC12AMP_2 + DAC12ENC;// DAC0 enable DAC12_1CTL = DAC12CALON + DAC12IR + DAC12AMP_2 + DAC12ENC; // DAC1 enable DAC12_1DAT = 0x099A; // Offset level = 1.5V for op amp bias //DAC12_1DAT = 0x0000; // Offset level = 1.5V for op amp bias// Initialize and enable opamps OA0CTL0 = OAP_1 + OAPM_1 + OAADC1; // OA0 enable power mode 1, OA0- = P6.0, 0A0+ = P6.2, OA0O = P6.1 OA0CTL1 = OARRIP; // General purpose mode, no Rail-to-Rail inputs OA1CTL0 = OAP_3 + OAPM_1 + OAADC1; // OA1 enable power mode 1, OA1- = P6.4, OA1+ = DAC1, OA1O = P6.3 OA1CTL1 = OARRIP; // General purpose mode, no Rail-to-Rail inputs OA2CTL0 = OAP_3 + OAPM_1 + OAADC1; // OA2 enable power mode 1, OA2+ = DAC1, OA2O = P6.5, Select inputs, power mode OA2CTL1 = OAFC_1 + OARRIP; // Unit gain Mode, no Rail-to-Rail inputs _EINT(); // Enable global Interrupts} //init
void ClearLCD(void){ int i; // for( i = 0; i < 16; i++){ // Clear LCDMEM LCDMEM[i] = 0; // }}//clear LCD
int itobcd(int i) // Convert hex word to BCD.{ int bcd = 0; // char j = 0; // while (i > 9) // {bcd |= ((i % 10) << j); // i /= 10; // j += 4;} // return (bcd | (i << j)); // Return converted value}// itobcd(i)
int filterlp(int sample) // Lowpass FIR filter for EKG{ static int buflp[32]; // Reserve 32 loactions for circular buffering static int offsetlp = 0; long z; int i; buflp[offsetlp] = sample; z = mul16(coeffslp[8], buflp[(offsetlp – 8) & 0x1F]); for (i = 0; i < 8; i++) z += mul16(coeffslp[i], buflp[(offsetlp – i) & 0x1F] + buflp[(offsetlp – 16 + i) & 0x1F]); offsetlp = (offsetlp + 1) & 0x1F; return z >> 15; // Return filter output}// int filter
int filterhp(int samplehp) // Highpass FIR filter for hear rate{ static int bufhp[32]; // Reserve 32 loactions for circular buffering static int offsethp = 0; long z; int i; bufhp[offsethp] = samplehp; z = mul16(coeffshp[8], bufhp[(offsethp – 8) & 0x1F]); for (i = 0; i < 8; i++) z += mul16(coeffshp[i], bufhp[(offsethp – i) & 0x1F] + bufhp[(offsethp – 16 + i) & 0x1F]); offsethp = (offsethp + 1) & 0x1F; return z >> 15; // Return filter output}// int filterhp
#pragma vector = PORT2_VECTOR__interrupt void Port2ISR (void){ P2IFG = 0;}//Push buttons unused
#pragma vector = ADC_VECTOR // ADC12 ISR__interrupt void ADC12ISR (void){ Datain = ADC12MEM0; // Store converted value in Datain LPM0_EXIT; // Exit LPM0 on return}// ADC12ISR
灰小子:
回复 KANG YANG1:
这个代码貌似不是ti官方的。
另外,由于用到 INA321,建议结合电路图来看。
灰小子:
回复 KANG YANG1:
int filterlp(int sample) 和int filterhp(int samplehp) 看起来是一样的,会不会代码有问题?
KANG YANG1:
回复 灰小子:
滤波算法真心没看懂,这是官方没差啊。