Kamis, 13 Maret 2014

PWM basic teory



Adalah mudah bagi microcontroller untuk membuat Led ON dan Off ataupun membuat berbagai variasi jika memakai beberapa buah Led. Tetapi itu hanya ON dan OFF saja.Kemudian bagaimana jika ingin mengontrol kecerahan dari Led, Masalah yang sama juga dalam pengontrolan robot, dimana jika ingin mengontrol kecepatan motornya dengan menggunakan microcontroller. Tidak cukup hanya dengan meng-ON dan OFF kan motornya. Untuk mengontrol kecerahan dari Led atau speed dari motor harus dikontrol jumlah arus yang melaluinya. Satu solusi yang bisa dilakukan adalah dengan meng ON dan OFF kan Led atau motor dengan sangat cepat .Arus hanya mengalir ketika output Low ( Untuk rangkaian Led dengan microcontroller com + ). Output dari microcontroller akan terlihat seperti gelombang kotak.




Apabila membuat Led dan motor ON dan OFF dengan cukup cepat maka akan tampak seperti normal menyala atau berputar tidak terlihat hidup-mati. Karena arus yang melaluinya kurang maka Led akan menyala kurang cerah atau motor berputar kecepatan rendah. Dengan solusi ini kita dapat membuat Led flash on dan off lambat 30/detikatau lebih lambat lagi dan kita start maka akan terlihat led blinking hidup-mati, tentunya bukan ini yang diharapkan. Atau untuk motor akan hilang kehalusannya dan tampak tersendat sendat. Solusi ini tidak bekerja dengan baik karena led masih terlihat cerah pada 30/s.

Dari pada merubah frekwensi ON dan OFFnya, bagaimana merubah panjang output tetap on dan off. mari kita lihat lebih dekat pada satu output cycle. sebuah output cycle terdiri dari low period,tlow dan high period, thigh. tlow+thigh=T, dimana T adalah perioda ( panjang waktu ) untuk satu output cycle. thigh juga dinamakan output pulsa.



Kita akan jaga T tetap sama jumlah per detiknya. Jika kita tingkatkatkan lebar dari thigh maka kita harus menurunkan tlow untuk menjaga T tetap sama. begitupun sebaliknya. Untuk gambar dibawah thigh lebih kecil.

Terlihat bahwa output 0 waktunya paling panjang dan led atau motor akan lebih cerah dan cepat untuk motor. Untuk kasus lainnya thigh dibuat lebih panjang seperti dibawah



Output Vcc waktunya paling panjang yang mana membuat led off. Arus mengalir melalui led dalam waktu singkat.Karena masih menyalakan led on dan off sangat cepat

( misal sekitar 600/s ). kita tidak akan melihat lednya blinking dan akan terlihat kecil kecerahannya. Total arus yang melalui led rendah. Untuk motor akan burputar palan secara halus.

Jadi kita dapat mengontrol kecerahan dari led dan atau kecepatan motor dengan merubahpanjang dari thigh-nya. Ini adalah rahasia dari PULSE WIDTH MODULATION

Dibawah ditampilkan source code PWM yang diadjust secara digital dan ditampilkan melalui LCD, digunakan untuk mengontrol motor dc, bisa juga untuk mengatur kecerahan LED.

Install Led di output PWMPIN = P3.0

$include(reg51.inc)
;8 bit LCD routines with check busy flag before sending data, command to LCD      
;*************************************************************
LCD DATA P2 ;define LCD data port on port 1
BUSY BIT LCD.7 ;define LCD busy flag
RS BIT P0.0 ;define LCD register select pin on port 2.0
RW BIT P0.1 ;define LCD read/write pin on port 2.1
E BIT P0.2 ;define LCD enable pin on port 2.2
;*************************************************************
        ORG      00H
     
MOV P3,#0FFH ; Reset P3
MOV P1,#0FFH ; force P1 high state
PWMPIN EQU P3.0 ; Output PWM pulse
MOVELEFT EQU P3.1 ; Output indikator lamp motor putar kiri
MOVERIGHT         EQU P3.2 ; Output indikator lamp motor putar kanan
SWLEFT         EQU P1.0 ; Switch motor putar kiri
SWRIGHT EQU P1.1 ; Switch motor putar kanan
SPEEDDOWN EQU P1.2 ; Switch setting speed/ kecerahan jika output LED
SPEEDUP EQU P1.3 ; Switch setting speed/ kecerahan jika output LED
MOV TMOD,#00H ; Timer0 in Mode 0 ( untuk PWM frekuensi )
MOV R3,#0FAH ; Default untuk nilai pertama power ON ( 0 - 255 )
MOV R0,#00H
ACALL LCD_INIT

STARTUP:
        MOV A,#80H ;Force text di line1 kiri              
      ACALL COMMAND
      MOV     DPTR,#TEST
      ACALL   DISP_STRING
        MOV     A,#0C0H ;Force text di line2 kiri              
      ACALL COMMAND
      MOV DPTR,#TEST1
      ACALL   DISP_STRING

GESER :
          ACALL DELAY3
 ACALL DELAY3
 ACALL DELAY3
          MOV    A,#18H              
          ACALL  COMMAND
           INC R0
 CJNE R0,#0FH,GESER
 ACALL LCD_INIT
 ACALL DELAY3

; Main Program
MAIN:
MOV R4,#0FFH ; Force isi R4= 0FFH/255
MOV P3,#0FFH ; Reset P3
MOV P1,#0FFH ; force P1 high state
MOV   A,#80H ;Force text di line1 kiri              
      ACALL COMMAND
      MOV     DPTR,#TEST5
      ACALL   DISP_STRING
MOV     A,#0C0H ;Force text di line2 kiri              
      ACALL COMMAND
      MOV DPTR,#TEST4
      ACALL   DISP_STRING
ACALL TAMPIL
      JNB SWLEFT,LEFT ; Tunggu Swleft ditekan lanjut ke routine LEFT, jika tidak lanjut ke bawah
      JNB SWRIGHT,RIGHT  ; Idem diatas
      JNB SPEEDDOWN,DOWN ; Tunggu SPEEDDOWN ditekan lanjut ke routine DOWN, jika tidak lanjut ke bawah
      JNB SPEEDUP,UP ; Idem diatas
      JMP MAIN ; loop ke main

DOWN: ; Routine speed down
MOV   A,#80H ;Force text di line1 kiri              
   ACALL COMMAND
   MOV     DPTR,#TEST7
   ACALL   DISP_STRING
MOV     A,#0C0H ;Force text di line2 kiri              
   ACALL COMMAND
   MOV DPTR,#TEST4
   ACALL   DISP_STRING
   ACALL TAMPIL ; Menampilkan kecepatan di LCD
MOV A,R3
CJNE A,#0FFH,MAX
MOV R3,#0FFH
ACALL   DELAY
JNB         SPEEDDOWN,$
AJMP     MAIN

UP: ; Routine speed up
   MOV   A,#80H ;Force text di line1 kiri              
   ACALL COMMAND
   MOV     DPTR,#TEST6
   ACALL   DISP_STRING
   MOV     A,#0C0H ;Force text di line2 kiri              
   ACALL COMMAND
   MOV DPTR,#TEST4
   ACALL   DISP_STRING
   ACALL TAMPIL ; Menampilkan kecepatan di LCD
MOV A,R3
CJNE A,#00H,MIN
MOV R3,#00H
ACALL DELAY
JNB         SPEEDUP,$
AJMP MAIN
MAX: ; Routine speed down
INC A
ACALL DELAY
JNB          SPEEDDOWN,$
MOV R3,A
AJMP MAIN
MIN: ; Routine speed up
DEC A
ACALL DELAY
JNB         SPEEDUP,$
MOV R3,A
AJMP MAIN

LEFT:
   CLR         MOVELEFT ; Output lampu putar kiri ON
   MOV         A,#80H ;Force text di line1 kiri              
   ACALL COMMAND
   MOV     DPTR,#TEST2
   ACALL   DISP_STRING
    MOV     A,#0C0H ;Force text di line2 kiri              
   ACALL COMMAND
   MOV DPTR,#TEST4
   ACALL   DISP_STRING
   ACALL TAMPIL ; Menampilkan kecepatan di LCD
JMP PWM
   
RIGHT:
CLR MOVERIGHT ; Output lampu putar kanan ON
MOV   A,#80H ;Force text di line1 kiri              
   ACALL COMMAND
   MOV     DPTR,#TEST3
   ACALL   DISP_STRING
MOV     A,#0C0H ;Force text di line2 kiri              
   ACALL COMMAND
   MOV DPTR,#TEST4
   ACALL   DISP_STRING
   ACALL TAMPIL ; Menampilkan kecepatan di LCD

PWM:
JB         F0, HIGH_DONE ; the high section of the cycle so Jump to HIGH_DONE
MOV A,P1
CPL         A
JZ PWM_END
  MOV A,R3
SUBB A,R4
JZ LOW_DONE
DEC R4
     
LOW_DONE:
SETB F0 ; Make F0=1 to indicate start of high section
CLR  PWMPIN ; Make PWM output pin High
MOV  TH0,R4 ; Load high byte of timer with R4
SETB TR0
WAIT:
JNB TF0,WAIT
CLR TF0 ; Clear the Timer 0 interrupt flag
CLR TR0
JMP PWM ; Return from Interrupt to where
; the program came from
HIGH_DONE:
CLR F0 ; Make F0=0 to indicate start of low section
SETB PWMPIN ; Make PWM output pin low
MOV A, #0FFH ; Move FFH (255) to A
CLR C ; Clear C (the carry bit) so it does
; not affect the subtraction
SUBB A, R4 ; Subtract R7 from A. A = 255 - R4.
MOV TH0,A ; so the value loaded into TH0 + R4 = 255
SETB TR0
WAIT1:
JNB TF0,WAIT1
CLR TF0 ; Clear the Timer 0 interrupt flag
CLR TR0
JMP PWM ; Loop

PWM_END: AJMP MAIN


TAMPIL:
MOV     A,#0CBH ;Force text di line2 kiri              
      ACALL COMMAND
      MOV A,R3 ; Pindahkan data speed ke Acc
      CPL A ; Inverse Acc
      ANL A,#11110000B ; Masking Acc dengan #0F0H, disimpan di Acc
CJNE A,#00H,D1 ; Compare isi A dengan#00H, jika tidak sama lompat ke D1
      MOV A,#'0' ; Isi A #00H, Pindahkan karakter huruf 'A' Ke Acc
      ACALL DISPLAY ; Tampilkan huruf A ke LCD
      JMP NEXT
D1:
     CJNE         A,#10H,D2
     MOV A,#'1'
     ACALL DISPLAY
     JMP NEXT
D2:
     CJNE A,#20H,D3
     MOV A,#'2'
     ACALL DISPLAY
     JMP NEXT
D3:
     CJNE A,#30H,D4
     MOV A,#'3'
     ACALL DISPLAY
     JMP NEXT
D4:
     CJNE A,#40H,D5
     MOV A,#'4'
     ACALL DISPLAY
     JMP NEXT
D5:
     CJNE A,#50H,D6
     MOV A,#'5'
     ACALL DISPLAY
     JMP NEXT
D6:
     CJNE A,#60H,D7
     MOV A,#'6'
     ACALL DISPLAY
     JMP NEXT
D7:
     CJNE A,#70H,D8
     MOV A,#'7'
     ACALL DISPLAY
     JMP NEXT
D8:
     CJNE A,#80H,D9
     MOV A,#'8'
     ACALL DISPLAY
     JMP NEXT
D9:
     CJNE A,#90H,DDA
     MOV A,#'9'
     ACALL DISPLAY
     JMP NEXT
DDA:
     CJNE A,#0A0H,DDB
     MOV A,#'A'
     ACALL DISPLAY
     JMP NEXT
DDB:
     CJNE A,#0B0H,DDC
     MOV A,#'B'
     ACALL DISPLAY
     JMP NEXT
DDC:
     CJNE A,#0C0H,DDD
     MOV A,#'C'
     ACALL DISPLAY
     JMP NEXT
DDD:
     CJNE A,#0D0H,DDE
     MOV A,#'D'
     ACALL DISPLAY
     JMP NEXT
DDE:
     CJNE A,#0E0H,DDF
     MOV A,#'E'
     ACALL DISPLAY
     JMP NEXT
DDF:
     MOV A,#'F'
     ACALL DISPLAY

NEXT:
     MOV A,R3
     CPL A
     ANL A,#00001111B
     CJNE A,#00H,DA1
     MOV A,#'0'
     ACALL DISPLAY
     JMP NEXT1
DA1:
     CJNE A,#01H,DA2
     MOV A,#'1'
     ACALL DISPLAY
     JMP NEXT1
DA2:
     CJNE A,#02H,DA3
     MOV A,#'2'
     ACALL DISPLAY
     JMP NEXT1
DA3:
     CJNE A,#03H,DA4
     MOV A,#'3'
     ACALL DISPLAY
     JMP NEXT1
DA4:
     CJNE A,#04H,DA5
     MOV A,#'4'
     ACALL DISPLAY
     JMP NEXT1
DA5:
     CJNE A,#05H,DA6
     MOV A,#'5'
     ACALL DISPLAY
    JMP NEXT1
DA6:
     CJNE A,#06H,DA7
     MOV A,#'6'
     ACALL DISPLAY
     JMP NEXT1
DA7:
     CJNE A,#07H,DA8
     MOV A,#'7'
     ACALL DISPLAY
     JMP NEXT1
DA8:
     CJNE A,#08H,DA9
     MOV A,#'8'
     ACALL DISPLAY
     JMP NEXT1
DA9:
     CJNE A,#09H,DAA
     MOV A,#'9'
     ACALL DISPLAY
    JMP NEXT1
DAA:
     CJNE A,#0AH,DAB
     MOV A,#'A'
     ACALL DISPLAY
    JMP NEXT1
DAB:
     CJNE A,#0BH,DAC
     MOV A,#'B'
     ACALL DISPLAY
    JMP NEXT1
DAC:
     CJNE A,#0CH,DAD
     MOV A,#'C'
     ACALL DISPLAY
    JMP NEXT1
DAD:
     CJNE A,#0DH,DAE
     MOV A,#'D'
     ACALL DISPLAY
     JMP NEXT1
DAE:
     CJNE A,#0EH,DAF
     MOV A,#'E'
     ACALL DISPLAY
     JMP NEXT1
DAF:
     MOV A,#'F'
     ACALL DISPLAY
NEXT1:  
NOP
RET  

DELAY: ; Routine delay
MOV R5,#001H
MOV R6,#001H
DELAY1:
DJNZ R5,DELAY1
DJNZ R6,DELAY1
RET

DELAY2: ; Routine delay
MOV R5,#0FFH
MOV R6,#0FFH
DELAY3:
DJNZ R5,DELAY3
DJNZ R6,DELAY3
RET



; Routine inisialisasi untuk LCD
;**************************************************************
LCD_INIT:
        MOV      A,#38H                ;2 line 5x7
        ACALL    COMMAND  
        MOV      A,#0CH                ;LCD on cursor off
        ACALL    COMMAND
        MOV      A,#01H                ;clear LCD
        ACALL    COMMAND
        MOV      A,#06H                ;shif cursor right
        ACALL    COMMAND
Ret

;=============================================================
COMMAND:
        ACALL READY ;is LCD ready?
        MOV LCD,A ;issue command code
        CLR RS ;RS=0 for command
        CLR RW ;R/W=0 to write to LCD|
        SETB E ;E=1 for H-to-L pulse
        CLR E ;E=0 ,latch in
        RET
;=============================================================
DISPLAY:
        ACALL READY ;is LCD ready?
        MOV LCD,A ;issue data
        SETB RS ;RS=1 for data
        CLR RW ;R/W=0 to write to LCD
        SETB E ;E=1 for H-to-L pulse
        CLR E ;E=0 ,latch in
        RET
;=============================================================
READY:
        SETB BUSY ;make P0.7 input port
        CLR RS ;RS=0 access command reg
        SETB RW ;R/W=1 read command reg
;read command reg and check busy flag
BACK:
        CLR E ;E=1 for H-to-L pulse
        SETB E ;E=0 H-to-l pulse
        JB BUSY,BACK ;stay until busy flag=0
        RET
;=============================================================
DISP_STRING:
   CLR A ;A=0
MOV R7,#00H ;R7=0
NEXT_CHAR:
INC R7 ;R7+1
MOVC A,@A+DPTR
ACALL DISPLAY
  MOV A,R7
CJNE R7,#0FH,NEXT_CHAR
RET          
;=============================================================
TEST: DB "PWM BASIC TEORI"
TEST1: DB "  MICROTECH    "
TEST2: DB "  PUTAR KIRI   "
TEST3:    DB "  PUTAR KANAN  "
TEST4:    DB "KECEPATAN :    "
TEST5:    DB " TUNGGU INPUT  "
TEST6: DB "    SPEED UP   "
TEST7: DB "  SPEED DOWN   "
 ;=============================================================


END


Menghitung Duty Cycle :



           
           




           
            

Tidak ada komentar:

Posting Komentar