Sari la conținut
ELFORUM - Forumul electronistilor

Convert 1 byte to 8 bit BASCOM / SPI comunication


Cilibiu

Postări Recomandate

Acum 13 minute, Cilibiu a spus:

When using a processor for both the master and slave : Take in mind that the SPI master processor clock frequency must be 1/4 of the SPI slave processor frequency.

Lasa procesoarele master/slave la aceeasi frecventa (16).

Eu cred ca citatul de mai sus vrea sa spuna:

Nu seta clock SPI la viteza mai mare decat 1/4 din clock PROCESOR slave.

La ce speed ai setat SPI?

Link spre comentariu
  • Răspunsuri 62
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • Cilibiu

    32

  • Liviu M

    23

  • djvas

    6

  • gas2 dan

    2

Top autori în acest subiect

Imagini postate

Am facut loop la master si am adaugat un delay de 100ms, la slave am modificat delay de la 10ms la 100ms, merge perfect, dar.....tot timpul exista un DAR, am simulat ca in master mai am ceva lini de cod care produc intarzieri si am modificat delay de la 100ms la 200ms in master iar in slave a ramas delay la 100ms, daca dau mai multe refreshuri la slave se schimba ordinea, deci cat timp dureaza loop-ul la slave trebuie sa dureze si la master ca totul sa fie sincronizat, ceea ce sigur nu voi reusi la SLAVE 2 (MAIN PROGRAM).

 

SPI e setat la 1mhz am crystal de 16mhz si setarea este de 16 16000000/16=1000000

 

 

Editat de Cilibiu
Link spre comentariu
Acum 5 minute, Cilibiu a spus:

Acum cum fac sa pot trimit informatiile acestea cat mai repede posibil fara sa se decaleze???

Nu trimisul e problema, ci receptia. Probabil cu un pin suplimentar de la receptor la master, care-i spune masterului cand sa transmita. Dar n-o sa fie prea usor, ca trebuie sa implementezi un mecanism de sincronizare in ambele directii.

Link spre comentariu

Acum am pus din nou delay la 100ms la ambele si din nou sunt decalate........imi scoate peri albi.

Clar renunt la sitemul asta, deja m-am apucat sa inlocuiesc cele 3 arduino uno cu atmega 128.

Macar stiu ca pot face comunicatie SPI cu 1 byte atat sa trimit cat si sa primesc, pe mai multi byte va ramane un mister, ciudat ca in simulator functioneaza perfect codul dar in realitate nu.

Editat de Cilibiu
Link spre comentariu

Pai slave-ul trebuie sa-l sincronizezi in functie de datele receptionate, nu cu delay-uri. Numai ca habar n-am cum faci asta cu functiile predefinite ale Bascom. Teoretic atunci cand ai date noi, se modifica SPI Interrupt Flag (SPIF), asa ca daca-l testezi pe asta, te prinzi cand ai date in buffer. Numai ca sunt sanse ca functia Spiin() sa-l reseteze inainte sa apuci tu sa-l citesti.

 

Eventual faci o sincronizare soft: incepi transmisia cu un byte "start" (adica trimiti/receptionezi 5 bytes in loc de 5, cu primul byte = valoarea "start byte").

La receptie, afisezi A(2) .. A(5) numai cand A(1) are valoarea de start (if A(1) = start byte then afisare), dupa care, iin acelasi if faci A(1) = 0.

Link spre comentariu

Transmisie/master:

$regfile = "m328pdef.dat"
$crystal = 16000000

Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = High , Phase = 0 , Clockrate = 16 , Noss = 0
'Config Spi = Soft , Din = Pinb.4 , Dout = Portb.3 , Ss = None , Clock = Portb.5 , Spiin = 0 , Mode = 0 , Speed = 1 , Setup = 1
Spiinit
Enable Spi

Dim A(5) As Byte                                            'Status Sursa pozitiva canal R

A(1) = &HAA 'start byte, 10101010
A(2) = 248
A(3) = 128
A(4) = 200
A(5) = 116

Spiout A(1) , 5

Waitms(300)

End

Receptie/slave

$regfile = "m328pdef.dat"
$crystal = 16000000


Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = No , Polarity = High , Phase = 0 , Clockrate = 16 , Noss = 1
Spiinit
Enable Spi

$lib "glcdra6963.lib"

Config Graphlcd = 240 * 128 , Dataport = Portd , Controlport = Portc , Cd = 1 , Rd = 3 , Wr = 4 , Ce = 0 , Reset = 2 , Fs = 5 , Mode = 8

Cursor Off Noblink
Cls

Dim A(5) As Byte                                            'Status Sursa pozitiva canal R


Do

  Spiin A(1) , 5

  if A(1) = &HAA then
    Locate 8 , 2
    Lcd A(2)
    Locate 9 , 2
    Lcd A(3)

    Locate 10 , 2
    Lcd A(4)
    Locate 11 , 2
    Lcd A(5)
    
    A(1) = 0
  end if
    

Loop

End
Link spre comentariu

Eu incercasem ceva asemanator cand un bit il aveam 1 atunci sa citesc SPI dar nu a mers.

Am incercat ce ai zis si resultatele sunt urmatoarele.

Dupa ce dau reset la slave apar datele in ordinea care trebuie,

Dar daca modific datele in master in slave nu le transmite doar daca dau reset la ambele MCU.

Am setat portd pe A5 , pentru ca pe portul D pot modifica biti extern sa vad daca transmite noile date, dar din pacate doar la reset la amandoua MCU  ,trimite datele din momentul respectiv si atat.

 

Link spre comentariu

Trebuie pus loop-ul inapoi in master, am copiat codul din testul tau cu transmis doar o data:

 

$regfile = "m328pdef.dat"
$crystal = 16000000

Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = High , Phase = 0 , Clockrate = 16 , Noss = 0
'Config Spi = Soft , Din = Pinb.4 , Dout = Portb.3 , Ss = None , Clock = Portb.5 , Spiin = 0 , Mode = 0 , Speed = 1 , Setup = 1
Spiinit
Enable Spi

Dim A(5) As Byte                                            'Status Sursa pozitiva canal R

  A(1) = &HAA 'start byte, 10101010
  A(2) = 248
  A(3) = 128
  A(4) = 200
  A(5) = 116

  do 
    
    'A(2) = PORTD 'ca sa modifici datele. Nu stiu sintaxa exacta, corectezi tu
    Spiout A(1) , 5

    Waitms(300)
  loop
  
End

Daca vrei sa modifici din date folosind pini din portul D, faci de exemplu A(2) = PORTD (nu stiu sintaxa exacta, corectezi tu).

Editat de Liviu M
Link spre comentariu

Testat codul urmator si merge perfect.

Master:


$regfile = "m328pdef.dat"
$crystal = 16000000

Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = High , Phase = 0 , Clockrate = 16 , Noss = 0
'Config Spi = Soft , Din = Pinb.4 , Dout = Portb.3 , Ss = None , Clock = Portb.5 , Spiin = 0 , Mode = 0 , Speed = 1 , Setup = 1
Spiinit
Enable Spi

Config Portd = Input


Dim A(5) As Byte                                            'Status Sursa pozitiva canal R

Do

A(1) = &HAA 'start byte, 10101010
A(2) = 248
A(3) = 128
A(4) = 200
A(5) = Pind

Spiout A(1) , 5

Waitms 300
Loop
End

 

Editat de Cilibiu
Link spre comentariu

Totusi ar exista o conversie din Byte in bit?

Gen trimit portd pe A(1) dar in slave vreau sa ii fac detectie gen cand Portd.0 din master este 1 sa fac ceva.

Link spre comentariu

Ma bucur, numai ca e doar inceputul. O sa mai tot ai de ajustat pana sa mearga cu trebuie.

De exemplu, acum te poti juca cu intarzierea la transmisie, ca cred ca 300 ms e cam lunga.

Link spre comentariu
Chiar acum, Cilibiu a spus:

Totusi ar exista o conversie din Byte in bit?

Gen trimit portd pe A(1) dar in slave vreau sa ii fac detectie gen cand Portd.0 din master este 1 sa fac ceva.

La intrebarea asta a raspuns deja @djvas.

Cum zice si el, folosesti mastile - octeti cu toti bitii 0, mai putin bitul de testat, care-i 1. O operatie AND cu masca respectiva va fi 0 daca bitul care te intereseaza e 0, sau 1 daca bitul e 1.

La exemplul tau, cu bitul 0 din port, masca = 0000 0001 (nu mai stiu cum se sccrie in binar), iar operatia Portd.0 AND masca va dfi 0 daca Portd.0 = 0 si 1 daca Portd.0 = 1, adica fix ce te intereseaza pe tine.

Link spre comentariu

Aici e drept daca vreau ca detele primite pe spi sa le trimit catre porturi, dar in cazul asta vreau sa il afisez.

Exemplu de afisare doar 1 byte pe SPI

Master 


Config Portd = Input


Dim A(1) As Byte   

                                     

Do

A(1) = Pind

 

Spiout A(1) , 1

Waitms 300
Loop
End

 

 

Slave:

 


 

dim A(1) as byte

Dim B as bit    'portd.0 din master

 

do

 

spiin A(1),1

b=a and 10000000     ' nu merge ca imi da eroare de compilare deoarece B nu este aray

 

if b=1 then

locate 1,1

lcd "on"

else 

locate 1,1

lcd "off"

end if

 

loop

end

 

 

Link spre comentariu

Am incercat codul urmatoru. Iar B nu ma lasa sa il setez decat Byte nu Bit

Dim A(5) As Byte                                            'Status Sursa pozitiva canal R
Dim B As Byte

Do

  Spiin A(1) , 5

  if A(1) = &HAA then
    Locate 8 , 2
    Lcd A(2)
    Locate 9 , 2
    Lcd A(3)

    Locate 10 , 2
    Lcd A(4)
    Locate 11 , 2
    B = A(5) And &B10000000
    Lcd B

    A(1) = 0
  end if


Loop

End

Editat de Cilibiu
Link spre comentariu

Cred ca ma apropi dar totusi nu merge afisare pe On OFF

Ma gandesc ca daca am 2 biti activi nu o sa mai mearga si compararea.

slave:


$regfile = "m328pdef.dat"
$crystal = 16000000


Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = No , Polarity = High , Phase = 0 , Clockrate = 16 , Noss = 1
Spiinit
Enable Spi

$lib "glcdra6963.lib"

Config Graphlcd = 240 * 128 , Dataport = Portd , Controlport = Portc , Cd = 1 , Rd = 3 , Wr = 4 , Ce = 0 , Reset = 2 , Fs = 5 , Mode = 8

Cursor Off Noblink
Cls

Dim A(5) As Byte                                            'Status Sursa pozitiva canal R
Dim B As String * 10
Dim C As Byte

C = &B10000000


Do

  Spiin A(1) , 5

  if A(1) = &HAA then
    Locate 8 , 2
    Lcd A(2)
    Locate 9 , 2
    Lcd A(3)

    Locate 10 , 2
    Lcd A(4)
    Locate 11 , 2
    B = Bin(a(5))                                           ' And &B10000000
    Lcd B

    If B = C Then
    Locate 13 , 2
    Lcd "on"
    Else
    Locate 13 , 2
    Lcd "off"
    End If


    A(1) = 0
  end if


Loop

End

 

20200502_135517.jpg

Editat de Cilibiu
Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări