150 likes | 234 Views
Programming 을 이용한 ECG 증폭기 설계. 6 조. - 목차 -. 과제 순위 생체신호의 실시간 DSP 신호처리의 순서도 Digital Filter 신호처리부의 중요개념 신호처리부분의 프로그래밍. 과제 순위. 2004200459 장재필 2004200456 임명준 2007102856 임영민 2007102854 이준관 2005200439 이지민. 생체신호의 실시간 DSP. “Setting”. ECG 증폭기. + -. ADC. Micro processor.
E N D
- 목차 - • 과제 순위 • 생체신호의 실시간DSP • 신호처리의 순서도 • Digital Filter • 신호처리부의 중요개념 • 신호처리부분의 프로그래밍
과제 순위 • 2004200459 장재필 • 2004200456 임명준 • 2007102856 임영민 • 2007102854 이준관 • 2005200439 이지민
생체신호의 실시간 DSP “Setting” ECG 증폭기 + - ADC Micro processor Start Stop H.R : 75bpm Embedded Software : 특정한 기능을 하는 전자제품에 ( = Firmware) 들어있는 Software
신호처리의 순서도 START Initialization No Key? Yes Mode = Key Digital Signal Processing Display
Digital Filter * Digital filter (1) FIR필터의 특징 ⓐ 선형위상특성을 정확히 그리고 용이하게 실현할 수 있다. 이러한 성질은 데이터 전송과 같은 파형정보를 중요시하는 응용에 필수적인 성질. ⓑ 귀환이 없기 때문에 항상 안정하다. ⓒ 주파수 영역에서 급 준한 감쇠특성을 실현할 때는 높은 차수의 필터 필요 (2) IIR필터의 특징 ⓐ FIR필터보다 적은 차수로 급 준한 감쇠특성을 실현할 수 있다. ⓑ 선형위상특성을 실현하기 어렵다. ⓒ 귀환이 있기 때문에 항상 안정하다고는 할 수 없다. 그러므로 시스템이 안정한가를 항상 판별해야 한다. H[n] • 목적 : 신호처리의 가장 기본적인 목적의 하나로 본래의 신호에 잡음이 첨가될 경우 주어진 측정신호로부터 본래의 신호를 찾아내고자 하는 경우 • 정의 : 관측된 신호에 어떠한 처리를 하여 그 중에서 필요한 성분만 추출해 내어야 하는데 이와 같은 필터링(filtering) • 종류 : 임펄스 응답이 유한인가 무한인가라는 관점에서 FIR(Finite Impulse Response)과 IIR(Infinite Impulse Response)디지털필터로 분류 X[n] Y[n] Y[n]=a0x[n]+a1x[n-1]+…+anx[n-n] -b1y[n-1]-b2y[n-2]-…-bny[n-n] 위의 식에서 bi의 값이 모두 0이면 =>FIR bi의 값이 하나라도 0이 아니면 =>IIR
프로그램에 쓰이는 파일 • monitor.c • GetADC.c • Dsp.c • my_def.h • Initialization.c • Key.c
Monitor.c & GetADC.c //GetADC.c #include my_def.h Int GetADCData(void) { int d; // Read Data from ADC … … … return 0; } // monitor.c #include my_def.h Int main(){ Init(); while(1){ mode = Key(); switch(mode){ case start; d = GetADCData(); dn = Dsp(d); Display signal(d); Display HR(dn); break; default : break; } } return 0; } // my_def.h # define START 0xff; # define STOP 0x00; # define FALSE 0; # define TRUE 1; // 자주쓰이는 값들을 하나의 헤더파일에 저장
Initialization.c & Key.c & Dsp.c // Initialization.c Void Init(void) { … … } // 프로그램의 초기값들을 저장 // Key.c #inlcude my_def.h Unsigned char key(void) { if(key_value == 1) return (START); else return (STOP); } // Dsp.c #include my_def.h Int Dsp(int d) { int d1, d2, d3, d4; d1 = lpf(d); d2 = hpf(d1); d3 = differentiate(d2); d4 = absolute(d3); d5 = mwi(d4); d6 = threshould(d5); d7 = RR_interval(d6); d8 = computeHR(d7); return (d8); } //데이터를 처리해주는 부분, 각각의 함수를 호출하여 연산을 거친 값을 반환한다. 새로 키가 눌려지기 전에는 이전의 키 값으로 return 해주는 program을 짜야한다.
lpf() & hpf() h[n] h[n] x[n] x[n] y[n] y[n] y[n] = {x[n] + 2x[n-1] + x[n-2]} / 4 y[n]=x[n]-2y[n-1] • //lpf() • Int lpf(int x) • { • Int y; • static int x1,x2; • // x1, x2는 함수 호출시 마다 저장 • y={x+(x1<<1)+x2}>>2; • // 프로그램의 성능을 빠르게 하기 위하여 << 시프트 연산자 사용 • x2=x1; • x1=x; • return (y); • } • //hpf() • int hpf(int d) • { • Int y; • static int y1; • y=d-(y1<<1); • y1=y; • return (d); • } 왼쪽의 함수는 High Pass Filter로 왼쪽함수에서 사용된 식은 Y[n]=x[n]-2y[n-1] 의식이다. 위의 함수는 Low Pass Filter로 왼쪽함수에서 사용된 식은 Y[n]={X[n]+2X[n-1]+X[n-2]}/4 의식이다.
Differentiate() & absolute() *미분 ex) y[n] = x[n] – x[n-1] 왼쪽의 함수는 Data값을 받아 미분하는 함수이다. 왼쪽의 미분치 식을 보면 Ts는 고정된 값이므로 미분을 f(n) – f(n-1)로 표현할 수 있는 것을 볼 수 있다. • // Differentiate() • Int differentiate (int d) • { • int y; • static int d1; • y=d-d1; • d1=d; • return (y); • } ƒ(t) Sampling interval n-1 n t • //Absolute() • Int absolute (int d) • { • if(d<0) • return (-d); • else • return (d); • } 왼쪽의 함수는 Data의 값이 음의 값을 가지게 되면 그값에 음수를 취하여 줌으로써 모든 Data의 값을 양의 값을 가지도록 하는 함수이다. Ts는 고정된 값
mwi() y[n] = ∑x[n-i] = x[n] + x[n-1] + … + x[n-29] // i=0 ~ 29 • //mwi() – moving window integral • Int mwi(int x) • { • int y; • static int x1, x2, x3, … x29; • y = x + x1 + x2 + … + x29; • x29 = x28; x28 = x27; …. • x2 = x1; x1 = x; • return (y); • } • // mwi() • Int mwi(int x) • { • int y1; • static int y, p, x[30]; • if(++p==30) • P=0; • y=y-x[p]+x; // y:running sum • x[p] = x; • return(y); • } 제일 예전 Data P 위의 함수는 최근 30개의 Data의 값을 더하여 주는 함수이다. 제일 예전의 Data에 새로운 Data를 넣는 Program -> Ring buffer
threshould() & computeHR() // ComputeHR() Int computeHR(int r){ static int hr; if(r==0) return(hr); else{ hr=12000/r; return(hr); } } 위의 함수는 심장 박동수를 계산하는 함수이다. 이 함수는 전 함수에서부터 입력받은 R-R interval값을 가지고 의 식에 의해 HR을 계산하게 된다. 여기서 시간은 data r값이 1상승하는데 걸리는 시간이라고 할 수 있다. 이 시간을 1분에 대하여 나누어 주면 HR의 값을 얻을 수 있게 된다. // threshould() Int threshould(int d) { int Th = x; if(d>Th) return 1; else return 0; } 위의 함수는 이 다음에 행하여질 R-R interval을 계산하기 위해 필요로 하는 R파형을 나타내는 함수이다. 입력 받은 Data의 값이 특정값 (Threshold값)보다 크게되면 1의 값을 다음 함수에 넘겨 줌으로써 다음 함수에서 이 1의 값을 넘겨받는 시간을 계산하여 R-R interval의 값을 계산하도록 하여주는 함수이다.
RR_interval() * QRS 파형 검출 심전도 신호를 미분하고, 미분한 값의 절대값을 취해준 뒤에 그 값을 다시 적분해주면 일정한 주기를 가지는 구형파가 된다. 이 값들이 가지는 주기로 RR_interval을 구할 수 있다. //RR_interval() int RR_interval(int t) { int r; static int t1,c; If(t1==0 & t==1){ r = ++c; c = 0; t1=t; return(r); } else{ ++c; t1 = t; Return(0); } } //RR_interval() int r; int RR_interval(int t) { static int t1,count; If(!(t1==0&t==1)){ ++count; t1=t; return(0); } else{ t1=t; r=++count; count=0; return(r); } } 왼쪽의 함수는 이전의 함수로부터 data의 값을 입력받아 그 입력 받은 값이 1이 되는 두 입력사이의 시간을 계산함으로써 R-R interval의 시간을 계산하여 다음의 함수로 넘겨주게 된다. 그 원리로는 처음에 1을 입력받은 시점으로부터 다음의 1의 data값을 받을 때까지 count의 값을 증가시킴으로써 이 count 값을 다음의 함수로 넘겨주어 HR(심장 박동수)을 계산하도록 하여주는 함수이다.