单片机 > 单片机程序设计 > 详情

PIC单片机对步进电机的控制设计

发布时间:2020-09-03 发布时间:
|

pIC16f874步进电机程序

listp=16f874

include

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

#defineCOMMAND_2’B’

#defineCOMMAND_3’C’

#defineCOMMAND_4’D’

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

cmdNumequ0x20;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’;enabletrasmit(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,

;incaseyouwanttoachieve1: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;(inDICatedviatransmitinterruptflagbit: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’;andmask

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

gotonext1;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’sagoodideatoflushthebuffer

clrfRCREG;afterreceivingabyte,soit’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;wewantexactly2bytesfromthepc

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》bitissignificantformotordirection

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

;--==*[ERRORHANDLING-fortheserialcommunication]*==--

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


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
PIC单片机基础知识之二