/* ALBERT.C 68HC11 CONTROL PROGRAM */ /* copyright 1999 - John Cutter */ #code 0x0800 /* make sure RAM is installed on U2 socket */ #data 0x0700 /* PORTA ASSIGNMENTS PA0 - SONAR ECHO INPUT PA1 - ENCODER INPUT 1 PA2 - ENCODER INPUT 2 PA3 - MOTOR 1 DIRECTION PA4 - MOTOR 2 DIRECTION PA5 - MOTOR 1 ON PA6 - MOTOR 2 ON PA7 - SONAR UNIT 5 INIT PORTD ASSIGNMENTS PD0 - RS232 PD1 - RS232 PD2 - SONAR UNIT 1 INIT PD3 - SONAR UNIT 2 INIT PD4 - SONAR UNIT 3 INIT PD5 - SONAR UNIT 4 INIT PORTE ASSIGNMENTS PE0 - COMPASS INPUT 1 PE1 - COMPASS INPUT 2 PE2 - COMPASS INPUT 3 PE3 - COMPASS INPUT 4 PE4 - BUMP SWITCH INPUT 1 PE5 - BUMP SWITCH INPUT 2 PE6 - LIGHT SENSOR INPUT PE7 - OPEN */ #include #include <68hc11.h> #include /* libraries needed by fprintf() */ #include #include #include #include #include #include #include #include #include #include #include /* Link in the device driver for the 68hc11 */ #include #include char a; char b; char c; char d; char e; int count=0; int sonar_range=0; int sonar_init=0; unsigned int m1count=0; unsigned int m2count=0; unsigned int temp=655; int m1old=0; int m2old=0; int m1temp=0; int m2temp=0; int photo=0; int left_count=0; int right_count=0; int touch=0; int compass=0; int test; FILE stdout; /* ******************** FUNCTIONS ***********************/ /* SONAR FUNCTION */ ping(unit) char unit; { switch(unit) { case '1': pokeb(REG_BASE+PORTD,4); /* PING SONAR UNIT 1*/ break; case '2': pokeb(REG_BASE+PORTD,8); /* PING SONAR UNIT 2*/ break; case '3': pokeb(REG_BASE+PORTD,16); /* PING SONAR UNIT 3*/ break; case '4': pokeb(REG_BASE+PORTD,32); /* PING SONAR UNIT 4*/ break; case '5': bit_set(REG_BASE+PORTA,128); /* PING SONAR UNIT 5 PA7*/ break; } /* end case */ sonar_init=peek(REG_BASE+TCNT); sonar_range=0; while( ( (peekb(REG_BASE+PORTA)&1) !=1)&&(sonar_range<30000)) { } sonar_range=peek(REG_BASE+TCNT)-sonar_init; fprintf(stdout,"%d\n",sonar_range); pokeb(REG_BASE+PORTA,0); pokeb(REG_BASE+PORTD,0); return(sonar_range); }/* end ping function */ main() { /* INIT PWM */ pokeb(REG_BASE+DDRD,60); /* setup last four bits as outputs */ bit_set(REG_BASE+TCTL1,160); poke(REG_BASE+TOC1,0); poke(REG_BASE+TOC2,1); /* SPEED of motor 1 */ poke(REG_BASE+TOC3,1); /* SPEED of motor 2 */ stdout=fopen(FOR_out); pokeb(REG_BASE+PACTL,136); /* setup bit 3 as output -- was 72 */ pokeb(REG_BASE+PORTA,0); m1temp=peekb(REG_BASE+PORTA); m1temp=m1temp&2; m1old=m1temp; m2temp=peekb(REG_BASE+PORTA); m2temp=m2temp&4; m2old=m2temp; while(a!='Q') { count=peekb(0xB02F); if (count!=33) { m1temp=peekb(REG_BASE+PORTA); m1temp=m1temp&2; if(m1temp!=m1old) { m1old=m1temp; m1count++; } m2temp=peekb(REG_BASE+PORTA); m2temp=m2temp&4; if(m2temp!=m2old) { m2old=m2temp; m2count++; } } else { a=FOR_in(); if (a=='S') /* 'S'ensor - always followed by 1 byte */ { b=FOR_in(); if (b=='1') { ping('5'); /* PING SONAR UNIT */ } if (b=='2') { ping('1'); /* PING SONAR UNIT */ } if (b=='3') { ping('2'); /* PING SONAR UNIT */ } if (b=='4') { ping('3'); /* PING SONAR UNIT */ } if (b=='5') { ping('4'); /* PING SONAR UNIT 5 PA7*/ } if (b=='C') { compass = ((peekb(REG_BASE+PORTE)&15)); fprintf(stdout,"%d\n",compass); } if (b=='P') /* Photoresistor (Light Meter) */ { pokeb(REG_BASE+ADCTL,0x14); /* set A/D control register to last four bits */ while(peekb(REG_BASE+ADCTL+4)==0); /*wait until high bit is set */ photo=peekb(REG_BASE+ADCTL+3); /* bit 6 is light sensor */ fprintf(stdout,"%d\n",photo); } if (b=='T') /* Touch sensors */ { touch=0; if ((peekb(REG_BASE+PORTE)&16)==16) { touch++; } if ((peekb(REG_BASE+PORTE)&32)==32) { touch++; touch++; } fprintf(stdout,"%d\n",touch); } if (b=='<') /* Left encoder */ { fprintf(stdout,"%d\n",m1count); } if (b=='>') /* Right encoder */ { fprintf(stdout,"%d\n",m2count); } } if (a=='M') /* Indicates a motor command - followed by 4 bytes */ { b=FOR_in(); /* Will be 'L' for Left motor, or 'R' for Right motor */ c=FOR_in(); /* Will be 'F' for Forward, or 'B' for Back */ d=FOR_in(); /* Will be 10's digit of speed */ e=FOR_in(); /* Will be 1's digit of speed */ if ((b=='L') && (c=='F')) { bit_clr(REG_BASE+PORTA, 0x10); } if ((b=='L') && (c=='B')) { bit_set(REG_BASE+PORTA, 0x10); } if ((b=='R') && (c=='F')) { bit_clr(REG_BASE+PORTA, 0x08); } if ((b=='R') && (c=='B')) { bit_set(REG_BASE+PORTA, 0x08); } if ((b=='L')) { test=((d-'0')*10 + (e-'0')); if (test<11) { pokeb(REG_BASE+OC1M,0); pokeb(REG_BASE+OC1D,0); poke(REG_BASE+TOC2,1); poke(REG_BASE+TOC3,1); } else { pokeb(REG_BASE+OC1M,96); pokeb(REG_BASE+OC1D,96); temp=(655*test); poke(REG_BASE+TOC3,temp); } } if (b=='R') { test=((d-'0')*10 + (e-'0')); if (test<11) { pokeb(REG_BASE+OC1M,0); pokeb(REG_BASE+OC1D,0); poke(REG_BASE+TOC2,1); poke(REG_BASE+TOC3,1); } else { pokeb(REG_BASE+OC1M,96); pokeb(REG_BASE+OC1D,96); temp=(655*test); poke(REG_BASE+TOC2,temp); } } } } } /* end forever while */ }/* end main */ /****************************************/ /* SMALL C COMPILER */ /* SYSTEM LIBRARY FOR THE 68HC11 */ /****************************************/ #asm ARG1 EQU 6 ARG2 EQU 8 #endasm /* NOTE: CCARGC MUST BE PASSED THE NUMBER OF BYTES OF LOCAL (STACK) */ /* STORAGE FROM THE CALLING ROUTINE */ /* EX: sort_lst(argc)int *argc;{ */ /* char maxlen; */ /* char day; */ /* char numargs; */ /* int year; */ /* numargs=CCARGC(1+1+1+2); /*note the param=number of local bytes */ CCARGC(n) int n; { #asm PSHX PULA PULB #endasm } /* Enable interrupts */ e_int() { #asm CLI #endasm } /* Disable interrupts */ d_int() { #asm SEI #endasm } /* Called with 1's in the position to be set */ bit_set(addr,val) int addr; char val; { #asm LDX ARG2,Y LDAB ARG1+1,Y ORAB 0,X STAB 0,X #endasm } /* Called with 1's in the position to be cleared */ bit_clr(addr,val) int addr; char val; { #asm LDX ARG2,Y LDAB ARG1+1,Y COMB ANDB 0,X STAB 0,X #endasm } pokeb(addr,val) unsigned int addr; unsigned char val; { #asm LDX ARG2,Y LDAB ARG1+1,Y STAB 0,X #endasm } poke(addr,val) unsigned int addr; int val; { #asm LDX ARG2,Y LDD ARG1,Y STD 0,X #endasm } peekb(addr) unsigned int addr; { #asm LDX ARG1,Y CLRA LDAB 0,X #endasm } peek(addr) unsigned int addr; { #asm LDX ARG1,Y LDD 0,X #endasm } #asm ************************************************* *** START OF LOW LEVEL LIBRARY ROUTINES **** *** PARTS BORROWED FROM MOTOROLA, OTHERS **** *** RE-WRITTEN BY MATT TAYLOR **** ************************************************* ******** * MUL12 __MUL12 PSHX PSHX PSHB PSHA TSX LDAA 3,X MUL STD 4,X LDD 1,X MUL ADDB 4,X STAB 4,X LDAB 3,X MUL ADDB 4,X STAB 4,X PULX PULX PULA PULB RTS ******** * ASR12 __ASR12 XGDX __ASRLOOP CPX #0 BEQ __ASRDONE ASRA RORB DEX BRA __ASRLOOP __ASRDONE RTS ******** * ASL12 __ASL12 XGDX __ASLLOOP CPX #0 BEQ __ASLDONE ASLD DEX BRA __ASLLOOP __ASLDONE RTS ******** * __GE __GE PSHX CPD 0,X BLT __TRUE BRA __FALSE ******** * __UGE __UGE PSHX TSX CPD 0,X BLO __TRUE BRA __FALSE ******** * __GT __GT PSHX TSX CPD 0,X BLE __TRUE BRA __FALSE ******** * __UGT __UGT PSHX TSX CPD 0,X BLS __TRUE BRA __FALSE ******** * __LE __LE PSHX TSX CPD 0,X BGT __TRUE BRA __FALSE ******** * __ULE __ULE PSHX TSX CPD 0,X BHI __TRUE BRA __FALSE ******** * __LNEG __LNEG PSHX CPD #0 BNE __FALSE BRA __TRUE ******** * __LT __LT PSHX TSX CPD 0,X BGE __TRUE BRA __FALSE ******** * __ULT __ULT PSHX TSX CPD 0,X BHS __TRUE BRA __FALSE ******** * __EQ __EQ PSHX TSX CPD 0,X BEQ __TRUE BRA __FALSE ******** * __NE __NE PSHX TSX CPD 0,X BNE __TRUE BRA __FALSE ******** *__TRUE __TRUE PULX LDD #1 RTS ******** *__FALSE __FALSE PULX LDD #0 RTS ******** * __SWITCH __SWITCH PULX __XLOOP PSHX LDX 0,X CPX #0 PULX BEQ __XDEFAULT CPD 2,X BEQ __XMATCH INX INX INX INX BRA __XLOOP __XDEFAULT INX INX JMP 0,X __XMATCH LDX 0,X JMP 0,X #endasm