ضبط السرعة
ضبط السرعة:
الآن لنضبط السرعة لو كانت بالزيادة سنبطئ الاستجابة و إن كانت بالنقصان سنجعلها فورية، وهذا باستخدام المتغير السابق ذكره وهو Sscntr أو Slow Start Counter و فرضنا له قيمة 5 لكنها يمكن أن تكون متغيرة برغبة المستخدم و تحتاج أزرار. أو تجعل أى زر من المستخدم يعرض المهام و 2 للزيادة و النقصان.
هنا سننقص Sscntr بواحد فإن لم يكن = صفرا سنترك الدورة ولا نعدل شيئا و إلا سنضع 5 من المتغير SlowStart فى العداد Sscntr و نزود السرعة الحالية CurrSpeed بواحد ثم نذهب لضبط السرعة.
كود:
SpeedUP:
DJNZ SScntr,AdjSpeed
MOV SScntr,#SlowStart
INC CurrSpeed
AdjSpeed:
JNB OutLo,ShowValues ; update only when OutLo = 1 i.e motor stop
MOV TH0,CurrSpeed ; The motor in off time, the next update is on time
SETB TR0 ; Startt Timer0
; Add here Current check if you like, then stop or decrease output.
ShowValues:
MOV A,CurrSpeed ; Hi=1 and low = 254
ACALL Bi2BCD_Ascii
هنا لو كانت OutLo = صفرا فهذا يعنى أن الخرج على طرف PWMout أيضا = صفر و من ثم الموتور فى زمن التغذية أى الطاقة موصلة لذا ليس من الحكمة تطبيق تعديلات الآن فنترك الدورة و إلا سيكون فى وقت الإطفاء وهو يحسب بالعداد TH0 و القيمة التالية هى زمن التوصيل وهى فى TH0 لذا نضع القيمة الجديدة من CurrSpeed فى TH0 ثم بعد ذلك نذهب لعرض القيم و العودة للدورة.
هنا نقطة لم نذكر عنها شيئا وهى قياس التيار و كتابته على الشاشة، حسنا فى الجزء الخاص بين SpeedUP و ShowValues يمكنك اختبار قيمة التيار و تقلل الخرج أو توقفة لو زاد عن حد معين أو ما شئت.
التالى هو الكود مجمع
كود:
; This program Controls A DC motor according to a Volume setting.
$NOMOD51
$INCLUDE (89S8253.MCU)
ADC equ P0
LEDS EQU P1
LCD Equ P2
Cmnds Equ P3
AutoLED Equ LEDS.0
ManLED Equ LEDS.1
SaveLed Equ LEDS.2
StopLed equ LEDS.3
RUNLed Equ LEDS.4
ADCStrt EQU LEDS.5
InotV EQU LEDS.6
PWMout EqU LEDs.7
RunSW EQU P3.0
SaveSW Equ P3.1
StopSW Equ P3.2
ManAuto Equ P3.3
EOC EQU P3.5
LCD_RS Equ P3.6
LCD_Ena EQU P3.7
Man_Nauto EQU 10h ; FF Manual, 0 Auto
SavedSpeed EQU 11h
ReqSpeed EQU 12H
CurrSpeed EQU 13h ; Duity Ratio
SScntr EQU 14H ; Slow Start Counter
Del1 EQU 15h
Del2 EQU 16h
Disp00 EQU 20h
Disp01 Equ 21h
Disp02 Equ 22h
Disp03 Equ 23h
Disp04 Equ 24h
Disp05 Equ 25h
Disp06 Equ 26h
Disp07 Equ 27h
Disp08 Equ 28h
Disp09 Equ 29h
Disp10 Equ 2Ah
Disp11 Equ 2Bh
Disp12 Equ 2Ch
Disp13 Equ 2Dh
Disp14 Equ 2Eh
Disp15 Equ 2Fh
SlowStart Equ 5
Line1 EQU 0 ; 00h :0fh
Line2 EQU 40H ; 40H :4FH
Line3 EQU 10H ; 10H :1FH
Line4 EQU 50H ; 50H :5FH
OutLo EQU F0
org 000
AJMP BeginP
org 003h ; Adress of INT0 (IE0)Emergency
SETB PWMout ; Hi = STOP
CLR TR0 ; Stop counter
SJMP Emrgncy
org 00Bh ; Adress of Interrupt Timer 0 (TF0)
XRL TH0,#255 ; Complement Timer Hi
CPL OutLo
MOV C,OutLo
MOV PWMout,C
RETI
BeginP:
CLR LCD_Ena ; Clear LCD ENA bit Init_LCD
MOV IE,#10000011b ; Enable T0 & INT0 external
MOV TMOD,#00000110b ; T0 8bit counter auto reload
MOV TCON,#1 ; Clr All interrupts, Set INT0 Edge trigger #5 for INT0,INT1
mov Del1,#20 ; call del with 20 ms
ACALL wait_n_ms ; Wait LCD
MOV LCD,#00111000b ; 8bit, 2line, 5X8 display
LCALL Do_LCD ; Execute: WAIT IS ADDED TO STORE_CMD INSTEAD
MOV LCD,#00001100b ; Set display on,cursor off, blinking off
LCALL Do_LCD
MOV LCD,#00000110b ; Set Increment +1 mode, move screen off
LCALL Do_LCD
MOV LCD,#00010100b ; Shift Cursor, dcn=right
LCALL Do_LCD
MOV LCD,#1 ; clear entire display
LCALL Do_LCD
ORL EECON,#00010000b ; XX,EELD Page/nbyte, mem Write ena,MOVX w dptr to eeMem,DPS=0 Bank1 or 1 bank2
; 1 = ready 0 busy, if VDD << it is ZERO (Read only) Write_Inh
MOV DPTR,#Testing
ACALL WriteMsg ; write testing pls wait
ACALL GetADC ; if error will ret to ADC Fault
SJMP OKey
ADCFault:
Setb PWMout
MOV DPTR,#ADCErr
ACALL WriteMsg
SJMP $
OKey:
Emrgncy:
MOV Cmnds,#00111111b ; All Off RS,E low
MOV ADC,#255
MOV LEDs,#11110101b ; PWM off,InV=I,ADC start,RUN off,Stop On,Save off,Manual On,Auto Off
MOV SP,#70 ; Move stack away
MOV WDTCON,#01101010b ; 7,6,5 time,WDTidle=0,DISRTO(dis Rst out)=no out,HWDT Hard wdt=no
; WSWRST soft reset ,WDTEN read only disabled low power
MOV DPTR,#0 ; Read Mem 00
MOVX A,*DPTR
MOV MAN_Nauto,A ; MAN_Nauto
JZ Auto
CLR MANLED
SETB AutoLED
SJMP GoOn
Auto:
CLR AutoLED
SETB ManLED
GoOn:
INC DPTR
MOVX A,*DPTR
MOV SavedSpeed,A ; Value
MOV SScntr,#SlowStart
MOV TL0,#254 ; Hi=1 and low = 254
MOV TH0,#1
SETB OutLo ; Zero =Motor Run, 1= Motor Off. OutLo = PWMout
MOV CurrSpeed,#0 ; Start from zero
JNB STOPsw,$ ; Wait while sw pressed
MOV A,MAN_NAuto
SUBB A,#1Fh ; C if zero or 0f, otherwise defective
JC Looping
MOV DPTR,#MemFlt
ACALL WriteMsg
Looping:
ORL WDTCON,#2 ; clear WDT
JNB MANAuto,Save
CPL MANLED ; Switch AutuMan
CPL AutoLED
JNB MANAuto,$ ; Wait Sw released
JB MANLED,SetMan ; MAN off, set man on
CLR AutoLED ; Auto On
MOV MAN_Nauto,#0 ; MAN_Nauto =0
MOV DPTR,#Auto4
SJMP WriteIT
SetMan:
CLR MANLED ; Man On
Setb AutoLED ; Auto Off
MOV MAN_Nauto,#0Fh ; MAN_Nauto = 0F mem default
MOV DPTR,#Man4
WriteIt:
ACALL LCD4
Save:
JB SaveSw,RUN ; Save Not Pressed
ACALL WriteEEPROM
Run:
JNB RUNSW,GoNow ; RUN pressed
JNB STOPled,ShowValues ; Stop Mode do nothing
SJMP Running
GoNow:
JNB RUNSW,$ ; Wait release
CLR RUNLed
SETB STOPLed
Running: ; Runing
ORL WDTCON,#3 ; Start and clear WDT
MOV A,Man_Nauto
JNZ ManualControl
MOV ReqSpeed,SavedSpeed ; Set required Speed as saved
SJMP SetMotor
ManualControl:
CLR InotV
ACall GetADC
MOV ReqSpeed,A ; Set required speed as ADC
SetMotor: ; set pwm
MOV A,ReqSpeed
SUBB A,CurrSpeed ; If Curr > Req in A then carry=1 and needs to slow down
JNC SpeedUP
MOV CurrSpeed,ReqSpeed ; Slow Down at once
SJMP AdjSpeed
SpeedUP:
DJNZ SScntr,AdjSpeed
MOV SScntr,#SlowStart
INC CurrSpeed
AdjSpeed:
JNB OutLo,ShowValues ; update only when OutLo = 1 i.e motor stop
MOV TH0,CurrSpeed ; The motor in off time, the next update is on time
SETB TR0 ; Startt Timer0
ShowValues:
MOV A,CurrSpeed
ACALL Bi2BCD_Ascii
MOV Disp00,R7
MOV Disp01,R6
MOV Disp02,R5
MOV Disp03,#"0"
MOV Disp05,#" "
MOV Disp06,#"R"
MOV Disp07,#"P"
MOV Disp08,#"M"
MOV Disp09,#"."
MOV Disp10,#26h ; Type "&"
MOV LCD,#2 ; Goto HOME
ACALL WriteLine ; Line no 1 = 00, it has goto line nu
ORL WDTCON,#2 ; clear WDT
SETB InotV ; Get Current Reading
ACALL GetADC
ACALL Bi2BCD_ASCII
MOV Disp00,R7
MOV Disp01,R6
MOV Disp02,#"."
MOV Disp03,R5
MOV Disp05,#"A"
MOV Disp06,#"m"
MOV Disp07,#"p"
MOV Disp08,#"s"
MOV Disp09,#" "
MOV Disp10,#" "
MOV LCD,Line2+080H ; 80H to create Goto Location in LCD memory
ACALL WriteLine ; Line no 1 = 00
AJMP Looping
Bi2BCD_Ascii: ; converts data in Acc to 3 digits Ascii in R5(units) and R6(tens),R7(Hundred)
MOV B,#100
DIV AB ; Devide A/100, Hunderds in A, remainder in B
ORL A,#30h ; Convert to ascii
MOV R7,A ; save 100's
MOV A,B ; Get remainder
MOV B,#10d ;
DIV AB ; Devide A/10, Tens in A, remainder in B
ORL A,#30h ; Convert to ascii
MOV R6,A ; save Units
ORL B,#30h
MOV R5,B ; put result
RET
WriteEEPROM: ; Address in A reply in A
CLR SaveLED
ORL EECON,#00111000b ; set page write mode
MOV DPTR,#0
MOV A,MAN_Nauto
MOVX *DPTR,A
INC DPTR
ANL EECON,#11011111b ; End page write
MOV A,ReqSpeed
MOVX *DPTR,A
MOV Del1,#5
acall Wait_n_ms
ANL EECON,#11000111b ; End write cycle
SETB SaveLED
RET
GetADC: ; Set ADC adress, reply in A
SetB ADCStrt
nop
Clr ADCStrt
MOV Del1,#20
DJNZ DEL1,$ ; Now EOC should be zero
JB EOC,Fault ; if still one it is a defective chip
MOV DEL1,#100
ADCloopChk:
JB EOC,ADCOK ; if EOC = Hi again it is ok
DJNZ DEL1,ADCloopChk ; did not responde
Fault:
AJMP ADCFault
ADCOK:
MOV A,ADC
RET
Do_LCD:
CLR LCD_RS ; Command Reg
SJMP LCD_CLK
Writ_LCD:
SETB LCD_RS ; Data Reg
NOP
LCD_CLK:
SETB LCD_Ena ;
NOP ; DELAY > 175 ns
CLR LCD_Ena
ACALL wait_120 ; Wait Execution CurTime
RET
WriteLine: ; Put Line number on buss then call
acall Do_Lcd ;
MOV R0,#Disp00
LineLoop:
Mov LCD,*R0
ACALL Writ_LCD
INC R0
CJNE R0,#Disp11,LineLoop
RET
ClrTxt: MOV R0,#Disp00
TTT: Mov *R0,#20h
Inc R0
cjne R0,#30h,TTT
Ret
LCD4:
MOV LCD,#13+80H ; 80H is Goto Command + address 13
ACALL Do_LCD
MOV R7,#4 ; write 4 chrs
SJMP NextC
RET
WriteMsg: ; Writes a message on LCD, start in DPTR
ANL EECON,#11111011b ; Clear DPS bit in EECOM to selecl DPTR0
MOV R7,#16 ; 16 character
NextC:
CLR A
MOVC A,*A+DPTR ; Read 1st byte
MOV LCD,A ; put on lcd data
ACALL Writ_LCD
INC DPTR
DJNZ R7,NextC
RET
Wait_n_ms: ; 333 instruction / ms ; Time in ms saved in Del1
MOV Del2,#165
_wait_n:
nop
DJNZ Del2,_Wait_n
DJNZ Del1,Wait_n_ms
RET
wait_120: ; 3usec per inst
MOV Del2,#38
RET
Testing: DB "Testing Pls Wait"
ADCErr: DB "ADC: No Responce"
MemFlt: DB "Mem Err,MAN Def "
Auto4: DB "Auto"
Man4: DB "Manu"
end
المرة القادمة نبدأ فى الجهاز بالمتحكم ATMega مع البيزك
|