Professional Documents
Culture Documents
0871.ixchel - Portable Maternal and Fetal Ecg System - Final Report PDF
0871.ixchel - Portable Maternal and Fetal Ecg System - Final Report PDF
0871.ixchel - Portable Maternal and Fetal Ecg System - Final Report PDF
List of Figures
Figure 1. General description: The project has three main SECTIONS: electrodes and analog conditioning, digital processing and visualization 1
Figure 2 ADS1292R Functional diagram _________________________________________________________________ 2
Figure 3 ADS1292R Functional diagram _________________________________________________________________ 3
Figure 4 Signal / Interference ratio Vs electrodes distance _______________________________________________________ 5
Figure 5 PCB Design ______________________________________________________________________________ 6
Figure 6 ADS1292 Test signal with gain = 12 _____________________________________________________________ 6
Figure 7 ECG Signal acquiered by ADS1292 with Gain = 6 _____________________________________________________ 7
Figure 8 Graphic for Buffered data _____________________________________________________________________ 7
I XCHEL . M ATERNAL -F ETAL ECG MONITOR
Detail Description Of the project design
The design of this device was divided in three main blocks: Electrodes and analogic-digital conditioning, digital
processing and graphic user interface. Figure 1. In the following pages we are explaining each one of the blocks in a
more detailed way.
F IGURE 1. G ENERAL DESCRIPTION : T HE PROJECT HAS THREE MAIN SECTIONS: ELECTRODES AND ANALOG CONDITIONING , DIGITAL
PROCESSING AND VISUALIZATION
Electrodes
One of the things we would like emphasis in is the fact that we pretend in a near future, to use IXCHEL on a clinical
environment where a practical and fast screening is needed. Therefore, we choose dry electrodes to put them in
Ixchel. Maternal-Fetal ECG monitor | 24/05/14
immediate contact with the skin and to avoid using electrolyte gels. We assume that dry electrodes can transduce the
electrical activity of the heart with acceptable quality, even at the abdominal surface of the pregnant women.
The electrodes we are using have a chemical composition of silver-nickel. The electrodes have a rectangular shaped
and a length of 2cm x 3cm. These kind of electrodes have been used in others protocols in the Laboratory of Human
Physiology at the Universidad Autonoma Metropolitana (UAM) and the results have been satisfactory in the
acquisition of pregnant women abdominal ECG signals, from 20 weeks of gestation to delivery.
For electrodes testing purpose, we used an ECG100C and the data acquisition system MP150 (BioPac System). The
reason for using the BioPac system is due to the fact this is a ratified system in the academic environment and we need
to obtain a reliable and trustful signal. So, we were able to compare the abdominal ECG signals acquired with the
biopac system with those recorded with our own device.
Analog-Digital Conditioning
For acquiring a physiological signal it is necessary to use specific electronic elements in order to assure a reliable
acquisition, these could be amplifiers with high input impedance, high values for gain and high Common Mode
1
in: 1, 2, 3, 4, 6, 8, or 12 signals for test, temperature, and lead-off detection.
or Bipolar Additionally, any configuration of input channels can
o 5.25 V be selected for derivation of the right leg drive (RLD)
output signal. The ADS1291, ADS1292, and
3.6 V
ADS1292R operate at data rates up to 8 kSPS. Lead-
Drive Amplifier, Lead-Off off detection can be implemented internal to the
gnals Rejection Relation, as the physiological signals the
device, using of interest
deviceat theinternal
abdominalexcitation
maternal surface have voltage values in the
current
tion Impedance range of microvolts. On the other
sink hand,
or using
source. high
The resolution
ADS1292R Analogic to Digital
version converters
includes aminimizes information
S1292R) waste. fully integrated respiration impedance measurement
function.
and ReferenceThe Analog Front End ADS1292 (Figure 2) for Biopotential Measurements includes all fundamental features that we
wn, Standby Mode need to acquire and convertThe devices ECG
the abdominal are packaged in ita integrates
analogic signal, 5-mm × a5-mm, 32-pin
multichannel, simultaneous sampling,
thin quad flat pack (TQFP) and a 4-mm x 4-mm, 32-
24-bit, deltasigma (ΔΣ) analog-to-digital converter (ADC) with a built-in programmable gain amplifier (PGA). In
Serial Interface pin quad
addition, it is ideal to low power medicalflat packandwith
devices, no leads
therefore using the(QFN).
ADS1292 Operating
becomes convenient in portable
ature Range: –40°C
devices. to +85°C temperature is specified from –40°C to +85°C.
REF
SPI
SPI
ing: Holter, event, stress,
including ECG, AED, and (ADS1292R)
CLK
RESP
A1 ADC1
DEMOD
Oscillator
INPUTS
!
(ADS1292R)
RESP
1292, and ADS1292R are MOD
!
RESP
eous sampling, 24-bit, delta-
igital converters (ADCs) with a RLD
gain amplifier (PGA), internal
oard oscillator. F IGURE 2 ADS1292R F UNCTIONAL DIAGRAM
The analog functional configuration of the ADS1292R was based in the configuration suggested by the manufacturer
using a Bipolar Supply as shows in Figure 3. Additionally a passive conditioning for the electrodes was included, in
order to reduce offset voltages and noise due the electrode-patient interface. All tests were performed in a
breadboard using an SMT to Dip adapter from Schmartboard, this allowed us an easier manipulation of the ADS1292.
at an important notice concerning availability, standard warranty, and use in critical applications of
Also, and
semiconductor products the internal configuration
disclaimers of the front
thereto appears at theend
endwas done
of this through
data sheet.SPI communication with the Tiva C Series TM4C
la. LaunchPad Evaluation Kit.
Digital Processing
To configure the ADS functions it was necessary to configure the SPI communication, therefore we use the TivaWare
library to save time. The configuration was set through 3 channels (SCLK, DOUT and DIN) for SPI communication.
CS, START and PWnD/RESET were programmed in specifics I/O ports.
We configure the microcontroller clock to run at 120MHz, using the main oscillator and the PLL to ensure the speed
from the clock. After Clock initialization, we configured the specific registers for SSIO.
For the SSIO configuration we selected: phase 1 and polarity 0, TM4C129 as master mode, speed at 1MHz and 8 bits
packages. The clock was set to 120MHz to make a fast SPI communication with the ADS1292R and 8 bits because it
is the package size for the front end. Also in this module we configure the interruptions activated by DRDY pin.
2
F IGURE 3 ADS1292R F UNCTIONAL DIAGRAM
We create two subroutines, the first one sends opcodes to configure ADS and the other sends and receive data trough
SPI. These routines are described more detailed below and the code is located in the appendix.
The interruption routine is activated when DRDY sends a 0 to pin PH0. The routine contains the sequence to get data
Ixchel. Maternal-Fetal ECG monitor | 24/05/14
from the ADS1292R. The Status register doesn´t matter, the second sequence of 3 bytes corresponds to Channel 1’s
information, which is stored in 3 variables. The last sequence is for the Channel 2’s information, as we are using only
one channel we ignore this data. We also add a led indicator to watch the configuration process.
After receiving the information of channel 1, we joined the three packages into one variable and then we stored it at a
circular buffer.
We faced some problems related to ADS1292R configuration. The ADS1292R needs to reset the SPI communication
in order to receive data and we didn´t notice this initially. We had some problems with the received data and the
correct order to join it.
In the code section we show the described functions and the time diagrams for SPI communication are showed in the
results.
3
We needed a graphic user interface GUI “user friendly”, so we decided to use a Tiva development card
(TM4C129X), which have a KenTec touch screen TFT LCD Display of 320x240 pixels.
The software we choose to create the code is a Code Composer Studio version 5.5.0, the reason we use this software
is due to the fact it is an integrated development environment (IDE) that supports TI's Microcontroller and
Embedded Processors portfolio. It includes an optimizing C/C++ compiler, source code editor, project build
environment, debugger, profiler, and many other features.
The main program is configured with the clock at 120MHz, the clock must be configured this way in order to work at
the same rhythm so we could communicate with the ADS 1292 by SPI communication. This configuration let us
acquire the data from the ADS 1292, and to make the graphics for both ECG signals, maternal and fetal.
The visualization software use libraries from TivaWare. It is conform by 6 canvas and 8 touchscreen bottoms. The
function of this screen is based on hierarchy. Canvas and bottoms are divided from the more to the less important.
Finally each bottom has a dual function; to display the signal or to return to the main screen.
We also have another 3 bottoms, the first bottom called “SEL” initializes the configuration to acquire and process the
signal.
The other two bottoms set the sample rate and visualization. We used these bottoms because the screen is small and
we need to scale and to adjust the signal for… achieving better visualization. The bottoms with “+” and “-“ let us the
option to see from 1 to 3 seconds of the sign.
Hardware Design
The design has three main stages, the transducer and analog-digital conditioning, the digital processing, and the
interface and display.
1) The transducer stage consists in three rectangular silver-nickel electrodes, two of them for active monitoring while
the third one is the reference electrode. According with previous studies about abdominal recordings, the optimum
distance we found between the active electrodes was in a range from 10 to 15 cm. The electrodes are connected to
the analog-digital stage through three shielded cables for ECG recording.The analog signal is read through one
channel of the Front End ADS1292R for Biopotential Measurements and it was configured using the Tiva C Series
TM4C123G LaunchPad with the following features:
4
• LCD colors with LED backlight
• Resistive Touch Overlay
Electrodes
The electrical analysis of the project electrodes showed us that the better length between then is around 8.5 cm. This
was assume from our signal / interference graphic which shows at that distance our relation between the signal and
the interference is better and causes the higher point of operation. (Figure 4)
Analog-Digital Conditioning
As mentioned before, all the tests were performed using a patient simulator. The simulator was connected to the
corresponding ADS channel 1, through ECG cables.
Ixchel. Maternal-Fetal ECG monitor | 24/05/14
The first test consisted in display the analogic signal in the oscilloscope (Tektronix TDS1002) screen. The analogic
tests were done using the default front- end configuration, it includes a factor gain of 6 for de PGA’s because of that
the signal visualization only was possible connecting an Instrumentation Amplifier on corresponding pin to PGA1.
The Instrumentation Amplifier allowed us the signal visualization, due to the acquired signal had a small voltage value
(0.5mV– 1.5 mV). The amplitude in the display signal was in the range between 500mV until 1.0V. Thanks to this
test was possible to verify the ADS1292R analog operation.
Once the Front End was configured through SPI communication, the test were focus in acquiring signals with the
minimum noise levels, fitting the electrode-ADS1292 interface in order to eliminate offset voltages and external
noise.
There were multiple tests using different configurations for the gain factor in both of the Front End Channels, in this
test stage the Instrumentation Amplifier was removed from the design, and the signal visualization was possible using
an Analog-Logical-Digital Analyzer KIT from DIGILENT. The analyzer works through a specific software that could
be installed in a PC.
5
The functional analogic design was schematized in software for PCB designs, due to the future goal is to have an
“ADS1292 Booster Pack”.
Digital Processing
We accomplish to configure the ADS1292R to be able to communicate by the SPI protocol. We make several test
with different inputs for example we test the signal, also we make short-circuit and finally test the inputs with normal
signal. These entire tests were made with different gains in both channels. (Figure 5)
6
When we introduce a simulated signal of the ECG on the entries of the channel 1. We could observe the processed
signal in the outputs of the PGA1P and the PGA1N with the oscilloscope.
We used the CMSIS library for the DSP and compilated it for Tiva C, then we created a FIR in order to eliminate
high and very low frequency. We obtained successfully results with that processing stage and we could eliminate
noise from respiration and electromyography mixed in the desired ECG signal.
Interfaces
7
This is the hierarchy of the GUI using the graphic library of the TivaWare.
Main Screen
Main screen is a canvas that contains an image and two buttons, each of this buttons has a function.
By pushing the button “Start” shows the next screen which contains 5 buttons:
• Principal
• Maternal
• Fetal
• m/f
• Abdominal
The screen in the top has a label “ABDOMINAL SIGNAL” this label indicate the signal to deploy. The label “Press
SEL to start” appear in the center of the screen, this means that it has to be pushed the button “Sel”, located on the
lower right part of the board, until the button is not pressed it will not acquire the signal.
8
By pressing the butto “Maternal” the label on the top of the screen will change to “MATERNAL SIGNAL” and only
the maternal ECG will be display.
Bye pressing “Fetal” the label will change for “FETAL SIGNAL” and the fetal ECG will be display.
Ixchel. Maternal-Fetal ECG monitor | 24/05/14
By pressing the button “m/f” the top label will change to “MATERNAL & FETAL” and both signals will be
displayed.
If you want to return to the abdominal ECG you just have to push “Abdominal”.
9
When pressing button ”Principal” it takes us back to the main screen where it can be seen the buttons “Start” and
“Credits” and if pressed the button “Credits” we will watch the next screen: In this screen the team thanks the project
Ixchel
We acquired important acknowledge about the management of Tivaware libraries, which allows to save time in the
development of projects related to digital signal processing and display on LCD screens.
The project aim was to achieve the separation of the two signals (Maternal and fetal), however some algorithms were
tested without the better results, but we consider this stage as our next challenge. It is important to note that the
real-time separation of these signals is complex and remains as an open research topic. The important point of this
project is that we designed a prototype, which allows acquiring abdominal signals with a good signal to noise ratio
about 10 microvolts amplitude.
10
• TivaWare™ Peripheral Driver Library USER’S GUIDE
• http://www.ti.com/lit/ug/spmu298/spmu298.pdf [consulted: 5 March of 2014]
• Getting Started with the Tiva™ TM4C123G LaunchPad Workshop Student Guide and Lab Manual PDF Digital
• TivaWare™ Peripheral Driver Library http://www.ti.com/lit/ug/spmu298/spmu298.pdf [consulted: 10
January of 2014]
• TivaWare™ Peripheral Driver Library USER’S GUIDE
• http://www.ti.com/lit/ug/spmu298/spmu298.pdf [consulted: 5 March of 2014]
• TivaWare™ Boot Loader
• http://www.ti.com/lit/ug/spmu301/spmu301.pdf [consulted: 5 March of 2014]
• TivaWare™ C Series TM4C123G LaunchPad README First
http://www.ti.com/lit/ug/spmu286a/spmu286a.pdf [consulted: 3 March of 2014]
• Low-Power, 2-Channel, 24-Bit Analog Front-End for Biopotential Measurements
• http://www.ti.com/lit/ds/symlink/ads1292.pdf [consulted 5 march 2014]
• CORONA Fraga Jaime. Metodología de evaluación de algoritmos de extracción del electrocardiograma fetal a
partir del electrocardiograma abdominal. Thesis for the master’s degree in Biomedical Engineer. Mexico D.F:
Universidad Autonoma Metropolitana, 2013.
• JIMENEZ Angeles Luis. Estimación computacional de la linea de base del cardiograma fetal. Thesis for the
master’s degree in Biomedical Engineer. Mexico D.F: Universidad Autonoma Metropolitana, 2003.
• ARIAS Ortega Ronald. Diseño e implementación de un electrocardiógrafo materno-fetal como base para el
desarrollo de un monitor de variables fisiológicas materno-fetales. Thesis for the master’s degree in Biomedical
Engineer. Mexico D.F: Universidad Autonoma Metropolitana, 2010.
• Franco, Sergio. Design with operational amplifiers and analog integrated circuits, 3rd Edition
• http://www.mit.edu/~gari/CODE/ECG_lab/
Ixchel. Maternal-Fetal ECG monitor | 24/05/14
11
Appendix
Schematics
4 47 pf 3 10 kΩ 3 electrodes cables
1 10 µF 1 1 MΩ 1 Tiva TM4C129XNCZAD
12
5 1 µF 1 330 Ω 1 Tiva TM4C129X
3 experimental tablets
1 osciloscope Tektronix
(TDS1002)
1 schmart board
1 instrumental amplifier
Software Code
//*****************************************************************************
//Programa
de
la
interfaz
grafica
del
monitor
//contiene
ademas
la
implementación
de
dibujar
la
señal
mediante
una
interrucpción
//por
puerto
//*****************************************************************************
/*
*
librerias
*/
#include
<stdbool.h>//
#include
<stdint.h>//
#include
"driverlib/rom.h"
#include
"driverlib/rom_map.h"
#include
"driverlib/sysctl.h"
#include
"grlib/grlib.h"
#include
"grlib/widget.h"
#include
"grlib/canvas.h"
#include
"grlib/pushbutton.h"
#include
"drivers/frame.h"
#include
"drivers/kentec320x240x16_ssd2119.h"
#include
"drivers/pinout.h"
#include
"drivers/touch.h"
#include
"math.h"
Ixchel. Maternal-Fetal ECG monitor | 24/05/14
13
//
//*****************************************************************************
extern
tCanvasWidget
g_sBackground;
extern
tCanvasWidget
Abdominal;
extern
tCanvasWidget
g_sCreditos;
extern
tCanvasWidget
SegFetal;
extern
tCanvasWidget
Materno;
extern
tCanvasWidget
SegCombin;
extern
tCanvasWidget
Logouam;
extern
tCanvasWidget
g_sHello;
//botones
de
bienvenida
extern
tPushButtonWidget
g_sPushBtn;
extern
tPushButtonWidget
g_sPushBtn_bis;
extern
tPushButtonWidget
Ajustes_PushBtn;
//////////////////////////////////////////
extern
tPushButtonWidget
g_sPushBtn_1;
extern
tPushButtonWidget
g_sPushBtn_2;
extern
tPushButtonWidget
g_sPushBtn_3;
extern
tPushButtonWidget
g_sPushBtn_4;
extern
tPushButtonWidget
PushBtnRegresar;
extern
tPushButtonWidget
PushBtninicio;
extern
tPushButtonWidget
PushBtAb;
extern
const
uint8_t
g_pui8Image[];
extern
const
uint8_t
UamLogoImage[];
uint32_t
ui32SysClock;
//
//Variables
para
el
protocolo
SPI
uint32_t
a,b,c,d,e,f,g,h,j;
signed
long
CH1;
signed
long
CH2;
unsigned
long
Status;
14
int
x_a
=
0;
int
x_m=
0;
int
x_f
=
0;
int
Tiempo
=
0;
int
GananciaD=
0;
char
CanvasFlag
=1;
//1==adbominal
//2=materno
//3
fetal
//4
materno-‐fetal
bool
flag1=
false;
bool
flag2=
false;
const
char
*g_pcPanelNames
=
{
"To
all
of
us
and
our
families"
"Thanks!"
};
//*****************************************************************************
//
Declaración
de
las
variables
utilizadas
para
graficar
la
señal.
//*****************************************************************************
tContext
sContext;
tRectangle
sRect;
////////////////////////////////////////////////////////////////////
/*
*
Funciones
que
se
utilizan
para
graficar
las
señales
en
distintos
Canvas
*
*/
Ixchel. Maternal-Fetal ECG monitor | 24/05/14
//funciones
para
el
protocolo
SPI
void
config_spi_puertos(void);
void
config_ads(void);
void
Escribe_registros(unsigned
long,
unsigned
long);
void
Recepcion_datos(void);
void
Escribe_comandos(unsigned
long);
void
Buffer1(unsigned
long,
unsigned
long);
//
funciones
para
despliegue
de
señal
ECG
/*
*
Funcion
que
realiza
el
escalamiento
de
los
valores
del
ECG
*/
/*
*
Funcion
para
graficar
señal
de
ECG
del
buffer
*/
15
void
crear_signal(void);
void
grafica_signal
(tContext
*psContext,char,long);
void
ClrScreen(void);
void
ClrScreenBlack(void);
void
ClrScreenWhite(void);
void
PopUp
(void);
void
CambiaText(tWidget
*psWidget);
//*****************************************************************************
//
//
Funcion
que
es
llamada
al
presionar
el
boton
(cual)
//
//**************************************************************************
void
Principal
(tWidget
*psWidget);//
sin
utilizar
void
CreditosOnPress
(tWidget
*psWidget);
void
MaternoOnPress
(tWidget
*psWidget);
void
AbdominalOnPress
(tWidget
*psWidget);
void
FetalOnPress
(tWidget
*psWidget);
void
MaternoFetOnPress
(tWidget
*psWidget);
//**************************************************************************
//Funcion
que
muestra
en
el
widget
con
los
creditos
//**************************************************************************
//*****************************************************************************
//
//
Funcion
que
es
llamada
al
presionar
el
boton
(cual)
//
//*****************************************************************************
void
OnButtonPress(tWidget
*psWidget);
//*****************************************************************************
//
//
Canvas
que
contiene
el
fondo
de
toda
la
aplicacion
//
16
//
//
Boton
que
despliegan
los
creditos
//
//*****************************************************************************
//*****************************************************************************
//
//
Boton
que
despliegan
los
creditos
//
//*****************************************************************************
RectangularButton(g_sPushBtn_bis,&g_sBackground,0,
0,
&g_sKentec320x240x16_SSD2119,250,200,70,
40,
(PB_STYLE_OUTLINE
|
PB_STYLE_TEXT_OPAQUE
|
PB_STYLE_TEXT
|
PB_STYLE_FILL
|
PB_STYLE_RELEASE_NOTIFY),
ClrBlack,
ClrMediumBlue,
ClrWhite,
ClrWhite,
g_psFontCmss22i,
"Credits",
0,
0,
0,
0,
&CreditosOnPress);
//*****************************************************************************
//
//
Boton
que
despliegan
los
creditos
//
//*****************************************************************************
RectangularButton(PushBtnRegresar,
WIDGET_ROOT,0,
0,
&g_sKentec320x240x16_SSD2119,110,
200
,120,
40,
(PB_STYLE_OUTLINE
|
PB_STYLE_TEXT_OPAQUE
|
PB_STYLE_TEXT
|
PB_STYLE_FILL
|
PB_STYLE_RELEASE_NOTIFY),
ClrBlack,
ClrMediumBlue,
ClrWhite,
ClrWhite,
g_psFontCmss22i,
"Back",
0,
0,
0,
0,
&Principal);
//*****************************************************************************
//
//
Boton
que
despliega
señal
materna,
acción
//
//*****************************************************************************
RectangularButton(g_sPushBtn_1,WIDGET_ROOT,
&g_sPushBtn_2,
0,
Ixchel. Maternal-Fetal ECG monitor | 24/05/14
17
//*****************************************************************************
//
//boton
que
despliega
la
señal
materna
y
fetal,
acción
al
presionar:
Dibujamaterna
//
//*****************************************************************************
RectangularButton(g_sPushBtn_3,
WIDGET_ROOT,
0,
0,
&g_sKentec320x240x16_SSD2119,
192,
200
,
64,
40,
(PB_STYLE_OUTLINE
|
PB_STYLE_TEXT_OPAQUE
|
PB_STYLE_TEXT
|
PB_STYLE_FILL
|
PB_STYLE_RELEASE_NOTIFY),
ClrDarkBlue,
ClrBlue,
ClrWhite,
ClrWhite,
g_psFontCmss12i,
"ECG&Noise",
0,
0,
0,
0,
&MaternoFetOnPress);
//*****************************************************************************
//
//boton
que
despliega
el
canvas
que
contiene
el
menu
ajustes,
accion
al
presionar:
NINGUNA
//
//*****************************************************************************
RectangularButton(g_sPushBtn_4,
WIDGET_ROOT,
0,
0,
&g_sKentec320x240x16_SSD2119,
240,
200
,
64,
40,
(PB_STYLE_OUTLINE
|
PB_STYLE_TEXT_OPAQUE
|
PB_STYLE_TEXT
|
PB_STYLE_FILL
|
PB_STYLE_RELEASE_NOTIFY),
ClrDarkBlue,
ClrBlue,
ClrWhite,
ClrWhite,
g_psFontCmss14i,
"ajustes",
0,
0,
0,
0,
0);
/////////////////////////////////////////////////////////////////////
//
//boton
para
regresar
al
inicio
//
/////////////////////////////////////////////////////////////////////
RectangularButton(g_sPushBtninicio,
WIDGET_ROOT,
0,
0,
&g_sKentec320x240x16_SSD2119,
0,
200
,
64,
40,
(PB_STYLE_OUTLINE
|
PB_STYLE_TEXT_OPAQUE
|
PB_STYLE_TEXT
|
18
//
//
Canvas
que
contiene
la
primer
señal,
materna
//
//*****************************************************************************
Canvas(g_sHello,
&g_sPushBtn_1,
0,
0,
&g_sKentec320x240x16_SSD2119,60,90,
200,
60,
(CANVAS_STYLE_FILL|CANVAS_STYLE_OUTLINE
|
CANVAS_STYLE_TEXT|CANVAS_STYLE_TEXT_HCENTER|CANVAS_STYLE_TEXT_VCENTER
),
ClrBlack,ClrBlack,
ClrWhite,
g_psFontCmss14i,
"Press
'SEL'
to
start",
0,
0);
//*****************************************************************************
//Canvas
que
contiene
la
segunda
señal
fetal
//
//*****************************************************************************
Canvas(g_Creditos,
&PushBtnRegresar,
0,
0,
&g_sKentec320x240x16_SSD2119,0,90,
320,
60,
(CANVAS_STYLE_FILL|
CANVAS_STYLE_TEXT|CANVAS_STYLE_TEXT_HCENTER|CANVAS_STYLE_TEXT_VCENTER
),
ClrWhite,0,
ClrBlack,
g_psFontCm20i,"To
all
of
us
and
our
Families",
0,
0);
//*****************************************************************************
//
//canvas
que
contiene
la
tercera
señal,
materna
y
fetal
//*****************************************************************************
Canvas(Logouam,&PushBtnRegresar,
0,
0,
&g_sKentec320x240x16_SSD2119,0,
0,320,43,
(CANVAS_STYLE_FILL|CANVAS_STYLE_IMG),
0,
0,0,0,
0,
UamLogoImage,
0);
//*****************************************************************************
//
//
//*****************************************************************************
Canvas(Materno,
&g_sPushBtn_1,
0,
0,
&g_sKentec320x240x16_SSD2119,0,0,
320,200,
(CANVAS_STYLE_FILL|
CANVAS_STYLE_TEXT|CANVAS_STYLE_TEXT_HCENTER|CANVAS_STYLE_TEXT_TOP
),
ClrBlack,ClrBlack,
ClrWhite,g_psFontCmss14i,
"MATERNAL
SIGNAL",
0,
0);
Ixchel. Maternal-Fetal ECG monitor | 24/05/14
/////////////////////////////////////////////////////////
Canvas(SegFetal,
&g_sPushBtn_2,
0,
0,
&g_sKentec320x240x16_SSD2119,0,0,
320,200,
(CANVAS_STYLE_FILL|
CANVAS_STYLE_TEXT|CANVAS_STYLE_TEXT_HCENTER|CANVAS_STYLE_TEXT_TOP
),
ClrBlack,ClrBlack,
ClrWhite,g_psFontCmss14i,
"FETAL
SIGNAL",
0,
0);
///////////////////////////////////////////////////////////
Canvas(SegCombin,
&g_sPushBtn_2,
0,
0,
&g_sKentec320x240x16_SSD2119,0,0,
320,200,
(CANVAS_STYLE_FILL|
CANVAS_STYLE_TEXT|CANVAS_STYLE_TEXT_HCENTER|CANVAS_STYLE_TEXT_TOP
),
ClrBlack,ClrBlack,
ClrWhite,g_psFontCmss14i,
"MATERNAL
&
FETAL",
0,
0);
19
////////////////////////////////////////////////////////
//
///////////////////////////////////////////////////
Canvas(Abdominal,
&g_sPushBtn_2,
0,
0,
&g_sKentec320x240x16_SSD2119,0,0,
320,200,
(CANVAS_STYLE_FILL|
CANVAS_STYLE_TEXT|CANVAS_STYLE_TEXT_HCENTER|CANVAS_STYLE_TEXT_TOP
),
ClrBlack,ClrBlack,
ClrWhite,
g_psFontCmss14i,
"ABDOMINAL
SIGNAL",
0,
0);
//*****************************************************************************
//
//
The
error
routine
that
is
called
if
the
driver
library
encounters
an
error.
//
//*****************************************************************************
#ifdef
DEBUG
void
__error__(char
*pcFilename,
uint32_t
ui32Line)
{
}
#endif
//*****************************************************************************
//Funcion
de
accion
del
boton
//
//*****************************************************************************
void
OnButtonPress(tWidget
*psWidget)
{
flag1=
!flag1;
//esta
funcion
quita
la
imagen
de
bienvenida
GPIOPinWrite(GPIO_PORTH_BASE,
GPIO_PIN_2,
0X02);
//suspender
20
//
//funciones
que
quitan
todos
los
componentes
de
la
pantalla
principal
WidgetRemove((tWidget
*)&g_sPushBtn);
WidgetRemove((tWidget
*)&
PushBtnRegresar);
WidgetRemove((tWidget
*)&Logouam);
WidgetRemove((tWidget
*)&g_sPushBtn_bis);
WidgetRemove((tWidget
*)&g_Creditos);
WidgetRemove((tWidget
*)&g_Creditos);
WidgetRemove((tWidget
*)&Materno);
WidgetRemove((tWidget
*)&SegFetal);
WidgetRemove((tWidget
*)&SegCombin);;
GrFlush(&sContext);
//
//Pinta
el
arbol
de
widgets
configurado
anteriormente
WidgetPaint(WIDGET_ROOT);
}
//funcion
de
crear
señales
void
crear_signal()
{
int
k=0;
float
PI=3.1416;
for
(
k=0;
k<=1499;
k++)
{
Ixchel. Maternal-Fetal ECG monitor | 24/05/14
s_materna[k]=sin(2*PI*5*0.002*k);
s_fetal[k]=sin(2*PI*10*0.002*k);
s_abdominal[k]=s_materna[k]+s_fetal[k];
s_materna[k]=30*s_materna[k]+110;
s_fetal[k]=30*s_fetal[k]+110;
s_abdominal[k]=30*s_abdominal[k]+110;
}
}
void
CreditosOnPress(tWidget
*psWidget)
{
21
ClrScreenWhite();
//esta
funcion
quita
la
imagen
de
bienvenida
CanvasImageOff(&g_sBackground);
CanvasFillColorSet(&g_sBackground,
ClrWhite);
WidgetRemove((tWidget
*)&g_sPushBtn);
WidgetRemove((tWidget
*)&g_sPushBtn_bis);
WidgetRemove((tWidget
*)&g_sHello);
//
funciones
que
agregan
cada
uno
de
los
botones
al
canvas
principal
WidgetAdd((tWidget
*)&g_sBackground,
(tWidget
*)&PushBtnRegresar);
WidgetAdd((tWidget
*)&PushBtnRegresar,
(tWidget
*)&g_Creditos);
WidgetAdd((tWidget
*)&PushBtnRegresar,
(tWidget
*)&Logouam);
//
//funciones
que
quitan
todos
los
componentes
de
la
pantalla
principal
//
//Pinta
el
arbol
de
widgets
configurado
anteriormente
WidgetPaint(WIDGET_ROOT);
GrFlush(&sContext);
}
22
//
funciones
que
agregan
cada
uno
de
los
botones
al
canvas
principal
WidgetAdd((tWidget
*)&g_sBackground,
(tWidget
*)&g_sPushBtn_1);//Boton
de
Materno
WidgetAdd((tWidget
*)&g_sBackground,
(tWidget
*)&g_sPushBtn_2);
WidgetAdd((tWidget
*)&g_sBackground,
(tWidget
*)&g_sPushBtn_3);
WidgetAdd((tWidget
*)&g_sBackground,
(tWidget
*)&g_sPushBtninicio);
WidgetAdd((tWidget
*)&g_sBackground,
(tWidget
*)&PushBtnAb);
//
//funciones
que
quitan
todos
los
componentes
de
la
pantalla
principal
WidgetRemove((tWidget
*)&SegFetal);
WidgetRemove((tWidget
*)&Abdominal);
WidgetRemove((tWidget
*)&SegCombin);
WidgetRemove((tWidget
*)&g_sHello);
GrFlush(&sContext);
//
//Pinta
el
arbol
de
widgets
configurado
anteriormente
WidgetPaint(WIDGET_ROOT);
CanvasFlag=2;
}
/////
funcion
del
boton
fetal
void
FetalOnPress(tWidget
*psWidget)
{
Ixchel. Maternal-Fetal ECG monitor | 24/05/14
ClrScreenWhite();
//esta
funcion
quita
la
imagen
de
bienvenida
x_f=0;
WidgetAdd((tWidget
*)&g_sPushBtn_1,
(tWidget
*)&SegFetal);
//
funciones
que
agregan
cada
uno
de
los
botones
al
canvas
principal
WidgetAdd((tWidget
*)&g_sBackground,
(tWidget
*)&g_sPushBtn_1);//Boton
de
Materno
WidgetAdd((tWidget
*)&g_sBackground,
(tWidget
*)&g_sPushBtn_2);
WidgetAdd((tWidget
*)&g_sBackground,
(tWidget
*)&g_sPushBtn_3);
WidgetAdd((tWidget
*)&g_sBackground,
(tWidget
*)&g_sPushBtninicio);
WidgetAdd((tWidget
*)&g_sBackground,
(tWidget
*)&PushBtnAb);
//
//funciones
que
quitan
todos
los
componentes
de
la
pantalla
principal
23
WidgetRemove((tWidget
*)&Materno);
WidgetRemove((tWidget
*)&Abdominal);
WidgetRemove((tWidget
*)&g_sHello);
GrFlush(&sContext);
//
//Pinta
el
arbol
de
widgets
configurado
anteriormente
WidgetPaint(WIDGET_ROOT);
CanvasFlag=3;
}
//////boton
abdominal
void
MaternoFetOnPress(tWidget
*psWidget)
{
ClrScreen();
//esta
funcion
quita
la
imagen
de
bienvenida
x_m=0;
x_f=0;
WidgetAdd((tWidget
*)&g_sPushBtn_1,
(tWidget
*)&SegCombin);
//
funciones
que
agregan
cada
uno
de
los
botones
al
canvas
principal
WidgetAdd((tWidget
*)&g_sBackground,
(tWidget
*)&g_sPushBtn_1);//Boton
de
Materno
WidgetAdd((tWidget
*)&g_sBackground,
(tWidget
*)&g_sPushBtn_2);
WidgetAdd((tWidget
*)&g_sBackground,
(tWidget
*)&g_sPushBtn_3);
WidgetAdd((tWidget
*)&g_sBackground,
(tWidget
*)&g_sPushBtninicio);
WidgetAdd((tWidget
*)&g_sBackground,
(tWidget
*)&PushBtnAb);
//
//funciones
que
quitan
todos
los
componentes
de
la
pantalla
principal
24
//////////////////////////////////////////////////
void
AbdominalOnPress(tWidget
*psWidget)
{
ClrScreen();
//esta
funcion
quita
la
imagen
de
bienvenida
x_a=0;
CanvasFlag=1;
WidgetAdd((tWidget
*)&g_sPushBtn_1,
(tWidget
*)&Abdominal);
//
funciones
que
agregan
cada
uno
de
los
botones
al
canvas
principal
WidgetAdd((tWidget
*)&g_sBackground,
(tWidget
*)&g_sPushBtn_1);//Boton
de
Materno
WidgetAdd((tWidget
*)&g_sBackground,
(tWidget
*)&g_sPushBtn_2);
WidgetAdd((tWidget
*)&g_sBackground,
(tWidget
*)&g_sPushBtn_3);
WidgetAdd((tWidget
*)&g_sBackground,
(tWidget
*)&g_sPushBtninicio);
WidgetAdd((tWidget
*)&g_sBackground,
(tWidget
*)&PushBtnAb);
//
//funciones
que
quitan
todos
los
componentes
de
la
pantalla
principal
WidgetRemove((tWidget
*)&Materno);
WidgetRemove((tWidget
*)&SegFetal);
WidgetRemove((tWidget
*)&SegCombin);
WidgetRemove((tWidget
*)&g_sHello);
GrFlush(&sContext);
//
//Pinta
el
arbol
de
widgets
configurado
anteriormente
WidgetPaint(WIDGET_ROOT);
}
/////////////////////////////////////////
//ESTA
LO
HICISTE
TU
DAMIAN
Ixchel. Maternal-Fetal ECG monitor | 24/05/14
//////////////////////////////////
/*
*
Funciones
que
son
llamadas
para
pintar
los
canvas
*/
void
Principal
(tWidget
*psWidget)
{
CanvasFillColorSet(&g_sBackground,
ClrBlack);
ClrScreenBlack();
GPIOPinWrite(GPIO_PORTH_BASE,
GPIO_PIN_2,
0X00);
//suspender
conversión
CanvasImageOn(&g_sBackground);
//
//
Pintamos
todos
los
widgets
iniciales
//
25
WidgetAdd(WIDGET_ROOT,
(tWidget
*)&g_sBackground);
WidgetAdd((tWidget
*)&g_sBackground,
(tWidget
*)&g_sPushBtn);
WidgetAdd((tWidget
*)&g_sBackground,
(tWidget
*)&g_sPushBtn_bis);
WidgetRemove((tWidget
*)&g_sPushBtn_1);
WidgetRemove((tWidget
*)&g_sPushBtn_2);
WidgetRemove((tWidget
*)&g_sPushBtn_3);
WidgetRemove((tWidget
*)&g_sPushBtninicio);
WidgetRemove((tWidget
*)&PushBtnRegresar);
WidgetRemove((tWidget
*)&PushBtnAb);
WidgetRemove((tWidget
*)&g_sHello);
GrFlush(&sContext);
WidgetPaint(WIDGET_ROOT);
};
/*
*
Funcion
que
es
llamada
para
mostrar
la
pantalla
de
creditos
*
contiene
un
boton
cuya
accion
es
regresar
a
la
pantalla
de
inicio
*/
/*
*
Funcion
que
escala
la
señal
*/
/*
*
Funcion
para
graficar
la
señal
de
ECG
abdominal
*/
void
grafica_signal
(tContext
*psContext,char
grafica,
long
indice)
{
GrFlush(&sContext);
26
{
x_a=0;
ClrScreen();
GrFlush(&sContext);
}
p_abdominal=Dato2+45;
break;
case
2:GrFlush(&sContext);
GrLineDraw(psContext,x_m,p_materno,x_m+1,s_materna[i]/2+65);
if(x_m<=319)
{
x_m++;
}
else
{
x_m=0;
ClrScreen();
GrFlush(&sContext);
}
p_materno=s_materna[i]/2+65;
break;
case
3:GrFlush(&sContext);
GrLineDraw(psContext,x_f,p_fetal,x_f+1,Dato+45);
if(x_f<=319)
{
x_f++;
}
else
{
x_f=0;
ClrScreen();
GrFlush(&sContext);
}
p_fetal=Dato+45;
break;
case
4:
Ixchel. Maternal-Fetal ECG monitor | 24/05/14
GrLineDraw(psContext,x_f,p_materno,x_f+1,Dato/2+45);
p_materno=Dato/2+45;
//fetal
GrLineDraw(psContext,x_f,p_fetal,x_f+1,(s_materna[i]/2)+90);
if(x_f<=319)
{
x_f++;
}
else
{
x_f=0;
ClrScreen();
GrFlush(&sContext);
27
}
p_fetal=(s_materna[i]/2)+90;
break;
default:
break;
}
}
/*
*
Función
utilizada
para
limpiar
la
pantalla
cada
que
se
grafica
la
señal
*/
void
ClrScreen()
{
sRect.i16XMin
=
0;
sRect.i16YMin
=
0;
sRect.i16XMax
=
319;
sRect.i16YMax
=199;
GrContextForegroundSet(&sContext,
ClrBlack);
GrRectFill(&sContext,
&sRect);
GrFlush(&sContext);
}
void
ClrScreenWhite()
{
sRect.i16XMin
=
0;
sRect.i16YMin
=
0;
sRect.i16XMax
=
319;
sRect.i16YMax
=239;
GrContextForegroundSet(&sContext,
ClrWhite);
GrRectFill(&sContext,
&sRect);
GrFlush(&sContext);
28
//llama
la
funcion
Linea_1
que
pinta
la
señal
//*************************************************
GPIOIP1ntltHandler()
{
if(flag1)
{
config_ads();
IntEnable(INT_GPIOH);
GPIOIntClear(GPIO_PORTP_BASE,
GPIO_INT_PIN_1);
}
else
{
GPIOPinWrite(GPIO_PORTN_BASE,
GPIO_PIN_5,
0X20);
SysCtldelay_miliseg(100);
GPIOPinWrite(GPIO_PORTN_BASE,
GPIO_PIN_5,
0X00);
SysCtldelay_miliseg(100);
GPIOPinWrite(GPIO_PORTN_BASE,
GPIO_PIN_5,
0X20);
SysCtldelay_miliseg(100);
GPIOPinWrite(GPIO_PORTN_BASE,
GPIO_PIN_5,
0X00);
SysCtldelay_miliseg(100);
GPIOPinWrite(GPIO_PORTN_BASE,
GPIO_PIN_5,
0X20);
SysCtldelay_miliseg(100);
GPIOPinWrite(GPIO_PORTN_BASE,
GPIO_PIN_5,
0X00);
SysCtldelay_miliseg(100);
GPIOPinWrite(GPIO_PORTN_BASE,
GPIO_PIN_5,
0X20);
SysCtldelay_miliseg(100);
GPIOPinWrite(GPIO_PORTN_BASE,
GPIO_PIN_5,
0X00);
GPIOIntClear(GPIO_PORTP_BASE,
GPIO_INT_PIN_1);
}
}
void
CambiaText(tWidget
*psWidget)
{
CanvasTextSet((tCanvasWidget*)&psWidget,
"Configurando
Adquisicion...");
WidgetPaint(WIDGET_ROOT);
}
Ixchel. Maternal-Fetal ECG monitor | 24/05/14
//***********************************************************************************
**************************************
//
_____________________________________________________________________________________
____________________________________
//
|
|
//
|
|
//
|
Programa
para
la
comunicación
con
el
ADS
|
//
|
mediante
protocolo
SPI
|
29
//
|_____________________________________________________________________________
__________________________________________|_
//
//***********************************************************************************
****************************************
enum
spi_opcode
{
WAKEUP
=
0x02,
STANDBY
=
0x04,
RESET
=
0x06,
START
=
0x08,
STOP
=
0x0A,
RDATAC
=
0x10,
SDATAC
=
0x11,
RDATA
=
0x12,
RREG
=
0x20,
WREG
=
0x40
};
enum
registros
{
ID
=
0x00,
/*-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐
-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|
|
ID:
This
register
is
programmed
during
device
manufacture
to
indicate
device
characteristics.
|
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐
-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|
|
Bits[7:5]
|
Bit
4
|
Bits[3:2]
|
Bits[1:0]
|
|
Revision
identification
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|
Revision
identification
|
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|
high
|
low
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐
30
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐
-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|
*/
CONFIG1
=
0x01,
/*-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐
-‐-‐-‐|
|
CONFIG1:
This
register
configures
each
ADC
channel
sample
rate.
|
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐
-‐-‐-‐|
|
Bit
7
|
Bits[6:3]
|
Bits[2:0]
|
|
Single-‐shot
conversion
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|
Channel
oversampling
ratio
|
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|
Must
be
set
to
'0'
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐
-‐-‐-‐|
|
0
=
Continuous
conversion
|
|
000
=
125
SPS
|
|
mode
(default)
|
|
001
=
250
SPS
|
|
1
=
Single-‐shot
mode
|
|
010
=
500
SPS
(default)
|
|
|
|
011
=
1
kSPS
|
|
|
|
100
=
2
kSPS
|
|
|
|
101
=
4
kSPS
|
|
|
|
110
=
8
kSPS
|
|
|
|
111
=
Do
not
use
|
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐
-‐-‐-‐|
*/
CONFIG2
=
0x02,
/*-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐
Ixchel. Maternal-Fetal ECG monitor | 24/05/14
-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|
|
CONFIG2:
This
register
configures
the
test
signal,
clock,
reference,
and
LOFF
buffer.
|
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐
-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|
|
Bit
7
|
Bit
6
|
Bit
5
|
Bit
4
|
Bit
3
|
Bit
2
|
Bit
1
|
Bit
0
|
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|
Lead-‐off
comparator
|
Reference
buffer
|
Enables
4-‐
V
reference
|
CLK
connection
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|
Test
signal
|
Test
signal
|
|
Must
be
|
power-‐down
|
power-‐down
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐
-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|
Must
be
|
selection
|
frequency
|
|
set
to
'1'
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|
0
=
2.42-‐V
reference
|
0
=
Oscillator
|
set
to
'0'
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|
|
|
0
=
Lead-‐off
comparators
|
0
=
Reference
buffer
is
|
(default)
|
clock
output
|
|
0
=
Off
|
0
=
At
dc
|
|
|
disabled
(default)
|
powered
down
|
1
=
4.033-‐
V
reference
|
disabled
|
|
(default)
|
(default)
|
31
|
|
1
=
Lead-‐off
|
(default)
|
|
(default)
|
|
1
=
On
|
1
=
Square
wave
|
|
|
comparators
enabled
|
1
=
Reference
buffer
is
|
|
1
=
Oscillator
|
|
|
at
1
Hz
|
|
|
|
enabled
|
|
clock
output
|
|
|
|
|
|
|
|
|
enabled
|
|
|
|
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐
-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|
*/
LOFF
=
0x03,
/*-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐
-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|
|
LOFF:
This
register
configures
the
lead-‐off
detection
operation.
|
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐
-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|
|
Bits[7:5]
|
Bit
4
|
Bits[3:2]
|
Bit
1
|
Bit
0
|
|
Lead-‐off
comparator
threshold
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|
Lead-‐off
current
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|
Lead-‐off
frequency
|
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|
Must
be
|
magnitude
|
Must
be
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|
|
Comparator
positive
side
|
Comparator
negative
side
|
set
to
'1'
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐
-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|
set
to
'0'
|
0
=
At
dc
lead-‐off
|
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|
|
00
=
6
nA
(default)
|
|
detect
(default)
|
|
000
=
95%
(default)
|
000
=
5%
(default)
|
|
01
=
22
nA
|
|
1
=
At
ac
lead-‐off
|
|
001
=
92.5%
|
001
=
7.5%
|
|
10
=
6
microA
|
|
detect
at
fDR
/
|
|
010
=
90%
|
010
=
10%
|
|
11
=
22
microA
|
|
4
(500
Hz
for
an
|
|
011
=
87.5%
|
011
=
12.5%
|
|
|
|
2-‐kHz
output
rate)
|
|
100
=
85%
|
100
=
15%
|
|
32
|
Bit
7
|
Bits[6:4]
|
Bits[3:0]
|
|
Channel
n
power-‐down
|
Channel
n
PGA
gain
setting
|
Channel
1
input
selection
|
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐
-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|
|
0
=
Normal
operation
(default)
|
000
=
6
(default)
|
0000
=
Normal
electrode
input
(default)
|
|
1
=
Channel
1
power-‐down
|
001
=
1
|
0001
=
Input
shorted
(for
offset
measurements)
|
|
|
010
=
2
|
0010
=
RLD_MEASURE
|
|
|
011
=
3
|
0011
=
MVDD
for
supply
measurement
|
|
|
100
=
4
|
0100
=
Temperature
sensor
|
|
|
101
=
8
|
0101
=
Test
signal
|
|
|
110
=
12
|
0110
=
RLD_DRP
(positive
input
is
connected
to
RLDIN)
|
|
|
|
0111
=
RLD_DRM
(negative
input
is
connected
to
RLDIN)
|
|
|
|
1000
=
RLD_DRPM
(both
positive
and
negative
inputs
are
connected
to
RLDIN)
|
|
|
|
1001
=
Route
IN3P
and
IN3N
to
channel
1
inputs
|
|
|
|
1010
=
Reserved
|
|-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐
-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐|
*/
RLD_SENS
=
0x06,
LOFF_SENS
=
0x07,
LOFF_STAT
=
0x08,
RESP1
=
0x09,
RESP2
=
0x0A,
Ixchel. Maternal-Fetal ECG monitor | 24/05/14
GPIO
=
0X0B
};
void
config_spi_puertos(void)
{
//C
/*uint32_t
ui32SysClock;
ui32SysClock
=
SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ
|
SYSCTL_OSC_MAIN
|
SYSCTL_USE_PLL
|
SYSCTL_CFG_VCO_480),
16000000);
//A
16
MHz
*/
PinoutSet();
//
Configure
the
device
pins.
SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI2);
//Habilitacion
del
sistema
SSI2
33
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
//Habilitacion
de
los
perifericos
GPIO
G
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH);
//Habilitacion
de
los
perifericos
GPIO
K
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOQ);
GPIOPinConfigure(GPIO_PG7_SSI2CLK);
//Pin
G_7
Reloj
SCLK
GPIOPinConfigure(GPIO_PG6_SSI2FSS);
GPIOPinConfigure(GPIO_PG4_SSI2XDAT1);
//Pin
G_4
Recepcion
de
datos
GPIOPinConfigure(GPIO_PG5_SSI2XDAT0);
//Pin
G_5
Transmicion
de
datos
GPIOPinTypeSSI(GPIO_PORTG_BASE,
GPIO_PIN_7
|
GPIO_PIN_6
|
GPIO_PIN_5
|
GPIO_PIN_4);
GPIOPinTypeGPIOOutput(GPIO_PORTH_BASE,
GPIO_PIN_1
|
GPIO_PIN_2
|
GPIO_PIN_3);
//Habilitaciones
puerto
H
como
salida
para
Start,
Reset/PWDN
y
CS
GPIOPinTypeGPIOInput(GPIO_PORTH_BASE,
GPIO_PIN_0);
//Habilitacion
puerto
H
como
entrada
para
DRDY
GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE,
GPIO_PIN_5);
GPIOPinTypeGPIOOutput(GPIO_PORTQ_BASE,
GPIO_PIN_4
|
GPIO_PIN_7);
SSIConfigSetExpClk(SSI2_BASE,
ui32SysClock,
SSI_FRF_MOTO_MODE_1,
SSI_MODE_MASTER,
1000000,
8);
//SPI
maestro,
polarity
0,
phase
1,
a
1MHz
GPIOIntTypeSet(GPIO_PORTH_BASE,
GPIO_INT_PIN_0,
GPIO_FALLING_EDGE);
//Interrupcion
por
flanco
de
bajada
GPIOIntEnable(GPIO_PORTH_BASE,
GPIO_INT_PIN_0);
SSIEnable(SSI2_BASE);
}
//Funcion
de
configuracion
del
ADS1292
void
config_ads()
{
34
GPIOPinWrite(GPIO_PORTH_BASE,
GPIO_PIN_1,
0X02);
//PWDN/RESET
=
1
GPIOPinWrite(GPIO_PORTQ_BASE,
GPIO_PIN_7,
0X80);
SysCtldelay_seg(1);
GPIOPinWrite(GPIO_PORTH_BASE,
GPIO_PIN_3,
0X00);
//CS
=
0
GPIOPinWrite(GPIO_PORTN_BASE,
GPIO_PIN_5,
0X00);
SysCtldelay_seg(1);
GPIOPinWrite(GPIO_PORTH_BASE,
GPIO_PIN_3,
0X08);
//CS
=
1
GPIOPinWrite(GPIO_PORTN_BASE,
GPIO_PIN_5,
0X20);
SysCtldelay_miliseg(50);
Escribe_comandos(SDATAC);
//DETIENE
COMUNICACIÓN
PARA
PODER
ESCRIBIR
REGISTROS
SysCtldelay_10microseg(1);
Escribe_registros(CONFIG1
,
0x00);
Escribe_registros(CONFIG2
,
0xA3);
//
HABILITANDO
REFERENCIA
INTERNA
Y
ENCENDIENDO
TEST
SIGNAL
A
1HZ
(REF=2.42)
Escribe_registros(CH1SET,
0x10);
//CANAL
1
G=1
Y
OFF
&
SHORT
CIRCUIT
Escribe_registros(CH2SET,
0x10);
//CANAL
2
G=1
Y
OFF
&
SHORT
CIRCUIT
//Escribe_registros(LOFF,
0x01);
Escribe_registros(RLD_SENS,
0x23);
Escribe_registros(RESP2,
0x81);
Escribe_registros(GPIO,0x00);
GPIOPinWrite(GPIO_PORTH_BASE,
GPIO_PIN_2,
0X04);
//Start
=
1
GPIOPinWrite(GPIO_PORTQ_BASE,
GPIO_PIN_4,
0X10);
Escribe_comandos(RDATAC);
flag1=
!flag1;
WidgetRemove((tWidget
*)&g_sHello);
WidgetPaint(WIDGET_ROOT);
Ixchel. Maternal-Fetal ECG monitor | 24/05/14
}
void
Recepcion_datos()
{
GPIOPinWrite(GPIO_PORTH_BASE,
GPIO_PIN_3,
0X00);
//CS
=
0
GPIOPinWrite(GPIO_PORTN_BASE,
GPIO_PIN_5,
0X00);
SysCtlDelay(1);
SysCtlDelay(1);
SSIDataPut(SSI2_BASE,
0x00);
SSIDataGet(SSI2_BASE,
&h);
while(SSIBusy(SSI2_BASE)){}
SysCtlDelay(1);
SSIDataPut(SSI2_BASE,
0x00);
SSIDataGet(SSI2_BASE,
&j);
35
while(SSIBusy(SSI2_BASE)){}
SysCtlDelay(1);
SSIDataPut(SSI2_BASE,
0x00);
//while(SSIBusy(SSI0_BASE)){}
SSIDataGet(SSI2_BASE,
&a);
while(SSIBusy(SSI2_BASE)){}
SysCtlDelay(1);
SysCtlDelay(1);
SSIDataPut(SSI2_BASE,
0x00);
//while(SSIBusy(SSI0_BASE)){}
SSIDataGet(SSI2_BASE,
&b);
while(SSIBusy(SSI2_BASE)){}
SysCtlDelay(1);
SSIDataPut(SSI2_BASE,
0x00);
//while(SSIBusy(SSI0_BASE)){}
SSIDataGet(SSI2_BASE,
&c);
while(SSIBusy(SSI2_BASE)){}
SysCtlDelay(1);
SSIDataPut(SSI2_BASE,
0x00);
//while(SSIBusy(SSI0_BASE)){}
SSIDataGet(SSI2_BASE,
&d);
while(SSIBusy(SSI2_BASE)){}
SysCtlDelay(1);
SysCtlDelay(1);
SSIDataPut(SSI2_BASE,
0x00);
//while(SSIBusy(SSI0_BASE)){}
SSIDataGet(SSI2_BASE,
&e);
while(SSIBusy(SSI2_BASE)){}
SysCtlDelay(1);
SSIDataPut(SSI2_BASE,
0x00);
//while(SSIBusy(SSI0_BASE)){}
SSIDataGet(SSI2_BASE,
&f);
while(SSIBusy(SSI2_BASE)){}
SysCtlDelay(1);
SSIDataPut(SSI2_BASE,
0x00);
36
if
(CH2
>
8388607)
//
si
el
bit
23
es
1
daría
un
número
mayor
a
este
valor
{
CH2
&=
0x007FFFFF;
CH2
=
CH2-‐8388608;
}
SysCtlDelay(1);
Buffer1(CH1,
CH2);
if
(i
==
1500)
{
i=0;
}
GPIOPinWrite(GPIO_PORTH_BASE,
GPIO_PIN_3,
0X08);
//CS
=
1
GPIOPinWrite(GPIO_PORTN_BASE,
GPIO_PIN_5,
0X20);
}
//Funcion
de
Interrupcion
void
Interrupcion_puertoH()
{
Recepcion_datos();
grafica_signal
(&sContext,CanvasFlag,i);
GPIOIntClear(GPIO_PORTH_BASE,
GPIO_INT_PIN_0);
}
//Funcion
que
escribe
comandos
void
Escribe_comandos(unsigned
long
opcode)
{
GPIOPinWrite(GPIO_PORTH_BASE,
GPIO_PIN_3,
0X00);
//CS
=
0
GPIOPinWrite(GPIO_PORTN_BASE,
GPIO_PIN_5,
0X00);
SysCtldelay_5microseg(1);
SSIDataPut(SSI2_BASE,
opcode);
while(SSIBusy(SSI2_BASE)){}
SysCtldelay_10microseg(1);
GPIOPinWrite(GPIO_PORTH_BASE,
GPIO_PIN_3,
0X08);
//CS
=
1
GPIOPinWrite(GPIO_PORTN_BASE,
GPIO_PIN_5,
0X20);
Ixchel. Maternal-Fetal ECG monitor | 24/05/14
}
//Funcion
que
describe
la
escritura
de
Datos
sobre
un
Registro
void
Escribe_registros(unsigned
long
registro,
unsigned
long
dato)
{
GPIOPinWrite(GPIO_PORTH_BASE,
GPIO_PIN_3,
0X00);
//CS
=
0
GPIOPinWrite(GPIO_PORTN_BASE,
GPIO_PIN_5,
0X00);
SysCtldelay_5microseg(1);
SSIDataPut(SSI2_BASE,
0x40
|
registro);
while(SSIBusy(SSI2_BASE)){}
SysCtldelay_5microseg(1);
SSIDataPut(SSI2_BASE,
0x00);
while(SSIBusy(SSI2_BASE)){}
SysCtldelay_5microseg(1);
SSIDataPut(SSI2_BASE,
dato);
while(SSIBusy(SSI2_BASE)){}
SysCtldelay_10microseg(1);
GPIOPinWrite(GPIO_PORTH_BASE,
GPIO_PIN_3,
0X08);
//CS
=
1
37
GPIOPinWrite(GPIO_PORTN_BASE,
GPIO_PIN_5,
0X20);
}
void
Buffer1(unsigned
long
Dato1,
unsigned
long
Dato2)
{
Arreglo[i]
=
Dato1;
Arreglo_negativo[i]=Arreglo[i]*-‐1;
//Arreglo2[i]
=
Dato2;
i
=
i++;
}
/////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////
int
main(void)
{
//
//
Configuración
del
reloj
usando
el
PLL
a
120Mhz
//
ui32SysClock
=
MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ
|
SYSCTL_OSC_MAIN
|
SYSCTL_USE_PLL
|
SYSCTL_CFG_VCO_480),
120000000);
/*
*
Configuración
de
los
puertos
para
utilizar
el
SW1
mediante
interrupcion
*
*/
38
//
//
Inicializa
el
driver
del
display
//
Kentec320x240x16_SSD2119Init(ui32SysClock);
//
//
Inicializa
el
contenedor
grafico
//
GrContextInit(&sContext,
&g_sKentec320x240x16_SSD2119);
GrContextForegroundSet(&sContext,ClrWhite);
//
//
Inicializa
el
driver
del
touch
//
TouchScreenInit(ui32SysClock);
//
//
Set
del
manejador
del
touchscreeen
//
TouchScreenCallbackSet(WidgetPointerMessage);
//
//
Pintamos
el
el
canvas
de
fondo
//
Principal
(WIDGET_ROOT);
/*
*
Configuración
y
habilitación
de
las
interrupciones
por
puerto
en
SW1
*
*/
IntEnable(INT_GPIOP1);
//habilitacion
de
las
interrupciones
en
puerto
P1
GPIOIntEnable(GPIO_PORTP_BASE,GPIO_INT_PIN_1);
/*
Ixchel. Maternal-Fetal ECG monitor | 24/05/14
39
40