;8051 SOURCE CODE for the CHEAP SONAR SYSTEM ;********************** ;LRAC Robotic Systems ;EFJ Devices. ;********************** ;Carl Motsinger July 8, 1996 ;#1 STEPPER MOTOR MODULE port assignment. ;Code is for Intel MCS51 microcontroller - 8031h ;Updated August 7, 1996 ;Updated October 3, 1996 ;********************** ;Ports 0 & 2 are used for addressing program memory. ;Port 1 provides STEP and DIRECTION for 2 UCN5804B IC's ;Port 3 ;p3.0 is RxD. ;p3.1 is TxD. ;p3.2 is INT0 ;p3.3 is unused ;p3.4 is unused ;p3.5 is Pulse ;p3.6 is Return ;p3.7 is unused ;p3.2 is also used for INT0. It is tied to p3.0. Pulled low by Master module on INT. ;Only when interrupts are enabled is it active LOW. ;Serial port link is also tied to p3.0 and p3.1 RxD is p3.0. TxD is p3.1 ;Serial port is set to 9600 bps. ;******************** ;SYSTEM CONFIG ;******************** #include "Equates.051" ;******************************************* .ORG 0000H ljmp Begin clr ie.0 ljmp SerInt ljmp Start ;********************************* Begin: mov 20h,#10 mov 21h,#10 mov 22h,#36 ;Here we set the sweep angle. mov p1,#0h setb p1.2 setb p1.3 mov p3,#0ffh Start: lcall HardLeft ljmp More HardLeft: mov r1,#100 SetLeft: setb p1.0 ;Push the Stepper hard left. clr p1.1 ;against the post. lcall Wait1000 setb p1.1 lcall Wait1000 clr p1.0 lcall Wait1000 clr p1.1 lcall Wait1000 djnz r1,SetLeft mov r1,#2 SetStart: setb p1.1 ;Move right 2 steps. clr p1.0 lcall Wait1000 setb p1.0 lcall Wait1000 clr p1.1 lcall Wait1000 clr p1.0 lcall Wait1000 djnz r1,SetStart clr p3.3 ret ;Here we should go to a Main program. ;Wait for Master to tell us to go. More: clr p3.3 ;Turn off LED. ;This is the sweep routine. mov r1,22h ;Sweep range is put in 22h at start Fwd: setb p1.0 ;and by Master when int is ON. clr p1.1 ;Initialized to 36. 36 steps x 1.8 degree = 65 degree sweep. lcall Wait1000 ;One step.... setb p1.1 ;Unipolar pulsing. lcall Wait1000 clr p1.0 lcall Wait1000 clr p1.1 lcall Wait1000 lcall Pulse ;Do your thing... lcall Echo djnz r1,Fwd ;Are we done? >No! mov r1,#255 ;Yes! The number 255 (ffh) is a reset flag. mov r2,22h Rev: setb p1.1 ;Now the other way. clr p1.0 ;One step. lcall Wait1000 setb p1.0 lcall Wait1000 clr p1.1 lcall Wait1000 clr p1.0 lcall Wait1000 lcall Pulse ;>GO send 10 pulses of 25 KHz. lcall Echo ;Get echo time. djnz r2,Rev ;Are we done yet? >No! mov r2,#255 ;Yes. sjmp More Echo: ;10 pulses have been sent. mov tl0,#0 ;Initialize timer. mov th0,#0 mov Tmod, #11h setb Tcon.4 ;Timer running. EchoIn: jb p3.6,Round ;> if echo received. mov a,th0 cjne a,#10,EchoIn ;Times out at 2550 usec. 10 x 255. ret ;Adjust for optimum performance. Round: clr Tcon.4 ;Timer 0 has time for return echo. setb p3.3 ;Echo received. Turn on LED. ;Code will go here to calculate distance. ret ;This routine was used for pushbutton adjustment of the timing loop. Key: jb p3.6,Bak sjmp Take1 Bak: jb p3.7,Key inc 20h sjmp More Take1: dec 20h sjmp More ;****************************************** ;This is the PULSE routine. 9 djnz's of r3 produce 20 uS pulse ;at 12 MHz. Pulse: mov r5,#10 ;10 pulse at 25 KHz. Loop1: mov r4,#9 mov r3,#9 ;9 equals 20 uS ON. setb p3.5 djnz r3,$ clr p3.5 ;20 uS OFF. djnz r4,$ djnz r5,Loop1 ;Do it 10 times. ret ;*********************** ;Main program goes here. ;Test serial ports first. ;*********************** SerInt: push psw ;We're here because Master sent a dummy byte mov Scon,#0c0h ; to interrupt us. mov Tmod,#20h mov th1,#0fdh ;9600 baud 11.0592 MHz. mov Tcon,#40h clr ri setb p3.1 setb p3.0 ;Set-up for address byte. Receive: jb p3.1,$ ;Set here til master is ready with address byte. setb Scon.4 jnb ri,$ ;Getting address byte. mov a,Sbuf clr ri jb acc.2,ItsUs ljmp GetOut ;> Not for us - Go back to stepping. ;Bit 3 must be set to acknowledge the ItsUs: jnb ri,$ ;interrupt. mov 34h,Sbuf clr ri jnb ri,$ mov 35h,Sbuf clr ri jnb ri,$ mov 32h,Sbuf clr ri jnb ri,$ mov 33h,Sbuf clr ri pop psw pop acc pop acc mov a,#8 ;Push our own interrupt return push acc ;address. mov a,#0 push acc reti GetOut: lcall Wait1000 ;Master sent four byte regardless. lcall Wait1000 ;We have to wait because the INT line is being ;used. lcall Wait1000 ;If we go back too soon we'll get a false interrupt. lcall Wait1000 lcall Wait1000 pop psw pop acc pop acc mov a,#8 push acc mov acc,#0 push acc reti Wait1000: ;Not actually 1000 usec. 6400 + usec. mov r0,#64 ;This will be changed when the module is Pol: ; optimized for the final integration. lcall Wait100 djnz r0,Pol ret Wait100: lcall Wait10usec lcall Wait10usec lcall Wait10usec lcall Wait10usec lcall Wait10usec lcall Wait10usec lcall Wait10usec lcall Wait10usec lcall Wait10usec nop nop ret Wait10usec: nop nop nop nop nop nop ret WaitLong: mov r5,#5 T22: mov r6,#128 T52: mov r7,#128 ;lcall Key djnz r7,$ djnz r6,T52 djnz r5,T22 ret .end