⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 heart rate with ekg demo.c

📁 msp430心电仪程序代码 ............Heart rate ............Heart rate with DAC output ............Heart rat
💻 C
字号:
//*****************************************************************************
//   MSP430FG439-Heart Rate Monitor Demo
//
//   Description; Uses one Instrumentation Amplifier INA321 and the three
//   internal opamps of the MSP430FG439
//
//   Murugavel Raju 
//   Texas Instruments, Inc
//   October 2004
//   Edited by: M Morales, November 2008 
//   * Updated to non-depracated intrinsic functions
//   * Changed spacing for legibility 
//   Built with IAR Embedded Workbench Version: 4.11B
//*****************************************************************************
//*****************************************************************************
// THIS PROGRAM IS PROVIDED "AS IS". TI MAKES NO WARRANTIES OR
// REPRESENTATIONS, EITHER EXPRESS, IMPLIED OR STATUTORY,
// INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR
// COMPLETENESS OF RESPONSES, RESULTS AND LACK OF NEGLIGENCE.
// TI DISCLAIMS ANY WARRANTY OF TITLE, QUIET ENJOYMENT, QUIET
// POSSESSION, AND NON-INFRINGEMENT OF ANY THIRD PARTY
// INTELLECTUAL PROPERTY RIGHTS WITH REGARD TO THE PROGRAM OR
// YOUR USE OF THE PROGRAM.
//
// IN NO EVENT SHALL TI BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
// CONSEQUENTIAL OR INDIRECT DAMAGES, HOWEVER CAUSED, ON ANY
// THEORY OF LIABILITY AND WHETHER OR NOT TI HAS BEEN ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGES, ARISING IN ANY WAY OUT
// OF THIS AGREEMENT, THE PROGRAM, OR YOUR USE OF THE PROGRAM.
// EXCLUDED DAMAGES INCLUDE, BUT ARE NOT LIMITED TO, COST OF
// REMOVAL OR REINSTALLATION, COMPUTER TIME, LABOR COSTS, LOSS
// OF GOODWILL, LOSS OF PROFITS, LOSS OF SAVINGS, OR LOSS OF
// USE OR INTERRUPTION OF BUSINESS. IN NO EVENT WILL TI'S
// AGGREGATE LIABILITY UNDER THIS AGREEMENT OR ARISING OUT OF
// YOUR USE OF THE PROGRAM EXCEED FIVE HUNDRED DOLLARS
// (U.S.$500).
//
// Unless otherwise stated, the Program written and copyrighted
// by Texas Instruments is distributed as "freeware".  You may,
// only under TI's copyright in the Program, use and modify the
// Program without any charge or restriction.  You may
// distribute to third parties, provided that you transfer a
// copy of this license to the third party and the third party
// agrees to these terms by its first use of the Program. You
// must reproduce the copyright notice and any other legend of
// ownership on each copy or partial copy, of the Program.
//
// You acknowledge and agree that the Program contains
// copyrighted material, trade secrets and other TI proprietary
// information and is protected by copyright laws,
// international copyright treaties, and trade secret laws, as
// well as other intellectual property laws.  To protect TI's
// rights in the Program, you agree not to decompile, reverse
// engineer, disassemble or otherwise translate any object code
// versions of the Program to a human-readable form.  You agree
// that in no event will you alter, remove or destroy any
// copyright notice included in the Program.  TI reserves all
// rights not specifically granted under this license. Except
// as specifically provided herein, nothing in this agreement
// shall be construed as conferring by implication, estoppel,
// or otherwise, upon you, any license or other right under any
// TI patents, copyrights or trade secrets.
//
// You may not use the Program in non-TI devices.
//*****************************************************************************
#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 d 0x08
#define c 0x04
#define b 0x02
#define a 0x01
#define h 0x80
#define e 0x40
#define g 0x20
#define f 0x10

// variables declaration
static char beats;
int Datain, Dataout, Dataout_pulse, pulseperiod, counter, heartrate;
// Lowpass FIR filter coefficients for 17 taps to filter > 30Hz
static const int coeffslp[9] = {
     5225, 5175, 7255, 9453, 11595, 13507, 15016, 15983, 16315 };
// Highpass FIR filter coefficients for 17 taps to filter < 2Hz
static const int coeffshp[9] = {
     -763, -1267, -1091, -1867, -1969, -2507, -2619, -2911, 29908 };
// Character generator definition for display
const 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 prototypes
void Init(void);                            // Initializes device for the application
void ClearLCD(void);                        // Clears the LCD memory
int filterlp(int);                          // 17 tap lowpass FIR filter
int filterhp(int);                          // 17 tap highpass FIR filter
long mul16(register int x, register int y); // 16-bit signed multiplication
int itobcd(int i);                          // 16-bit hex to bcd conversion
// main function
void main(void)
{ 
  Init();                                   // Initialize device for the application
  while(1)
  {
    __bis_SR_register(LPM0_bits);           // Enter LPM0 needed for UART TX completion
    __no_operation(); 
                 
    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) Dataout = 255;        // Set boundary 255 max       
    if(Dataout < 0)   Dataout =   0;        // Set boundary 0 min         
    //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
      counter = 0;                          // Reset debounce counter
    }                                            
    if (counter == 128)                     // Allow 128 sample debounce time
    {
      LCDM10 = 0x00;                        // Disable "^" on LCD for blinking effect
      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[0] = char_gen[heartrate & 0x0f];           // Display current heart rate units
        LCDMEM[1] = char_gen[(heartrate & 0xf0) >> 4];    // tens
        LCDMEM[2] = char_gen[(heartrate & 0xf00) >> 8];
      }
    } // hundreds
  }
}//main
// Initialization function
void 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
// 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
  __enable_interrupt();                     // 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]);
  
  __no_operation();
  
  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
  __bic_SR_register_on_exit(LPM0_bits);     // Exit LPM0 on return
}// ADC12ISR


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -