7 Kasım 2019 Perşembe

proton basic usart kesmesi hakkında bilgiler

Etepic forumunda inventor rumuzlu üyenin proton basic usart kesmesi hakkında yapmış olduğu paylaşımlara aşağıdaki linkten ulaşabilirsiniz. Bilgileri bloğada ekliyorum, ete hocanın usart kesmesi ile ilgili bilgileri de aşağıda mevcut.

https://www.etepic.com/index.php?topic=911.0


inventor yazmış:
Merhaba arkadaşlar,

Son bir kaç haftadır proton ile yazdığım bir programla uğraşıyorum. İsiste sorunsuz çalışmasına rağmen gerçek devrede çalışmayan bir proje. Bu program ile uğraşırken
protonda ne kadar sorun çıkabileceğini de görmüş oldum. Kısa programlar için sıkıntı çıkarmayan pek çok konu uzun ve ağır programlarda sorun yaratabiliyor.
Burada karşılaştığım sorunlarla ve çözümleri ile ilgili bilgileri paylaşayım dedim.

İlk olarak protonda kesme konusuna değinelim. Çoğumuz programlarımızda kesme rutinini programımızın en altına yazıyoruz. Bu belki pbp dan kalan bir alışkanlık.
Kısa döngülerde bu alışkanlık protonda da kullanılabiliyor. Ama portb kesmesi ile usart kesmesini bir arada kullandığınız zaman kesinlikle KESME rutininin programın
en üstünde olması gerekiyor. Yani programınıza BASLA ile değil KESME ile başlamanız gerekiyor. KESME: satırının hemen üstüne GOTO BASLA yazarak normal çalışma
yaptırabilirsiniz. Eğer bunu yapmazsanız büyük ihtimalle benim yaşadağım bir sıkıntıyı yaşarsınız. Programınızda kullandığınız bütün DelayMs komutlarında programınız
USART kesmesi yapar. Bununla da kalmaz print at 1,1,"........" gibi komutları peş peşe kullandığınızda da kesmeye girecektir. Bu durumlarda tek yapmanız gereken KESME
rutinini programın en üstüne almak olacaktır. Bu konu protonun kendi veb sitesinde ve manualde de öneriliyor.Örnek verelim;
-----------------------------------------------------------------
GoTo BASLA
 
KES:             
Context Save
        HSerIn 5,CIK,[Wait ("~"),BILGIAL]
        HSerOut [BILGIAL]
        A=1           
CIK:
    TEMP=RCREG   ' USART Kesme bayragi sifirlandi (RCIF)
Context Restore

BASLA:   
    If A=1 Then HESAP
-----------------------------------------------------------------
Diğer bir konu da Temp=RCREG konusu. PBP da karşılaşmadığım ama protonda zaman zaman sorun çıkaran bir konu var. Temp=RCREG komutunu programın başına eklemeniz gerekiyor.
Aksi halde RCRIF set olarak geliyor. Ve sistem kesmeye gitmiyor. Genelde bizler RCREG registerini  KESME rutini içerisinde sıfırlıyoruz. RCRIF ilk açılışta SET olarak
gelince program kesmeye girmiyor. Girmeyince RCREG boşaltılamıyor ve siz usart kesmesi olacak diye bekliyorsunuz. RCRIF in niye set olarak geldiğini hala anlamış değilim
ama PBP da yazdığım bir programı protonda yazınca yine set olarak başladı. Aslında bir inceleme yapmak lazım bu konuda. Örnek verelim;

ORAN=ERead 10
If ORAN>2 Then ORAN=1
Print  $fe,1
DelayMS 200
I=0 : BILGIAL=0 : VIN=0 : VCIK=0 : A=0   : EN_Pin=0
TEMP=RCREG
'****************************************************************************************************************
GoTo BASLA
 
KES:             
Context Save
        HSerIn 5,CIK,[Wait ("~"),BILGIAL]
        HSerOut [BILGIAL]
-----------------------------------------------------------------     

Protonda kesmeleri ayarlarken de uyulması gereken kurallar var. Mesela ilk kural sıralama. Kesme ile ilgili registerları ayarlarken ilk olarak genel kesmeleri kapatmanız
gerekiyor. Sonra sırası ile önce SW kesmelerini ,sonrasında da HW kesmeleri ayarlayıp en son olarak genel kesmeyi açmalısınız.

-----------------------------------------------------------------
Symbol GIE  =INTCON.7   'genel interruptlar  aciyor
Symbol PEIE =INTCON.6   'Cevresel kesmeleri  aciyor
Symbol INTE =INTCON.4   'RB0 Kesmesini aciyor
Symbol INTF =INTCON.1   'RB0 kesme bayragi
Symbol RCIE =PIE1.5     'USART kesmesini aciyor
Symbol RCIF =PIR1.5     'USART Receive interrupt flag bit
GIE=0     'Butun kesmeler kapalı
INTE=1    'RB0 kesmesi devrede     
RCIE=1    'USART kesmesi devrede
PEIE=1    'Cevresel kesmeler devrede
GIE=1     'Butun kesmeler devrede
-----------------------------------------------------------------

Başka bir konu da On interrupt ile On_interrupt arasındaki fark. Genelde bilinen bir konu ama ben yine de bildiklerimi aktarayım. pbp da tek olan komut
On interrupt Goto .... iken bu komut protonda üç adet. İlki PBP ile aynı.
On interrupt Goto ......
Bu Software kesmesi oluyor. Protonda donanımsal kesme var. Bunu iki komut satırı ile yazabiliyoruz.
on_interrupt .......   ya da
on_hardware_interrupt ........
Burada şunu bilmek gerekiyor. Eğer yazılımsal kesme kullanıyorsak KESME rutininin hemen üstüne Disable komutunu ekliyoruz. Kesmeden çıkarken de eneble resume diyerek
çıkıyoruz. Bu pbp ile aynı. Donanımsal kesmede ise kesme rutinine girince Context Save diyoruz. Çıkarkende Context Restore yazıp çıkıyoruz. Manuale bakınca bu komutların
sadece 16f serisi için geçerli olduğunu yazmışlar. Her iki kesmeye de örnek verirsek;

-----------------------------------------------------------------
Disable
KES:             
        HSerIn 5,CIK,[Wait ("~"),BILGIAL]
        HSerOut [BILGIAL]
        A=1           
CIK:
    TEMP=RCREG   ' USART Kesme bayragi sifirlandi (RCIF)
enable
resume

-----------------------------------------------------------------
KES:             
Context Save
        HSerIn 5,CIK,[Wait ("~"),BILGIAL]
        HSerOut [BILGIAL]
        A=1           
CIK:
    TEMP=RCREG   ' USART Kesme bayragi sifirlandi (RCIF)
Context Restore
-----------------------------------------------------------------
Başka bir konu da Hserout komutunun kullanımı. Bu konu PBP için de geçerli. ETE hoca da dile getiriyor bu konuyu. Göndereceğiniz komutun sonuna mutlaka başka bilgilerde
ekleyin. Aksi halde veri zaman zaman eksik gidebiliyor.Aşağıdaki kod da 10,13 bu amaçla kullanıldı.
-----------------------------------------------------------------
GONDER:
    EN_Pin=1
    GoSub GECIKME
    KOD=118
    HSerOut [Rep $AA\5,Rep $00\5,Rep $FF\5]'uyandirma sinyali preamble
    HSerOut ["~",KOD,10,13]
    EN_Pin=0       
    Return
-----------------------------------------------------------------

Proton Delay komutlarında beklerkende donanım kesmesine girebiliyor. Bunu da aklınızın bir köşesinde bulundurun. Örneğin aşağıdaki programda 10 sn lik bekleme sırasında
gelen bir usart bilgisi anında kesmeye neden oluyor. Kesme işi tamamlandıktan sonra zaman sayacı kaldığı yerden saymaya devam ediyor.

-----------------------------------------------------------------
BASLA:
    DelayMS 10000
    '****  olcme talebi gelince yapilacaklar  ****   
     If A=1 Then
        A=0
        RCIE=0
        BILGIAL=0
-----------------------------------------------------------------
Başka bir konu da High Low komutları ile ilgili. Sanırım bu konu PBP içinde geçerli olmalı. Çoğumuz pinlerin durumunu değiştirmek için bu komutları kullanıyoruz.
Gözden kaçırdığımız nokta ise manuallerde belirtilmiş aslında. Bu komutlar kullanıldığı anda ilgili pin çıkış yapılır  diyor. Bu komutu kullanmak için zaten pini çıkış
yapmış oluyoruz ne fark eder gibi bir şey aklınıza gelebilir. Neyin farkettiğini kullandığınız picin hafızası dolmaya başladığında görüyorsunuz. Örnek verecek olursak;

-----------------------------------------------------------------
basla:
    High PORTA.1
   End

-----------------------------------------------------------------

Proton ile  derlenen yukarıdaki komutların derleme sonrasında Assembler karşılığı şu şekilde oluyor;
-----------------------------------------------------------------
basla
        bsf STATUS,5
        bcf TRISA,1
        bcf STATUS,5
        bsf PORTA,1
        end
-----------------------------------------------------------------

High Low komutları yerine porta.1=1 komutunun assembler karşılığına bakalım;
-----------------------------------------------------------------
basla
        bsf PORTA,1
        end
-----------------------------------------------------------------

 
Ete yazmış:
RF olsun kablulu alışverişler olsun hepsi için geçerli bir altın kural vardır.
Bu verici mesajını verdiği zaman alıcıda onu almaya hep haır halde beklemelidir.
Alıcı programlarda kullanılan pause ler programın orada çakılıp kalmasına sebep olur ve o anda veri gelmiş ise alıcının bu veriyi kaçırması da kaçınılmaz olur. Zira alma işini senin SERIN komutun yapacak. Program henüz SERIN komutuna gelemeden verici veriyi aktarmış ise başka bir sonuç beklenmesi doğru olmaz.

Çözüm USART kesmesi kullanmaktadır. USART kesmesi şu işe yarar. Programın bir yerde bekliyor ise ve aynı anda veri geliyor ise geri planda çalışan Pic içindeki kendi programı (ROM diyelim) veriyi alır ve Buffera (RCREG) koyar ve kesme bayrağını kaldırarak programın otomatikman alma rutinine yönlendirilmesini sağlarki tamda istediğimiz budur. Böylece program derhal alma işlemine girişir ve gelen verileri alır.

Serin komutu otomatikman programı da bloke eder ve yaklaşık 65 ms orada veri gelmesini bekler. Gelmiyor ise 65 ms sonra komutu atlar ve alttaki satıra geçer. Alttaki satırlarda Delayms 1000 komutun varki bütün sorunu bu komut çıkartıyor bence.
Bu gecikmeleri bedava dağıtılıyor gibi kullanmayın. Mantıklı yerlerde gereken süreleri verin.
O gecikmeyi kaldırıp yeniden dene diyeceğim ama yinede tekrarlıyorum. Kesin çözüm USART kesmesinde dir.
Ete



Burada biraz daha detay vermeye çalışacağım.
USART kesmesi için kullandığın 16F628A işlemcinin USART modülünü ve portunu kullanman gerekiyor.
Bu şu demek oluyor. PORTB.1 pininden Alış yani RX yapacaksın. PORTB.2 pininden ise TX yani gönderme yapacaksın. USART portunu kullandınmı bir kere bu iki pin port tarafından bloke edilir ve bu pinleri başka amaçla kullanamazsın. Örnek vereyim Bir programda yalnızca TX yapıyorsun diyelim RX pinini hiç kullanmıyor olsan bile onu başka amaçla kullanamazsın. En azından kullanmadığın bu pini boş bırakman gerekir.

USART portunu aktive etmen için ;
KodSeç
Declare hserin_pin PORTB.1Declare Hserout_pin PORTB.2    Declare Hserial_Baud 9600      Declare Hserial_RCSTA 90h       Declare Hserial_Clear OnDeclare Hserial_TXSTA 20hkomut satırlarını programın başına eklemen gerekiyor.
RX pini ise TRISB registerinde giriş olarak tanımlanmalıdır.

Bütün bunları yaptıktan sonra,
Şimdi gelelim TX yani verici programına,
Daha öncede belirtmiştim. RF sistemlerinde senkron tutturmak önemlidir. Yani verici veriyi verirken alıcıda alma konumunda hazır olmalıdır. Bu programların birinde en ufak bir gecikme olması durumunda veren vereceğini verirken alacak olan senkron tutturamadığı için alması gerekenleri alamaz.

Senkron tutturmanın en önemli şartlarından birisi Verici tarafında veri yollanmadan önce alıcı tarafındaki USART portunu uyandırmak ve programı kesmeye sevk etmek için bir Preambl denilen ön uyandırma sinyali gönderilir.
       HSEROUT [REP$AA\5,REP$00\5,REP$FF\5]'uyandirma sinyali preambl
       HSEROUT ["E","T","E",VERI1,VERI2,VERI3]
Burada ilk satırda verilen bilgiler işin uyandırma kısmıdır. ALıcı bu bilgileri ilk olarak aldığında hemen porta bilgi gelmeye başladığını anlar ve programı kesme kısmına sevk eder.
Veriler ie bir paket halinde gönderilmeli ve başına bir işaret koyularak alıcının önce bu işareti yakalaması sağlanmalıdır.
Bu örnekte işaret ETE bilgisidir. Peşinden Veri1, Veri2, Veri3 şeklinde Byte bilgisi olarak veriler sıralanır. Burada şu noktaya işaret etmek isterim. TX tarafı kaç byte yollamış ise alıcı tarafında da o kadar sayıda byte alınmalıdır. Bir taraf eksik olursa yine senkron kayabilir.
Burada görüleceği üzere veri bir paket şeklinde verilir. Her zaman TREN vagonlarına benzetirim bu sistemi.
Lokomotif işaretçi konumundadır. Vagonlar ise verileri temsil eder. Birisine vagonları bul dediğinizde o kişi önce lokomotifi arayarak peşinden gelen vagonları bulmalıdır. İşin temelinde bu fikir yatıyor. Şayet işaretçi kullanmazsanız alan taraf veriye ortadan girer ve hiç bir tutarlı bilgi alamaz.
TX tarafında kesme kullanmaya gerek yoktur. Çünki ne zaman veri yollanacağını siz belirlersiniz ve direk yukarıdakine benzer satırlar ile veriyi yollarsınız.
İşin alıcı kısmında ise Kesme kullanılması zorunludur. Ancak bu şekilde senkron yakalanır. Bu işi Serin komutu ilede yapabilirsiniz ama programda,
KodSeç
Basla:SerIn PORTB.1,84,[varl]
goto 
basla 
komutlarındanbaşka birşey olmaması gerekir. Böylece program yalnızca gelen veriye odaklanmış olur.
USART kesmesi kullanılırken ise program başka işlerle uğraşırken geri planda veri alınır ve program bu alınan veriyi değerlendirir. İşin güzel yanı buradadır.
Alıcı tarafında USART kesmesi açmak için;
Önce INTCON registerine INTCON=%11000000 değeri verilerek global kesmeler ve peripheral kesmeler aktive edilir.
Ardından USART kesmesi için PIE1 registeri 5 nolu biti (RCIE) set edilir . Bu Usart kesmesini aktive eder. Kesme oluştuğunda kesme bayrağı set edilir. Bu bayrak PIR1 registeri 5 nolu biti (RCIF) ile kontrol edilir. Önceden oluşmu kesmelerde set edilmiş kesme bayrağı ihtimaline karşın önce bu bayrak sıfırlanır. PIR1.5=0. Ancak bu bayrak aslında programcı tarafından direk ulaşılabilen bir bit değildir. Üretici (microchip) bunu otomatiğe bağlamıştır. Bunun için RCREG denilan alma registerinin içinin boşaltılması yani TEMP=RCREG şeklinde başka bir değişkene aktarılması söz konusu bayrağı otomatikmen sıfırlar. Bu nedenle BASLA satırından evvel TEMP=RCREG komutununda verilmesi uygun olacaktır.
Programa birde ON INTERRUPT GOTO KESME komutunu ekledinmi sistem tamamlanmış olacaktır. Proton da komutun yazılım şeklinde farklılıklar olabilir onları sen düzeltirsin. Ben Proton kullanmıyorum. PBP kullanırım.
Program içinde KESME şeklinde bir etiket belirliyoruz. BU etiketten önce Global gesmelerin pasif edilmesi amacı ile DISABLE komutu yer almalıdır. Böylece program kesme etiketine geldiğinde bir başka kesme oluşması engellenmiş olur ve DISABLE bunu otomatik yapar.
Program kesmeye nasıl geldi o kısmı bir kez daha yinelemek isterim. Geri planda çalışan kontrolcü USART portuna bir veri geldiğini tespit etti ve RCIF=1 yaparak kesme bayrağını set etti. Bu nedenle programda hemen kesme etiketine atlamış oldu. Demekki bir veri geliyor. Tabiiki önce Uyandırma sinyali porta ulaşacak ve program kesme etiketine gelinceye kadar bir kaç veri alınmaya devam edecektir. Bu nedenle uyandırma sinyalimiz bir kaç byte dan oluşuyor (toplamda 15 byte). Kesme etiketinde;
hSerIn ,10,ATLA,[WAIT("ETE"),VERI1,VERI2,VERI3] 
komut satırı yer alıyor. Altında ise ATLA isimli etiket yer alıyor. Komut içindeki 10 rakamı Timeout değeridir. Anlamı şu, bir veri geldiğinde 10 ms süre ile ETE bilgisini ara. gelmemiş ise ATLA isimli etikete geç demektir. Komuta timeout değeri ve atlama etiketini eklemeyebilirsiniz. O zaman yanlış (parazit gibi) bir veri geldiğinde program orada epeyce ETE bilgisini almak için beklemek zorunda kalır. BU şekilde ise belirli bir zaman peryodu koymuş olursunuz. Zaten gelecek ise bu süre içinde mutlaka gelir.
ATLA etiketi altına ise,
TEMP=RCREG
RESUME
ENABLE
komutları yer alır.
Program beklenen verileri alsada almasada mutlaka RCREG içini boşaltarak kesme bayrağını sıfırlamalıdır. Böylece yeniden ve gereksiz yere kesme oluşması engellenmiş olur.   

Basic de birde şöyle bir kural vardır. Bu kural Proton için kısmen geçerli. Ama yinede uyulmasında yarar vardır. Kesme aktive edilmiş bir programda kesme bayrağı set edilmiş ise program kesme etiketine gitmeye çalışır. Ancak o anda bir basic komutu (mesela Delayms 1000 gibi) icra ediliyor ise bu komut işlemesi bitmeden kesmeye geçmesi mümkün olmaz. Bu nedenle biz özellikle kesme kullandığımız programlarda uzun süreli Delayms (veya Pause) kullanmaktan kaçınırız. EN büyük süre 5us olmalıdır. Böylece program kesmeye gidebilmek için en fazla 5us beklemiş olurki bu ihmal edilebilecek bir süredir. Uzun gecikmeler gerekirse bir döngü kurularak gecikme adedi artırılır. Örneğin,
FOR W=0 to 1000
  Delayus 5
Next
bu döngü size 1000 adet 5us lik gecikme yaratır. Döngünün kendi komut gecikmeside eklenirse bu gecikme yaklaşık 10 ms dolayında gerçekleşir. Tahmini bir değerdir daha az da olabilir.
Kesme içinde Hserin komutu altına birde ALdı=1 şeklinde bir bit değişkeni set edilir ise ve Programın ana kısmında (BASLA etiketi altındaki komut satırlarında, IF ALDI=1 then şeklinde başlayan bir komut olursa programın herhangi bir bilgi alma durumunda alınan bilgileri ne yapacağınıza o komut altında karar verebilirsiniz ALdı=0 deyip işi bitirirsiniz.

Anlatacaklarım bu kadar. Umarım artık anlaşılmıştır.
Ete projelerinde RF_Termometre isimli bir çalışma var. Örnekleri incelemni öneririm. Bütün bu yazdıklarımı anlatıyor.

Ete



devamını oku ...

5 Kasım 2019 Salı

gps modülü greenwich saat farkı düzeltme kodu

Türkiye ile İngiltere arasında +3 saat farkı bulunuyor. Bu nedenle gps modülün uydudan aldığı saati düzeltmeniz gerekir. Kodu aşağıda inceleyebilirsiniz. Basic ile hazırlansa da diğer dillere mantık çevrilebilir. Sadece saat hanesi düzeltiliyor. Gps kodunun tamamı burada.

'GREENWICH 3 SAAT ZAMAN FARKI DÜZELTME KODU:
GPSSAAT[0] = GPSSAAT[0] * 10
GPSSAAT[1] = GPSSAAT[1] * 1
SAAT = GPSSAAT[0] + GPSSAAT[1]
SAAT = SAAT + 3
If SAAT =24 Then SAAT = 0
If SAAT =25 Then SAAT = 1
If SAAT =26 Then SAAT = 2
devamını oku ...

29 Ekim 2019 Salı

adc okuma referans alma yöntemi dijital filtre

Bir işlemcinin adc pinlerinden okuma yaparken 1 ölçüm yerine 15-20 ölçüm alıp ortadaki değerleri değerlendirmek daha doğru sonuçlar almamızı sağlayacaktır. Etepic forumunda rast geldiğim adc okuma yöntemi basic formunda ama diğer dillere de çevrilebilir.  Önemli olan mantığı kavramak. Ete hoca yine püf noktaları anlatmış.

Örnek aşağıdadır
HAM VAR WORD
TOPLAM 
VAR WORD
OKUNAN 
VAR WORD[20]TEMP VAR WORD
VAR BYTE

PAUSE 200

BASLA
:
FOR 
I=0 TO 19
    ADCIN 0
,HAM
    OKUNAN
[I]=HAM
    PAUSEUS 10
NEXT

TOPLAM
=0FOR I=7 TO 12
TEMP
=OKUNAN[I]TOPLAM=TOPLAM+TEMP
NEXT
HAM
=TOPLAM/6
Bu sistemin avantajı, okumanın daha stabil olduğu ortalardan belirli bir sayıdaki okuma adedini dizi içinden alıp toplayıp ortalamasını almak şeklinde açıklanabilir. Birde digital filtre örneği yine ete'den:


OKUNAN 
VAR WORD[15]  'parentez içinde kaç adet dizideğişkeni ihtiyacımız var ise o rakamı yazıyoruz . 15 adet okuma yapacağımız için değişken adedimiz 15 olacaktır. Ama sıralamada sıfır dahil olduğu için 0-14 arasını kullanacağız.

TEMP VAR WORD
TOPLAM VAR WORD
HAM VAR WORD
X     VAR BYTE
Y     VAR BYTE

Program başladıktan sonra önce 15 adet ADC okumasını yapıp okuma değerlerini dizi değişkenine aktaracağız.

FOR X=0 to 14
  ADCIN 0, HAM
  OKUNAN[X]=HAM+1
  PAUSEUS 100
NEXT

Buraya kadar 15 adet değişkenimizde okunan adc değerleri rastgele yerleşmiş oldu.
Şimdi bunları bir sıraya dizmemiz gerekiyor. Bubble Sort yöntemini kullanacağız.
FOR X=0 to 13 
   FOR Y=(X+1) TO 14
      IF OKUNAN[X]>OKUNAN[Y] THEN
          TEMP=OKUNAN[X]
           OKUNAN[X]=OKUNAN[Y]
           OKUNAN[Y]=TEMP
      ENDIF
   NEXT
NEXT
Buraya kadar dizi değerlerini küçükten büyüğe doğru sıraya dizmiş olduk.
Şimdi ortadan 5 elemanı alıp ortalamasını alacağız.
TOPLAM=0
FOR X=5  TO 9
  TOPLAM=TOPLAM+OKUNAN[X]
NEXT
TEMP=TOPLAM/5
İşte sonunda ortada yer alan 5 elemanın ortalamasını alıp TEMP değişkenine yerleştirmiş olduk.
Yanlış yapılmaması için bu kod parçasında kullanılan diğer değişkenleride olması gerektiği gibi tanımladım.
Umarım anlaşılmıştır.


Kaynak etepic.com











devamını oku ...

19 Ekim 2019 Cumartesi

en büyük en küçük sayıyı bulma kodu c basic

Bazı değerleri karşılaştırmak istediğinizde kullanabileceğiniz örnek C ve basic kodları aşağıdadır:

Basic:
Dim sayi1 as integer =12456
Dim sayi2 as integer =12245
Dim sayi3 as integer =13456
Dim sayi4 as integer =12411
Dim kontrol as integer = sayi1

if sayi2 < kontrol then kontrol = sayi2
if sayi3 < kontrol then kontrol = sayi3
if sayi4 < kontrol then kontrol = sayi4

print kontrol

C:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Dört_Sayıdan_En_Büyüğü
{
    class Program
    {
        static void Main(string[] args)
        {
            //Kullanıcının klavyeden girdiği dört sayıdan büyük olanının hangisi
            //olduğunu ekrana yazan C# console programını yazın.
         
            int kontrol,sayi1,sayi2,sayi3,sayi4;

            Console.Write("1. Sayıyı Giriniz:");
            sayi1 = Convert.ToInt16(Console.ReadLine());
            Console.Write("2. Sayıyı Giriniz:");
            sayi2 = Convert.ToInt16(Console.ReadLine());
            Console.Write("3. Sayıyı Giriniz:");
            sayi3 = Convert.ToInt16(Console.ReadLine());
            Console.Write("4. Sayıyı Giriniz:");
            sayi4 = Convert.ToInt16(Console.ReadLine());

            kontrol = sayi1;
            if (sayi2 > kontrol)
            {
                kontrol = sayi2;
            }
            if (sayi3 > kontrol)
            {
                kontrol = sayi3;
            }
            if (sayi4 > kontrol)
            {
                kontrol = sayi4;
            }

            Console.WriteLine("--------------------------");
            Console.WriteLine("En Büyük Sayı:" + kontrol);
            Console.ReadKey();
        }
    }
}






devamını oku ...

17 Ekim 2019 Perşembe

HMC5883L HMC5983 pusula devresi proton basic

Proton basic compass code
Proton basic compass code

Bir süredir HMC5883L pusula modülü ile çalışmalar yapıyorum, bunları paylaşmamın doğru olacağını düşündüm.

Öncelikle piyasada FAKE olarak adlandırabileceğimiz modüller mevcut. Bu modüllerin chip üzerinde hmc önünde DB veya DA ibaresi mevcut. Bu db ve da ile üretilen modellerin kalibre ve bir takım işlemlerle çalıştığı söyleniyor ama çalışan sağlam modül varken kimse bu işle uğraşmak istemez.

Paylaştığım kod hem HMC5883 hem de HMC5983 ile çalıştığını da belirteyim. Daha önce aynı modül için CCS C kodu paylaşmıştım. Onu da kullanabilirsiniz. Eğer orjinal HMC5883L  bulamazsanız HMC5983L veya basınç sensörü barındıran HMC5983L+BMP180 kullanabilirsiniz.

Ayrıca manyetik sapma koda ilave edilmeli. Dünyadaki her yerin manyetik sapma değeri farklı oluyor. Ve bu değere her yıl 6 dakika eklemek gerekiyor. Manyetik sapma değerlerini aşağıdaki linkten öğrenebilirsiniz:

http://www.magnetic-declination.com/

Ben pic18f2550 ile test ettim siz diğer işlemcileri de kullanabilirsiniz.
Proton Kodu: Proton derleyicisine kopyalayıp kaydediniz.

Device = 18F2550
Declare Xtal = 20

Config_Start
FOSC = HS
MCLRE = On
PWRT = On
FCMEN = Off
IESO = Off
BOR = Off
VREGEN = Off
WDT = Off
PBADEN = Off
CCP2MX = Off
STVREN = Off
LVP = Off
XINST = Off
Debug = Off
Cp0 = Off
Cp1 = Off
Cp2 = Off
Cp3 = Off
CPB = Off
CPD = Off
WRT0 = Off
WRT1 = Off
WRT2 = Off
WRT3 = Off
WRTB = Off
WRTC = Off
WRTD = Off
EBTR0 = Off
EBTR1 = Off
EBTR2 = Off
EBTR3 = Off
EBTRB = Off
Config_End

Include "AtnFc.inc"
 
Declare LCD_DTPin PORTB.4
Declare LCD_RSPin PORTB.2
Declare LCD_ENPin PORTB.3
Declare LCD_Interface 4
Declare LCD_Lines 4
Declare LCD_Type 0
Declare LCD_CommandUs = 2000
Declare LCD_DataUs =50 ' YADA 255

'Declare Optimiser_Level = 2
'Declare Dead_Code_Remove = On
'Declare Float_Display_Type = Fast     
Declare    Hserial_Baud  = 9600
Declare    Hserial_RCSTA = %10010000     
Declare    Hserial_TXSTA = 100100     
Declare    Hserial_Clear = On
'Declare    PORTB_Pullups true
     
Symbol SCL = PORTB.1
Symbol SDA = PORTB.0 
 
Symbol X_MSB = $03 'Read Register, Output of X MSB 8-bit value.
Symbol X_LSB = $04 'Read Register, Output of X LSB 8-bit value.
Symbol Z_MSB = $05 'Read Register, Output of Z MSB 8-bit value.
Symbol Z_LSB = $06 'Read Register, Output of Z LSB 8-bit value.
Symbol Y_MSB = $07 'Read Register, Output of Y MSB 8-bit value.
Symbol Y_LSB = $08 'Read Register, Output of Y LSB 8-bit value.
 
Symbol WRITE_ADDRESS = $3C  ' Requests Write operation
Symbol READ_ADDRESS  = $3D  ' Requests Read operation
Symbol MODE = $02           ' Mode setting register
Symbol I2C_VAL = $0
 
Dim X As SWord 'x sensor measured value
Dim Y As SWord 'y sensor measured value
Dim Z As SWord 'z sensor measured value
 
Dim XC As Float
Dim YC As Float

Dim Heading As Float
Dim DeclinationAngle As Float
Dim Pi As Float
Dim Pi2 As Float
     
Pi  = 3.141592654
Pi2 = 6.283185307 ; 2*pi
 
DelayMS 100
 
I2COut SDA,SCL, 0x3c, 0x00, [0x70] '(8-average, 15 Hz default, normal measurement)
I2COut SDA,SCL, 0x3c, 0x01, [0xA0] ' (Gain=5)
I2COut SDA,SCL, 0x3c, 0x02, [0x00] ' Send continuous output command

Cls

Main:
I2CIn SDA, SCL, $3D, $03,[X.HighByte ,X.LowByte,Z.HighByte,Z.LowByte,Y.HighByte,Y.LowByte]
XC = X      ;Convert the numbers to Float
YC = Y      ;Either Result will come garbage

ATan2(YC, XC, Heading)                         ;Calculate the ATaan2
'DeclinationAngle = 0.0457;                     ;DeclinationAngle is different in every place
DeclinationAngle = 5.38;                     ;eskişehir manyetik sapma değeri
Heading = Heading + DeclinationAngle;
   
If Heading < 0 Then Heading = Heading + Pi2    ;Add 2*Pi
If Heading > Pi2 Then Heading = Heading - Pi2  ;Subtract 2*Pi
 
Heading = Heading * 57.295779                  ;Convert radians to degrees

Print At 1,1,"Head : ",Dec2 Heading," N   " 

DelayMS 200
GoTo Main

INC Dosyası: Aşağıdaki satırları txt dosyasına kaydedip daha sonra uzantısını inc yapmalısınız.

'-------------------------------------------------------------------------------------------------------------------------------------
' Name      : Atan2                                                       
' Purpose   : Computes the principal value of arc tangent of Y/X, using the
'           : signs of both the arguments to determine the quadrant of the return value
' Input     : PP_AARG holds the Y input
'           : PP_BARG holds the X input
' Output    : PP_AARG holds the arc tangent of Y/X.         
' Notes     : All values are in Radians
'

' Bring two of the compiler's floating point system variables into the program for the Atan2 macro
'
$ifndef __Atan2__

    Dim PP_AARG As Float System
    Dim PP_BARG As Float System
'----------------------------------------------------------------------------------------------- 
    GoTo _Atan2_Main                              ' Jump over the subroutines
'----------------------------------------------------------------------------------------------- 

$define ATan2(pYin, pXin, pResult) '
    PP_AARG = pYin '
    PP_BARG = pXin '
    _Atan2         '
    pResult = PP_AARG

_Atan2 Macro-
    GoSub __Atan2
Endm

#ifMacro- _Atan2 
__Atan2:         
    Dim fYin As PP_AARG
    Dim fXin As PP_BARG
    Dim bQuadrant As Byte System
    Dim tSign As bQuadrant.7

    tSign = 0
    bQuadrant = 0

    If fYin <= 0.0 Then
        If fXin <= 0.0 Then
            bQuadrant = 3
        Else
            bQuadrant = 4
        EndIf 
    ElseIf fXin < 0.0 Then
        bQuadrant = 2
    Else
        bQuadrant = 1
    EndIf 

    If fYin < 0.0 Then
        tSign = 1
        fYin = Abs fYin
    EndIf
   
    fXin = Abs fXin
 
    If fXin = 0.0 Then
        PP_AARG = 1.570796325
        If tSign = 1 Then
            PP_AARG = -PP_AARG
        EndIf
    Else
        PP_AARG = fYin / fXin
        PP_AARG = ATan(PP_AARG)
        bQuadrant = bQuadrant & %01111111   ' Mask out the Sign bit
        Select bQuadrant
            Case 2
                PP_BARG = PP_AARG
                PP_AARG = 3.14159265 - PP_BARG
            Case 3
                PP_AARG = PP_AARG - 3.14159265
            Case 4
                PP_AARG = -PP_AARG
        EndSelect
    EndIf
    Return
#endIfMacro-


 _Atan2_Main:
$endif




devamını oku ...

10 Ekim 2019 Perşembe

proton basic pic18f2550 config setting ayarları

config settings
pic18f2550 proton basic config

Proton basic son sürümünü kullanmak istediğimde pic18f2550 için bazı sıkıntılarla karşılaştım. Eski proton basic versiyonunda config ayarlamaları derleyici tarafından yapılırken 3.7.2.8 versiyonunda biraz uğraştırıcı oluyor. Neyseki etepic forumunda ete hocanın pic basic pro için hazırladığı pic18f2550 config ayarları yardımıma yetişti ve aşağıdaki listeyi oluşturabildim. Bu listenin altında usb config ayarları olan ikinci bir listede mevcut onuda etepic forumdaki pwm.c rumuzlu üye hazırlamış.

Ayrıca aşağıdaki linkteki programı proton basic yüklü pcye kurarsanız, proton idesine fuse generator eklenmiş olacak. Bu sayede istediğiniz config fuse ayarını yapabilirsiniz:

http://www.protonbasic.co.uk/content.php/2607-PIC-FuseConfigurator-Mk2


Config_Start
FOSC = HS
MCLRE = On
PWRT = On
FCMEN = Off
IESO = Off
BOR = Off
VREGEN = Off
WDT = Off
PBADEN = Off
CCP2MX = Off
STVREN = Off
LVP = Off
XINST = Off
Debug = Off
Cp0 = Off
Cp1 = Off
Cp2 = Off
Cp3 = Off
CPB = Off
CPD = Off
WRT0 = Off
WRT1 = Off
WRT2 = Off
WRT3 = Off
WRTB = Off
WRTC = Off
WRTD = Off
EBTR0 = Off
EBTR1 = Off
EBTR2 = Off
EBTR3 = Off
EBTRB = Off
Config_End

Usb config ayarları:

Config_Start
PLLDIV = 1
CPUDIV = OSC1_PLL2
USBDIV = 2
FOSC = HSPLL_HS
FCMEN = OFF
IESO = OFF
PWRT = On
BOR = OFF
BORV = 0
VREGEN = On
WDT = OFF
WDTPS = 1
MCLRE = OFF
LPT1OSC = OFF
PBADEN = On
CCP2MX = OFF
STVREN = OFF
LVP = On
XINST = OFF
Debug = OFF
CP0 = OFF
CP1 = OFF
CP2 = OFF
CP3 = OFF
CPB = OFF
CPD = OFF
WRT0 = OFF
WRT1 = OFF
WRT2 = OFF
WRT3 = OFF
WRTB = OFF
WRTC = OFF
WRTD = OFF
EBTR0 = OFF
EBTR1 = OFF
EBTR2 = OFF
EBTR3 = OFF
EBTRB = OFF
Config_End

Proton basic led blink kodu ve asm çıktısındaki config ayarları:

    Device = 18F2550
    Declare Xtal = 20
    Do
        High PORTC.0
        DelayMs 1000
        Low PORTC.0
        DelayMs 1000
    Loop

Asm config çıktısı:

__config config1h, FOSC_HSPLL_HS_1
__config config2l, PWRT_OFF_2 & BOR_ON_2 & BORV_3_2 & VREGEN_ON_2
__config config2h, WDT_OFF_2 & WDTPS_128_2
__config config3h, PBADEN_OFF_3
__config config4l, LVP_OFF_4 & XINST_OFF_4 & DEBUG_OFF_4



devamını oku ...

8 Ekim 2019 Salı

mikrobasic button led code sample



Mikro basic ve MikroC derleyici örnek kodlarında port bazlı buton led örnekleri verilmiş, aynı portta buton led örneği yoktu bu nedsenle hazırlamak istedim. Portc 2. bitine buton, 0 bitine ise led bağlanmış durumda.  Derleyicide buton kütüphanesi seçilmeli.

program Button_Test

dim eskidurum as byte

main:
  ANSELA = 0   'A PORTU ADC KAPATILDI
  ANSELB = 0   'B PORTU ADC KAPATILDI
  ANSELC = 0   'C PORTU ADC KAPATILDI

  TRISC2_bit = 1 'PORTC.2 BİTİ GİRİŞ OLARAK AYARLANDI
  TRISC0_bit = 0 'PORTC.0 BİTİ ÇIKIŞ OLARAK AYARLANDI
  LATC = 0       'PORTC SIFIRLANDI

  eskidurum = 0 'DURUM DEĞİŞKENİ

  while TRUE
    if (Button(PORTC, 2, 1, 1)) then ' POTRC 2. BİTİNİ KONTROL ET
      eskidurum = 1
      LATC.0 = 0
    end if
    if (eskidurum and Button(PORTC, 2, 1, 0)) then 'PORTC2 PİNİNİN 1-0 DURUMUNU KONTROL ET
      eskidurum = 0
      LATC.0 = 1
    end if
  wend
end.






devamını oku ...