12f675

Başlatan dagadamı, 21 Eylül 2023, 15:42:07

dagadamı

12f675 ADC Nasıl okunur..

ete

#1
12F675 de AN0-AN3 arası analog kanallar mevcut.
Öncelikle kullanmak istediğin kanalı TRISIO registerine ilgili bitine 1 vererek giriş pini haline getirmen gerekir.
Daha sonra aynı pini Analaog giriş pinine çevirmen için ANSEL registerinde ilgili bite 1 vererek o pini analog pin haline getirmen gerekir.Ansel registeri aynı zamanda ADC clock işinide belirlediği için ANSEL.4 bitini 1 yapman da gerekiyor.
Daha sonra ADCON0 registerinde 7 nolu biti 0 yaparak sağa yazlı sonuç almak için ayarlaman gerekiyor.
Daha sonra, Programın baş taraflarına;
DEFINE ADC_BITS 10    ' ADCIN resolution  (Bits)
DEFINE ADC_CLOCK 1    ' ADC clock source  (Fosc/8)
DEFINE ADC_SAMPLEUS 20 ' ADC sampling time (uSec)
satırlarınıda eklemen gerekiyor. Söz konusu değerler 4 Mhz OSC frekansına uygun değerlerdir.
Bu aşamaları yaptıktan sonra;
ADCIN X,HAM  (HAM burada word tipi değişken olacaktır)
şeklinde ADC değeri okuyabilirsin. ADC pinine gelecek olan 0-5V aralığındaki voltaj HAM değer olarak 0-1023 şeklinde değer alarak okunmaktadır. Daha sonra istenilen değere çevrilebilir.
Bu gibi durumlarda İşlemciye ait data sheet'i açıp Analog to Digital Converter Module başlığını ve gerisinde gelenleri okur yada görsel olarak incelerseniz hangi registerleri kullanmanız gerektiğini kolaylıkla görebilirsiniz. Özellikle bu Analog To Digital Converter konusu sonunda bu işle ilgili tüm registerlerin bir listesi de verilmektedir. Buradan da olayı görebilirsiniz.

Ete

dagadamı

Ete hocam bu kod niye çalışmıyor yardım lütfen...

'****************************************************************
'*  Name    : AC_Dimmer_Control.bas                            *
'*  Author  : Your Name Here                                   *
'*  Date    : September 2023                                   *
'*  Version : 1.0                                               *
'*  Notes   : AC Dimmer Control with PIC12F675                  *
'****************************************************************

Device = 12F675
Config INTRC_OSC_NOCLKOUT, WDT_OFF, PWRTE_ON, BODEN_ON, CP_OFF, MCLRE_OFF
Xtal = 4

' ADC Configuration
ADCON0 = %00001100  ' Select Channel 3 (AN3)
ANSEL = %00011000   ' Set AN3 as analog input, Fosc/8 
Declare Adin_Res = 10  ' 10-bit resolution
Declare Adin_Tad = FRC  ' Use the internal oscillator
Declare Adin_Stime = 20 ' Sampling time of 20us

' I/O Pin Symbols
Symbol Triac_out = GPIO.0   ' Triac control output
Symbol Test_giris = GPIO.1  ' Mains presence input
Symbol Zero_cross = GPIO.2  ' Zero-crossing detection input

' Interrupt Symbols
Symbol GIE = INTCON.7  ' Global Interrupt Enable
Symbol T0IE = INTCON.5 ' TMR0 Overflow Interrupt Enable
Symbol INTE = INTCON.4 ' External Interrupt Enable
Symbol T0IF = INTCON.2 ' TMR0 Overflow Interrupt Flag
Symbol INTF = INTCON.1 ' External Interrupt Flag

' Variables
Dim HAM As Word       ' ADC result
Dim Load_Value As Word ' Dimming level
Dim I As Word         ' General-purpose variable
Dim SURE As Word      ' General-purpose variable
Dim Alt_limit As Byte ' Lower dimming limit
Dim Ust_Limit As Byte ' Upper dimming limit

'********************************************************************
' Initialization Section
'********************************************************************

DelayMS 500

On Interrupt GoTo Interrupt_Detect

GoTo BEGIN

'********************************************************************
' Main Program Loop
'********************************************************************

BEGIN:

  ' Analog and I/O Setup
  ANSEL.4 = 1 ' Enable AN4 for analog input
  ANSEL = 0    ' Configure other pins as digital
  CMCON = 7    ' Disable the comparator
  OPTION_REG = %01010101 ' Prescaler 1:64, External Interrupt Edge: Rising
 
  ' TRISIO = %111110 ' Set GP1 as input, others as output
  ' WPU = %110000   ' Enable pull-ups on GP4 and GP5 (if needed)

  ' Interrupt Configuration
  T0IF = 0    ' Clear TMR0 overflow flag
  INTF = 0    ' Clear the external interrupt flag
  Alt_limit = 101 ' Set the lower dimming limit
  Ust_Limit = 255 ' Set the upper dimming limit
  Load_Value = Alt_limit ' Initialize the dimming level

  ' Enable Interrupts
  INTE = 1    ' Enable External Interrupt
  GIE = 1     ' Enable global interrupts

' Main Program Loop
MAIN:
  If Test_giris = 0 Then
    INTE = 0
    T0IE = 0
    DelayMS 100
    While Test_giris = 0
    Wend
    INTE = 1
    T0IE = 1
    Clear
    @clrf PCLATH
    @GoTo 0
  End If
 
  ' Add your main program logic here
 
  GoTo MAIN

'********************************************************************
' Subroutines
'********************************************************************

ADC_BAK:
  ADCIN 3, HAM
  Load_Value = ((HAM * 3129) / 100 + 110) / 10 ' Adjust scaling if needed
  Return

'********************************************************************
' Interrupt Service Routine
'********************************************************************

Interrupt_Detect:
  If INTF = 1 Then
    TMR0 = Load_Value
    T0IE = 1 ' Enable TMR0 overflow interrupt
    INTF = 0 ' Clear INT Flag
  End If

  If T0IF = 1 Then
    High Triac_out
    DelayUS 100 ' Triac trigger delay (adjust as needed)
    Low Triac_out
    T0IF = 0
  End If

  Resume

End

ete

Bir çok kusur var programda.
Birincisi İŞlemci pinlerinin giriş mi  değer verilmemiş yoksa çıkışmı olduklarını ayarlayan TRISIO registerine değer verilmemiş (verilmiş olan satır kapatılmış her nedense!!!!) Hal böyle olunca giriş olarak düşünülen Zero_Cross, Test_Giriş pinlerinin çalışması hayal olur ki çalışmıyorlar.

İkincisi yine giriş olarak ayarlanması gereken ADC pinleride çalışmayacaktır. Birincisi TRISIO registerinden ayarlanmadıkları için. İkincisi ise ANSEL yani ANalog_SELect registerinden ayarlanmadıkları için. Birlikte bakalım programa.
Programın başlarında benim söylediğim gibi (ANSEL = %00011000   ' Set AN3 as analog input, Fosc/8) Ansel registerine değer vererek ayarlamayı yapmışsın burası doğru olan kısım.
Ama sonra  (ANSEL.4 = 1 ' Enable AN4 for analog input) vererek ANSEl registerini bozmaya başlamışsın. Bu komut ANSEL registerinin 4 nolu bitini 1 yapar. Halbuki önceden aynı biti 1 yapmıştın neden yeniden verdin bu değeri? Üstelik açıklama kısmıda yanlış. Ansel.4 pini analog olamaz bu işlemcide yanlızca Ansel.0-1-2-3 nolu pinler analog yapılabilir. Ansel.4 biti ADC için CLK seçme bitidir. Data sheet'e ANSEL registerine bir bak istersen.
En kötüsü de bir sonraki satırda geliyor. (ANSEL = 0    ' Configure other pins as digital) Bu komutu vererek bütün ANSEL ayarlarını sıfırlamış oluyorsun. Yani analog pin ayarlaması falan kalmamış bütün giriş olarak ayarlanmış işlemci pinlerini Analog yerine Digital yapmış oldun bu komut ile.
Program yazmak mantık kontrolü gerektirir. Ama sen rastgele komutlar vererek işi bozmuşsun maalesef.

Devam ediyoruz ve programın öncelikle BEGIN isimli etikete gelip altındaki satırları icra ettiğini görüyoruz. Program daha sonra MAIN isimli etikete geliyor ve oradaki komutları icra ediyor. Ne var orada TEST_GIRIS butonuna basılmışmı basılmamışmı onu test eden satırlar var.
Basılmış ise altındaki satırlar çalışıyor basılmamış ise en altta yer alan GOTO MAIN komutu ile program yeniden Main isimli etikete geliyor ve döngü bu şekilde devam ediyor.

Alt programlara bakacak olursak bir ADC okuma bölümü var ama ne yazıkki program içinde programı buraya gönderen (yönlendiren) hiç bir komut görmüyoruz. Demekki Bu ADC okuma kısmı hiç çalışmayacaktır. Çünki program oraya gelemiyor daha doğrusu oraya gönderme yapmamışsın. Bu konuda benim açıklamamı okumanı öneririm.

Bu program şayet düzgünce yazılmış olsa idi zaten çalışması için öncelikle TEST_Giriş butonuna bir kere basılıp kesmenin aktif edilmesi gerekirdi. Umarım bunuda biliyorsun.

Son bir şey daha. PROTON da ENDIF komutu End If şeklindemi yazılıyor. Derleyici buna itiraz etmiyormu. Bildiğim kadarı ile bitişik yazılması gerekir. Proton kullanmadığım için çok iyi bilmiyorum ama eskiden hatırladığım kadarı ile o komut ENDIF şeklinde yazılması gerekir.

Ete

mehmet

TMR0 'ın 8-bit olduğunu da unutmayınız.
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
http://www.mehmetbilgi.net.tr

dagadamı

#5
kıdemli teşekküler

onurinci

ADCON0= %10000001  en sol bit 10 bit çözünürlük için logic 1 olmalıydı sanırım.

ete

Onur,
Haklısın gözden kaçmış gözüküyor.
ADCON0 = %10001100 şeklinde olmalı o komut satırı.

Diğer bir kusur da Alt ve üst limit değerleri değişmiş gözüküyor.
Önceden üst limit 235 , alt limit ise 110 idi ve bende ona uygun bir hesap formülü geliştirmiştim.
Yeni değerler ise Üst Limit=255 ve alt limit=101 şeklinde görülüyor.
Bu durumda hesap formülünü değiştirmek gerekir.
255-101=154 bunu 1023 e bölersek (154/1023=0,1505376344086022) bulunur.
BU sayıyı 256 ile çarparsak 38,53763440860215 değerini buluruz. En azından virgülü 2 hane ötelersek ve son haneyide 1 artırırsak formülümüzde kullanacağımız sabit çarpanı bulmuş olacağız ki buda 3854 olacaktır. Bu durumda yeni ADC hesap formülümüz;
Load_Value=(ham*/3854)/100+101  şeklinde olacaktır.
Pot değeri min da olunca okunacak ADC (HAM) değeri sıfır olacağından Load_Value=101 hesaplanacaktır. ADC değerinin sıfırdan büyük olması durumunda ise hesaplanan değer 101 eklenecek olup maksimum okumada ham yerine 1023 koyulursa hesaplanan değer 154 olacak ve buna 101 eklenince Load_value=255 bulunmuş olacaktır.

Bu iki değişikliği yapıp tekrar denemelisin.
- ADCON0=%10001100
- Load_Value=(ham*/3854)/100+101
şeklinde.

Yinede çalışmaz ise benim yapacak bir şeyim kalmıyor.

Ete

Pepe

#8
.

dagadamı

#9
PEPE Hocam  Teşekkür ederim...  HEX dosyası çalışıyor bas.dosyası tekrar derleyince çalışmıyor bas dosyasını bir kontrol edermisiniz..
iş bilenin kılıç kuşananın..

Pepe

#10
.

dagadamı

pepe hocam similosyonda bakarsanız ilk gönderdiğiniz bas dosyası sıkıntılı idi hex dosyası stabil çalışıyor ...

son gönderdiğiniz bas .hex stabil çalışmıyor similsyona bakarsanız..

ilginize teşekkür ederim..

Pepe

#12
.

dagadamı

#13
hacam bas dosyasını tekrar derleme yapıyorum derlerken hata yok  fakat hex dosyasını yuklediğimde çalışmıyor 
sizin derlediğiniz hex değişiyor...

bas dosyasını bi konrol edermisiniz ..

CMCON=7
  OPTION_REG = %01010101 ;presc 1:64 ,External Interrupt Edge to rising edge
  TRISIO = %000111110;1- input, 0-output
  WPU =%00110010
  ANSEL.3 = 1          ' Configure other pins as digital
  ADCON0=%10000001

ete

#14
TRISIO = %000111110;1- input, 0-output
Bu satırda TRISIO'ya 8 bit yerine 9 bitlik değer vermişsin.
Sorun bundandır muhtemelen.
Giriş olan pinlerin bit karşılığı "1", çıkış olanların bit karşılığı "0" olacak.
Pinleri sırası ile kontrol edip registere 8 bitlik değer vermeye çalış.

Bildiğim kadarı ile derleyici 9 bit olarak verilen bilginin bir bitini atarak değerlendiriyor.
Şayet soldan atarsa sorun olmazdı ama sağdan bir bit atarsa herşey bozuluyor.
En iyisi doğrusunu vermek. Programa bakarak olması gereken değeri %00001110 şeklinde hesapladım. Sende bak değişiklik varsa değiştir. GPIO.4 ve GPIO.5 de bir şey bağlımı bilemiyorum. Boş iseler benim verdiğim değer tam uyacaktır.
Ama en azından verdiğim değeri vererek tekrar derleyip deneyebilirsin.

Ete

Powered by EzPortal