Design of stepper motor control using PIC microcontroller

Publisher:MindfulBeingLatest update time:2020-01-11 Source: elecfans Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

pIC16f874 Stepper Motor Program

listp=16f874

include

;--==*[CONSTANTS]*==--

#defineCOMMAND_2 'B'

#defineCOMMAND_3 'C'

#defineCOMMAND_4 'D'

;--==*[VARIABLES]*==--

Design of stepper motor control using PIC microcontroller

cmdNumeq0x20;commandnumber.0xFFforinvalidcommand

recByteequ0x21;receivedbyte

motorLequ0x22;motordata-lowbyte

motorHequ0x23;motordata-highbyte

byteCntequ0x24;internalcounterforbytecountingduringreception

TIckLequ0x25;TIcks:lowbyte

TIckHequ0x26;ticks:highbyte

result1Lequ0x27;result:thisoneisneededforstorageofticks

result1Hequ0x28

winkelLequ0x29;winkel:tickcounterwithoutoverflowchecketc.

winkelHequ0x30

quadequ0x31;quadraturesignal,fordirectionstorage

oldbequ0x32;oldvalueofPORTB

newbequ0x33;newvalueofPORTB

tmr0o0equ0x34;tmr0overflowcounter0

tmr0o1equ0x35;tmr0overflowcounter1

wtemp1equ0x60; storagefortheWregister (rbif)

wtemp2equ0x61; storagefortheWregister (CCp2if)

wteMP3equ0x62;storagefortheWregister(rcif)

wtemp4equ0x63; storagefortheWregister(usarterrorroutines)

org0x00;--==*[RESETVECTOR]*==--

bmain

org0x04;--==*[INTVECTOR]*==--

bint_handler

org0x05;--==*[MAINPROGRAM]*==--

main:

;--==*[VARIABLES-initialize]*==--

MOVlw0xFF

MOVwfcmdNum

clrfmotorL

clrfmotorH

clrftickL

clrftickH

clrfresult1L

clrfresult1H

clrfwinkelL

clrfwinkelH

clrfquad

clrfoldb

clrfnewb

clrftmr0o0

clrftmr0o1

;--==*[PORTS-setupportB]*==--

clrfPORTB

bsfSTATUS, RP0; PIN4and5asinput (photo-interruptersignals)

MOVlwb'00110000';pin1hastobeanoutput(directionsignal)

MOVwfTRISB; allotherpinsareoutputs, too (default)

bcfSTATUS, RP0

;--==*[PORTS-setupportC]*==--

clrfPORTC

bsfSTATUS, RP0

MOVlwb'11111011';pin2asoutput(PWMsignal)

MOVwfTRISC;pins6and7havetobeinputs (default)

bcfSTATUS,RP0;allotherpinsareinputs,too (default)

;--==*[CCP1-setupPWMModule]*==--

bsfSTATUS, RP0

MOVlwd'249';pwmperiod(calculatedwithformula)

MOVwfPR2

bcfSTATUS,RP0;dutycycle=0

clrfCCPR1L;CCPR1Lisupper8 (bit:9...2) bitsofdutycycle

MOVlwb'00000101';enabletimer2(bit:2)andsetprescaleof1:4(bit:0-1)

MOVwfT2CON; timer2isimportantforpwmoperation!

MOVlwb'00001111';selectpwmmodeforccp1module(bit:0-3)

MOVwfCCP1CON; andresetlowertwobitsofdutycycle(bit:4-5)

;--==*[USART-setup]*==--

bsfSTATUS, RP0

MOVlw0x40; configurebaudgeneratorregister (calculatedwithformula)

MOVwfSPBRG; with: 9600baud, noparity, 8databits, nohandshake

MOVlwb'00100100';enabletransmit(bit:5)andhighspeedbaudrate(bit:2)

MOVwfTXSTA

bcfSTATUS, RP0

MOVlwb'10010000';enableserialport(bit:7)andcontinuousreception(bit:4)

MOVwfRCSTA

clrw;w=0

MOVwfRCREG;resetUARTreceiverandfifo

MOVwfRCREG;soweCANavoidreceive/framing/overrunerrorsatthebeginning

MOVwfRCREG

MOVwfTXREG; justincase: thetxifflagisnowvalid(=1; avoidsinfiniteloopsinsendByte)

;--==*[TIMER0-setup]*==--

bsfSTATUS,RP0;thisistricky;prescalerhastobeassignedtotheWDT,

;incase you want to achieve1:1prescale

bcfOPTION_REG,PS0;first,setprescalerto1:2

bcfOPTION_REG,PS1

bcfOPTION_REG,PS2

bsfOPTION_REG,PSA;then,assignprescalertowdt;nowwehavea1:1prescalefortimer0:-)

bcfOPTION_REG, T0SE

bcfOPTION_REG, T0CS

bcfSTATUS, RP0

;--==*[INTERRUPTS-setup]*==--

bsfSTATUS, RP0

clrfPIE1

bsfPIE1, RCIE; enable "receivebyte" interrupt

bcfSTATUS, RP0

clrfINTCON;resetallinterruptflags

bsfINTCON, RBIE; enable "interruptonchange" interrupt

bsfINTCON, T0IE; enable "timer0overflow" interrupt

bsfINTCON, PEIE; enableperipheralinterrupts

bsfINTCON,GIE;enableglobalinterrupts

;--==*[MAINLOOP]*==--

loop:

bloop

;--==*[sendByte-ROUTINE]*==--

sendByte:;sendbyte(whichisstoredinW)

sendByte_l0:;waituntilnewdataarrivedintxreg

btfssPIR1,TXIF;(inDICate DVI atransmitinterruptflagbit:txif)

bsendByte_l0

sendByte_l1:

MOVwfTXREG;sendnewdata

return

;--==*[INTERRUPTHANDLINGROUTINE]*==--

int_handler:

btfscRCSTA, OERR; overflowerroroccured, handleit

berr_Overflow

btfscRCSTA,FERR;framingerroroccured,handleit

berr_Frame

btfscPIR1,RCIF;receiveinterrupt:rcif

bint_USART_receive

btfscINTCON,RBIF;pininterrupt:rbif

bint_RB_change

btfscINTCON,T0IF;tmr0interrupt:t0if

bint_timer0_reset

retfie

int_RB_change:

incftickL, 1; incrementticks (lowbyte)

btfscSTATUS,Z

incftickH,1;incrementticksonoverflow(highbyte)

incfwinkelL,1;sameastick,butwillnotbereset(eichungswert)

btfscSTATUS,Z

incfwinkelH,1

MOVwfwtemp1;saveW

MOVfwPORTB

MOVwfnewb;newb=PORTB

MOVlwb'00110000';an dma sk

andwfoldb,1;resetallbitsexcept4and5

andwfnewb,1;resetallbitsexcept4and5

clrfquad;resetquadvalue

clrw;oldb==00?

subwfoldb,W

bzo00

MOVlwb'00010000';oldb==01?

subwfoldb,W

bzo01

MOVlwb'00100000';oldb==10?

subwfoldb,W

bzo10

bo11;else,oldb==11

o00:

MOVlwb'00010000';newb==01?

subwfnewb,W

bnzquit

bsfquad,7;left

bquit

o01:

MOVlwb'00110000';newb==11?

subwfnewb,W

bnzquit

bsfquad,7;left

bquit

o10:

clrw;newb==00?

subwfnewb,W

bnzquit

bsfquad,7;left

bquit

o11:

MOVlwb'00100000';newb==10?

subwfnewb,W

bnzquit

bsfquad,7;left

quit:

MOVfwPORTB

MOVwfoldb;oldb=PORTB

MOVfwwtemp1;restoreW

bcfINTCON, RBIF; resetinterrupt (important)

retfie

int_timer0_reset:

btfsctmr0o0,7;wait128overflows

gotoa1

incftmr0o0,1

gotoa0

a1:

btfsctmr0o1,6;wait64overflows

gotoa4

incftmr0o1,1

gotoa0

a4:

btfscPORTB,7;ashorthack,sowecanmeasuretheimpulses

goto next1;oftimer0withanoscillograph

bsfPORTB,7;signalisonbit7ofportb

gotomainl

next1:

bcfPORTB,7

mainl:

MOVwfwtemp2;saveW

MOVfwtickL;storeticksinresult1

MOVwfresult1L

MOVfwtickH

MOVwfresult1H

MOVfwquad;andblendthedirectionbitonMSBofresult1

iorwfresult1H,1

clrftickH;cleartickcounter

clrftickL

clrftmr0o0;cleartimer0overflowcounters

clrftmr0o1

MOVfwwtemp2;restoreW

a0:

bcfINTCON, T0IF; resetinterrupt (important)

retfie

int_USART_receive:

MOVwfwtemp3;saveW

MOVlwCOMMAND_3;command3active?

subwfcmdNum,W

bzgetData_command3;yes,handleit

MOVfwRCREG;storereceivedbyte

clrfRCREG; it's a good idea at of lush the buffer

clrfRCREG; after receiving a byte, so it's

clrfRCREG; forcedthatwehaveanewbyteinthebufferinthenextstep

MOVwfrecByte

MOVlwCOMMAND_2;--executecommand2?

subwfrecByte,W

bzcommand2;yes,doit

MOVlwCOMMAND_3;--executecommand3?

subwfrecByte,W

bzcommand3;yes,doit

MOVlwCOMMAND_4;-executecommand4?

subwfrecByte,W

bzcommand4;yes,doit

commandUnknown:; else, receivedbyteisunknown

bsfPORTB,0;showerroronLEDs

MOVfwwtemp3;restoreW

retfie

;--==*[COMMANDEXEC-transmitmotordataindebugmode]*==--

command2:

MOVfwresult1H

callsendByte

MOVfwresult1L

callsendByte

MOVfwwinkelH

callsendByte

MOVfwwinkelL

callsendByte

MOVfwwtemp3;restoreW

retfie

;--==*[COMMANDINIT-setupforreceivemotordata(part1/2)]*==--

command3:;command3

MOVlwCOMMAND_3

MOVwfcmdNum;cmdNumcontainsnowthecurrentcommandvalue

MOVlw.2

MOVwfbyteCnt;wewantexactly2bytesf rom thepc

MOVfwwtemp3;restoreW

retfie

;--==*[COMMANDEXEC-receivemotordata(part2/2)]*==--

getData_command3:

decfbyteCnt, 1; handlebytecounter

bzc3_b2;ifbytecounteris0thenitisthe2ndbyte

MOVfwRCREG;else,1stbytereceive

MOVwfmotorL;storeinmotorL

bouthere;andexit

c3_b2:

MOVfwRCREG;2ndbytereceive

MOVwfmotorH;storeinmotorH

MOVlw0xFF;resetcmdNumtoundefinedvalue(0xFF)

MOVwfcmdNum

;reconfigurePWM

MOVfwmotorH

MOVwfCCPR1L;storehighbyte(8;bits9-2)

bcfCCP1CON,CCP1Y

btfscmotorL,0;storelowbyte(2;bits0)

bsfCCP1CON,CCP1Y

bcfCCP1CON, CCP1X

btfscmotorL,1;storelowbyte(2;bits1)

bsfCCP1CON,CCP1X

btfssmotorL,2;motorL《2》bitissignificantformordirection

bturn_left

bsfPORTB,1;turnmotorright

Bouthere

turn_left:

bcfPORTB,1;turnmotorleft

outhere:

MOVfwwtemp3;restoreW

retfie

;--==*[COMMANDEXEC-transmitmotordata]*==--

command4:

MOVfwresult1H;transmithighbyte

callsendByte

MOVfwresult1L;transmitlowbyte

callsendByte

MOVfwwtemp3;restoreW

retfie

;--==*[ERROR HANDLING-for the serial communication]*==--

err_Overflow:;handleoverflowerror

MOVwfwtemp4;saveW

bsfPORTB,7;showerroronleds(10)

bcfPORTB,6

bcfRCSTA,CREN;dISAblecontinuousreception

MOVfRCREG,W;flushreceivefifobuffer(3bytesdeep)

MOVfRCREG,W

MOVfRCREG,W

bsfRCSTA,CREN;reenablecontinuousreception

MOVfwwtemp4;restoreW

retfie

err_Frame:;handleframeerror

MOVwfwtemp4;saveW

bcfPORTB,7;showerroronleds(01)

bsfPORTB,6

MOVfRCREG,W;flushreceivefifobuffer(3bytesdeep)

MOVfRCREG,W

MOVfRCREG,W

MOVfwwtemp4;restoreW

retfie

end

Reference address:Design of stepper motor control using PIC microcontroller

Previous article:What are the factors that affect the power consumption of microcontrollers?
Next article:Design of Virtual Serial Communication of PIC Microcontroller

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号