In SX Microcontrollers, SX/B Compiler and SX-Key Tool, JonnyMac wrote: Have a look at the attached framework -- it will allow you to modulate and control two IR LEDs, send data to a serial LCD, and control up to four servos. Everything is done in code, no 555 required. Sorry, the forum will not let me attache this file and I don't know why. [code]' ========================================================================= ' ' File...... SXB-Bot.SXB ' Purpose... ' Author.... Jon Williams, EFX-TEK ' Copyright (c) 2009 EFX-TEK ' Some Rights Reserved ' -- see http://creativecommons.org/licenses/by/3.0/ ' E-mail.... jwilliams@efx-tek.com ' Started... ' Updated... 02 NOV 2009 ' ' ========================================================================= ' ------------------------------------------------------------------------- ' Program Description ' ------------------------------------------------------------------------- ' ------------------------------------------------------------------------- ' Conditional Compilation Symbols ' ------------------------------------------------------------------------- ' ------------------------------------------------------------------------- ' Device Settings ' ------------------------------------------------------------------------- ID "SXB-BOT" DEVICE SX28, OSCXT2, BOR42 FREQ 20_000_000 ' ------------------------------------------------------------------------- ' I/O Pins ' ------------------------------------------------------------------------- IrMod PIN RA.0 OUTPUT ' to IR LED cathodes IrCtrlA PIN RA.1 OUTPUT ' anode ctrl A (via 220 ohms) IrCtrlB PIN RA.2 OUTPUT ' anode ctrl B (via 220 ohms) TX PIN RA.3 OUTPUT ' for serial LCD SensorPort PIN RB IrInA PIN RB.0 INPUT ' from IR detectors IrInB PIN RB.1 INPUT ServoPort PIN RC Servo1 PIN RC.0 OUTPUT Servo2 PIN RC.1 OUTPUT Servo3 PIN RC.2 OUTPUT Servo4 PIN RC.3 OUTPUT ' ------------------------------------------------------------------------- ' Constants ' ------------------------------------------------------------------------- ' Dividers for ISR UART ' -- values set for 3.333us Baud9600 CON 31 Baud19K2 CON 16 Baud38K4 CON 8 Baud1x0 CON Baud9600 ' 1 bit period (ISR counts) Baud1x5 CON Baud1x0 * 3 / 2 ' 1.5 bit periods LF CON 10 CLS CON 12 CR CON 13 Yes CON 1 No CON 0 IsOn CON 1 IsOff CON 0 ' ------------------------------------------------------------------------- ' Variables ' ------------------------------------------------------------------------- flags VAR Byte isrFlag VAR flags.0 irTix VAR Byte global3 VAR Byte ' ------------------------------------------------------------------------- ' user vars tmpB1 VAR Byte tmpB2 VAR Byte tmpB3 VAR Byte tmpB4 VAR Byte tmpW1 VAR Word tmpW2 VAR Word txSerial VAR Byte (16) BANK txBuf VAR txSerial(0) ' eight-byte buffer txCount VAR txSerial(8) ' tx bit count txDivide VAR txSerial(9) ' bit divisor timer txLo VAR txSerial(10) ' holds start bit txHi VAR txSerial(11) ' tx output reg txHead VAR txSerial(12) ' buffer head (write to) txTail VAR txSerial(13) ' buffer tail (read from) txBufCnt VAR txSerial(14) ' # bytes in buffer svoData VAR Byte (16) ' bank servo data pos VAR svoData(0) ' position table pos0 VAR svoData(0) pos1 VAR svoData(1) pos2 VAR svoData(2) pos3 VAR svoData(3) pos4 VAR svoData(4) pos5 VAR svoData(5) pos6 VAR svoData(6) pos7 VAR svoData(7) svoTix VAR svoData(8) ' isr divider svoFrame_LSB VAR svoData(9) ' frame timer svoFrame_MSB VAR svoData(10) svoIdx VAR SvoData(11) ' active servo pointer svoTimer VAR svoData(12) ' pulse timer svoPin VAR svoData(13) ' active servo pin ' ========================================================================= INTERRUPT NOPRESERVE 300_000 ' every 3.333us ' ========================================================================= ISR_Start: \ SETB isrFlag ' ----------------- ' IR LED Modulation ' -- 37500 Hz ' ----------------- ' IR_Modulation: ASM INC irTix CJB irTix, #4, IR_Exit CLR irTix XOR RA, #%0001 ' modulate RA.0 (cathodes) IR_Exit: ENDASM ' ------- ' TX UART ' ------- ' ' UART code by C. Gracey, A. Williams, et al ' -- buffer and flow control mods by Jon Williams ' Transmit: ASM BANK txSerial ' (1) TEST txCount ' (1) transmitting now? JZ TX_Buffer ' (2/4) if txCount = 0, no DEC txDivide ' (1) update bit timer JNZ TX_Done ' (2/4) time for new bit? MOV txDivide, #Baud1x0 ' (2) yes, reload timer STC ' (1) set for stop bit RR txHi ' (1) rotate TX char buf RR txLo ' (1) DEC txCount ' (1) update the bit count MOVB TX, txLo.6 ' (4) output the bit JMP TX_Done ' (3) TX_Buffer: TEST txBufCnt ' (1) anything in buffer? JZ TX_Done ' (2/4) exit if empty MOV W, #txBuf ' (2) point to buffer tail ADD W, txTail ' (1) MOV FSR, W ' (1) MOV txHi, IND ' (2) move byte to TX reg CLR txLo ' (1) clear for start bit MOV txCount, #10 ' (2) start + 8 + 1 stop INC txTail ' (1) update tail pointer CLRB txTail.3 ' (1) keep 0..7 DEC txBufCnt ' (1) update buffer count TX_Done: ENDASM ' ---------------- ' Servo Processing ' ---------------- ' Test_Servo_Tix: ASM BANK svoData ' (1) INC svoTix ' (1) update divider CJB svoTix, #3, Servo_Done ' (4/6) done? CLR svoTix ' (1) yes, reset for next ' Code below this point runs every 10 uS Check_Frame_Timer: CJNE svoFrame_LSB, #2000 & 255, Inc_FrTmr ' (4/6) svoFrame = 2000 (20 ms)? CJNE svoFrame_MSB, #2000 >> 8, Inc_FrTmr ' (4/6) CLR svoFrame_LSB ' (1) yes, reset CLR svoFrame_MSB ' (1) MOV svoPin, #%0000_0001 ' (2) start servo sequence CLR svoIdx ' (1) point to servo 0 MOV FSR, #pos ' (2) MOV svoTimer, IND ' (2) JMP Refesh_Servo_Outs ' (3) Inc_FrTmr: INC svoFrame_LSB ' (1) DEC svoFrame ADDB svoFrame_MSB, Z ' (2) Check_Servo_Timer: TEST svoPin ' (1) any servos on? SNZ ' (1) JMP Servo_Done ' (1) no, exit DEC svoTimer ' (1) yes, update timer SZ ' (1) still running? JMP Servo_Done ' (1) yes, exit Reload_Servo_Timer: INC svoIdx ' (1) point to next servo MOV W, #pos ' (1) get pulse timing ADD W, svoIdx ' (1) MOV FSR, W ' (1) MOV W, IND ' (1) MOV svoTimer, W ' (1) move to timer Select_Next_Servo: CLC ' (1) RL svoPin ' (1) AND svoPin, #%0000_1111 ' (2) limit servo channels Refesh_Servo_Outs: AND ServoPort, #%1111_0000 ' (2) clear last OR ServoPort, svoPin ' (2) update outputs Servo_Done: ENDASM ISR_Exit: RETURNINT ' (4) ' ========================================================================= ' Subroutine / Function Declarations ' ========================================================================= TX_STR SUB 2, 2, Word ' transmit a string TX_BYTE SUB 1 ' transmit a byte DELAY_MS SUB 2, 2, Word ' delay in ms DELAY_TIX SUB 2, 2, Word ' delay in 5s ticks ' ========================================================================= PROGRAM Start ' ========================================================================= Start: PLP_B = %0000_0011 ' pull-ups on open pins PLP_C = %0000_1111 TX = 1 ' set TX to idle state PUT pos, 150, 150, 150, 150 ' stop/center servos Main: GOTO Main ' ------------------------------------------------------------------------- ' Subroutine / Function Code ' ------------------------------------------------------------------------- ' Use: TX_STR [String | Label] ' -- pass embedded string or DATA label SUB TX_STR '{$IFUSED TX_STR} tsAddr VAR tmpW1 tsChar VAR __PARAM1 tsAddr = __WPARAM12 ' capture address DO READINC tsAddr, tsChar ' read a character IF tsChar = 0 THEN EXIT ' if 0, string complete TX_BYTE tsChar ' send the byte LOOP '{$ENDIF} ENDSUB ' ------------------------------------------------------------------------- ' Use: TX_BYTE aByte ' -- moves "aByte" to 8-byte circular buffer (when space is available) ' -- will wait if buffer is presently full ' -- txBufCnt holds byte count of transmit buffer (0 to 8) SUB TX_BYTE '{$IFUSED TX_BYTE} ASM BANK txSerial JB txBufCnt.3, @$ ' prevent buffer overrun MOV W, #txBuf ' point to buffer head ADD W, txHead MOV FSR, W MOV IND, __PARAM1 ' move byte to tx buf INC txHead ' update head pointer CLRB txHead.3 ' keep 0..7 INC txBufCnt ' update buffer count BANK $00 ENDASM '{$ENDIF} ENDSUB ' ------------------------------------------------------------------------- ' Use: DELAY_MS duration ' -- delay in milliseconds SUB DELAY_MS '{$IFUSED DELAY_MS} ms VAR __WPARAM12 msTix VAR __WPARAM34 DO WHILE ms > 0 msTix = 300 ' load 1 ms timer DO WHILE msTix > 0 ' let timer expire \ CLRB isrFlag ' clear ISR flag \ JNB isrFlag, @$ ' wait for flag to be set DEC msTix ' update 1 ms timer LOOP DEC ms ' update delay timer LOOP '{$ENDIF} ENDSUB ' ------------------------------------------------------------------------- ' Use: DELAY_MS ticks ' -- delay in 5us ticks SUB DELAY_TIX '{$IFUSED DELAY_TIX} tix VAR __WPARAM12 DO WHILE tix > 0 \ CLRB isrFlag ' clear ISR flag \ JNB isrFlag, @$ ' wait for flag to be set DEC tix ' decrement ticks LOOP '{$ENDIF} ENDSUB ' ========================================================================= ' User Data ' =========================================================================[/code] ---------- End of Message ---------- You can view the post on-line at: http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=397841#m398310 Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2009 (http://www.dotNetBB.com)