Advertisement
Jugurtha_Hadjar

Stepper Motor Control PIC16F84A & ULN2003

Apr 15th, 2012
173
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
MPASM 15.85 KB | None | 0 0
  1. ;***********************************************************************************
  2. ;*                            Stepper Motor Control v1.5                           *
  3. ;*                             PIC16F84A & ULN2003                                 *
  4. ;*                                                                                 *
  5. ;*                         Jugurtha Hadjar & Raouf Moualdi.                        *
  6. ;*                 4ème Année Ingénieur Instrumentation U.S.T.H.B                  *
  7. ;*                                                                                 *
  8. ;*          Université des Sciences et de la Technologie Houari Boumédiène.        *
  9. ;*                                                                                 *
  10. ;*               Contact: Remove capital letters from the address.                 *
  11. ;*              [email protected]                *
  12. ;*                             http://docs.com/@jhadjar                            *
  13. ;***********************************************************************************
  14.  
  15. ;***********************************************************************************
  16. ;* Description:                                                                    *
  17. ;* TEC 585 Project00: Stepper Motor Control using PIC1684A                         *
  18. ;* A ULN2003 (7 Darlington Array) is used as an interface.                         *
  19. ;* Two push-buttons to make the motor rotate to the LEFT or to the RIGHT.          *
  20. ;*                                                                                 *
  21. ;* Original code provided courtesy of my teacher, Mr Bouchefra, and put as a       *
  22. ;* comment for memo at the end of this file, to keep track of modifications.       *
  23. ;* It contains errors intentionally slipped by the teacher to stimulate learning.  *
  24. ;*                                                                                 *
  25. ;***********************************************************************************
  26.  
  27.  
  28.  
  29.     errorlevel -302 ; Kill bank selection warnings.
  30.             ; I had to deal with 205: Found directive in column 1 which means
  31.             ; directives must not be in the first column of the code. Use tab.
  32.  
  33. ;***********************************************************************************
  34. ;*                                   THE SETUP                                     *
  35. ;***********************************************************************************
  36.  
  37.     LIST p=16F84A              ;Which processor ?                                            
  38.     #include "p16F84A.inc"     ;Where's the file?                                            
  39.                                                                                          
  40.  
  41.     __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _RC_OSC      
  42.    
  43.     ;Code Protection OFF
  44.     ;Watchdog Timer  OFF
  45.     ;Power Up Timer  ON
  46.         ;RC Oscillator.
  47.         ;__CONFIG H'3FF9'
  48.  
  49.  
  50. ;************************************************************************************
  51. ;*                    CONFIGURATION BITS                    *
  52. ;************************************************************************************
  53.  
  54. ; PAGE 21 of the DATASHEET DS35007A - PIC16F84A, Chapter 6.1 - Configuration Bits
  55. ; Programmed   : Read 0
  56. ; Unprogrammed : Read 1
  57.  
  58. ; Mapped in memory location 2007h: (Test/Configuration memory space 2000h-3FFFh)
  59.  
  60. ; Bit 13:4  CP: Code Protection Bit (0: Protected, 1: CP off)
  61. ; Bit 3 : ~PWRTE(Active Low): Power-Up Timer Enable Bit (1: Disabled, 0: Enabled)
  62. ; Bit 2 : WDTE: Watchdog Timer Enable Bit (1: WDT Enabled, 0: WDT Disabled)
  63. ; Bit 1:0 : FOSC1:FOSC0 Oscillator Selection Bits:
  64. ;           11 RC : Resistor/Capacitor
  65. ;           10 HS : High Speed Crystal/Resonator
  66. ;           01 XT : Crystal/Resonator
  67. ;           00 LP : Low Power Crystal            
  68.  
  69. ; See Page 22 of said datasheet.
  70. ; In our case, the word is : 3FF9, we dismiss two bits since it's a 14bit core
  71. ; 11 1111 1111 1001
  72. ; We notice the Oscillator selection bits are wrong, they should be 11.
  73. ; The word should be : 3FFBh instead of 3FF9h  (This was confirmed in Proteus ISIS
  74.  
  75.    
  76.  
  77. ;************************************************************************************
  78. ;*                                  EQUATES                                         *
  79. ;************************************************************************************
  80.  
  81. ;STEP   EQU 0x0C      ; This line doesn't pretty much have a meaning,
  82.                       ; SINCE we would do a CLRF STEP before the loop.
  83.                      
  84.  
  85.  
  86. ; Assigning names to PINs so that if we'd like to change their disposition, we will
  87. ; only have to change them in here, instead of replacing all occurences in the code.
  88.                      
  89. #define RIGHTBUTTON PORTA,0
  90. #define LEFTBUTTON  PORTA,1
  91.  
  92. ;#define RIGHTLED    PORTB,6
  93. ;#define LEFTLED     PORTB,7
  94.  
  95.  
  96.  
  97. ;**********************************
  98. ;       Stepper Motor Phases      *
  99. ;---------------------------------*
  100.  
  101. ;Assigning names to phases to see the program flow better.
  102.  
  103. #define SETPHASE0 retlw B'00001001'
  104. #define SETPHASE1 retlw B'00001010'
  105. #define SETPHASE2 retlw B'00000110'
  106. #define SETPHASE3 retlw B'00000101'
  107. ;*********************
  108.  
  109.  
  110. ;**********************************************************************************              
  111. ;* See chapter 2.2 Data Memory Organization, Page 6 & 7, Figure 2-1.              *
  112. ;* TRISB is the PORTB data direction register. It's on 8 bits.                    *
  113. ;* Clearing TRISB configures the PORTB as an OUTPUT.(Bits can be set/cleared      *
  114. ;* individually to configure each I/O port separately. RB0,RB1,...,RB7            *
  115. ;**********************************************************************************
  116.  
  117.  
  118.  
  119.  
  120.         cblock 0x0C          
  121.                        
  122.             STEP:1         ; The byte at 0x0C:STEP.
  123.                      
  124.                 endc
  125.      
  126.    
  127.         org 0x00                   ;Reset Vector. See Page 5: Program Memory Map and Stack
  128.  
  129.             goto ENTRYPOINT
  130.  
  131.         org 0x04                   ;Interrupt Vector, see Page 5.
  132.        
  133.  
  134.  
  135. ENTRYPOINT
  136.    
  137.     ; TRISA & TRISB are the Data Direction Registers, used to set whether a pin (thus a port)
  138.     ; is an input or an output.    
  139.  
  140.  
  141.     banksel TRISB            ; Selecting Bank 1 (TRISB is in BANK1)
  142.                  ; This is equivalent to doing BSF STATUS, RP0
  143.        
  144.     movlw 0x00               ; Load W with 0x00
  145.     movwf TRISB              ; All bits to 0. (TRISB=00000000)  PORTB OUTPUT.
  146.                              
  147.                    
  148.     ;banksel TRISA           ; This wasn't needed since we're already in BANK1.
  149.    
  150.     movlw 0xFF               ; Load W with 0xFF.
  151.     movwf TRISA          ; All bits to 1. (TRISA=11111111)  PORTA INPUT.
  152.                              
  153.     movlw 0x96              
  154.     movwf OPTION_REG     ; Configure OPTION_REG (81h in Bank1).
  155.    
  156.     ; PAGE 15: Each of PORTB pins has a weak pull-up. These are disabled automatically
  157.     ; when the port is configured as an output, which is the case here.
  158.  
  159. ;******************************************************************************************
  160. ;*                             OPTION_REG Description                                     *
  161. ;*----------------------------------------------------------------------------------------*
  162. ;* Bit7:RBPU(active low) PORTB Pull-Up Enable Bit (1, Disabled)                           *
  163. ;* Bit6:INTEDG, Interrupt Edge Select Bit(0, Interrupt on falling edge B0/INT)            *
  164. ;* Bit5:T0CS, TMR0 Clock Source Select Bit (0, Internal Instruction Cycle Clock)          *
  165. ;* Bit4:T0SE, TMR0 Source Edge Select Bit(1, Increment on Hi-to-Lo transition on RA4)     *
  166. ;* Bit3:PSA,PRESCALER Assignment Bit(0, Prescaler assigned to TMR0 module)                *
  167. ;* Bit2:0: PRESCALER Select Bits (110, 1:128)                                             *
  168. ;******************************************************************************************
  169.  
  170.  
  171.  
  172.  
  173.     banksel PORTB ; Selecting Bank0
  174.    
  175.     movlw 0x00
  176.         movwf TRISB ;All PORTB pins to 0.
  177.    
  178.     clrf STEP       ;Clearing STEP at 0x0C
  179.     clrf TMR0       ;Clearing TMR0
  180.        
  181.     goto START      ;Here we go..
  182.  
  183.  
  184. ;******************************************************************************************
  185. ;*                        MOTOR SEQUENCE: PHASES (In Program Memory)                      *
  186. ;******************************************************************************************
  187.        
  188.             ;Computed GOTO. We add w to PCL.        
  189.             ;This is the sequence used to control the motor.
  190.             ;It's a Table in the program memory
  191.             ;When a call gets with an offset value loaded in w
  192.             ;We then add the Program Counter low 8bits to that value,
  193.             ;The result is branching to the new value of PCL.
  194.             ;See Application Note 556 "Implementing a Table Read"
  195.             ;Stan D'Souza , Microchip Inc .
  196.  
  197. SEQUENCE     addwf PCL,f    ; Adds W to the PC Low 8 bits. The location
  198.                                 ; of the next instruction is computed that way.
  199.        
  200.     SETPHASE0           ;Return With Literal in W 0x09. With an initial w of 0x00
  201.     SETPHASE1           ;Return With Literal in W 0x0A. With an initial w of 0x01
  202.     SETPHASE2           ;Return With Literal in W 0x06. With an initial w of 0x02
  203.     SETPHASE3           ;Return With Literal in W 0x05. With an initial w of 0x03
  204.  
  205. ;***************************************************************************************
  206.  
  207. START   btfsc   TMR0,7 ; Bit Test File TMR0, 7 Skip Next Instruction If Clear.
  208.                        ; In the original code, it was BTFSS. Which doesn't make sens.
  209.                        ; Because we've just cleared TMR0, so TMR<7>=0 , so GOTO START
  210.                        ; gets executed in a never ending loop.
  211.                        ; Although, I have to figure out this TMR0 thing later.
  212.                        ; Its purpose, and all.
  213.  
  214.                        ; Test the 7th bit of TMR0, and skip the goto START if it's 0
  215.                
  216.                        ; 4.1 TMR0 Operation (Page 17 of Datasheet):
  217.                        ; Counter Mode or Timer Mode.
  218.  
  219.  
  220.                 goto START ; Only if TMR0<7>=1
  221.                 clrf TMR0  ; Clear TMR0 (All bits 0)
  222.  
  223.  
  224.  
  225.  
  226. ;**************************************************************************************
  227. ;*                                RIGHT SUBROUTINE                                    *
  228. ;**************************************************************************************
  229. ;This makes the motor turn right when RA0 is pulled down.(button pushed and kep down)
  230.  
  231. RIGHT  
  232.        
  233.         btfsc   RIGHTBUTTON ;Test RA0. If it's Zero, skip to Incf. If it's 1, goto left.
  234.         goto    LEFT
  235.         incf    STEP,f  ;Increment the value held in STEP (address 0x0C)
  236.         movlw   0x04    ;Move literal to W (0x04-->w)
  237.         subwf   STEP,w  ;Substract w from f, the result goes to w. f-w--->w
  238.                                    
  239.         btfsc   STATUS,C ;Test the Carry bit(flag) of STATUS register
  240.         clrf    STEP     ;Clear STEP
  241.         movf    STEP,w   ;STEP---->w
  242.         call    SEQUENCE ;Wondering what this does ?
  243.  
  244.         movwf PORTB     ;w---->PORTB. Outputs whatever value was in w to PORTB pins.
  245.        
  246.         goto     START
  247.  
  248. ;**************************************************************************************
  249. ;*                                 LEFT SUBROUTINE                                    *
  250. ;**************************************************************************************
  251. ;This makes the motor turn lefht when RA0 is pulled down.(button pushed and kept down)*
  252.  
  253. LEFT   
  254.  
  255.         btfsc   LEFTBUTTON ;Test RA1, Goto start if it's 1.
  256.         goto    START
  257.         decf    STEP,f  ;f-1---->f
  258.         movlw   0x03    ;0x03--->w
  259.         btfsc   STEP,7  ;Test STEP<7> , skip next instruction if clear.
  260.        
  261.                 movwf   STEP    ;Why are we doing this ? movwf STEP then movf STEP, w. Killing time ?
  262.         movf    STEP,w  ;It's because movwf STEP gets executed only the first time
  263.                                 ;When STEP=0-1 (decf STEP) = 0xFF = 11111111
  264.  
  265.         call    SEQUENCE ;We call SEQUENCE, where we'll add the low 8 bits of the
  266.                                  ;Program counter to W to do a computed goto.
  267.         movwf PORTB              ;Loads PORTB with the value of w.
  268.                          
  269.        
  270.         goto    START
  271.  
  272.     end
  273.  
  274.  
  275.  
  276.  
  277.  
  278.  
  279.  
  280. ;****************************************************************************
  281. ;                     LOG: Code Updates, Rambling & Rants                   *
  282. ;****************************************************************************
  283. ;
  284. ;
  285. ;Tuesday December 8th, 2011:
  286. ;I put the RIGHT subroutine as a comment, so that there's only the LEFT subroutine
  287. ;that will be executed.
  288. ;RA1 is pulled up to 5V by a 10K resistor, and as long as the push-button isn't pushed
  289. ;RA1 is logical 1, so the BTFSC PORTA,1
  290. ;                         GOTO  START
  291. ;It always hooks to START and starts all over again.
  292. ;Now We push the push-button (LEFT), we pull down RA1. And the program skips GOTO START
  293. ;because RA1 is 0. And the program does its stuff.
  294. ;PORTB = 00000101 , 00000110, 00001010, 00001001, then cycles again 00000101,.
  295.  
  296. ;Then I'll put the LEFT subroutine as a comment, and do the same thing to check it out.
  297. ;RIGHT and LEFT subroutine work.
  298.  
  299.  
  300.  
  301. ;Friday December 9th, 2011:
  302. ;-Added some macros and got rid of 'hardcoded' literals to make the code
  303. ; more easily reusable elsewhere.
  304. ;-Changed the place of LOG to the end of file for clarity.
  305. ;-Defined RA0 as RIGHTBUTTON, and RA1 as LEFTBUTTON.
  306.  
  307.  
  308. ;Saturday December 10th, 2011
  309. ;Some bugs slipped in the code and went undetected.
  310. ;The code compiled successfully, but I didn't test it
  311. ;if it works. It didn't, but does now.
  312.  
  313. ;-Bugs in v1.3 fixed in v1.4:
  314. ; -SEQUENCE was in the wrong place (before GOTO START)
  315. ; -mSelectBank1 macro was declared as such
  316. ;  but invoked as mBankSelect1 and didn't work obviously.
  317. ; -mOPTION_REGConfigure was invoked as such, but the register
  318. ;  in the macro was CONFIG_REG, which doesn't exist as far
  319. ;  as I know.
  320.  
  321. ;RULE1: -In macros, Always start with a VERB. This way, if invoking
  322. ;        a macro doesn't start with a verb, I'll immediately know.(crossing fingers)
  323. ;        -Macros start with a lower case 'm'.
  324.  
  325. ;Thursday December 13th, 2011: v1.5
  326. ; -Macros related to Bank Selection were deleted, as there already
  327. ;  is a directive  to deal with that. "banksel".
  328. ;  Thanks to Jon Wilder on ETO for bringing this to my attention.
  329.  
  330.  
  331. ;                              ********************************
  332. ;                              *      BANK RELATED MACROS     *
  333. ;                              ********************************
  334.    
  335.     ;mSelectBank0 macro
  336.     ;            bcf STATUS,RP0
  337.     ;             endm        
  338.  
  339.     ;mSelectBank1 macro
  340.     ;             bsf STATUS,RP0
  341.     ;             endm
  342.  
  343. ;******************************************
  344. ;* RP0 is the Bank Select Bit (in STATUS).*
  345. ;* We chose the Bank1 by setting it to 1. *
  346. ;* And chose Bank0 by setting RP0 to 0  . *
  347. ;******************************************
  348.  
  349.  
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356.  
  357.  
  358.  
  359. ;*****************************************************************************
  360. ;*                          ORIGINAL CODE                                    *
  361. ;*****************************************************************************
  362.  
  363. ;LIST p=16F84A
  364.  
  365. ;#include p16F84A.inc
  366. ;;_CONFIG H'3FF9'
  367. ;__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _RC_OSC
  368.  
  369. ;Pas EQU 0x0C
  370.  
  371. ;   org 0x00
  372. ;   bsf STATUS, RP0
  373. ;   clrf TRISB
  374.  
  375.  
  376. ;    movlw B'11111111'
  377. ;    movwf TRISA
  378. ;       movlw B'10010110'
  379. ;       movwf OPTION_REG
  380. ;   bcf STATUS,RP0
  381. ;   clrf PORTB
  382. ;       clrf Pas
  383. ;       clrf TMR0
  384. ;       goto Debut
  385.  
  386. ;Table  addwf PCL,f
  387. ;               retlw B'00001001'
  388. ;               retlw B'00001010'
  389. ;               retlw B'00000110'
  390. ;               retlw B'00000101'
  391.  
  392. ;Debut  btfss   TMR0,7
  393. ;               goto Debut
  394. ;               clrf TMR0
  395.  
  396. ;Droite btfsc   PORTA,0
  397. ;       goto    Gauche
  398. ;       incf    Pas,f
  399. ;       movlw   0x04
  400. ;       subwf   Pas,w
  401. ;       btfsc   STATUS,C
  402. ;       clrf    Pas
  403. ;       movf    Pas,w
  404. ;       call    Table
  405. ;       movwf   PORTB
  406. ;       goto    Debut
  407.  
  408. ;Gauche btfsc   PORTA,1
  409. ;       goto    Debut
  410. ;       decf    Pas,f
  411. ;       movlw   0x03
  412. ;       btfsc   Pas,7
  413. ;       movwf   Pas
  414. ;       movf    Pas,w
  415. ;       call    Table
  416. ;       movwf   PORTB
  417. ;       goto    Debut
  418. ;end
  419. ;****************************************************************************
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement