Universidad Autónoma Metropolitana
- Iztapalapa
Seminario de
Proyecto
Ingeniería Biomédica
Procesamiento Digital de Seííales Fisiológicas
Eduardo Nnvarrcte
Paz
85226557
Asesor:
INTRODUCCION
Existen muchos filtros digitales y diseño de algoritmos reconocidos usados en procesamiento
digital de señales biomedicas. En un instrumento médico uno dispone de esos algoritmos tipicos
que deben operarse en tiempo real. Por ejemplo, una unidad de cuidados intensivos
computarizada debe adquirir el electrocardiograma
de un paciente, reorganiza las
caracteristicas claves de la señal, determinando si la señal es normal o anormal, y reportando
esta información en un modo oportuno.
Existen tres tipos de datos que pueden ser adquiridos, manipulados y almacenados en un
hospital. Datos alfanumericos que incluyen el nombre del paciente y dirección, numero de
identificación, resultados de la prueba de laboratorio, y notas físicas. Datos para imagenes que
incluyen rayos x y rastreo de tomógrafia computarizada, resonancia magnetica de imagenes y
ultrasonido.
Datos
proporcionados
por
señales
fisiologicas,
por
ejemplo
el
electrocardiograma(ECG), el electroencefalograma(EEG), y trazado de presión sanguinea.
Diferentes sistemas son necesarios para manipular cada uno de
los
tres tipos de datos. Los
datos alfanumericos son generalmente controlados y organizados dentro de una base de datos
usando una computadora personal de proposito general.
Los
datos de imagen son almacedos en pelicula. Sin embargo son desarrollodos para
almacenamiento de imagenes y sistemas de comunicación que puedan almacenar imagenes en
forma digital y discos opticos y distribuidos entonces en demanda sobre un area local de red de
alta velocidad para graficas de alta resolución desplegadas en monitores localizados a través
de un hospital.
Las señales fisiologicas requieren que sean monitorizadas durante una cirugia en el cuarto de
operaciones, requiriendo procesamiento en tiempo real. El clinico puede conocer
inmediatamente si el instrumento encuentra lecturas anormales con el anális de datos
continuos.En este tipo de datos es en el que se concentra este proyecto.
En las decadas pasadas el microprocesador tuvo un impacto significante en el diseño de
instrumentación biómedica. La evolución natural de
los
instrumentos basados en
microprocesador son para m8s dispositivos inteligentes.
La evolución del microprocesador empezo desde muy temprano a partir de 1971, como una
unidad central de procesamiento primitiva, hasta
los
componentes potentes de hoy, con un
impacto significativo
en el disefio de instgrumentacih biomédica. Muchas computadoras
tes y memorias
son
empaquetadas dentro de circuitos integrados muy pequeños para
proporcionar coda vez mas
instrumentos optimos y potentes. Las pcs han venido a ser
herramientas poderosas con muchas aplicaciones biomedicas que requieren procesamiento de
información y almacenamiento. En el futuro se podra desarrollar nuevos instrumentos médicos
para direcdonar problemas que no han sido resueltos. Esta posibilidad existe porque sistemas
basados en microprocesadores continuamente se optimizan en tanto en tamaño, costo y
consumo de potencia, al igual que
los
elementos de almcenamieto como las memoria,
lo
cual
da a un sistema una gran potencia.
El concepto general de convertir una señal de tiempo continuo a una representación utilizable
por un microprocesador, radica en el hecho de que se puede representar una señal de tiempo
continuo por valores de amplitud instantaneos tomados en puntos periodicos en el tiempo
(
valores discrestos). Aun se es
mas importante, la capacidad de recontruir la señal original
perfectamente con exacto esos puntos muestreados.
Las señales biomedicas vienen en todas las formas y tamaños, sin embargo, para poder
capturar y analizar esas señales, algunos pasos generales de procesamiento son requeridos
para todas las señales. La siguiente figura ilustra un sistema de conversión de señal general
analogica a digital (ND).
es bastante pequeña en amplitud
(
e.g.
El
ECG tiene rangos de
l o p
a 5mv). La amplificacion es
necesaria para brindarle
la amplificación de la señal dentro
de
los rangos de el
ND. La
amplificacion debe ser hecha de
tal manera que la señal fuente no se degrade.
Si hay varias
señales de entrada para ser convertidas, un
multiplexor anhlogico es necesitado para enviar a
cada señal a el convertidor
ND.
Para minimizar aliasing, un filtro pasa-bajas es despues usado
para limitar en banda a
la señal para despues ser muestreada.
Un circuito de
muestre0 y
retención es requerido en la entrada a el convertidor
A/D para retener la señal analógica en un
valor constante durante
el proceso de conversión. Finalmente el convertidor
analogico-digital
cambia
los voltajes analógicos a una representación digital.
Despues la información de la señal biomedica digital es almacenada en un dispositivo
de
almacenada en un dispositivo de memoria para mas tarde procesarla por una computadora. En
algunos casos este procesamiento puede ser dado en tiempo real. Otro posible uso para la señal
digital es un sistema de control. Después el controlador requiere una señal analógica, para esto
un convertidor Digital-Analogica es necesario.
La salida analógica puede
ser usada para
controlar el flujo de gases en una maquina de anestesia
o
la temperatura en un incubadora.
Una vez adquirida la señal digital esta puede se manipulada por el procesamiento digital
de la señal, que puede consistir en
integrarla, derivarla, obtener su espectro
de potencia,
su
correlación, autocorrealcion, filtrar la señal ya se para obtener un rango
de frecuencia que nos
proporcione la información deseada, como un filtro pasa-banda, rechazar frecuencias muy bajas
como ruido esto se puede con un
filtro pasa-bajas
o
filtros pasa-altas si se requiere analizar
frecuencia altas
etc. Todo es tipo de procesmiento
digital de señales tiene como objetivo
obtener información de señales biomédicas para poder tener un
mejor diagnostico de
el
paciente.
OBJETIVO
Dado el protocolo de comunicación serial de un sistema minimo basado en el microcontrolador
68HC11 con una
PCde propocito general, capturar una señal fisiologica con el miccrocontrolador
y
transmitirla a la
PCdesplegando la informacion en tiempo real y posteriormente
realizar
el
procesamieto digital de señales biomedicas como:
a).- Integración
b).- Derivación.
c).- Analizia espectral.
d).- Correlacion.
e).- Aufbcorrelacion.
9.-
Filtrado (Pasa-bajas y Pasa altas)
DISEÑO
Requerimientos de diseño:
1
.-
Un sistema minimo basado en el microcontrolador 68HC11
2.-
Una PC de proposito general 286/AT con disco duro de 80 Mbytes y 2 Mbytes en memoria
3.-
Un protocolo de comunicación serial RS232.
4.-
Fuentes de alirnentacion (5volts, +9volts,-9volts).
5.-
Soporte de Software para progamación de el 68HC11 a nivel ensamblador.
6.-
Soporte de Software para el despliegue
y
procesamiento
,
programando en lenguaje C.
Configuracion del diseño a bloques.
Fuente
PC
5
volts
Señal
fislologica
l i l
1U
68HC11
RS232
I
I
e -
U
Fuente
DESARROLLO DE SOFTWARE
Se realizaron dos programas, uno en ensamblador para
la
captura
y
transmision de la seiial, la
transmicion se realizo a
9600
baudios
y
el programa recide en la EMPROM del sistema minimo
del 68HC11.
El
otro programa fue realizado en lenguaje C para
la
recepcion, despliegue
y
procesamiento de la señal.
Acontinuacion se presentan los dos programas.
PROGRAMA EN
c
PARA LA RECEPCION, DESPLIEGUE
Y PROCESAMIENTO DE LA SEÑAL
#include <dos.h> #include <math.h> #include cgraphics.h> #include <conio.h> #include <stdio.h>
union REGS rin,rout;
int dato1 [1024],dato2[1024],dato3[1024];
int num=63; char resp,rn = *S';
char nom1 [30], nom2[30]; FILE 'fp;
void main()
I
void A-D(int nurn, int dato[1024]); void initgraph(v0id);
void init-rs(void);
void leer-CAD(int nurn,int ret); void rnenu(char resp); void C-Arch(void); void Conv(void);
int Prueba(char nom[30]); void Convolve(void);
void Captura(char norn[30],int 'dato,int 'I);
void Conv(void); void Corr(void); void AutC(void); void Correl(void); void Aut(void); void VerArch(void); void FilH(inbnurn); void FilL(int nurn); void Int(int num); void Der(int num);
menu(resp);
P
Digitalizaci6n de senales analogicas de magnitud 5 volts y despliegue en monitor ' Ivoid A-D(int num,int dato[1024])
char c = 0x00;
int i;
float ejex;
ejex = (float)542/nurn;
clearviewport(); outtextxy(53,395,");
for (i
=
1; i e= num-1; i++)c = getch(); closegraph(); restorecrtmode(); textbackground(BLUE); textcolor(YELL0W); clrscr();
lineto(i*ejex,abs( 0.307'dato[i]));
void init_graph(void)
{
int i,md, mn = DETECT; char s[l2];
initgraph(&mn, &md,"..\\bgi"); cleardevice();
setcolor(WH1TE);
settextjustify(CENTER-TEXT,TOP-TEXT); setfillstyle(1 ,BLUE);
floodfill(O,O.BLUE);
outtextxy(320,20,"68HCll Transmisi6n serial COMZ);
outtextxy(320,41O,"ESC
-
Terminar"); setlinestyle(SOLID-LlNE,O,NORM_WIDTH);rectangle(50,78,600,397);
for (i = O ; i c 6 ; i++)
{
itoa(i,s,7);
outtextxy(40.398 -(64 ¡),S);
setviewport(53,80,595,395,1); clearviewport();
1
I
void init-rs(void) I' inicializaci6n de la linea serie ' I {
rin.h.ah = O; rin.x.dx = O;
rin.h.al = OxC3; I' 4800Bd, N-paridad, 1 bit stop, 8 bits data ' I
int86(0x14,&rin, &rout);
I
Avoid leer-CAD(int num,int ret) I' Lee consecutivamente num datos por cada llamada'/
( int i;
for (i = O; i <= num; i++) (
delay(ret); rin.h.ah = 2; rin.x.dx = O;
int86(0x14,&rin,&rout); dato1 [i] = (rout.h.a1)'4;
1
I
void menu(char resp) /* menu principal */ {
resp = * ';
while( resp I= Y )
textbackground(BLUE); textcolor(YELL0W);
clrscr();
gotoxy(l,7);
printf(" a) Crear archivos W); printf(" b) Convoluci6n W);
printf(" c) Correlacibn W); printf(" d) Autocorrelaci6nW); printf(" e) Ver archivoW); printf(" x) SalirW); printf(" Opci6n?");
resp = tolower(getch()); printf(" W);
switch(resp)
(
case 'a' : Cprch();
case 'b : Conv();
case 'c' : Corro;
case 'd : AutC();
case 'e' : VerArch(); break;
break;
break;
break;
break;
1
1
textbackground(BLACK); textcolor(WH1TE); clrscr();
I
void C-Arch(void)
(
char car; int ¡,ret = -1 ;
int yi = O;
while((num%64 I= O)
11
(ret < O)) (clrscr(); gotoxy(l,8);
printf(" Nombre del archivo ");
scanf("%s",noml); printf(" W); 14
printf(" Numero de puntos ");
scanf("%d,&num); printf(" W);
printf(" Retardo entre muestras ");
scanf("%d,&ret); printf("W);
1
P init-rs();'/I' leer-CAD(num,ret);'/
/*for (i = O; i < 1024; i++) (
yi =y¡ + 10;
if (yi <= 50) datol [i] = O; else{
datol [i] = 1024;
I
if (yi > 100) yi =o;
Y/
{
yi = yi + 1;
if (y¡>= 256)
{
yi =
o;
1
datol [i] = 4'yi; ekeI
yi = yi + 1;
I
datol [i] = 4'yi;
I
P datol[i] = (int) i;'/
fp = fopen(nom1 ,"wb);
fwrite(&num,sizeof(int),l ,fp);
fwrite(dato1, sizeof dato1,l ,fp); fclose(fp);
P fp
=
fopen(norn1 ,"rb); fread(dato1 ,sizeof dato1,l ,fp); for (i = O; i < nurn; i++)fclose(fp);*/ printf("%d ",dato1 [i]);
printfrdesea graficarlo? ");
car = tolower(getch()); if (car == Y ) {
A-D(nurn,datol); textbackground(BLACK);
int Prueba(char nom(301)
{
if((fp = fopen(nom,"rb)) == NULL )
return 1 ;
fclose(fp); return O;
I
void Captura(char nom[30],int 'dato.int 'I)
{ int i=l; ~~
fp = fopen(nom,"rb); fread(dato1 ,sizeof dato1,l ,fp);
*I = datol [O];
for (i = O; i '1+1; ++i) dato[¡] = datol [i];
fclose(fp);
I
void Conv(void)
{
printf("Nornbre del primer archivo ");
scanf("%s",noml); printf(" W);
printf("Nombre del segundo archivo ");
scanf("%s",nom2); printf(" W);
if(Prueba(norn1)
11
Prueba(nom2)){
1
else{ printf("Archivos abiertos
,
espere un momentoh");I
Convolve();} void Corr(void)(
printf("Nombre del primer archivo ");
scanf("%s",noml); printf(" W);
printf("Nombre del segundo archivo ");
scanf("%s".nom2); printf(" h");
if(Prueba(nom1)
11
Prueba(nom2)){
if(Prueba(nom1)) printf("No se pudo abrir el primer archivoh"); else printf("No se pudo abrir el segundo archivoW);
else{ printf("Archivos abiertos , espere un momentoh");
Carrel();}
1
I
void AutC(void)
(
printf("Nombre del archivo ");
scanf("%s",noml); printf(" W); if(Prueba(nom1))
(
1
printf("No se pudo abrir el primer archivoh");else{ printf("Archivo abierto , espere un momentoh");
AutO;)
1
void Convolve(void)
int It ,I2,Max; int j,k,i;
Captura(nom1,Bdatol ,811); Captura(nom2 &dato2,812); Max I t +12-1!
if (Max >= 1023)
{
if((ll>=l024) 88 (12>=1024))
{
I1 = H/2; 12 = 12/2 ;
Max = 1023;
1
else
if (I1 >=1024) I1 = 1112; else 12 = 12/2;
Max = I t +12-1;
1
I
for(k=l; k <= Max; ++k) dato3[k] = o;
for(i=l ; i <= It; ++i)
for(j=l ; j <= 12; ++j)
{
dato3[kl = ((dato3[k] + datol(i]'dato2~])r>4)+420;
I
A_D((Max+260)/2,dato3); textbackground(BLACK);
I
void Correl(void)
int I1 J2,Max; int k,l,nl;
Captura(nom1 ,&dato1 ,&ll);
Captura(nom2,&dato2,&12);
Max =12;
for(l= O; I< Max-1; ++I)
nl = 12+1 -I;
if (ni >= I1 -1) ni = 11-1; dato3[1] = O;
for( k= O; k .Z nl-l;++k)
dato3[1] = 1024 -1 O'((dato3[I] + datol [k]*dato2[k-l))>>200); {
{
I
A-D(Max+l ,dato3); textbackground(BlACK);
void Aut(void) { int k,nd,nk,ndk;
int Max,ll ;
Captura(nom1 ,&dato1 ,&ll); Max = I1 '2-1 ;
if (MaxSlO23) Max = 1023; for(k=O;k<Max;++k)
dato2[k] = O; nk = 11-k+l;
for(nd=O; ndcnk;++nd) {
{
n d k = n d + k - 1 ;
dato2[k] = (dato2[k] + datol [ndl'datol [ndk])>>l M);
I
I
Max = Max
+y;
AVD((Max+l)/2,dato2); textbackground(BLACK);I
void VerArch(void) ( int 11;
char resp;
clrscr();
printf(" Nombre del archivo: "); scanf("%s",noml);
printf(" W);
if(Prueba(nom1)) gotw12,5);
{
I
printf("No se pudo abrir el primer archivow); elseresp = * I ;
while(resp I= Y )
{
Captura(nom1 ,&dato1 ,&ll);
printf(" a) Ver Sena1 h"); printf(" b) Fil-H W); printf(" c) FiI-L W); printf(" d) Integrar W); printf(" e) Derivar W); printf(" x) SalirW); printf(" Opcih? ");
resp = tolower(getch());
switch(resp) gotoxy(l,7);
{
case 'a' : A-D(I1 ,datol);
textbackground(BLACK); break;
break;
break;
break;
break: case 'b : FiIH(I1);
case 'c' : FiIL(I1);
case 'd : Int(l1);
case 'e' : Der(l1);
1
textbackground(BLUE); textcolor(YELL0W); clrscr();
I
I
1
void FilH(int num) {int y1 = O,x[66],n=32;
int yU,i;
for (i = O ; i <= num; i++)
x[n] = x[n+33]=datol [i];
y0 = y1 +x[n]-x[n+32]; Y1 =Yo;
if(--n<o) n= '92;
dato2[i] = x[n+16] - (yo-5);
{
1
A_D(nurn,dato2); textbackground(BLACK);
I
void FilL(int num)
{int y1 = O,y2 = O,x[26],n=12; int y0,i;
for (i
=
O ; i <= num; i++) {x[n] = x[n+l3]=datol [i];
y0 = (yl<<l)
-
y2+x[n]-
(x[n+6]<<l) + x[n+l2];A-D(num,datoZ); textbackground(BlACK));
I
void Int(int num) {int ptr = 0.~1321;
long sum = O;
long ly; int y,¡; int Mx =O;
for (i = O ; i c= num; i++)
if (++ptr == 32) ptr =O; sum -= x[ptr]; sum += datol[i]; x[ptr] = datol [i];
ly
= sum >> 5;if(1y > 32400) y = 32400; else y = (int) ly;
dato2[i] = y; (
1
for (i = O;icnum;i++) dato2[i] = (dato2[i]/2)-100; A_D(num,dato2);
l'textbackground(BLACK);'l
I
void Der(int num) {
int y,i,m; int xder[4];
for (m = 0;m cnum;m++)
y = (datol[m] 4 )+ xder[3]-xder[l]-(xder[O]~cl);
for(i=O;ic3;++i) xder[i] = xder[i+l]; xder[3] = datol [m]; dato2[rn] = y+512; y >>= 3;
1
1
AA_D(num,dato2); textbackground(BLACK);
I* fp
=
fopen(nom1 ,"rb'); fread(dato1 ,sizeof dato1,l ,fp); for (i=
O; i < num; i++)fclose(fp);'/
printf("%d ",dato1 [i]);
Pfor (i = O; i c 300; i++)
{ dato[¡] = (int) i'2;
1
printf("%d ",dato[¡]);if ((fp = fopen(norn,"rb)) == NULL)
printf("No se pudo abrir h"); fread(dato,sizeof dato,l ,fp); for (i = O; i < 200; i++)
PROGRAMA MONITOR PARA
EL
68HC11
RAM-1-1 EQU RAM-I-F EQU RAM-E-I EQU RAM-E-F EQU ROM-I EQU ROM-F EQU EEPROM-I EQU EEPROM-F EQU DATOS-TECL EQU INSTR-TECL EQU A-INVALIDA EQU
'Codigo de las teclas
TECL-O TECL-1 TECL-2 TECL-3 TECL-4 TECL-5 TECL-6 TECL-7 TECL-8 TECL-9 TECL-A TECL-B TECL-C TECL-D TECL-E TECL-F TECL-F1 TECL-F2 TECL-F3 TECL-F4 CTNL-F1 CTNL-F2 CNTL" CNTL" SHIFT-Fl SHIFT-F2 SHIFT-F3 S H I FT-F4 T-NULL FUNC-SCI T-RESET EQU EQ U EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU $0000 $OOFF $2000 $3FFF $E000 $FFFF $8600 $B7FF $c001
$4000 direccion invalida para nuestro mapeo
$c000 $DD $D5 $DI $D2 $CD $C9 $CA $C5 $C1 $C2 $C3 $CB $D3 $DB $DA $D9 $C4 $CC $04 $DC $44 $4C $54 $9C
$84 Ejec $8C Edit $94
$9C
Registros internos Revisar
$00
$1
c
combinaci6n CNTL-SHIFT-F4 $04 cornbinaci6n CNTL-SHIFT-F1'Codigo de los caracteres para el display
CARACT-D EQU CARACT-E EQU CARACT-F EQU CARACT-P EQU CARACT-t EQU BLANCO EQU PUNTO EQU SUBLINEA EQU GUION EQU CARACT-H EQU CARACT-L EQU CARACT-r EQU CARACT-i EQU CARACT-o EQU CARACT-h EQU CARACT-n EQU CARACT-v EQU CARACT-U EQU CARACT-J EQU CARACT-T EQU
codigo numerico para putch2 $00 codigo numerico para putch2 $01
codigo numerico para putch2 $02 codigo nurnerico para putch2 $03
codigo numerico para putch2 $04
codigo numerico para putch2 $05 codigo numerico para putch2 $06 codigo numerico para putch2 $07 codigo numerico para putchi! $08 codigo numerico para putch2 $09
Declaraccidn de variables ORG RAM-1-1
AuxO RMB 1
Auxl RMB 1
Aux2 RMB 1
Aux3 RMB 1
ORG ROM-I
*-Principal
'Organiza el monitor.
Principal EQU
ldaa #$93
staa $1039 option ldaa #$O0
staa $1024 tm5k2 ldaa $1020
oraa #$O3
staa $1020 trace en pin oc5
Ids #RAM-I-F Inicializa la pila.
jsr InitTecl Inicializa el teclado para leer teclas y escribir en display.
'Aqui van las funciones CHECK RAM y ROM jsr P ~ P Y
ldaa #$OC ldab #$O0
jsr putch ldaa #CARACT-h ldab #$O1 jsr putch2 ldaa #$OE ldab #$O2 jsr putch
ldaa #$OC ldab #$O3 jsr putch
ldaa #BLANCO ldab #$O4 jsr putch2 ldaa #$OE ldab #$O5
ldaa #CARACT-P ldab #$O6
ldaa #CARACT-r
jsr putch
ldab #$O7
jsr putch2 ldaa #$44 jsr Delay jsr clrdpy
jsr ChkRom jsr Bien ldaa #$OC ldab #$O0
jsr putch ldaa #CARACT-h ldab #$O1 jsr putch2 ldaa #$OE ldab #$O2 jsr putch
ldaa #$OC ldab #$O3
jsr putch ldaa #BLANCO ldab #$O4 jsr putch2
ldaa #CARACT-r ldab #$O5
jsr putch2 ldaa #$OA ldab #$O6
jsr putch ldaa #CARACT-n ldab #$O7
ldaa #$44 jsr Delay jsr clrdpy
jsr putch2
jsr ChkRam jsr Bien ldaa #%OOOOOOO0
tap Tranfiere $00 a CCR (habilita interrupci6n XIRQ)
Ciclo: nop
ldab #$O0
ldaa #CARACT-P jsr putch2
ldaa #CARACT-r jsr putch2
ldaa #CARACT-E ldab #$O1
Idasp #$O2
jsr putch2 ldab #$O3
jsr putch2 ldab #$O4
ldaa #CARACT-5 jsr putch2 ldab #$O5 ldaa #BLANCO
ldab #$O6
ldaa #CARACT-F jsr putch2 ldab #$O7
ldaa #CARACT-T jsr putch2 ldaa
#$m
jsr Delay jsr clrdpyldaa #CARACT-5
jsr putch2
wai Espera interrupcibn para ejecutar comando noP
noP jmp Ciclo
END
fin del programa principal
'Continuan las subrutinas.
ChkRom equ
clra limpia ACCA Idx #ROM-I apuna a la ROM
inx
cpx #ROM-F si no ha terminado ble suma suma otro BYTE cmpa #$O0 si suma no correcta beq merror manda mensaje de error
ltS
ldaa #$AA
Idx #RAM-E-I apunta a la RAM suma adda $ 0 , ~
ChkRam equ
escribe staa $ 0 , ~ almacena un $AA en la ram inx
CPX
ble Idx compara cmpa
bne inx CPX ble ltS
#RAM-E-F si no ha terminado escribe almacena otro BYTE #RAM-E-I apunta a la RAM
$ 0 , ~ compara la memoria con $AA merror
#RAM-E-F compara
merror ldab #O ldaa #$OE
jsr putch escribe E ldab #1
ldaa #CARACT-r jsr putch2 escribe r ldab #2
ldaa #CARACT-r jsr putch2 escribe r
stop wai ,l
ltS
*-InitTecl
'Inicializa los parametros del controlador de teclado 8279
InitTecl EQU
-
ldaa #%O001
oo00
8 caracteres 8 bits, entrada por la derecha exploraci6nde teclado codificada, bloque por pulsaci6n de dos teclas. staa INSTR-TECL Ejecuta comando en el 8279
ldaa #%O0101010 Divide la frecuencia del reloj E = 1 Mhz staa INSTR-TECL Ejecuta comando en el 8279
ldaa #%11 O1 O1 1 O Borra registros del 8279 staa INSTR-TECL Ejecuta comando en el 8279 noP
noP menhcll ldaa #$O6
ldab #$O0
jsr putch ldaa #$O8
beq Esc-tecl ldab #CARACT-9 cmpa #$O9 beq Esc-tecl ldab #CARACT-A cmpa #$OA beq Esc-tecl ldab #CARACT-B cmpa #$OB beq Esc-tecl ldab #CARACT-C cmpa #$OC beq Esc-tecl ldab #CARACT-D cmpa #$OD beq Esc-tecl ldab #CARACT-E cmpa #$OE beq Esc-tecl ldab #CARACT-F cmpa #$OF beq Esc-tecl
bra Finputch Linea solo para prueba (Borrar) Esc-tecl stab DATOS-TECL Escribe en RAM del display.
Finputch rts
pulb En ACCB permanece la posici6n
'Escribe un caracter en la RAM de display del 8279, en ACCA esta el codigo *del digito a imprimir y en ACCB la posici6n en donde se escribira.Mantiene
*los valores de todos los registros sin cambios.
putch2 EQU
cmpb #$O7
bgt Finputch2 Si la posici6n es mayor de 7 no imprimas nada pshb Guarda la posici6n
orab #%1OOOOooO lnstruccion de escritura en la RAM de display. stab INSTR-TECL Ejecuta el comando para el 8279.
staa DATOS-TECL Escribe en RAM del display.
noP Tiempo para que el 8279 decodifique la instrucci6n
pulb En ACCB permanece la posici6n Finputch2 ,*
rts
* a e t c h e
'En ACCB espera la posici6n en donde realizara el eco, ACCB=$FF para no hacer 'eco ( que equivale a esperar leer tecla de funci6n).
'Regesa en ACCA el valor de la tecla pulsada o $FF si es una tecla de funci6n. 'En ACCB regresa el codigo de la tecla segun la matriz del teclado.
getche EQU
cmpb #$FF Hacer eco 7
SinEco
beq ldaa jsr
jsr ldaa jsr ldaa jsr ldaa ldaa #$O5
SinEco
#BLANCO Codigo de blanco
putch2 En ACCB esta la posici6n de eco.
Delay Crea un retrazo de 0.1 25 seg #SUBLINEA Codigo de sublinea putch2
#$O5
ldaa #GUION ldab #$O2
jsr putch2 ldaa #CARACT-H
jsr putch2 ldaa #$OC
jsr putch ldaa #$O1
jsr putch ldaa #$O1
jsr putch ldaa #$44 jsr Delay
ldab #$O3
ldab #$O4
ldab #$O5
ldab #$O6
ldab #%10000000 lnstruccion de escritura en la RAM de display. ldaa #$O0
staa DATOS-TECL Escribe en RAM del display. incb
cmpb #%1 O001 O00
blt Del8279 rtS
Del8279 stab INSTR-TECL Ejecuta el comando para el 8279.
*Escribe un número HEX en la RAM de display del 8279, en ACCA esta el valor 'del digito a imprimir y en ACCB la posici6n en donde se escribira.Mantiene 'los valores de todos los registros sin cambios.
putch EQU
cmpb #$O7
bgt Finputch Si la posici6n es mayor de 7 no imprimas nada cmpa #$OF Número de caracteres validos en display. bgt Finputch
pshb Guarda la posicibn
orab #%1OOOOooO lnstruccion de escritura en la RAM de display. stab INSTR-TECL Ejecuta el comando para el 8279.
ldab #CARACT-O cmpa #$O0
beq Esc-tecl ldab #CARACT-l c&pa #$OI
beq Esc-tecl
ldab #CARACT-2
cmpa #$O2 beq Esc-tecl ldab #CARACT-3 cmpa #$O3 beq Esc-tecl ldab #CARACT-4 cmpa #$O4 beq Esc-tecl ldab #CARACT-S cmpa
#$O5
beq Esc-tecl ldab #CARACT-G cmpa #$O6anda #%O00001 11 Hay caracteres en la FIFO beq getche Espera hasta que exitan caracteres stab Auxl Almacena b en una variable auxiliar.
ldaa #%01000000 lnstruccion de lectura en la FIFO. staa INSTR-TECL Ejecuta el comando para el 8279.
ldab DATOSJECL Almacena en b el codigo de la tecla. clra
cmpb #TECL-O beq Notecl inca
cmpb #TECL-l beq Notecl inca
cmpb #TECL-2 beq Notecl inca
cmpb #TECL-3 beq Notecl inca
cmpb #TECL-4 beq Notecl inca
cmpb #TECL-5 beq Notecl
cmpb #TECL-G inca
beq Notecl inca
cmpb #TECL-7 beq Notecl inca
cmpb #TECL-8 beq Notecl inca
cmpb #TECL-S beq Notecl inca
cmpb #TECL-A beq Notecl inca
cmpb #TECL-B beq Notecl inca
cmpb #TECL-C beq Notecl inca
beq Notecl inca
cmpb #TECL-E beq Notecl inca
cmpb #TECL-F beq Notecl (, cmpb #TECL-D
ldaa #$FF bra Fingetche
ldab Auxl Pon en ACCB posicion de eco jsr putch Haz eco
Notecl pshb Guarda codigo de la tecla
pulb Pon en ACCB codigo de la tecla. Fingetche Its
Delay EQU
Dloop2 Idx #4166 tiempo = ACC 41 66' 6 ' 1000ns
Dloop dex
deca bne Dloop2
rtS pshx
bne Dloop
pulx
LeeDir
'Lee una direccion creando eco en los display y regresa la direcci6n 'leida en el registro IX, en ACCB se regresa el codigo de la ultima tecla 'oprimida, ACCB = O si se tuvo exito en la lectura de la direcci6n o el 'codigo de la tecla de funci6n que provoco la salida.
LeeDir EQU
-
ldab #$O0 Inicializa la posicibn del display. jsr getche Lee lo digito
cmpa #$FF Es tecla de funci6n beq EsFuncion
ldab #$lo
mu1 recorre a la parte alta del byte
stab Aux2 Almacena el resultado byte $ZO
ldab #$O1 posici6n 1 del display jsr getche Lee 20 digito cmpa #$FF
beq EsFuncion
adda Aux2 se obtiene el byte mas significativo psha almacena el byte mas significativo
ldab #$O2 posici6n 2 del display jsr getche Lee 3 O digito
cmpa #$FF Es tecla de funcidn 7 beq EsFuncionl
ldab #$lo
mu1 recorre a la parte alta del byte
stab Aux2 Almacena el resultado byte $ZO ldab #$O3 posici6n 3 del display
jsr getche Lee 4O digito cmpa #$FF
beq EsFuncionl
adda Aux2 se obtiene el byte menos significativo de la direcci6n. psha almacena el byte m& significativo
pula xgdx
ldab #$O0 Se tuvo exito en la asignaci6n de IX. EsFuncionl pula Se habia intoducido un dato a la pila se debe sacar. EsFuncion Idx #A-INVALIDA Regresa en x codigo de direcci6n invalida FinLeeDir tis
pulb
bra FinLeeDir
*-LeeByte
'Lee un byte creando eco en los display y regresa el valor
'leido en el registro ACCA y en ACCB el codigo si se oprimio una tecla *de funcibn (ACCB = O0 si se tuvo exito en la lectura del byte).
LeeByte EQU
ldab #$O6 posici6n 6 del display jsr getche Lee 1' digito cmpa #$FF Es tecla de funcibn 7
mu1 recorre a la parte alta del byte
stab A u d Almacena el resultado byte $20 ldab #$O7 posici6n 7 del display
jsr getche Lee 20 digito
cmpa #$FF beq FinLeeByte
adda A u d se obtiene el byte
ldab #$O0 asignaci6n de ACCA exitosa. FinLeeByte rts
-
putDir'Escribe el valor del registro IX en la secci6n de direcciones del display.
putDir
OtroC
OtroD
EQU pshx psha pshb ldaa #$O4
staa AuxJ Auxl es un contador con valor inicial 4 xgdx lntercambia los valores de ACCD y IX.
Idx #$O010
idiv divide d/$l O
pshb Guarda el caracter menos significativo dec AuxJ
bne OtroC ldab #$M)
pula En a en valor del caracter mas significativo. jsr putch
incb
cmpb #$O4
pulb pula pulx
bne OtroD Imprime los cuatro caracteres
FinputDir rts
-
putByte'Escribe el valor del registro ACCA en la seccidn de datos del display.
putByte E p J pshx psha pshb
tab El byte ahora esta en ACCB
Idx #$O010
idiv divide d/$l O pshb En la pila la parte baja del byte
clra En ACCD se tiene $OObyte.
stx Aux2 En AuxJ la parte alta del byte ldaa AuxJ
jsr putch
incb ' El dispaly 7
jsr putch
ldab #$O6 El Display 6
pula
pulb pula pulx FinputByte rts
'Mensaje de sistemas correctos.
Bien EQU psha pshb ldaa #CARACT-L ldab #O0 jsr putch2 ldaa #CARACT-¡ incb jsr putch2 ldaa #CARACT-5 incb jsr putch2 ldaa #CARACT-t incb jsr putch2
incb jsr putch2 ldaa #$44 jsr Delay ldaa #BLANCO ldab #$O0
BorraB jsr putch2 incb cmpb #$O5 bne BorraB pulb pula
rtS
ldaa #CARACT-o
*-clrdpy
'Rutina de borrado de los displays del 8279
clrdpy EQU psha
ldaa #%11 O1 O1 1 O
staa INSTR-TECL Borra display noP
pula
rtS
*-InterrupXlRQ
'Rutina de interrupci6n corno respuesta al 8279
InterrupXlRQ ,* EQU
ldab #$FF Lectura de caracter sin eco. jsr getche Lee la tecla que provoco la interrupci6n
bne Func2
jsr Ejec Si shift-fl brinca a funcion 1 Ejec. bra FinlXRQ
bne Func3
jsr Edit Si shift42 brinca a funcion 2 Edit. bra FinlXRQ
bne Func4
jsr R-r-i Si shift43 brinca a funcion 3
bra FinlXRQ reconfiguraci6n de registros internos.
bne Func5
jsr Revisar Si shift44 brinca a funcion 5 Revisar. bra FinlXRQ
bne FinlXRQ
jsr Transm-SCI Si ctnl-shift44 brinca a funcion 4 Funcl crnpb #SHIFT-Fl
Func2 crnpb #SHIFT-F2
Func3 cmpb #SHIFT-F3
Func4 crnpb #SHIFT-F4
Func5 crnpb #FUNC-SCI
FinlXRQ rti Regresa el control a Principal
*-Eiec
-
‘funcion de ejecutar captura sena1 del AD y lo escribe en display.
Ejec EQU jsr clrdpy
ldaa #CARACT-C ldab #$O0
jsr putch2 ldaa #CARACT-o ldab #$O1 jsr putch2 ldaa #CARACT-n ldab #$O2 jsr putch2 ldaa #CARACT-v ldab #$O3 jsr putch2 ldaa #CARACT-C ldab #$O0
jsr putch2 ldaa #CARACT-o ldab #$O1
jsr putch2 ldaa #CARACT-n ldab #$O2 jsr putch2 ldaa #CARACT-v ldab #$O3 jsr putch2 ldaa #$50
jsr Delay jsr clrdpy
hi-conv ldaa #$21 Conversi6n cont, un solo canal PE bit 1 staa $1030 y el resultado estara en ADR2 Cont-conv ldaa $1030 Ve el estado del registro ADCTL
bita #$80 La conversi6n ha terminado?
beq Cont-conv
ldaa $1 032 Captura el resultado dentro del ACCA ldab #$O0
jsr putch2 imprime el resultado ldab
#$m
jsr putch2
’” ldaa #$17
jsr Delay
ldaa INSTR-TECL Lee el estado de la FIFO anda #%O00001 11 Hay caracteres en la FIFO
beq In¡-conv Si
no
los hay comienza otra conversi611 Fin-AD rtsEdit
‘funcion de editar.
Edit EQU ldaa #$OE
ldab #$O0
jsr putch ldaa #$O0
ldab #$O1 jsr putch
ldaa #$O1
ldab #$O2
Continua
Casol
Caso2
Caso3
Caso4
FinEdit
ldab #$3 jsr putch2 ldaa #$OA
ldab #$O4 jsr putch
ldaa #$44 jsr Delay jsr clrdpy
jsr LeeDir cmpx #A-INVALIDA bne Continua
cmpb #TECL-F4
L
Es un escape 7beq FinEdit bra Edit
jsr putDir jsr putByte
ldab #$FF lee tecla sin eco. jsr getche
beq FinEdit cmpb #TECL-Fl bne Caso2 inx
bra Continua cmpb #TECL-F2
bne Caso3 dex
bra Continua cmpb #TECL-F3
bne Caso4 jsr LeeByte crnpb #$O0
bne Casol staa 0,x
inx
bra Continua cmpb TECL-F4
beq FinEdit bra Continua rtS
ldaa 0,x
cmpb #TECL-F4 (, Es un escape 7
'reconfiguracibn de registros internos.
R-r-i E6U
ldaa #$OC ldab #$O0
jsr putch ldaa #$O0
ldab #$O1
jsr putch
ldab #$O2
jsr putch2 ldaa #CARACT-n
ldaa #$OF ldab #$O3 jsr putch ldaa #$44
jsr Delay
jsr clrdpy
jsr LeeDir cmpx #A-INVALIDA bne Continual cmpb #TECL-F4
Continual
Cas1
Cas2
Cas3
Cas4
crnpx #$lo00 inicio del bloque de registros internos blt FinR-r-i
crnpx #$103F Fin de los registros internos bgt FinR-r-i
ldaa 0,x jsr putByte jsr putDir ldab #$FF jsr getche
crnpb #TECL-F4 (, Es un escape ?
beq FinR-r-i cmpb #TECL_Fl bne Cas2 inx
bra Continual cmpb #TECL-F2
bne Cas3 dex
bra Continual crnpb #TECL-F3
bne Cas4 jsr LeeByte cmpb #$O0
bne Continual staa 0,x
inx
bra Continual cmpb TECL-F4
beq FinR-r-i bra Continual FinR-r-i rts
*-Revisar
'revisa el contenido de la memoria.
Revisar EQU
ldaa #CARACT-r ldab #$O0
jsr putch2 ldaa #$OE ldab #$O1 jsr putch
ldab #$O2 jsr putch2
ldab #$O3 jsr putch
ldab #$O4 jsr putch ldaa #CARACT-v
*
ldaa #$O1
ldaa #O5
ldaa #$OA ldab #$O5
jsr putch ldaa #$44 jsr Delay jsr clrdpy
jsr LeeDir crnpx #A-INVALIDA bne Contl
cmpb #TECL-F4
L
Es un escape ?beq FinRevisar bra Revisar
Cas01
Cas02
Cas03
Trazo
Cas04
ldab #$FF jsr getche
bea FinRevisar
cmpb #TECL-F4
L
Es un escape 7 cmpb #TECL-Flbne Cas02 inx
bra Contl cmpb #TECL-F2
bne Cas03 dex
bra Contl cmpb #TECL-F3
bne Cas04 ldaa #$30
jsr Delay inx ldaa 0,x
jsr putByte jsr putDir ldaa INSTR-TECL anda #%OOOOO1ll beq Trazo bra Contl
beq FinRevisar bra Contl cmpb TECL-F4
Crea un retrazo
Lee el estado de la FIFO Hay caracteres en la FIFO Realiza el trazo
FinRevisar rts
*-Trasm-SCI
'Realiza trarnsrnicidn serial .Hace una conversidn continua y se envia por SCI.
Cont-SCI
Fin-SCI
Ink-SCI
Conv-AD In¡-conv
Transm-SCI
EQU
ldaa #$O5 ldab #$O0
jsr putch ldaa #$OC ldab #$O1 jsr putch ldaa #$O1 ldab #$O2 jsr putch Id& #$44
jsr Delay jsr clrdpy
jsr Inic-SCI
ldaa INSTR-TECL Lee el estado de la FIFO anda #%O00001 11 Hay caracteres en la FIFO jsr Conv-AD
beq rtS
EQU ldaa staa ldaa staa ldaa staa rtS EQU ldaa #$21
staa
Cont-SCI Si no ¡os hay comienza otra conversi6n
#$31
#$O0
$102b 4800Baud 8MHz 2400Baud 4MHz
$1 02c #$Oc $1 02d
Cont-conv ldaa $1030 Ve el estado del registro ADCTL bita #$80 La conversidn ha terminado? beq Cont-conv
ldaa $1032 Guarda el resultado en ACCA jsr Esc-Pto-Ser
rtS
Esc-Pto-Ser EQU
de-nuevo ldab $102e carga el edo. del registro para trans. bitb #$80 verifica si esta vacio para poder trans. beq de-nuevo
staa $1 02f escribe resultado en el puerto
bitb #$40 verifica si la transmisidn ha terminado beq Sigue-Tr
rtS
Sigue-Tr ldab $102e carga el edo. del registro
-
InterrupVacia'Evita la perdida del PC debido a una interrupci6n no esperada.
InterrupVacia EQU rti
ORG $FFF2
FDB InterrupXlRQ Se le asigna IRQ=XIRQ solo para prueba.
FDB InterrupVacia Se asigna SWI con interrupci6n vacia. FDB InterrupVacia Se asigna inlegal OP a interrupci6n vacia. FDB InterrupVacia Se asigna COP a interrupci6n vacia.
FDB InterrupVacia Se asigna COP clock monitor a interrupci6n vacia. lnterrupcion FDB InterrupXlRQ Vector de interrupci6n FFF4