Need Help for the next stage PIC programming

Thread Starter

bluebrakes

Joined Oct 17, 2009
252
Hi,

I've got pic code working to a stage where I need to take it to the next level.
Basically the code is for driving 3 stepper motors. Currently Just steps them in one direction.

So if you send the number 1 through the PC serial port, Stepper 1 steps. number 2 steps stepper 2 and 3 steps stepper 3.

What I would like to do now is send a message to the pic.
i.e. 1 500 5 So this translates into Stepper 1, 500 steps at 5ms interval
, 2 5 1 This translates into Stepper 2, 5 steps, 1ms interval

My current code....


Rich (BB code):
  LIST P=16F628, R=DEC    ; Use the PIC16F628 and decimal system 

        #include "P16F628.INC"  ; Include header file 

        __config  _INTRC_OSC_NOCLKOUT & _LVP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_ON 

        CBLOCK 0x20             ; Declare variable addresses starting at 0x20
        count1
          
          dataL
          Check_Temp
        ENDC
        
        #DEFINE STEPPER1 PORTB, 0
        #DEFINE STEPPER2 PORTB, 3
        #DEFINE STEPPER3 PORTB, 4

        ORG    0x000            ; Program starts at 0x000 
;
; --------------------------------
; SET ANALOG/DIGITAL INPUTS PORT A
; --------------------------------
;
    movlw 7
    movwf CMCON        ; CMCON=7 set comperators off         
; 
; ---------------- 
; INITIALIZE PORTS
; ---------------- 
; 
    movlw b'00000000'       ; set up portA
        movwf PORTA    
        
        movlw b'00000100'    ; RB2(TX)=1 others are 0
        movwf PORTB

        bsf STATUS,RP0          ; RAM PAGE 1

        movlw 0xFF
        movwf TRISA        ; portA all pins input

        movlw b'11100010'    ; RB7-RB5 and RB1(RX)=input, others output 
        movwf TRISB

; ------------------------------------
; SET BAUD RATE TO COMMUNICATE WITH PC
; ------------------------------------
; Boot Baud Rate = 9600, No Parity, 1 Stop Bit
;
        movlw 0x19              ; 0x19=9600 bps (0x0C=19200 bps)
        movwf SPBRG
        movlw b'00100100'       ; brgh = high (2)
        movwf TXSTA             ; enable Async Transmission, set brgh

        bcf STATUS,RP0          ; RAM PAGE 0

        movlw b'10010000'       ; enable Async Reception
        movwf RCSTA
;
; ------------------------------------
; PROVIDE A SETTLING TIME FOR START UP
; ------------------------------------
;
        clrf dataL
settle  decfsz dataL,F
        goto settle

        movf RCREG,W
        movf RCREG,W
        movf RCREG,W            ; flush receive buffer
;
; ---------
; MAIN LOOP
; ---------
;
    call message            ; send intro message
loop    call receive            ; wait for a char
    call Check_Input               ; Check to see what type of input it is
        goto loop
;
; -------------------------------------------
; RECEIVE CHARACTER FROM RS232 AND STORE IN W
; -------------------------------------------
; This routine does not return until a character is received.
;
receive btfss PIR1,RCIF         ; (5) check for received data
        goto receive

        movf RCREG,W            ; save received data in W
        return
;
; -------------------------------------------------------------
; SEND CHARACTER IN W VIA RS232 AND WAIT UNTIL FINISHED SENDING 
; -------------------------------------------------------------
;

send    movwf TXREG             ; send data in W 

TransWt bsf STATUS,RP0        ; RAM PAGE 1
WtHere  btfss TXSTA,TRMT        ; (1) transmission is complete if hi
        goto WtHere

        bcf STATUS,RP0          ; RAM PAGE 0
         return
      
Check_Input movwf Check_Temp ; Put the character received into memory
    
    MOVLW    0x31                        ; Is it the number 1? If so call Step1 to drive stepper motor 1 one nudge
    SUBWF    Check_Temp, w
    BTFSC    STATUS, Z                ; Does it match?
    CALL step1            ; Yes

    MOVLW    0x32                        ; Is it the number 2? If so call step2 to drive stepper motor 2 one nudge
    SUBWF    Check_Temp, w
    BTFSC    STATUS, Z                ; Does it match?
    CALL step2            ; Yes 
    
    MOVLW    0x33                        ; Is it the number 3? If so call step3 to drive stepper motor 3 one nudge
    SUBWF    Check_Temp, w
    BTFSC    STATUS, Z                ; Does it match?
    CALL step2            ; Yes 
    
    
    MOVLW    0x3F                        ; Is it a question mark? If so call intro message
    SUBWF    Check_Temp, w
    BTFSC    STATUS, Z                ; Does it match?
    CALL message            ; Yes 
    
           
    return

; --------------------------------
; STEPPER MOTOR STEP CONTROL - ONE (RB0)
;---------------------------------
step1 BSF STEPPER1 ; STEP the Stepper 1 motor
call Delay ; Call Delay so there is enough time for the stepper motor controller to see a high
BCF STEPPER1 ; Turn off the output ready for the next command.
Call Delay
return

step2 BSF STEPPER2 ; STEP the Stepper 2 motor
call Delay ; Call Delay so there is enough time for the stepper motor controller to see a high
BCF STEPPER2 ; Turn off the output ready for the next command.
call Delay
return

step3 BSF STEPPER3 ; STEP the Stepper 2 motor
call Delay ; Call Delay so there is enough time for the stepper motor controller to see a high
BCF STEPPER3 ; Turn off the output ready for the next command.
call Delay ; Call Delay so there is enough LOW period before going to the next cycle.
return


;
; -------
; MESSAGE
; -------
;
message movlw     'T'        
    call    send
    movlw     'i'
    call    send
    movlw     'm'
    call    send
    movlw     'e'
    call    send
    movlw     ' '
    call    send
    movlw     'L'
    call    send
    movlw     'a'
    call    send
    movlw     'p'
    call    send
    movlw     's'
    call    send
    movlw     'e'
    call    send
    movlw     ' '
    call    send
    movlw     'C'
    call    send
    movlw     'o'
    call    send
    movlw     'n'
    call    send
    movlw     't'
    call    send
    movlw     'r'
    call    send
    movlw     'o'
    call    send
    movlw     'l'
    call    send
    movlw     'l'
    call    send
    movlw     'e'
    call    send
    movlw     'r'
    call    send
    
    movlw     0x0D    ; CR
    call    send
    movlw     0x0A    ; LF 
    call    send
    return

; ====================== DELAY ROUTINES ===================================

Delay
    movlw    .1
    movwf    count1

dloop1    decfsz    count1,f
    goto    dloop1
    goto    $+1
    retlw    0x00

        END
 
Last edited:

Markd77

Joined Sep 7, 2009
2,806
I prefer to use interrupts to receive serial data so that I can do other things at the same time and not miss data.
Here's something I wrote, it also has a buffer for the incoming data so the whole input string can be analysed in one go, eg. your 1 500 5.
It's got some BCD to binary and the reverse which will come in handy too. It's a bit lacking in comments but should give you some ideas.
http://www.marksphotos.info/fg/
 

Thread Starter

bluebrakes

Joined Oct 17, 2009
252
thanks mark.

not really sure if i really understand what is going on there with your code. Totally agree with you that getting rid the existing method and waiting for a complete instruction string.

I wondering if the best way might be for it.....

It waits for a sync character i.e. # This takes it to a routine where the next character (being a number) selects the stepper motor, waits for a space character then......

It then goes to the next routine which calculates the number of steps before finally going onto the delay selection routine.
 

Markd77

Joined Sep 7, 2009
2,806
This is the buffer fill section.
The buffer is set up in the cblock with:
usartrxbuf:10 ;number after colon is size of buffer

Rich (BB code):
    movlw usartrxbuf           ;location of start of buffer
    addwf usartrxcount, W      ;received byte number
    movwf FSR
    movf RCREG, W
    movwf INDF
    incf usartrxcount, F
    sublw 0x0D                 ;check for CR or LF character
    btfsc STATUS, Z
    incf usartdone, F          ;to tell main routine that
    sublw 0x03                 ;the string has been received
    btfsc STATUS, Z
    incf usartdone, F
You could work backwards, putting the number of steps and delay into 2 variables, then calling a choice of 3 functions. It saves repeating code.
 
Last edited:

Thread Starter

bluebrakes

Joined Oct 17, 2009
252
can anyone see what's wrong here?

so the number in the W registry is placed into Check_Temp and it's a character recieved from serial.

Rich (BB code):
runstepper movwf Check_Temp ; Put the character received into memory
    xorlw 0x00 ; Is it Zero?
    btfsc STATUS, Z
    goto main ; if it is zero goto main
    
    BSF STEPPER2 ; pulse stepper high
    call Delay ; call 500us second delay
    BCF STEPPER2
    call Delay
    
    decf Check_Temp, f ; decrease the number until it reaches zero
goto runstepper
 

ErnieM

Joined Apr 24, 2011
8,377
How does the decremented value of Check_Temp get back into w for the 2nd pass?

(Hint: it doesn't)

Unless your Delay function doesn't change w you need to put it back.
 
Top