my little lab

MMcLaren

Joined Feb 14, 2010
861
So the compiler appears to be doing something like this;

Rich (BB code):
        movlw   b'00100000'     ; -0100---  postscale 5
        movwf   temp            ; ?
        movf    temp,W          ; ?
        iorlw   b'00000110'     ; -----1--  TMR2 "on"
                                ; ------10  prescale 16
        movwf   T2CON           ;
        movlw   d'100'          ;
        bsf     STATUS,RP0      ; bank 1
        movwf   PR2             ;
Which is similar to this;
Rich (BB code):
;
; // setup TMR2 for 1.6 ms PWM period and 8 ms interrupts (4 MHz clock)
;
;    T2CON = 0b00100110;        // -0100---  TOUTPS<3:0> postscale 5   
;                               // -----1--  TMR2ON "on"
;                               // ------10  T2CKPS<1:0> prescale 16
;                               // generate 16 us timer 'ticks'
;    PR2 = 100-1;               // period = 100 x 16 us 'ticks' (625 Hz)
;
        movlw   b'00100110'     ; -0100---  TOUTPS<3:0> postscale 5
                                ; -----1--  TMR2ON "on"
                                ; ------10  T2CKPS<1:0> prescale 16
        movwf   T2CON           ; generate 16 us timer 'ticks'
        bsf     STATUS,RP0      ; bank 1
        movlw   d'100'-1        ;
        movwf   PR2             ; period = 100 x 16us 'ticks' (625 Hz)
So what part of John's C code are you finding difficult to convert to assembler?
 

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
Just from a quick look it is nicely structured and commented.
I think you probably need a "goto main" after this
Rich (BB code):
main      
    call pwm_dutystep
Yes Sir...that means that i have to remove the goto stp_1 after the wait5 loop

As a cosmetic feature, instead of using "bsf _flag, 2" you can do "bsf _flags, one_second" if you put "one_second equ 2" after the cblock section, or you can use "bsf one_second" if you put "#define one_second _flag, 2". I prefer the first method, but both are common.
yes you are right! i'll edit that
 

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
But those percentages are what Microsoft Excel calculated for me, and the video suggests they're pretty much right. They wouldn't change even if you use a different frequency.
Ohk! But would you mind showing the equations you used with Excel? Sorry about this!

And yes, bits 2-5 of Port C are the pins you need to connect to.
Actually i meant the 'ccp1con = 0b00001101' and i can see the answer is YES
 

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
Well, I'm still confused about one thing though...

The data sheet (14.5.3: Set-up for PWM operation) says: "Make the CCPx pin output by clearing the appropriate TRISC bit", in this case its RC5 pin, right!?

So in my pwm_newsetup routine, '; bsf TRISC, CCP1 ; disable CCP1 output pin'
Shouldn't be 'bcf TRISC, CCP1. ; setting CCP1 pin as output'????

Also wouldn't it confict with :

Movlw c_trisc
Movwf trisc

?

Anyway does my pwm_newsetup routine make perfect sense??

I'm asking all possible question so I edit errthang at once and repost it ...also note that my template has lots of empty space that I will fill once da code runs perfectly!

Also, does the timer0 need to be reseted after each 1 second delay or it not really necessary in the case?? Well still checking it out

Regards,
 

Markd77

Joined Sep 7, 2009
2,806
I didn't notice that there was no chance of pwm_dutystep reaching the return statement. You can just use "goto pwm_dutystep" instead, it makes the program's intention clearer.
 

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
Kindly have a look at my edited version attached!

Still need to comment/ fill some gaps...

Would like you guyz to check if there's some wrong thinking somewhere...

I also edited my pwm_newsetup routine...please special attention to:
bcf CCP1 ; setting CC1 pin as output
Its in relation with my reply #84

I know you guyz are damn tired about this thread...sorry about this!
Regards,
 

Attachments

Markd77

Joined Sep 7, 2009
2,806
Can you edit to put the config in the code because otherwise we can't tell what you are using.
This is the line for the 690, just edit as necessary and put it after the #include line.

Rich (BB code):
    __CONFIG    _CP_OFF & _CPD_OFF & _BOR_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_ON & _FCMEN_OFF & _IESO_OFF
 

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
Yes Sir! I can't believe I forgot that....

I just edited it and tried programing the chip with the attached program BUT nothing happening at all...

I tried Hard but guess I'm about to give up one this one!
 

Markd77

Joined Sep 7, 2009
2,806
Don't give up just yet. I've just run it through the simulator and found a couple of things, just search the below for "problem". I think there are more bank problems than I've marked, you need to make sure you switch bank and then switch back to bank 0 for anything not in bank 0.

(I had to delete some comments to get it small enough to post).

Rich (BB code):
    list p=16F690            ; tell assembler what chip we are using
    #include <p16F690.inc>        ; include the default for the chip
__CONFIG    _CP_OFF & _CPD_OFF & _BOR_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_ON & _FCMEN_OFF & _IESO_OFF    
           
    errorlevel -302, -207
    radix    dec


    #define CCP1 TRISC,5    ;
    
    #define one_second 2      ; one second flag bit
            
   
    Cblock 0x20    ; start of general purpose registers
     
     _flags        ;
     tmr0_cnt    ;
     c_ccpr1l    ;
     c_trisc    ;
    endc 
    
    ;  use "shared" memory common to all banks for isr context vars
    ;Bank 0 0x070 - 0x07F (16 bytes -- copied into banks 1-3)

     cblock    0x70
      cs_W        ; context saving register for w
      cs_STATUS    ; context saving register for STATUS
     endc



    Org 0x0000    ; this is where the program starts running
    goto Init    ; go to the beginning of the program

   
    Org 0x0004            ; this is where the interrupt executes
    

    ; ***Save context***

    isr
      movwf     cs_W              ; save W register
      swapf     STATUS, w          ; 
      movwf     cs_STATUS          ; save STATUS register
      clrf     STATUS              ; force bank 0, IRP 0

    ;***TMR0 overflows every 4.096 ms***

      bcf INTCON, T0IF           ; clear timer 0 interrupt flag

      decfsz tmr0_cnt, f        ; decrement interrupts count      
      goto isr_end            ; ie count = 0 => exit               
      movlw 250            ; reload count                   
      movwf tmr0_cnt        ; reset tmr0_cnt for 1024 msecs     
      bsf _flags, one_second    ; set '1 second' flag for main program

    ;***Restore context and return

    isr_end
      swapf  cs_STATUS, w          ; 
      movwf     STATUS              ; restore STATUS
      swapf  cs_W, f          ; 
      swapf  cs_W, w          ; restore w
      retfie


;****************************************************************************************

     Init
      banksel ANSEL              ;               
      clrf      ANSEL              ; turn off analogue pin functions    
      clrf       ANSELH             
      
      

      ;  setup INTOSC for 8-MHz INTERNAL CLOCK

      movlw   b'01110000'     ; 01110000                       
                              ; -111---- IRCF<2:0>, 8-MHz
                              ; ----0--- OSTS, flag bit
                              ; -----0-- HTS, flag bit
                              ; ------0- LTS, flag bit
                              ; -------0 SCS, use config
      movwf   OSCCON          ; problem wrong bank                                    

      stable
      btfss   OSCCON,HTS      ; oscillator stable?                  
      goto    stable          ; no, loop & wait, else           

      ; configure TMR0 -- set for 4.096 ms time, base at 8mHZ

      
    
      movlw   b'10000100'     ; 10000010                       
                              ; 1------- /RABPU, pull-ups off
                              ; -0------ INTEDG, INT edge n/a
                              ; --0----- T0CS, TMR0 int source
                              ; ---0---- T0SE, source edge n/a
                              ; -----100 PS<2:0>, pre 1:32
      movwf   OPTION_REG      ; for 4096 us TMR0 overflows              


      ; register variables initialization

      clrf    _flags        ;
      movlw    250        ;
      movwf    tmr0_cnt    ;          
      movlw    1<<GIE|1<<T0IE  ;                                     
      movwf    INTCON          ; enable global & TMR0 interrupts     
     
      goto main

    
;    Main program
  

    main
    
    call pwm_dutystep
  
    goto main



    ; update the duty cycle and TRISC register

    pwm_newsetup

    banksel CCP1CON            ;
    clrf    CCP1CON            ; disable CCP module
    
    clrf    TMR2            ; clear Timer2

    bcf     CCP1                ; setting CCP1 pin as output

    banksel PR2            ;
    movlw    199            ; 200 - 1
    movwf    PR2            ; setting the PWM frequency 625Hz

    banksel CCP1CON            ;
    movlw    b'00001101'        ; PWM mode, 2 Lsbs of duty cycle = 00
    movwf    CCP1CON            ; P1A & P1C: active-high, P1B & P1D: active-low

    movf    c_ccpr1l, CCPR1L    ; problem load new duty cycle for next step
    
    bcf    PIR1, TMR2IF        ; CLEAR Timer2 interrupt flag
    
    movlw    b'00000110'        ; 00000110
                    ; -----1--  TMR2ON "on"
                                    ; ------10  T2CKPS<1:0> prescale 16
        movwf   T2CON               ; generate 16 us timer 'ticks'

    banksel    TRISC            ;
    movf    c_trisc, TRISC        ; problem configure new i/o pins for new duty cycle
    
    return
    
;****************************************************************************************


;***********************************************************
;**   Process Stepper Motor different steps/duty cycles   **
;***********************************************************
;** Step  1 --     PWM to 100%                               **
;**                Goto Step 2 when 1s expires               **
;**                                                       **
;** Step  2 --     PWM to 25%                                **
;**        Goto Step 3 when 1s expires               **
;**                                                       **
;** Step  3 --     PWM to 58%                              **
;**        Goto Step 4 when 1s expires               **
;**                                                  **
;** Step  4 --     PWM to 58%                                **
;**        Goto Step 5 when 1s expires               **
;**                                                       **
;** Step  5 --     PWM to 25%                                **
;**        Goto Step 1 when 1s expires               **
;***********************************************************

    

    pwm_dutystep

  stp_1 btfss    PIR1, TMR2IF        ; timer2 interrupt flag set?
    goto stp_1            ; No!

    movlw    b'11001000'        ; 8 msbs of (PWM duty cycle/PWM frequency)/(Tosc*TMR2 prescaler) = 800
    movwf    c_ccpr1l        ; 100% duty cycle of PWM period
    
    movlw    b'00001100'        ; P1A and P1B are output pins,
    movwf    c_trisc            ; P1C and P1D set to inputs
    call pwm_newsetup

    ;step 1 -- wait for 1 second then goto step 2

  wait1    btfss   _flags,one_second       ; flag set? yes, skip, else      
        goto    wait1                ; wait for 1 second                           
        bcf     _flags,one_second       ; reset flag for next step      

  stp_2    btfss    PIR1, TMR2IF        ; timer2 interrupt flag set?
    goto stp_1            ; No!

    movlw    b'00110010'        ; 8 msbs of (PWM duty cycle/PWM frequency)/(Tosc*TMR2 prescaler) = 200
    movwf    c_ccpr1l        ; 25% duty cycle of PWM period
    
    movlw    b'00001100'        ; P1A and P1B are output pins,
    movwf    c_trisc            ; P1C and P1D set to inputs
    call pwm_newsetup

    ;step 2 -- wait for 1 second then goto step 3

  wait2    btfss   _flags, one_second      ; flag set? yes, skip, else      
        goto    wait2                ; wait for 1 second                           
        bcf     _flags, one_second      ; reset flag for next step 

  stp_3    btfss    PIR1, TMR2IF        ; timer2 interrupt flag set?
    goto stp_1            ; No!

    movlw    b'01110100'        ; 8 msbs of (PWM duty cycle/PWM frequency)/(Tosc*TMR2 prescaler) = 464 
    movwf    c_ccpr1l        ; 58% duty cycle of PWM period
    
    movlw    b'00100100'        ; P1B and P1C are output pins,
    movwf    c_trisc            ; P1A and P1D set to inputs
    call pwm_newsetup

    ;step 3 -- wait for 1 second then goto step 4

  wait3    btfss   _flags, one_second      ; flag set? yes, skip, else      
        goto    wait3                ; wait for 1 second                           
        bcf     _flags, one_second      ; reset flag for next step 


  stp_4    btfss    PIR1, TMR2IF        ; timer2 interrupt flag set?
    goto stp_1            ; No!

    movlw    b'01110100'        ; 8 msbs of (PWM duty cycle/PWM frequency)/(Tosc*TMR2 prescaler) = 464 
    movwf    c_ccpr1l        ; 58% duty cycle of PWM period
    
    movlw    b'00110000'        ; P1C and P1D are output pins,
    movwf    c_trisc            ; P1A and P1B set to inputs
    call pwm_newsetup

    ;step 4 -- wait for 1 second then goto step 5

  wait4    btfss   _flags, one_second      ; flag set? yes, skip, else      
        goto    wait4                ; wait for 1 second                           
        bcf     _flags, one_second      ; reset flag for next step 


  stp_5    btfss    PIR1, TMR2IF        ; timer2 interrupt flag set?
    goto stp_1            ; No!

    movlw    b'00110010'        ; 8 msbs of (PWM duty cycle/PWM frequency)/(Tosc*TMR2 prescaler) = 200
    movwf    c_ccpr1l        ; 25% duty cycle of PWM period
    
    movlw    b'00011000'        ; P1A and P1D are output pins,
    movwf    c_trisc            ; P1B and P1C set to inputs
    call pwm_newsetup

    ;step 5 -- wait for 1 second then loop back to step 1 via goto main

  wait5    btfss   _flags, one_second      ; flag set? yes, skip, else      
        goto    wait5                ; wait for 1 second                           
        bcf     _flags, one_second      ; reset flag for next step 


    return

    end
 

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
Thx Sir!

I'll have a look at it in a few minutes and tried correcting it!

And how about the following:

bcf CCP1 ; setting CC1 pin as output
Its in relation with my reply #84

Is it ok? Is pwm_newsetup ok?

Thanks!
 

Markd77

Joined Sep 7, 2009
2,806
Actually I've never used a PIC with the advanced PWM module, I was just going to simulate it and see what happens :)
That bit of the datasheet is pretty heavy reading.
 

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
Eric, if you ask me nicely, I'll send you the C code and hex files.
John,

Would you mind sending me your C code and hex files so I can try it on my motor and see how it works?? while trying to figure out how to make my assembly code work as well...

Hope this is 'nicely' enough!

Kindly regards, Eric
 

John P

Joined Oct 14, 2008
2,026
All right Eric, I'll put the files in the Public folder on my Dropbox account, rather than sending you a PM about PWM. Anyone who wants this can have it, but if you make lots of money off it, I expect a share.

http://dl.dropbox.com/u/28291527/S_hand/s_hand.c
http://dl.dropbox.com/u/28291527/S_hand/S_HAND.HEX
http://dl.dropbox.com/u/28291527/S_hand/S_HAND.LST
http://dl.dropbox.com/u/28291527/S_hand/microstep.xls

If you're a beginner with PIC processors and stepper motors, and you haven't got a compiler, this is probably not the best project to start with. I don't want to sound discouraging, but there are a number of complicated things to deal with here. Anyway, I found this article about microstepping that could be useful:

http://www.stepperworld.com/Tutorials/pgMicrostepping.htm

Edited to say that the numbers listed in that article for microstepping duty cycles do agree with my spreadsheet. But if you use the technique Sgtwookie suggested where adjacent phases are complementary (i.e. the two duty cycles always add up to 100%) you won't get constant torque. That's only possible if you can give two phases independent duty cycles, which would mean more complex programming.
 
Last edited:

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
...but if you make lots of money off it, I expect a share.
i make NO money out of anything here in this forum...i'm just HUNGRY for knowledge!!!

If you're a beginner with PIC processors and stepper motors, and you haven't got a compiler, this is probably not the best project to start with. I don't want to sound discouraging, but there are a number of complicated things to deal with here.
I don't consider myself a beginner with PIC microcontroller (PIC16F690) NOMORE but i'm still learning though...i have been discussing 2 projects already starting with blinking LEDs at different frequency...and this is the 3rd one...and it will get more complicated with future ones

Given an algorithm, I can write a piece of code that will run nicely!
BUT the biggest challenge is to come up with that 'algorithm' that will solve the problem!! And converting the algorithm into code is generally no big deal...

Another point is that I've never tried writing PIC code in C...

Anyway, I found this article about microstepping that could be useful:

http://www.stepperworld.com/Tutorials/pgMicrostepping.htm
Thanks a lot for this link as it will serve for future reference and i'll read more on that for better understanding of how stepper motors work!
 

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
im readind you C code and trying to understand it...but i can see you used PIC16F877...any major change to do so it can run on the 690?

im NOT familiar with C for PiC programming! anyways....

Guess i should use the Hex file to write into the chip, right?
But this is for 16F877 and how to do it? im going to read about it in the meantime...

im using PICkit 3

regards,
 

Thread Starter

Eric007

Joined Aug 5, 2011
1,158
I'll edit my code according to John P and re-post later!
Hopefully it works and so I can discuss about sumthing else...

Thanks again John
 

John P

Joined Oct 14, 2008
2,026
im readind you C code and trying to understand it...but i can see you used PIC16F877...any major change to do so it can run on the 690?

im NOT familiar with C for PiC programming! anyways....

Guess i should use the Hex file to write into the chip, right?
But this is for 16F877 and how to do it? im going to read about it in the meantime...

im using PICkit 3

regards,
The point is in your question "Any major change?" and the answer is "no". All the PIC processors of that type--the ones with 8 data bits and a 14-bit instruction word--work exactly the same way, with simple differences like control registers for whatever features the individual processor has. I'm using an ancient version of the CCS compiler, which is way older than the PIC16F690, so I make it work by lying to the software, telling it that it's working with a PIC16F877. It obediently generates the code I want. Most of the lines beginning #byte are there to deal with PIC16F690 features.

On the other hand, when you go to write the code into the processor, you need to know which one you have. I had to add details of the PIC16F690 to my programmer's code, but that was just adding a block of text to the control file. Then yes, it's the Hex file that you feed to the programmer.

Starting by flashing LEDs is the classic way to get into microprocessor code. You'll find enough challenges there!

PIC16F690 data:
CHIPname=16F690
INCLUDE=Y
SocketImage=0pin
EraseMode=2
FlashChip=Y
PowerSequence=Vpp2Vcc
ProgramDelay=60
ProgramTries=1
OverProgram=1
CoreType=bit14_B
ROMsize=001000
EEPROMsize=00000100
FUSEblank=3FFF
CPwarn=N
CALword=N
BandGap=N
ICSPonly=Y
ChipID=1400
LIST1 FUSE1 "Oscillator" "EXTRC_CLKOUT"=3FFF "EXTRC_IO"=3FFE "INTRC_CLKOUT"=3FFD "INTRC_IO"=3FFC "EC"=3FFB "HS"=3FFA "XT"=3FF9 "LP"=3FF8
LIST2 FUSE1 "WDT" "Enabled"=3FFF "Disabled"=3FF7
LIST3 FUSE1 "PWRTE" "Disabled"=3FFF "Enabled"=3FEF
LIST4 FUSE1 "MCLRE" "Enabled"=3FFF "Disabled"=3FDF
LIST5 FUSE1 "Code Protect" "Disabled"=3FFF "Enabled"=3FBF
LIST6 FUSE1 "CPD" "Disabled"=3FFF "Enabled"=3F7F
LIST7 PUSE1 "BOREN0" "BOR on SBOREN off"=3FFF "BOR if run SBOREN off"=3EFF "SBOREN controls"=3DFF "Disabled"=3CFF
LIST8 FUSE1 "InEx Switch Over" "Enabled"=3FFF "Disabled"=3BFF
LIST9 FUSE1 "Fail Clock Mon" "Enabled"=3FFF "Disabled"=37FF
 
Last edited:
Top