PBP 16F887 ile PWM üretimi

Başlatan certy, 31 Temmuz 2013, 23:17:42

certy

#15
Yeni yazdığım yazılım ve yeni çizdiğim devre ile böyle bir sonuç aldım;

TA1USS

fatih6761

#16
Hocam bunun yerine R2R bir DAC yapıp sinüs dalganın uygun çözünürlükte sinyali ile sürebilirdiniz. Daha düzgün bir sinüz elde edersiniz. Siz 24-bit gibi yapmışsınız. Ses projesi olmadığına göre 8-bit bile yeterliydi.

https://skydrive.live.com/redir?resid=578DC56E532E555A!612&authkey=!AEA7SfE91z1hT74
Edit : hocam kodlar Proton ile yazıldı. Frekans 47 Hz gibi gözüküyor gecikmelerden kaynaklanan  bir hata. Periyor değerini biraz küçülterek doğru değere ulaşabilirsiniz.

certy

Alıntı yapılan: fatih6761 - 02 Ağustos 2013, 06:37:37
Hocam bunun yerine R2R bir DAC yapıp sinüs dalganın uygun çözünürlükte sinyali ile sürebilirdiniz. Daha düzgün bir sinüz elde edersiniz. Siz 24-bit gibi yapmışsınız. Ses projesi olmadığına göre 8-bit bile yeterliydi.
(Resim gizlendi görmek için tıklayın.)
https://skydrive.live.com/redir?resid=578DC56E532E555A!612&authkey=!AEA7SfE91z1hT74
Edit : hocam kodlar Proton ile yazıldı. Frekans 47 Hz gibi gözüküyor gecikmelerden kaynaklanan  bir hata. Periyor değerini biraz küçülterek doğru değere ulaşabilirsiniz.

Teşekkür ederim. Rica etsem sizin programın mantığını biraz ayrıntılı olarak açıklayabilir misiniz?
TA1USS

fatih6761

Mantığı çok basit hocam. Donanımda dirençli kısım R2R denen bir DAC türü. Değerlerden farkettiğiniz gibi dikey dirençler R değerinde, yatay olanlar 2R değerinde. Bu bize doğrusal bir DAC sağlıyor. Yazılımda;
öncelikle çıkış sinyalinin periyodunu belirliyoruz. İstediğimiz çıkış 50Hz sinüs. Dolayısıyla sinüs dalganın bir periyodu 1000/50 = 20 milisaniye olacak. Bu değer tam bir sinüs işareti ifade ediyor. Programın en sonunda bir "lookup table" var. Bu değerler sinüs fonksiyonunun 0'dan 2pi'ye tam bir periyodunun 256 eşit parçaya bölünüp bu anlardaki değerlerinin alınmasıyla oluşturulmuş. Yani tablonun ilk elemanı sin(0), 128. elemanı ise sin(pi) oluyor. Tabi bu değerler -1,1 aralığından 0,256 aralığına ölçeklendi. Böylece tamsayılarla daha kolay işlem yapılır(F877'de fpu yok). Program R2R DAC'a bu tablodan sıradaki değeri aktarıyor ve sonraki değerin zamanı gelene kadar bekliyor. Böylece sonsuz döngüde sin dalga üretiyor.

certy

Alıntı yapılan: fatih6761 - 02 Ağustos 2013, 18:10:15
Mantığı çok basit hocam. Donanımda dirençli kısım R2R denen bir DAC türü. Değerlerden farkettiğiniz gibi dikey dirençler R değerinde, yatay olanlar 2R değerinde. Bu bize doğrusal bir DAC sağlıyor. Yazılımda;
öncelikle çıkış sinyalinin periyodunu belirliyoruz. İstediğimiz çıkış 50Hz sinüs. Dolayısıyla sinüs dalganın bir periyodu 1000/50 = 20 milisaniye olacak. Bu değer tam bir sinüs işareti ifade ediyor. Programın en sonunda bir "lookup table" var. Bu değerler sinüs fonksiyonunun 0'dan 2pi'ye tam bir periyodunun 256 eşit parçaya bölünüp bu anlardaki değerlerinin alınmasıyla oluşturulmuş. Yani tablonun ilk elemanı sin(0), 128. elemanı ise sin(pi) oluyor. Tabi bu değerler -1,1 aralığından 0,256 aralığına ölçeklendi. Böylece tamsayılarla daha kolay işlem yapılır(F877'de fpu yok). Program R2R DAC'a bu tablodan sıradaki değeri aktarıyor ve sonraki değerin zamanı gelene kadar bekliyor. Böylece sonsuz döngüde sin dalga üretiyor.

Anladım. Peki lookup tabloyu nasıl oluşturdunuz?
TA1USS

fatih6761

Basit bir bilgisayar programıyla yapabilirsiniz. İnternette online programlar da var.
Önceden bir proje için yazdığım Visual Basic Script vardı. Windowsta kolay çalıştırılsın diye vbs ile yazmıştım.
Dim oFSO, oFile, Result, PI

PI = 3.14159265
SineFactor = 2 * PI / 255

Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFile = oFSO.CreateTextFile("table.bas")

oFile.WriteLine "'"
oFile.WriteLine "'	Sine Values Lookup Table 256"
oFile.WriteLine "'"
oFile.WriteLine vbCrLf

oFile.WriteLine "SineLookupTable:"
oFile.Write "LData As Byte "

For i = 0 To 255	
	' Sine Function
	Result = CInt ( Sin(i * SineFactor) * 127 + 128 )
	
	oFile.Write CStr(Result)
	
	If i < 255 Then
		oFile.Write ", "
	End If
	
	If (i Mod 8 = 7) And (i < 255) Then
		oFile.Write "_"
		oFile.Write vbCrLf
	End If
Next

oFile.Close

Bu kodu .vbs dosyası olarak kaydedip çift tıklayarak çalıştırdığınızda aynı klasörde table.bas isimli dosya oluşur. Bunun içindeki tabloyu proton kodunun sonuna eklemelisiniz. Bu kod program hafızasına yazılır. Tabloyu sona koymazsanız kodmuş gibi çalıştırılacaktır.

certy

Alıntı yapılan: fatih6761 - 02 Ağustos 2013, 19:57:11
Basit bir bilgisayar programıyla yapabilirsiniz. İnternette online programlar da var.
Önceden bir proje için yazdığım Visual Basic Script vardı. Windowsta kolay çalıştırılsın diye vbs ile yazmıştım.
Dim oFSO, oFile, Result, PI

PI = 3.14159265
SineFactor = 2 * PI / 255

Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFile = oFSO.CreateTextFile("table.bas")

oFile.WriteLine "'"
oFile.WriteLine "'	Sine Values Lookup Table 256"
oFile.WriteLine "'"
oFile.WriteLine vbCrLf

oFile.WriteLine "SineLookupTable:"
oFile.Write "LData As Byte "

For i = 0 To 255	
	' Sine Function
	Result = CInt ( Sin(i * SineFactor) * 127 + 128 )
	
	oFile.Write CStr(Result)
	
	If i < 255 Then
		oFile.Write ", "
	End If
	
	If (i Mod 8 = 7) And (i < 255) Then
		oFile.Write "_"
		oFile.Write vbCrLf
	End If
Next

oFile.Close

Bu kodu .vbs dosyası olarak kaydedip çift tıklayarak çalıştırdığınızda aynı klasörde table.bas isimli dosya oluşur. Bunun içindeki tabloyu proton kodunun sonuna eklemelisiniz. Bu kod program hafızasına yazılır. Tabloyu sona koymazsanız kodmuş gibi çalıştırılacaktır.

Anladım, çok teşekkür ederim.

Birde sizden bir ricam olacak. Yazdığınız programda 16f877'nin C.0 bitine 5V gelince çalışmasını istiyorum.  Bunu yapabilir misiniz?
TA1USS

fatih6761

Alıntı yapılan: certy - 02 Ağustos 2013, 20:27:53
Anladım, çok teşekkür ederim.

Birde sizden bir ricam olacak. Yazdığınız programda 16f877'nin C.0 bitine 5V gelince çalışmasını istiyorum.  Bunu yapabilir misiniz?
Ben yaparım yapmasına da, bunun size bir faydası olmaz  :)
5V gelmesi derken neyi kastediyorsunuz? Pin 1 olduğu sürece mi sinyal verecek? Yoksa birkez 1 olunca mı sinyal verilecek?

certy

#23
Alıntı yapılan: fatih6761 - 02 Ağustos 2013, 23:58:03
Ben yaparım yapmasına da, bunun size bir faydası olmaz  :)
5V gelmesi derken neyi kastediyorsunuz? Pin 1 olduğu sürece mi sinyal verecek? Yoksa birkez 1 olunca mı sinyal verilecek?

Faydası olmaz ama başka bir picle haberleştirmek için istedim. :)

Bir kez 1 olunca sinyal verecek, bir kez daha 1 olunca sinyali kesecek.
TA1USS

fatih6761

Öğrenmek isterseniz kesmelere bakabilirsiniz hocam. Mesela B portunda pinin değişmesi ile çalışan bir kesme var. DAC kısmını B den C portuna aktarıp B portunun kesmesini kullanabilirsiniz. Bir değişken tanımlarsınız ve bu kesme geldiğinde değerini 0 ise 1, 1 ise 0 yaparsınız. Ana programda ise her döngünün başında bu değişkeni kontrol edersiniz. 1 ise portbden devam edersiniz. Değilse index'i 0 yapıp while ile beklemeye alırsınız. Kodu sonra verebilirim...

certy

Alıntı yapılan: fatih6761 - 03 Ağustos 2013, 02:39:44
Öğrenmek isterseniz kesmelere bakabilirsiniz hocam. Mesela B portunda pinin değişmesi ile çalışan bir kesme var. DAC kısmını B den C portuna aktarıp B portunun kesmesini kullanabilirsiniz. Bir değişken tanımlarsınız ve bu kesme geldiğinde değerini 0 ise 1, 1 ise 0 yaparsınız. Ana programda ise her döngünün başında bu değişkeni kontrol edersiniz. 1 ise portbden devam edersiniz. Değilse index'i 0 yapıp while ile beklemeye alırsınız. Kodu sonra verebilirim...

Proton bilsem belki yapabilirim. :)
TA1USS

fatih6761


https://skydrive.live.com/redir?resid=578DC56E532E555A!616&authkey=!ABi_DPZaodkcrWM
Hocam RB0 pinine 0 => 1 şeklinde bir yükselen kenar geldiğinde sinüs çıkışı kaldığı noktada durduruyor. Tekrar 1 geldiğinde kaldığı yerden devam ediyor.

certy

Alıntı yapılan: fatih6761 - 03 Ağustos 2013, 05:07:24
(Resim gizlendi görmek için tıklayın.)
https://skydrive.live.com/redir?resid=578DC56E532E555A!616&authkey=!ABi_DPZaodkcrWM
Hocam RB0 pinine 0 => 1 şeklinde bir yükselen kenar geldiğinde sinüs çıkışı kaldığı noktada durduruyor. Tekrar 1 geldiğinde kaldığı yerden devam ediyor.

Teşekkürler ilginiz ve yardımınız için. :)
TA1USS

fatih6761