/* * motor.c * * Library of useful motor commands to interface to the Motor Mind B module. * * Copyright (C) 1998 Mark Crosbie mark@mastincrosbie.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * The Motor Mind B is available from Solutions Cubed Electronics * www.solutions-cubed.com * * It communicates at 2400 baud. It must be sent a SYNC byte (0x55) * before every message so it can sync up on the baud rate. * * Not tied to any port or pin. Specify the port,pin for each routine * * Copyright Mark Crosbie 9/20/98 * */ /******************* REDEFINE AS NECESSARY ********************/ #define MMSYNC 0x55 #define MMSTOP 0 #define MMREV 1 #define MMTACH 2 #define MMSETDC 3 #define MMSPDCON 4 #define MMSTATUS 5 #define MMCOUNT 6 /* defined in delays.c */ extern void delay_ms(char); /* how to turn on a bit in a byte */ /* const char bitson[] = {1,2,4,8,16,32,64,128}; const char bitsoff[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f}; */ /* Send a byte to the Motor Mind B * *** Assumes 2400 8N1 communication *** The constant MMPIN defines which pin the Module is on *** The constant MMPORT defines which port the Module in on * * Arguments: port: port for motor: either PORTA or PORTB * pin: pin driving FM line on module. 0 <= pin <= 7 * c: byte to send to motor in range 0 <= c <= 255 * * NON-INVERTED! * * !!! Do not assume that the parameter values are unchanged after * calling. !!! * * Return Value: none */ void mm_putc(char port, char pin, char c) { char i, biton, bitoff, bitcount; /* This code adapted from: * Copyright, Peter H. Anderson, Morgan State University, June 14, '97 */ /* compute the correct left shifted value based on pin * The pin value is in the range (0,7) on input, but we want it in * the range (1,8) for this loop to work. * Destroys parameter pin, but it's not needed again * bitoff is just the complement of biton (invert bits) */ asm incf param01_mm_putc,f asm clrf _biton_mm_putc asm bsf STATUS, C asm rlf _biton_mm_putc, f asm decfsz param01_mm_putc, f asm goto $-2 asm comf _biton_mm_putc, w asm movwf _bitoff_mm_putc /* set the INDF register to point to the port register */ asm movf param00_mm_putc, w asm movwf FSR /* turn on the bit - set the STOP bit */ asm movf INDF, w asm iorwf _biton_mm_putc, w asm movwf INDF i = 255; while(i-- != 0); /* let stop bit be set for a while */ asm MOVLW 9 asm MOVWF _bitcount_mm_putc asm BCF STATUS, C ; set C to 0, start bit /* if carry is set then we set the output high. * So we test if C is set, and if so, we skip the jump around the code */ asm BTFSS STATUS, C asm goto $+6 asm movf INDF, w asm iorwf _biton_mm_putc, w asm movwf INDF asm BTFSC STATUS, C asm goto $+4 asm movf INDF,w asm andwf _bitoff_mm_putc, w asm movwf INDF /* this takes some computation. Can range over 130-132 */ asm MOVLW 134 asm MOVWF _i_mm_putc ; one bit delay. 416 usecs at 2400 baud asm DECFSZ _i_mm_putc, F asm GOTO $-1 asm NOP asm RRF param02_mm_putc, F ; least sign bit now in C asm DECFSZ _bitcount_mm_putc, F ; does not affect status asm GOTO $-17 ; next character /* set the stop bit */ asm movf INDF, w asm iorwf _biton_mm_putc, w asm movwf INDF delay_ms(1); /* a pacing delay of 1ms between characters */ } /* stop the specified motor * Arguments: * port: motor port (either 0x5 or 0x6 for PORTA or PORTB) * pin: pin on the port for the motor * Return value: * none */ void mm_stop(char port, char pin) { mm_putc(port, pin, MMSYNC); mm_putc(port, pin, MMSTOP); } /* start the specified motor * Send the SETDC command followed by the dutycycle * Arguments: * port: motor port (either 0x5 or 0x6 for PORTA or PORTB) * pin: pin on the port for the motor * dutycycle: speed of motor from 0 (min) to 255 (max) * Return value: * none */ void mm_start(char port, char pin, char dutycycle) { mm_putc(port, pin, MMSYNC); mm_putc(port, pin, MMSETDC); mm_putc(port, pin, dutycycle); } /* reverse the specified motor * Arguments: * port: motor port (either 0x5 or 0x6 for PORTA or PORTB) * pin: pin on the port for the motor * Return value: * none */ void mm_reverse(char port, char pin) { mm_putc(port, pin, MMSYNC); mm_putc(port, pin, MMREV); }