i2c ile haberleşme

Başlatan cemilsivas, 09 Mart 2020, 23:59:18

ete

Yine aynı noktaya geliyoruz. Bu display ile ne yapmaya çalışıyorsun?.
Dİsplayden bir bilgimi alacaksın yoksa ekrana bir şeymi yazdıracaksın.?
Verdiğin örnekler hep ekrana bir şey yazdırmaya çalışanların örnekleri.
Ama bence eksikleri var sanki . EMinde olamıyorum.
Senin yaptıklarından farklı bir şey görmedim. Gördüğüm şey cihaz kodu olan $4A nın verilerek alete bir şey yazdırmaya çalıştıkları ama I2C formatı dışına çıkılıyor. Aklım ermedi bu işe açıkçası.

Ete

cemilsivas

Aynen hocam. Amacım ekrana birşeyler yazdırmak. Aracın kontağını açınca hoşgeldin falan yazsın istiyorum.

Peki hocam aklıma şu takıldı.

Şimdi bize topoloji verilmiş(kelimeyi yanlış kullandım mı bilmiyorum.)

İşte sda yı high yap 100 ms bekle sonra cevap al falan.
Biz picbasic'te i2cwrite dediğimizde zaten bu prosedür işlemiyor mu?

2. aklıma takılan konu, tam emin olmamakla birlikte, acaba bu veri gönderme işini shiftout ile yapsak nasıl olur?
Hatırlarsanız nrf modülü konusunda da hep önce adres sonra veri gönderirdik.
shiftout mosi,sck,1,[adres]
shiftout mosi,sck,1,[veri] gibi.
Ya da i2c'de bu formatta nasıl kullanırız?
Hocam sıkılmadan bıkmadan cevaplarınızı esirgemediğiniz için çok teşekkkür ederim.

ete

Ortada bir çok bilinmeyen var. Yapılmış örneklere bakınca orada da mantığa ter gelen husular olduğunu görüyorum.
Öncelikle işin şema (bağlantı) kısmına bakacak olursak, İŞlemciye MRQ hattı, SDA hattı ve SCL hattı bağlanması gerekiyor.
Sistem I2C ise SDA ve SCL hatlarının pullup lı olması gerekir. Ama yapılmış şemaya bakıyorum bu 3 hat birer diotla işlemciye bağlanmış üstelik diyotların çizgili ucu işlemciye bakacak şekilde yerleştirilmiş. BU farklı lojik seviyelerin çakışmasını önleyecek bir tedbir. Ama diğer yandan MRQ hattı işlemciden kontrol edilen ve aynı zamanda display tarafındanda lojjik değeri değiştirilen bir uç. BU açıklamaya SDA da dahil.
Diyotlu sisteme bakınca İşlemci MRQ hattını LOW a çekebilir. Ama HIGH a çekemez diyottan dolayı. Bu durumda bu hattın display tarafında pullup olması gerekir. İşlemci hattı serbest bırakırsa display tarafındaki pullup onu HIGH yapar. Bunun var olup olmadığını bilmiyoruz. Ama adamlar uygulamış ve böyle çalıştığını varsayacağız.
SDA hattına gelince benzer durum burada da var.
Şimdi gelelim protokol kısmına, normal bir I2C haberleşmede MRQ hattı kullanılmaz. Yanlızca SCL ve SDA hatları bulunur. Haberleşme başlangıcı için bir start durumu vardır. Bu şöyle uygulanıyor. SCL hattı HIGH da beklerken SDA hattı HIGH dan LOW a geçirilir. ardından byte alışverişi başlatılır. Display protokolüne bakıyorum, Öncelikle MRQ hattı master tarafından önce LOW ardından HIGH yapılıyor. Bu işlem haberleşme isteği yaratmak için veriliyor. Ardından yine İşlemci SCL hattını HIGH yapıyor ve Display (Ekran diyelim) SDA hattını önce LOW sonra HIGH yapıyor. İşlemcinin bu noktada SDA hattının önce LOW ardından da HIGH olmasını beklemesi gerekir. İşte bu noktada işlemci SDA hattını HIGH olarak algıladığında START sinyalini veriyor. Yani SDA hattını LOW a çekerek önce $4A bilgisini ardındandan 1. byte ardından 2.byte ... şeklinde gönderilmesi gereken bytlar gönderiliyor.
İşte bu noktada ekran haberleşme formatına bakmamız gerekiyor. Pdf dosyasında yazılanlara bakacak olursak,

Terümesi şöyle, Mesaj formatı, Mesaj, ekranın slave adresine sembol bytları (2 adet) ve data byte ları (8 adet) gönderilmesi ile yollanır diyor.
(Format einer Nachricht Die zu sendende Nachricht setzt sich zusammen aus der Slave Adresse des Displays, den Symbol-Bytes und den Daten-Bytes.)
Burada Sembol Byte ları nedir? bence display ekran adresi olması gerekir. Ama ne verilecek bunun için belli değil.
Data byte ları belli her bir digit için yazdırılacak yazının ASCII karşılıkları yollanmalı.
Symbol byte larının ne olduğunu bulabilirsek sorun aşağı yukarı çözülmüş olacak.
Bunu biraz araştır derim. Yada 2 adet sıfır göndererek burayı aşmayı dene bence.

Gelelim Standart I2C formatı ile bağdaşıp bağdaşmadığına. Görünüşe bakılırsa başlangıçtaki MRQ isteği dışında işlemin gerisi standart I2C formatında yürüyor. O zaman aşağıdaki sıralamaya uygun bir format oluşturulabilir diye düşünüyorum.
1.   İşlemci MRQ hattını LOW2 a çeker.
2.   Ekran SDA hattını LOW'a çekmesini bekle T1min = 100μ s     T1max = 15ms
3.   İşlemci MRQ hattını HIGH 'a çeker  süre T2min = 100μ s     T2max = 200μ s aralığında olmalı
4.   Bu noktadan sonra standart I2C komutu verilebilir artık KOmut start sinyalini otomatik verecektir. KOmut içinde control byte olarak $4A ardından 2 adet sıfır ve ardından 8 adet karekter byteı yollanmalı.

Şimdi bunları komut vererek yapmaya çalışalım.
MRQ_Line=LOW
SURE=0
WHILE SDA=HIGH
  SURE=SURE+1 
  IF SURE=15000 then GOTO HATA '15ms den fala beklersem hata ver
  pauseus 1
WEND
MRQ=HIGH
I2CWRITE SDA,SCL,$4A,0,0,["E","T","E"," ","Y","A","Z," "," "]
Aynı komut satırını bir kerede şöyle dene istersen,
I2CWRITE SDA,SCL,$4A,0,["E","T","E"," ","Y","A","Z," "," "] 'yani tek sıfırlı

Bu kezde çalışmaz ise artık benim yapabileceğim bir şey olmayacak. Zira çalışmaz ise bilgimiz eksik anlamına gelecek ve o eksikleri tamamlamadan bunun çalışması zor olacak.

Diğer dikkatimi çeken önemli bir konu daha var. BU ekranda birde AA (Anten Amplifikatörü) olarak isimlendirilmiş bir hat daha var ve asıl ekranı çalışmaya yönlendiren uç bu olmalı. Zira radyoyu açtığın anda bu hat HIGH konumuna geçerek ekranın açılmasını sağlıyor. Bu nedenle söz konusu hat dışarıdan çalıştırmalarda direk olarak pozitif beslemeye bağlanmış. Voltaj değeri nedir bilemiyorum ama bu ucun sürekli HIGH da tutulması gerekir. Yada işlemci üzerinden öncelikle bu hat HIGH a çekilmesi gerekir. Kendi açıklamasında 4V HIGH 1V ve altı low olarak nitelendirilmiş. O halde bu AA ucuna en azından 5V verilmeli. Emniyet açısından bir direnç ile bu hatta 5V verilmesi uygun olacaktır.
 
Başkada dikkatimi çeken bir husus yok. Kolay gelsin umarım bu sefer başarırsın.

Ete

cemilsivas

İyi günler hocam. Dün video çekmiştim. Burada sizinle paylaşıyorum.
@ DEVICE pic16F628a
@ DEVICE pic16F628a, WDT_ON
@ DEVICE pic16F628a, PWRT_ON
@ DEVICE pic16F628a, BOD_ON
@ DEVICE pic16F628a, PROTECT_OFF
@ DEVICE pic16F628a, LVP_OFF
@ DEVICE pic16F628a, CPD_OFF
@ DEVICE pic16F628a, MCLR_OFF
@ DEVICE pic16F628a, INTRC_OSC_NOCLKOUT
define OSC 4
TRISA=0  'A portu çıkış olarak ayarlandı.
TRISB=0  'B portu çıkış olarak ayarlandı.
PORTA=0
CMCON=7
    
Include "modedefs.bas"
DEFINE LCD_DREG PORTB 
DEFINE LCD_DBIT 4  
DEFINE LCD_EREG PORTA  
DEFINE LCD_EBIT 6  
DEFINE LCD_RSREG PORTA   
DEFINE LCD_RSBIT 7  
DEFINE LCD_BITS 4  
DEFINE LCD_LINES 2
 
symbol scl=portb.1
symbol mrq=portb.2
symbol sda=portb.0

a var byte
b var byte
c var byte
SURE VAR WORD

c=0
b=0
a=0
basla:
scl=0
mrq=0
sda=0
low MRQ
sure=0
WHILE SDA=1
  SURE=SURE+1 
  IF SURE=15000 then GOTO HATA '15ms den fala beklersem hata ver
  pauseus 1
WEND
high mrq

I2CWRITE SDA,SCL,$4A,0,0,[$01,$01,$AE,$AE,$AE,$AE,$AE,$AE,$AE,$AE]
'Aynı komut satırını bir kerede şöyle dene istersen,
'I2CWRITE SDA,SCL,$4A,0,["E","T","E"," ","Y","A","Z"," "," "] 'yani tek sıfırlı
 pause 1500 
 a=a+1
 lcdout $fe,1,"gonderim",dec SURE," ",DEC sda      
 GOTO BASLA

hata:
lcdout $fe,1,"hata "
PAUSE 1000
GOTO BASLA
end
Hocam videoda da dediğim gibi sanki display mrq pininin lojik seviyesine göre bize cevap veriyor. Ama görüntüyü niye basamadık anlamadım.
Dediklerinizi denedim. Adres kısmını iki tane 0 ile denedim. Bir harfin hex kodunu yazarak denedim. Veri kısmında verdiğiniz örnekteki gibi başa ve sona boşluk atarak denedim. Bir de paylaştığım asm kodundaki gibi önce veri bölümünde $01 yazarak gönderme yapmış. Onu da denedim.
Hocam bir de dediğiniz AA  pini ve ateşleme pinlerine(5. ve 8. pinler)  +12v verince ekran silindi. Bu pinlerin biri radyodan bilgi almak içinmiş. Diğeri de kontağı çevirdiğimde ekran ışıklarını yakıyormuş. Ben de ikisini birleştirip 12 v verdim.
Acaba dedim. Belki pic bizi yanıltıyordur. Aldığım süre bilgisini denedim. Sda pinini çıkardım. Pic'te sda hiç 1 olmadı. Ekranı kapattım yine olmadı. Demekki sda pini cevap veriyor. Bu da beni umutlandırıyor hocam.
Eğer önerileriniz varsa yine beklerim.

ete

AA pinine 5V vererek denesenmi acaba diyorum. Zira adam High için 4V demiş LOW için 1 volt demiş.
Başkada bir şey aklıma gelmiyor maalesef. Bir şeyler eksik gibi. Ekran adresleri farklı olabilir. Onları bilmeden ekrana birşey yazdırmak zor.
Ete

cemilsivas

S. A. Hocam. Hayırlı günler. Bugün yeni denemeler yaptım. Birkaç değişik yazma kodu denedim. Video çektiğim kodda ekran sürekli cevap vermeye başladı. Anladığım kadarıyla iletişim bu şekilde olacak.

Searching the Internet I got to know that there are only three lines used SDA, SCL (Yes from the Philips I2C protocol) and MRQ (Which made things more difficult). Doing some measurements I found that all three lines are pulled up to 5V by a resistor located in the display. This corresponds to the I2C specification. All devices connected to a I2C bus are only allowed to pull the communications lines low by a transistor (open collector output port). If no device pulls the communication line low it will be pulled high by the resistors.

Hocam araştırdığım kadarıyla dediğiniz doğru imiş. Yani ekran içeriden dirençle 5v'ye çekiliymiş.

Looks like a mess. But it can easily be explained. First click the picture to enlarge. In this picture each pixel in the X-direction is a sample of the three communication lines used. The black line is SCL, the blue is MRQ and the red is SDA. There are 65535 samples taken in 2.00 seconds. The sample rate is 32.8 kHz. The time each sample presents is about: 30 microseconds.

The radio was turned off. The measurement was set to start on a change. Than the radio was turned on. The result:

The power up sequence of the car radio shows that all three go low followed by a low pulse (line test?) of each line. Pulling MRQ is acknowledged by the display by pulling SDA low. Next there is a long period that MRQ is low This is a sort of reset pulse coming from the radio. The display responds by pulling all three lines low.
After an idle period (all high), you see a communication block. It is started by MRQ going low for a short period. Than an I2C start is send (SDA goes low while SCL is high). Next the address byte is send according the i2c protocol. Next MRQ goes low. And than the 10 data bytes follow. Next MRQ goes high and a I2C stop is send (SDA goes high while SCL is high).
And a second communication block is send, but the data makes no sense, as it suddenly appears to be terminated.
Analyzing the protocol shows:

Idle state all lines are high.
Pull MRQ low for a short period and let it go high again.
Send a "I2C Start"
Send the address byte (0x94).
Pull MRQ low.
Send 10 data bytes
Let MRQ go high
Send "I2C Stop"
We are back in the idle state.
The bytes contain in total 9 bits. First there are 7 bits of data followed by a parity bit (odd-parity) followed by an acknowledge bit (Part of I2C specification). The first byte is the address byte of the display. The next two bytes control the "lights" like "CD", "RDS" and the decimal points. The following 8 data bytes contain the characters to be shown on the display using 7 bits ASCII. Decoding the first block results in:

0x94 = 10010100A (This is the I2C address of the display)
0x10 = 00010000A (Turn one light on, I did not bother to check which bit belongs to which light.)
0x01 = 00000001A (Turn the other lights off)
0x8C = 10001100A = "F"
0xA4 = 10100100A = "R"
0x8A = 10001010A = "E"
0x8A = 10001010A = "E"
0xB5 = 10110101A = "Z"
0x40 = 01000000A = " "
0x8C = 10001100A = "F"
0x9B = 10011011A = "M"

Hocam burada da(google translate'den anladığım kadarıyla) yapacağımız işler belirtilmiş. Yanlış anlamadıysam yazdığımız kod doğru.

Ancak bence şöyle bir sıkıntı var. Pbp'de i2c komutu verdiğimizde kendi başlangıç yapıyor, kodları gönderiyor ve durdurma prosedürünü işletiyor.
Biz adresi i2c ile gönderirken prosedür gereği stop prosedürünü de gönderiyoruz. Ama öyle olmamalı.
mrq pinini high yaptıktan sonra
1- i2c ile adresi göndereceğiz.
2- mrq pinini low yapacağız.
3- veri baytlarını yollayacağız.(10 bayt göndereceğiz)
-Burada veri gönderdikten sonra stop biti göndereceğiz.
4- mrq pinini yükselteceğiz.
Biz 1. aşamada i2c ile adres gönderirken stop bitini de gönderiyoruz. Böylece diğer aşamalar olmadan prosedür sonlanıyor.

Bununla ilgili yapabileceğimiz birşey var mı hocam?

Eğer yoksa şöyle yapabilir miyiz? i2c protokolünü biz kendi elimizle işletsek. Yani sda'yı scl'yi kendimiz yükseltsek düşürsek. Start ve stop pinlerini kendimiz göndersek.
Aslında dökümanda start ve stopla ilgili bilgi var. Ama veri gönderirken ne yapacağımı tam olarak bilmiyorum.
Çözüm öneriniz varsa bekliyorum hocam. Saygılar. Hayırlı sağlıklı günler.

cemilsivas



Hocam burada da şema var. Ama şema bana yanlış gibi geldi. Siz de kontrol ederseniz sevinirim.

ete

Yanlışlık PORTA ya bağlı seri diyotlardan geçirilmiş hatlarda olsa gerek. Daha öncede bvu şemayı incelemiştim. Pic burada master olacak ise CLK palsi ondan çıkmalı. Peki diyottan o palsin bir peryodu geçer diğer peryodu geçmez. Ona karşılık diğer tarafta pullup yada pulldown direnci olmalı onlar yok.
Benzer şekilde Data sinyali de aynı şekilde olmalı ve PULLUP lar hiç ortada gözükmüyor.

Ete

Powered by EzPortal