Proton+ 16F628 Dimmer Devresi (Usart, Timer0 ve RB0 kullanarak)

Başlatan gtekdemir, 18 Şubat 2012, 21:48:47

gtekdemir

   
Üzerinde çalıştığım bir projenin dimmer kısmını sizinle paylaşmak istedim. Verdiğim şemasının üst kısmında dimmer devresi bulunmaktadır alt kısımda ise usart ile veri gönderen 16f628 bulunmaktadır. Siz isterseniz RF ile uzaktan kontrol yada bilgisayarın com portunu kullanarak lamba parlaklığını kontrol edebilirsiniz. Triyak olarak BT138 kullanabilirsiniz.

Devrede üç tane kesme kullanılmıştır;

1- İstenilen parlaklık değerinin elde edilmesi için USART Receiver kesmesi. Işık şiddeti ayarlanması için usart ile 1Byte büyüklüğünde bir veri gelmesi gerekir (3 ile 40 değerleri arasında )

2- RB0 kesmesi ile faz açısının 0 olduğu anlar yakalanır böylece triyak tetiklemesi için gereken gecikmenin başlayacağı nokta belirlenmiş olur.

3- Timer0 kesmesi ile triyak tetiklemesi için gereken gecikme sağlanır ve 100us triyak tetiklenir. Ardından 10ms sonra yani negatif alternansta tekrardan 100us triyak tetiklenerek bir cycle tamamlanmış olur.


Arkadaşlar gözden kaçırdığım bir hata dolayısı ile devre negatif alternanslarda triyağı tetiklemiyordu. Şema üzerinde de biraz değişiklik yaptım son hali şöyle.






'****************************************************************
'*  Name    : UNTITLED.BAS                                      *
'*  Author  : [select VIEW...EDITOR OPTIONS]                    *
'*  Notice  : Copyright (c) 2011 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 16.01.2012                                        *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
Device 16F628A
Config INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, BODEN_OFF, CP_OFF, MCLRE_ON, LVP_OFF
Xtal 4

Declare Hserial_Baud  = 9600       ' Set baud rate to 9600
Declare Hserial_RCSTA = %10010000  ' Bit7 SPEN: Serial Port Enable bit 
                                   ' Bit4 CREN: Continuous Receive Enable bit 
Declare Hserial_TXSTA = %00100100  ' Bit5 TXEN: tx enable , Bit2 BRGH: High Baud Rate Select = 1
Declare Hserial_Clear = On         ' Optionally clear the buffer before receiving
Declare Hserial_SPBRG = 25         ' 4MHZ osilatör ve 9600 baud rate için SPBRG=25 bkz.datasheet (BRGH=1 ise)

TRISA=%00000000
TRISB=%00000011             'RB0 zero cross detect pin, RB1 Usart RX pin

PORTA=0
PORTB=0

CMCON=7

Symbol out1 = PORTA.2     'Triyak çıkışı
Symbol main_led = PORTA.3 'Ana program ledi

Dim gecikme As Word      'Dimmer gecikme değişkeni
Dim t    As Byte         'timer0 için artım değişkeni
Dim t10  As Byte         'timer0 ile 10ms gecikme
Dim k As Bit             'İkinci triyak gate tetiklemesi için k biti

Dim veri1 As Byte        'usart receiver ile gelen veri değişkeni

t10=45           '10ms için t10 değeri yaklasık 50 olmalıdır.(50*200us=10000us=10ms) Gecikmeleden dolayı 45 
gecikme=5000    '%50 parlaklık için düşen kenardan sonra ilk anda 5ms gecikme
'-----------------------------------------------------------------------------


Symbol INTF = INTCON.1      'rb0 external interrupt flag
Symbol T0IF = INTCON.2      'Timer0 interrupt flag
Symbol INTE = INTCON.4      'rb0 external interrupt enable
Symbol T0IE = INTCON.5      'Timer0 interrupt enable bit
Symbol PEIE = INTCON.6      'Peripheral(çevresel) interrupt enable bit usart kesmesi için
Symbol GIE  = INTCON.7      'global interrupt enable


Symbol RCIE = PIE1.5        'Receiver interrupt enable bit
Symbol RCIF = PIR1.5        'Receiver interrupt flag

Symbol PS0  = OPTION_REG.0  'Timer0 prescaler0      1 }
Symbol PS1  = OPTION_REG.1  'Timer0 prescaler1      0 } Şeklinde kurularak 1/4 prescaler ayarlanacak 
Symbol PS2  = OPTION_REG.2  'Timer0 prescaler2      0 }
        
        PS2=0 : PS1=0 : PS0=1

Symbol PSA  = OPTION_REG.3  'Prescaler assignment bit (0=Timer0 için, 1=WDT için)
        PSA=0
        
Symbol T0CS = OPTION_REG.5  'Timer0 clock source bit (0=İnternal instruction cycle clock)
        T0CS=0

Symbol INTEDG=OPTION_REG.6  'RB0 interrupt falling edge=0 or rising edge=1
        INTEDG=0
              
GIE=0
INTE=1
RCIE=1
PEIE=1
T0IE=0
GIE=1

On_Interrupt GoTo int       'Hardware Interrupt oluştuğunda int etiketine dallan

TMR0=206        'TMR0=206 yapıldı 256-206=50 olur. 
                '[Fosc(4Mhz)/4]=(1) * [Prescaler 1/4]=(4) * (50) = 200us çözünürlük sağlandı

'/////////////////////////////////////////////////////////////////////////////
'--------------------------------ANA_PROGRAM----------------------------------

main:

    DelayMS 100
    Toggle main_led
    

GoTo main


'/////////////////////////////////////////////////////////////////////////////////     
'-----------------------------------------KESME RUTİNİ----------------------------

int:
GIE=0       'Global interrupt disable edildi

'------------------------------------------USART Receiver kesmesi-----------------

PEIE=0                     'Peripheral interrupt enable bit
RCIE=0                     'Receiver interrupt enable bit
                           
If RCIF=1 Then
   
    HSerIn 100,timeout,[veri1]
    gecikme=veri1*200          '600<=gecikme<=8000 olduğu için gelen veri(3-40 arasında) 200 ile çarpılır 
   
    
    If gecikme>8000 Then    'Min parlaklık degeri ayarı, değer arttıkça daha az parlaklık sağlanabilir 
        gecikme=8000
    EndIf
   
    If gecikme<600 Then     'Max parlaklık degeri ayarı, değer azaldıkça daha fazla parlaklık sağlanabilir    
        gecikme=600
    EndIf
    
    timeout:
    RCIE=1                     'Receiver interrupt enable bit
    PEIE=1                     'Peripheral interrupt enable bit
    RCIF=0
   
EndIf                      
                           
'------------------------------Zero Cross Detect-RB0 kesmesi--------------------------

INTE=0              'RB0 kesmesini disable et

If INTF=1 Then      'RB0 kesmesi oluştuysa INTF=1 ise

    t=gecikme/200   'Gecikme değeri timer0 kesmesi için t değişkenine yüklendi
                    'Örn: 5000us gecikme için t değeri 5000/200=25 bulunur
                    'T0IF 25 defa sağlandığında 5000us gecikme sağlanmış olur. Böylece %50 lamba parlaklığı sağlanır.
                      
    T0IE=1          'Timer0 interrupt enable
    TMR0=206        'TMR0=206 yapıldı 256-206=50 olur. 
                    '[Fosc(4Mhz)/4]=(1) * [Prescaler 1/4]=(4) * (50) = 200us çözünürlük sağlandı
            
    
    INTF=0          'RB0 kesmesi bayrağını sıfırla INTF=0
    INTE=1          'RB0 kesmesini enable et
        
EndIf


'Zero cross algılandı, artık Timer0 aktif edilecek
'------------------------------------------TIMER0 kesmesi----------------------------

T0IE=0              'Timer0 kesmesini disable et
TMR0=206            'TMR0=206 yapıldı 256-206=50 olur. 
                    '[Fosc(4Mhz)/4]=(1) * [Prescaler 1/4]=(4) * (50) = 200us çözünürlük sağlandı

If T0IF=1 Then      'Timer0 kesmesi olustuysa T0IF=1 ise
        
        '_____________________________________________________________________
        Dec t             't değerini 1 azalt (ilk tetikleme için) 
    
        If t=0 Then       't0 değeri 0 olduysa ilk triyak tetiklemesini gönderilecek 
           
           out1=1
           DelayUS 100    'Triyak gate girişine 100us süre ile tetikleme gönder
           out1=0
           k=1            'İlk tetikleme gönderildi, ikincisinin gönderilebilmesi için k=1
           
        EndIf
        '_____________________________________________________________________
        
        If k=1 Then          'k değeri 1 ise yani ilk triyak tetiklemesi gönderildiyse şimdi ikinci tetikleme gönderilecek
        
            Dec t10           't10 değerini 1 azalt (10ms ikinci tetikleme için)
            
            If t10=0 Then     't10 değeri 0 olduysa ikinci triyak tetiklemesi gönder (negatif alternans için) 
               
               out1=1
               DelayUS 100    'Triyak gate girişine 100us süre ile tetikleme gönder
               out1=0
               
               k=0           'İkinci tetikleme gönderildi k sıfırlanacak
               t10=45        '10ms için t10 değeri ~50 olmalıdır. (50*200us=10000us=10ms)
            EndIf
       
        EndIf    
        '_____________________________________________________________________
        
T0IF=0
T0IE=1
EndIf
'--------------------------------------------------------------------------------------
                 

Context Restore

End         'program sonu

Maxim


gtekdemir

Evet gerçak hayatta oldukça güzel çalışıyor hatta şu anda devreyi iki lambayı kontrol edebilecek şekilde uyarlıyorum ama hassas zamanlamalardan dolayı biraz zor olacak gibi. Devre gerçekte çalışıyor fakat proteus ile simülasyon yapamadım. Şöyle bir hata alıyorum ;



Maxim

ac 220 volttan 100k ile direk pice girmişsiniz o nasıl oluyor ?

önceki şemada da 12 volt trafonun çıkışında 1 tane diyot vardı sanırım
pice yarım dalga 12v dc vermiştiniz ?

2. picten diğerine seri giden data nedir ne işe yarar ?

ete

gtekdemir,

Güzel bir proje tebrik ederim.
Gerçekte çalıştığını söylemişsiniz ama bazı tuhaflıklar görüyorum. Bunlar çalışmaya engel teşkil etmiyormu merak ettim.
Birincisi, 220V AC den 100K ile alınan sıfır geçiş sinyali pic pinine 10V un üzerinde bir voltaj yükleyecektir bu ise pinin kısa zamanda bozulmasına sebep olacaktır. Orada benim denemelerimde 1M kullanılması bile yeterli seviyeyi sağlamıyor daima yüksek geliyor voltaj. Bir gerilim bölücü yapılması daha uygun olurdu sanırım.

İkincisi Kesme kısmında bu kadar fazla kod olması triac tetiklemesini etkilemiyormu?. Yani lambada az da olsa tireme gibi bir etki yaratmıyormu acaba?
Örneğin USART kesmesi kısmında 100ms lik veri bekleme süresi mevcut. Bu istenen veri gelmez ise programın orada beklemesi gereken süredir. Peki program orada 100ms beklerse her 10ms de bir olması gereken sıfır geçiş kesmesi nasıl oluşacak. Budamı bir etki yaratmıyor. ?
Gerçekten enteresan. Benim daha önce bir çok kereler deneyip sorun yaşadığım kısımlar için siz gayet güzel çalışıyor lafını kullanmışsınız merak ettim gerçekten.

Programın main kısmında 100ms lik gecikme kesme oluşmasında etkili olmuyordur herhalde PBP olsa idi olurdu. AMa bu Proton diyeceksiniz donanım kesmesi bu işi önlüyor her halde. Hadi bunu geçelim,

Kesme kısmında ;
En başta GIE=0 denilmiş ama kesmeden çıkarken bu yeniden set edilmemiş.  Peki global kesmeleri yeniden kim set ediyor? Context Restore olsa gerek herhalde.

Kesmeye kimin sebep olduğuna bakmadan direk
PEIE=0                     'Peripheral interrupt enable bit
RCIE=0
komutları ile USART ve TMR1 kesme lerini (PEIE=0 vererek) iptal ediyorsunuz ve daha sonra USART kesmesi oluşmuşmu diye bakıyorsunuz.
Oluşmamış ise bu iki bit sıfır olarak kalıyor ve o şekilde kesmeden çıkıyorsunuz. Bu durumda yalnızca PortB.0 kesmesi açık kalıyor. Nasıl oluyorda bu sistem düzgün çalışıyor? Yani nasıl oluyorde USART kesmesi açık değil iken gelen bilgiler sorunsuzca alınabiliyor?

Aynı hata aslında diğer kesmelerde de mevcut.
PortB.0 kesmesi kısmında INTE=0 ile başlıyor ve daha sonra B.0 kesmesi oluşmuşmu diye bakıyorsunuz. Oluşmamış ise INTE=0 da kalıyor maalesef. Bana göre bir kesmeyi aktif eden biti sıfırlamak için önce o kesme oluşmuşmu bakmak ve ondan sonra sıfırlamak gerekirdi. Aksi taktirde sıfırladığınız biti sonradan yeniden set etmeniz gerekirdi diye düşünüyorum.
Bu sistemin nasıl çalışıtğını gerçekten anlamadım. Proton da iyi değilim. Acaba bu disable edilen bitler kesmeden çıkarken "Context Restore" komutu ilemi set ediliyorlar.?
Yada benmi çok negatif bakıyorum olaya,  kaçırdığım noktalarmı var acaba?. Açıklarsanız sevinirim.

Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

gtekdemir

Dikkat ederseniz AC kaynak 220v değil 22v , ben gerçek hayatta 220V için 1M direnci faza bağladım ve portb.0' a girdim, nötr ile devre şasisini birleştirdim ve bu haliyle devre çalıştı. Daha sonra ise pic ile şebeke voltajının yalıtılması gerektiğinden 220V ile pic arasında pc817 opto kullandım.


İkinci pic' ten gelen seri data ise 1 byte büyüklüğünde parlaklık bilgisidir.

gtekdemir

Alıntı yapılan: ete - 19 Şubat 2012, 12:31:05
Kesme kısmında bu kadar fazla kod olması triac tetiklemesini etkilemiyormu?. Yani lambada az da olsa tireme gibi bir etki yaratmıyormu acaba?
Örneğin USART kesmesi kısmında 100ms lik veri bekleme süresi mevcut. Bu istenen veri gelmez ise programın orada beklemesi gereken süredir. Peki program orada 100ms beklerse her 10ms de bir olması gereken sıfır geçiş kesmesi nasıl oluşacak. Budamı bir etki yaratmıyor. ?
Gerçekten enteresan. Benim daha önce bir çok kereler deneyip sorun yaşadığım kısımlar için siz gayet güzel çalışıyor lafını kullanmışsınız merak ettim gerçekten.

Programın main kısmında 100ms lik gecikme kesme oluşmasında etkili olmuyordur herhalde PBP olsa idi olurdu. AMa bu Proton diyeceksiniz donanım kesmesi bu işi önlüyor her halde. Hadi bunu geçelim,

Bu sistemin nasıl çalışıtğını gerçekten anlamadım. Proton da iyi değilim. Acaba bu disable edilen bitler kesmeden çıkarken "Context Restore" komutu ilemi set ediliyorlar.?
Yada benmi çok negatif bakıyorum olaya,  kaçırdığım noktalarmı var acaba?. Açıklarsanız sevinirim.

Ete

Merhaba ETE hocam, öncelikle sayenizde çok şey öğrendim bunun için teşekkür ederim.

Ana program içindeki 100ms gecikme dediğiniz gibi proton+ hardware interrupt desteklediği için problem oluşturmuyor.

Kesme kısmında kullandığım kodların uzunluğu biraz zamanlama kaymasına neden oluyor fakat çok önemli değil. Çıkış sinyalini gerçek devrede osiloskop ile ölçüp gözlemledim herhangi bir problem yok.

Usart kesmesindeki 100ms timeout değeri bencede fazla ama bu zamana kadar hiç timeout olmadı :) 5ms den fazla olmamalı diye düşünüyorum.

Context Restore komutu ile disable edilen tüm kesme kaynakları enable edilmektedir.




F.T

Kesme içinde tetikleme sinyali artı ve eksi için yapmışsın.diğer işlemler için çok bir süre kalıyormu.kesmede fazla zaman harcaması olmuyormu.ben sıfır geçişin köprü çıkışındaki sinyal ile her iki alternans için yapılmasının daha uygun olduğunu düşünüyorum.
Hakk şerleri hayr eyler Zannetme ki gayr eyler Ârif anı seyreyler Mevlâ görelim neyler Neylerse güzel eyler.

gtekdemir

Alıntı yapılan: ferittt - 19 Şubat 2012, 14:05:55
Kesme içinde tetikleme sinyali artı ve eksi için yapmışsın.diğer işlemler için çok bir süre kalıyormu.kesmede fazla zaman harcaması olmuyormu.ben sıfır geçişin köprü çıkışındaki sinyal ile her iki alternans için yapılmasının daha uygun olduğunu düşünüyorum.

Benim devremin beslemesi smps olduğu için trafo kullanmadım. Zero cross detect için kullanacağım malzemenin en az sayıda olmasını istedim ve 220v input için PC817 opto kullandım. Kesme rutininde harcadığım zaman ise sorun oluşturmuyor.

thetrueman

Hi, Can you post source files? I just want to learn the technique you used. Thanks.