it explains all the basics of using adspIC to run a BLDC motor ,However the Code is in C (C18 from Microchip) I have ported it to Basic.
Note : The code is not optimized for speed and the programming style is not the optimum as the Idea is to keep it simple to show how to run a motor and not intended to comply to high Code standards,
The PID close loop the user can try to implement using this code as a Start template
The Initialzation Code
Code: Select all
'************************************************************
module Init
'**************************************************************
'Constants
'************************************************************
const FCY = 20000000 '20Mips XT 10Mhz PLL8
const FPWM = 20000 'Switch Frequency 20Khz
Const PolePairs = 5 'Number of motor pole pairs
const ADIE = 11 'AD Interrupt enable bit
const ADIF = 11 'AD Int Flag bit
const ADON = 15 'Swithch ADON Bit
const CNIF = 15 'CN Int Flag
const CNIE = 15 'CN Int Enable bit
const T3ON = 15 'Timer3 ON Bit
'************************************************************
'Variables
'************************************************************
Dim StateLowTableClk as word[8]
Dim StateLowTableAntiClk as word[8]
Dim RunLedCount as Byte
Dim PI_Tick as Byte
Dim PoleCount as Byte
'************************************************************
'Control Flags as a Structure of Bits (BitField)
'************************************************************
structure Flags
Dim Flag_StartMotor as Boolean
Dim Flag_MotorIsRunning as Boolean
Dim Flag_CalcSpeed as Boolean
Dim Flag_CalcDutyCycle as Boolean
end structure
Dim Flags as Flags
'************************************************************
'Implementation
'************************************************************
implements
'************************************************************
sub procedure Init ()
'************************************************************
'Configure Timer 1 interrupt
'************************************************************
TRISC.13 = 1 'RC13 as input stop Button
TRISD.0 = 1 'RD0 input for run Button
TRISD.01 = 0
IEC0.03 = 1 'T1 INT On
IPC0.14 = 0 'T1 Ip 4
IPC0.13 = 0
IPC0.12 = 1
IFS0.03 = 0 'T1IF Clear
PR1 = 2500
T1CON = $A010
'***************************************
'Clear Variables on Start up
'***************************************
PI_Tick = 0
RunLedCount = 0
Flags.Flag_StartMotor = 0
Flags.Flag_CalcDutyCycle = 0
Flags.Flag_MotorIsRunning = 0
PoleCount = 0
end sub
'************************************************************
'Initialize the Motor Control PWM Port
'************************************************************
sub procedure Init_MCPWM()
TRISE = $FFC0 'PWM Pins as output
PTPER = (FCY/FPWM) -1 'Set the PWM period register
PWMCON1 = $700 'Disable PWM module
OVDCON = $0 'allow control over OVDCON
PDC1 = 100
PDC2 = 100 'initialize DC register to 100
PDC3 = 100
SEVTCMP = PTPER 'ADC to trigger every new PWM cycle
PWMCON2 = $F00 '16 PWM value
PTCON = $8000 'Enable MCPWM module
'***********************************************************
'Load the switch sequence in table to MCPWM to fit Hall values
'Clockwise Direction
'************************************************************
StateLowTableClk[0] = $0
StateLowTableClk[1] = $210
StateLowTableClk[2] = $2004
StateLowTableClk[3] = $204
StateLowTableClk[4] = $801
StateLowTableClk[5] = $810
StateLowTableClk[6] = $2001
StateLowTableClk[7] = $0
'************************************************************
'Load the switch sequence in table to MCPWM to fit Hall values
'Anti Clockwise Direction
'************************************************************
StateLowTableAntiClk[0] = $0
StateLowTableAntiClk[1] = $2001
StateLowTableAntiClk[2] = $810
StateLowTableAntiClk[3] = $801
StateLowTableAntiClk[4] = $204
StateLowTableAntiClk[5] = $2004
StateLowTableAntiClk[6] = $210
StateLowTableAntiClk[7] = $0
end sub
'************************************************************
'Initializes the AD converter Module
'************************************************************
sub procedure Init_ADC ()
ADPCFG = $FFF8 'ALL PORTB pins Digital RB0-RB2 ANA
ADCON1 = $0064 'PWM Starts conversion
ADCON2 = $0200 'Simultanuos sample 4 Channels
ADCHS = $0002 'RB2 = AN2 Pottie
ADCON3 = $0080 'Tad internal RC 4usec
IFS0.ADIF = 0 'Clear Int Flag
IEC0.ADIE = 1 'Enable AD interrupt
ADCON1.ADON = 1 'Enable AD converter
end sub
'************************************************************
'Initialize the CN Pins for Hall sensor state change
'************************************************************
sub procedure Int_CNpins ()
CNEN1 = $E0 'CN5,6 and 7 enable
IFS0.CNIF = 0 'Clear Int Flag
IEC0.CNIE = 1 'Enable CN Interrupt
end sub
'************************************************************
'Initialize Timer 3 used for Speed calculation
'************************************************************
sub procedure Init_T3()
T3CON = $0030 'Internal clock Tcy/256
TMR3 = 0 'Clear the Timer
PR3 = $FFFF 'load max Time Frame
T3CON.T3ON = 1
end sub
end.
'************************************************************
Code: Select all
'************************************************************
module Interrupts
'************************************************************
'INTERRUPT SERVICE ROUTINES
'************************************************************
const Index = 1
'************************************************************
Dim HallValue as Byte
Dim SetSpeed as Word
Dim Timer3avg as Word
Dim Timer3Value as Word
'************************************************************
implements
'************************************************************
'Timer 1 Interrupt
'************************************************************
sub procedure Timer1Int org $1A
IFS0 = IFS0 and $FFF7
PI_Tick = PI_Tick +1
RunLedCount = RunLedCount +1
if PI_Tick = 40 Then
Flags.Flag_CalcDutyCycle = 1
PI_Tick = 0
end if
if (RunLedCount = 250) Then
LATD.01 = LATD.01 Xor 1
RunLedCount = 0
end if
end sub
'************************************************************
'ADC Interrupt
'************************************************************
sub procedure ADCInt org $2A
IFS0.ADIF = 0 'Clear ADC int Flag
SetSpeed = ADCBUF0 'Read ADC buffer
end sub
'************************************************************
'Change Notification Interrupt(Hallsensor State)
'Select next Step sequence to drive 3 Phase Bridge
'************************************************************
sub procedure CNInt org $32
IFS0.CNIF = 0 'Clear Int Flag
HallValue = PORTB and $38
HallValue = HallValue >> 3
OVDCON = StateLowTableClk[HallValue]
if(HallValue = Index) Then
PoleCount = PoleCount +1
if( PoleCount = PolePairs) then
Timer3Value = TMR3 ' 1 mechanical Rev Completed read Timer
TMR3 = 0
Timer3avg = ((Timer3avg + Timer3Value) >>1)
PoleCount = 0
Flags.Flag_CalcSpeed = 1
end if
end if
end sub
end.
'************************************************************
Code: Select all
'************************************************************
program Bldc_BlockCommutation
'************************************************************
' This code Run the Hurst 24V BLDC motor in Close Loop
'Block Commutation.
'Ported From C18 code to mikroBasic
'As per Microchip Application Note AN957
'Device dsPIC4012 or any dspIC with Motor Control PWM Port
'************************************************************
include "Init"
include "Interrupts"
'************************************************************
'symbols
'************************************************************
'constants
'************************************************************
const SpeedFactor = 1.949
const Timer3Const = 0.0000128
'************************************************************
'StateMachine Definitions
'************************************************************
const StartMotor = 1
const RunContinious = 2
const ErrorState = 3
Const StopMotor = 4
'************************************************************
'Variables
'*****************************************************************
Dim State as Byte
Dim ActualSpeed as Word
Dim DesiredSpeed as Word
Dim CapturedTime as float
'************************************************************
' Structures
'************************************************************
'************************************************************
'Procedures
'************************************************************
sub procedure CalcSpeed ()
CapturedTime = float(Timer3avg )* Timer3Const
CapturedTime = (pow(CapturedTime ,-1)* float(60) )
ActualSpeed = word(CapturedTime)
end sub
'******************************************************************
sub function CalcDutyCycle(Dim SetSpeed as word,Dim SpeedFactor
as real) as real
result = real(SetSpeed) * SpeedFactor
end sub
'***********************************************************
'Main Program
'***********************************************************
main:
'***********************************************************
'Configure microController
'***********************************************************
Init ()
Init_MCPWM()
Init_ADC ()
Int_CNpins ()
Init_T3()
State = 0
while True
'************************************************************
'Check if start button is pressed
'************************************************************
if Button(PORTD,0, 100, 0)= 1 then
if (Flags.Flag_StartMotor = 0 )then
Flags.Flag_StartMotor = 1
State = StartMotor ' Start Button pressed allow start
end if
end if
'************************************************************
'Check if Stop Button is pressed
'************************************************************
if Button(PORTC,13, 100, 0)= 1 then
State = StopMotor
end if
'***********************************************************
select case State
'***********************************************************
''Start EC Motor
'************************************************************
Case StartMotor
Flags.Flag_StartMotor = 1 'Block Start Button
HallValue = PORTB and $38
HallValue = HallValue >> 3
OVDCON = StateLowTableClk[HallValue]
PDC1= 500
PDC2 = PDC1
PDC3 = PDC1
PWMCON1 = $0777 'Enable PWM module
State = RunContinious 'Block Start State
'************************************************************
'Motor is Running go in Run Mode now
'************************************************************
case RunContinious
If (Flags.Flag_CalcSpeed = 1) then
CalcSpeed()
Flags.Flag_CalcSpeed = 0
end if
if (Flags.Flag_CalcDutyCycle = 1) then
DesiredSpeed = word(CalcDutyCycle(SetSpeed,SpeedFactor))
PDC1 = DesiredSpeed
PDC2 = PDC1
PDC3 = PDC2
Flags.Flag_CalcDutyCycle = 0
end if
'***********************************************************
'Errors in System Go into Error State
'***********************************************************
case ErrorState
'no error stae checking implemented
nop
'************************************************************
'Stop Selected - stop motor
'************************************************************
case StopMotor
PDC1 = 100
PDC2 = 100 'initialize DC register to 100
PDC3 = 100
PWMCON1 = $700 'Disable PWM module
Flags.Flag_StartMotor = 0 'allow restart of Motor on Button
end select ' pressed
wend
end.
'************************************************************