please rate
this thread
  •  
  • Subject
  • Author
  • Date
Posted by balla.venugopal on November 2, 2007, 7:57 am
  I want to design Motor speed controllers ( VFD) AC Drive 1-phase or 3-
phase for battery operated vehicles for short-distance use.
Anyone can help me ?
write to me....


Posted by BobG on November 2, 2007, 10:01 am
 On Nov 2, 7:57 am, balla.venugo...@gmail.com wrote:

======================================
Get this app note from Atmel:
AVR494: AC Induction Motor Control Using the constant V/f Principle
and a Natural PWM Algorithm



Posted by Tom2000 on November 2, 2007, 12:09 pm
 

On Fri, 02 Nov 2007 04:57:30 -0700, balla.venugopal@gmail.com wrote:


Here's a routine U wrote for a PIC 12F683 that implements a V/F
controller.  

I haven't gotten the hardware working yet, so it's untested. (I've
found that I have a lot to learn about HV switching...)

It might give you an idea or two of where to begin.

Good luck!

   Tom


===============================


;--------------------------------------------------------
;
; VF_Controller.asm
;
;  Voltage-Frequency Converter
;
;    PIC 12F683 firmware
;    to drive my VF Controller Mk II circuit
;
;    V1.00:  tested OK with scope on breadboard.
;            did not test it with the switching
;            hardware yet.
;
;    tjl  Sep 20,2007
;
;--------------------------------------------------------
;
;  This program implements a half-bridge voltage-frequency
;  speed controller for small single phase shaded pole
;  induction motors.
;
;  Speed range is from approx 60 Hz to 20 Hz, with the
;  voltage reduced by the following formula:
;
;     motor V = design V * motor freq / design freq
;
;  The wiper of a pot connected between +5v and ground
;  is connected to physical pin 3.  The pot setting
;  determines the motor speed.
;
;  Active low -> open outputs on physical pins 7 and 6
;  drive the high side and low side half-H switches,
;  respectively.
;
;  A half-cycle sinewave is synthesized via PWM, and
;  appears as an active high PWM signal on physical
;  pin 5.
;
;  Connect pins 7 and 6 to the cathodes of optoisolator
;  LEDs, and the PWM pin paralleled to the anodes through
;  a 330 ohm series resistor.
;
;  Use the optoisolator transistors to drive a high side
;  P-channel MOSFET and a low side N-channel MOSFET.  
;
;  Connect the motor between the junction of the two
;  MOSFETs and neutral.
;
;--------------------------------------------------------
;
;   Physical pin 3 (AN3) - Speed pot
;   Physical pin 5 (CCP1) - PWM output
;   Physical pin 6 (GP1) - Neg Switch (active low)
;   Physical pin 7 (GP0) - Pos Switch (active low)
;
;--------------------------------------------------------
;
;  12F683 RAM:
;    96 bytes in bank0, 0x20-0x7f
;    32 bytes in bank1, 0xa0-0xbf
;
;  Program memory:
;    2k 14-bit words, 0x000-0x7ff
;
;  Data EEPROM:
;    256 bytes, accessed through DE decls or
;    the four EExxx registers
;

;--------------------------------------------------------
;
;   Config section
;
;--------------------------------------------------------

        list      p=12F683
        #include  <p12F683.inc>

        __CONFIG   _FCMEN_ON & _IESO_OFF & _CP_OFF & _CPD_OFF &
_BOD_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTOSCIO


;--------------------------------------------------------
;
;   Radix, Defines, and Constants
;
;--------------------------------------------------------

        radix       dec
        
        errorlevel -302
        
        ;  I/O
        
        #define     PosSw      0
        #define     NegSw      1
        #define     PWMpin     2
        #define     Pot        4
        
        ; constants
        
        #define     Tmrbase    60      ; tune this for 60 Hz at
                                       ; max speed setting
        #define     PWM_val    254     ; 7.8 kHz w/ 8 MHz clock
                                       ; and no prescaling
        

;--------------------------------------------------------
;
;   Macro definitions
;
;--------------------------------------------------------

bank0        macro
             bcf        STATUS,RP0
             endm

bank1        macro
             bsf        STATUS,RP0
             endm

;--------------------------------------------------------
;
;   Storage
;
;--------------------------------------------------------

;  EEPROM table data

        org 0x2100
        
SineTbl de 0,13,25,37,50,62,74,86
        de 98,109,120,131,142,152,162,171
        de 180,189,197,205,212,219,225,231
        de 236,240,244,247,250,252,254,255
        de 255,255,254,252,250,247,244,240
        de 236,231,225,219,212,205,197,189
        de 180,171,162,152,142,131,120,109
        de 98,86,74,62,50,37,25,13

VoltTbl de 255,247,240,233,227,221,215,210
        de 205,200,195,191,186,182,178,174
        de 171,168,164,161,158,155,152,149
        de 147,144,142,139,137,135,133,131
        de 129,126,125,123,121,119,118,116
        de 114,113,111,110,108,107,106,104
        de 103,102,101,99,98,97,96,95
        de 94,92,92,90,90,89,88,87
        

;  Un-init RAM

        cblock        0x20
        
        w_bup           ; save W and STATUS from ISR
        stat_bup
        semaphore       ; semaphore set by ISR when TMR0 times out
        rawspeed        ; raw ADC speed pot measurement value
        speedval        ; speed value to load into TMR0
        sineptr         ; SineTbl pointer
        sineval         ; from SineTbl
        voltval         ; from VoltTbl
        pwmvalhi        ; high byte of sine x volt mult
        pwmvallo        ; low byte of sine x volt mult
        running
        temp0
        temp1
        temp2
        temp3
        
        endc
        

;--------------------------------------------------------
;
;   Program code begins here
;
;--------------------------------------------------------

        org        0                   ; processor reset vector

        goto       main  
        
        org        0x04                ; interrupt vector        
        
        goto       Int_Svc_Rtn
        
        
;--------------------------------------------------------
;
;   Interrupt service routine
;
;--------------------------------------------------------

Int_Svc_Rtn
        
        movwf       w_bup              ;  save the W and STATUS regs
        movf        STATUS,W
        movwf       stat_bup
        
        btfss       INTCON,T0IF        ; TMR0 overflow?
        goto        enableints         ; no, just enable ints and
return
        
        bcf         INTCON,T0IF
        movf        speedval,W         ; reload the TMR0 preset
        movwf       TMR0
        movlw       1
        movwf       semaphore          ; tell SendCycle that an
                                       ; int has occurred
        
enableints
        
        movf        stat_bup,W         ; restore the W and STATUS
                                       ; regs
        movwf       STATUS
        movf        w_bup,W
        
        bsf         INTCON,GIE         ; enable system interrupts
        retfie


;--------------------------------------------------------
;
;   Main program routine begins here
;
;--------------------------------------------------------
        
main

; Disable system interrupts

        bcf         INTCON,GIE
        
; set the internal oscillator to 8 MHz

        bank1
        movlw        0x71
        movwf        OSCCON
        bank0
        
; init I/O & ADC
        
        movlw        0x07
        movwf        CMCON0            ; 0,1,2 are digital I/O
        bank1
        movlw        b'01011000'       ; AN3 analog, others
                                       ; digital I/O, Fosc/16
        movwf        ANSEL
        movlw        b'00010011'       ; Preset PosSw and NegSw as
                                       ; inputs
        movwf        TRISIO
        bank0
        movlw        b'00001101'       ; AN3, left-justified,ADON
        movwf        ADCON0
        bcf          GPIO,PWMpin       ; set PWM output low
        
; set up PWM

        call        StartPWM
        
; begin        
        
        clrf        running            ; force parm init at first
                                       ; GetSpeed call
        call        Dly1Sec            ; 1 sec pause to let HV pwr
                                       ; supply settle
        
mainloop

        call        GetSpeed
        call        SetPosPhase
        call        SendCycle
        call        SetNegPhase
        call        SendCycle
        
        goto        mainloop        
        



;--------------------------------------------------------
;
;   Subroutines
;
;--------------------------------------------------------


PWMcalc                          ;  8 x 8 unsigned mult of sineval
                                 ;  x voltval
                                 ;  result in pwmvalhi and
                                 ; pwmvallo
                                 ;  modifies sineval,
                                 ; temp0,temp1,temp3
              
        bank0                                
        clrf        pwmvalhi
        clrf        pwmvallo
        movf        voltval,W
        movwf       temp0              ; holds low byte of shifted
                                       ; voltval
        clrf        temp1              ; holds high byte of
                                       ; shifted voltval
        movlw       8
        movwf       temp3              ;  counter
mult1   rrf         sineval,F
        btfss       STATUS,C
        goto        mult2
        movf        temp0,W
        addwf       pwmvallo,F
        btfss       STATUS,C
        goto        mult3
        incf        pwmvalhi,F
mult3   movf        temp1,W
        addwf       pwmvalhi,F
mult2   bcf         STATUS,C
        rlf         temp0,F
        rlf         temp1,F
        decfsz      temp3,F
        goto        mult1
        return
        
        
LoadPWM                          ; pwmvalhi to CCPR1L,
                                 ; pwmvallo<7:6> to CCP1CON<5:4>
        bank0
        bcf         CCP1CON,5
        bcf         CCP1CON,4
        btfsc       pwmvallo,7
        bsf         CCP1CON,5
        btfsc       pwmvallo,6
        bsf         CCP1CON,4
        movf        pwmvalhi,W
        movwf       CCPR1L
        return
                
        
        
GetSpeed                         ; read speed pot setting, set
                                 ; delay,
                                 ; then set TMR0 and semaphore
        
        bsf         ADCON0,1           ; start an ADC measurement
        btfss       PIR1,ADIF          ; wait for completion
        goto        $-1
        bcf         PIR1,ADIF
        
        movf        ADRESH,W           ; get the reading
        movwf       temp0
        
        movf        running,F          ; running?
        btfss       STATUS,Z
        goto        gslp2              ; if not, force parm
                                       ; initialization
        
        movlw       1
        movwf       running        
        goto        gslp1
        
gslp2   subwf       rawspeed,W         ; exit if it speed pot
                                       ; setting has not changed
        btfsc       STATUS,Z
        return
        
gslp1   movf        temp0,W            ; save the new reading
        movwf       rawspeed
        
        comf        temp0,F            ; subtract speed reading
                                       ; from 255...
        bcf         STATUS,C           ; ...and divide it by 4
        rrf         temp0,F  
        bcf         STATUS,C
        rrf         temp0,F            ; temp0 contains 0 (max) to
                                       ; 63 (min)
        
        movlw       VoltTbl            ; calc addr of volt table
        addwf       temp0,W
        call        EERead
        movwf       voltval
        
        bcf         STATUS,C           ; double the speed index
        rlf         temp0,F
        movlw       Tmrbase            ; add speed factor to timer
                                       ; base value
        addwf       temp0,W
        movwf       speedval
        
        comf        speedval,F         ; subtract from 256 (255),
                                       ; save as TMR0
                                       ;   preload value

        bcf         INTCON,GIE         ; disable interrupts
        movf        TMR0,F             ; write to TMR0
        bcf         INTCON,T0IF
        bsf         INTCON,T0IE
        clrf        semaphore          ; clear interrupt semaphore
        bsf         INTCON,GIE         ; enable interrupts
        
        return



        
SendCycle                        ; set pwm from sine table and
                                 ; volts tbl,
                                 ; wait for interrupt, set next
                                 ; step's vals
                                
        clrf        sineptr
        
sclp1   movf        sineptr,W          ; get sine value
        call        EERead                
        movwf       sineval
        call        PWMcalc            ; calc PWM from sine & pre-
                                       ; calc'd volts val
        call        LoadPWM            ; set new PWM duty cycle
        
        movf        semaphore,F        ; wait for TMR0 interrupt
        btfsc       STATUS,Z
        goto        $-2
        clrf        semaphore
        
        incf        sineptr,F          ; loop through the sine
                                       ; table
        movlw       64                 ; (SineTbl size)
        subwf       sineptr,W
        btfss       STATUS,Z
        goto        sclp1
        
        return
        
EERead                           ; EEPROM read.  Enter with addr
                                 ; in W,
                                 ; exit with data in W
        bank1
        movwf       EEADR
        bsf         EECON1,RD
        movf        EEDAT,W
        bank0
        return
        
        
        
SetPosPhase                      ; Open PWM path to Q1

        bank0
        bsf         GPIO,NegSw
        bsf         GPIO,PosSw
        bank1
        movlw       b'0010010'
        movwf       TRISIO
        bank0
        bcf         GPIO,PosSw
        return
        
        
        
SetNegPhase                      ; Open PWM path to Q2

        bank0
        bsf         GPIO,PosSw
        bsf         GPIO,NegSw
        bank1
        movlw       b'0010001'
        movwf       TRISIO
        bank0
        bcf         GPIO,NegSw
        return
        
        
        
StartPWM                         ;  Set up and start PWM

        bank1
        bsf         TRISIO,PWMpin      ; Disable the PWM output
                                       ; pin

        movlw       PWM_val            ; Set the PWM period into
                                       ; TMR2
        movwf       PR2
        bank0

        movlw       b'00001100'        ; Set CCP module for PWM
                                       ; mode        
        movwf       CP1CON
        
        movlw       0                  ; Inital duty cycle = 0%
        movwf       CCPR1L

        clrf        T2CON              ; Set TMR2 scalers for 1:1
        bsf         T2CON,TMR2ON       ; Start TMR2
        
        bcf         PIR1,TMR2IF        ; Clear TMR2's interrupt
                                       ; flag

        btfss       PIR1,TMR2IF        ; Wait for TMR2 overflow
        goto        $-1
        bcf         PIR1,TMR2IF        
        
        bank1                          ; Start PWM by setting the
                                       ; PWM pin
        bcf         TRISIO,PWMpin      ;   as an output
        bank0
        
        return
        
        
        
Dly1Sec                          ; 1 sec delay at 8 MHz
        movlw       7
        bank1
        movwf       OPTION_REG         ; set for 1:256 prescaling
                                       ; for TMR0
        bank0
        movlw       31
        movwf       temp0
dlylp   clrf        TMR0               ; TMR0:  254 ticks of 256
                                       ; instr cycles
        bcf         INTCON,T0IF
        btfss       INTCON,T0IF
        goto        $-1
        decf        temp0,F
        btfss       STATUS,Z
        goto        dlylp
        movlw       1
        bank1
        movwf       OPTION_REG         ; restore 1:4 prescaling
                                       ; for TMR0
        bank0
        return        
        
      
        end

        



  • Subject
  • Date