1/512 second delay if im not wrong.
Printable View
1/512 second delay if im not wrong.
I'm glad you posted up your program, because I wasn't understanding some of what you were doing, before.
I'm studying the software. I'd like the original version of the program and instructions to work this device, from the maker. What you had before you added anything to the program.
This is the original code.
Code:#include <msp430xG43x.h>
#include "math.h"
#include <stdlib.h>
#include <ctype.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)
{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; //
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(92160/pulseperiod); // Calculate 3 beat average heart rate per min
if(char_gen[(heartrate & 0xf0) >> 4]>4 || char_gen[(heartrate & 0xf00) >> 8]<2)
TXBUF0 = 92160/pulseperiod; // Transmit buffer
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
}
//pulseperiod = 0; // Reset pulse period for next measurement
}
}//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
*/
UBR00 = 0xDA; // 9600 from 2.097152MHz
UBR10 = 0;
UMCTL0 = 0xAA; // Modulation
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
_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
the part that i change is this:
I use IAR Embedded workbench to build and compile it as only the IAR can download the program to my board.Code:TXBUF0 = 92160/pulseperiod; // Transmit buffer
thank for your help if any question can ask me again.thank you.
any question can ask me again.thank you for ur help.
Shifu, why did you use 92160/pulseperiod for the TXBUF0?
Heartbeat rate per minute = 1/[pulseperiod/(3 ´ 512 ´ 60)] = 92160/pulseperiod.
pulseperiod is used for the calculation of heart-rate per minute and reset.
adak, i find it weird..i delete all the code for conversion because i cant get it. so i download back the code to the board and it work!!!!! miracle....here's the code can u tell me how come it can convert itself????
Code:#include <msp430xG43x.h>
#include "math.h"
#include <stdlib.h>
#include <ctype.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 num=0, div1=0;
unsigned char output[2];
int A,B;
int D,E;
int F,G;
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)
{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; //
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(92160/pulseperiod); // Calculate 3 beat average heart rate per min
if(char_gen[(heartrate & 0xf0) >> 4]>4 || char_gen[(heartrate & 0xf00) >> 8]<2)
{
TXBUF0 = 92160/pulseperiod; // Transmit buffer
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
*/
UBR00 = 0xDA; // 9600 from 2.097152MHz
UBR10 = 0;
UMCTL0 = 0xAA; // Modulation
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
_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
Persistence pays off - good deal! :)
adak.:) ya can i ask u 1 more question how do i put in a delay? i try putting in
but it prompt warning "function sleep declared implicitly".Code:sleep(1);
any other way to put i a delay?
my code is this:
Code:HR1 = 92160/pulseperiod;
ADDR1 = 1;
if(HR1 < 40)
{
}
else
{
TXBUF0 = ADDR1;
<---------------------------------// i want to put a delay of 0.1sec here
TXBUF0 = HR1;
}
Both the
delay(microseconds);
and the
sleep(seconds);
functions require a header file. In my case, it's dos.h.
If you have the header file called dos.h, then you can use that.
If you don't have delay(), they you can "roll your own". Code up a delay function of your own, and time it and adjust it as needed.
You may need to tinker with it a bit, to find the right amount of delay, but you get the idea. Be careful not to overflow your integer maximum value, however.Code:for(i = 0; i < 32000; i++)
i % 17;