Sari la conținut
ELFORUM - Forumul electronistilor

Probleme de incepatori


Postări Recomandate

If A > 1 ThenA = 0End If

De ce e If-ul asta aici?

 

Si mai ai portiunea asta:

If Porta.3 = 1 Then'Do'Loop Until Porta.3 = 0

Care cred ca ar trebui inlocuita cu

Do'WaitLoop Until Porta.3 = 1

considerand ca Porta.3 = 1 cand butonul e apasat

Link spre comentariu
If A > 1 ThenA = 0End If

De ce e If-ul asta aici?

 

Si mai ai portiunea asta:

If Porta.3 = 1 Then'Do'Loop Until Porta.3 = 0

Care cred ca ar trebui inlocuita cu

Do'WaitLoop Until Porta.3 = 1

considerand ca Porta.3 = 1 cand butonul e apasat

 

 

 

Primul IF l-am pus deoarece doresc deocamdata sa am doar doua valori in variabila A , adica 0 sau 1 (pe viitor posibil sa am 4) -> de aici conditia daca A este mai mare decat 1 sa devina 0.

 

La a doua portiune, daca pinul PortA.3 il pun pe 1 logic (apas butonul) sa ramana in bucla "Do - Loop" pana las butonul (pentru a  nu mi se incrementa aiurea variabila - necontrolat).

 

Nu inteleg unde am gresit, nici hex-ul nu mi se pare sa il compileze corect...am si reinstalat Bascom, plus ca am incercat si pe un alt calculator dar la fel mi-l compileaza....

 

post-224932-0-07247800-1431261755_thumb.jpg

Link spre comentariu

Bascom nu compileaza ce e dupa apostrof

'Do'Loop Until Porta.3 = 0

Nu merge fiindca dupa ce ce se incrementeaza A de la 0 la 1 din buton vine instructiunea

If A > 1 ThenA = 0

si-l face imediat zero la loc

 

Ca sa mearga trebuie facuta inca o conditie de apasare pe buton , numai atunci il face zero , ca sa fie doua stari de 0 si 1 comutabile din buton , sau explica ce vrei sa faci

Oricum trebuie facut si debounce la buton cu functia din bascom "Debounce" sau altfel din soft

Editat de Depanatoru
Link spre comentariu

Salut,

 

Corect, Bascom nu compileaza ce e dupa apostrof, cu acele doua randuri necomentate (fara apostrof ) tot nu functioneaza.

 

La pornirea programului , variabila A este pusa pe 0

Pe urma presupunem ca apas butonul, asadar se incrementeaza cu 1 si A =1

Conditia If A > 1 Then banuiesc ca nu se realizeaza in acest moment in care A = 1, si nu A > 1 (cel putin dupa logica mea). Oricum, ca sa ma conving am folosit si A > 2 si la fel nu mi se incrementeaza. 

 

Ca idee, eu doresc sa am doua stari comutabile din buton. Daca apasa o data butonul, valoarea din variabila A devine 1, daca mai apas o data devine 0, si tot asa, un fel de buton general On/Off. De cate ori apas pe buton, de atatea ori se modifica valoarea, 0 sau 1.

 

 

p.s.

 

Cred ca m-am prins de unde problema mea:

     - pentru citit starea unui pin se foloseste PINx.y , si nu PORTx.y

 

 

Da, asta era problema se pare, acum imi functioneaza corect...

Do   If Pina.3 = 0 Then   Do   Loop Until Pina.3 = 1   A = A + 1   If A > 1 Then   A = 0   End If   End IfLocate 2 , 1Lcd ALoop
Editat de mariuss_suciu
Link spre comentariu
If Pina.3 = 0 ThenDoLoop Until Pina.3 = 1

1. Scoate if-ul de aici, ca nu are niciun rost.2. Cand scrii cod, foloseste indentarea, ca se citeste foarte greu fara.3. Foloseste o intrerupere care prinde un front de unda (0->1 sau 1->0) pentru detectarea apasarii. Cu codul curent cat timp tii apasat butonul, chiar daca tu il tii apasat doar 10 ms, bucla aia se va executa de multe ori. Daca il lasi sa numere mai mult, o sa vezi ca iti incrementeaza cu valori aleatorii, in functie de cat ai apasat. O varianta alternativa ar fi sa pui un wait in bucla, ca sa poti sa vezi si schimbarile. Codul ar trebui sa arate cam asa: 

Do   Do   Loop Until Pina.3 = 1   A = A + 1   If A > 1 Then      A = 0   End If   Locate 2 , 1   Lcd A   WAITMS 300Loop
Link spre comentariu

Salut keenox,

 

Multumesc pentru sugestii.

 

1. In cazul de fata intradevar nu are rost if-ul, insa bucata asta de cod va face parte dintr-un program mai complex, si ma intereseze sa se execute aceasta bucata de cod doar cand apas acel buton, in rest sa sara peste ea. Ma gandesc ca exista variante mai profesionale decat am scris eu, insa nivelul la care am ajuns ma limiteaza oarecum la varianta pe care am scris-o pana acum, pe masura ce voi invata/experimenta am sa incerc sa optimizez codurile pe care le voi scrie.

 

2. Da, voi incerca sa folosesc identarea, mie mi-era usor sa il citesc asa pentru ca am toata ideea in cap..., chiar voi face modificarile necesare in acest cod.

 

3. Am sa studiez si intreruperile , deocamdata nu sunt convins ca stiu cum sa le folosesc, insa am o imagine asupra lor, care este rolul si cum functioneaza. Urmeaza sa experimentez pe placa de dezvoltare.

 

 

p.s. chiar acum ma joc cu un encoder cu contacte sa vad cum pot incrementa/decrementa valoarea dintr-o variabila folosind intreruperile , doar ca numara aiurea...:)

Link spre comentariu
  • 3 săptămâni mai târziu...

Salut,

 

Din nou ma lovesc de o alta problema la care incerc sa ma documentez de cateva zile si nu am gasit o explicatie care sa o inteleg.

 

La un atmega128a am conectat un DAC pe SPI (AD5320) respectand conexiunile la interfata hardware a uC-ului. Intr-un final dupa ce am oscilografiat informatiile care se transmit, am putut "vorbi" cu DAC-ul si sa ii setez o tensiune la iesire, insa totusi nu inteleg cum trebuie sa ii transmit informatia.

 

Informatia transmisa trebuie sa fie dupa urmatoarea forma: 

 

post-224932-0-51801000-1432755385_thumb.jpg

 

Am incercat sa ii transmit (am scris in binar sa pot urmari usor) in configuratia DATA ORDER = MSB:

 

val_16 = &b00001000_00000000     [&b "00 - xx" "00 - normal operation" "1000_00000000 - informatie"]

 

- dupa ceea ce am inteles, in cazul de mai sus ar fi trebui ca DAC-ul sa fie setat pe "normal operation" si tensiunea de la iesire sa fie egala cu jumatate din tensiunea lui de alimentare, valoarea din registrul ar fi fost 2048 ( 0 - 4095 ), insa mie mi se transmite sub alta forma informatia pe SPI si nu inteleg de ce.

 

Daca incerc sa transmit 16 biti sub urmatoarea forma:

 

val_16 = &b01234567_89abcdef

 

constat ca rezultatul nu este cel asteptat, si pe osciloscop vad: 76543210_fedcba98 , adica cei doi bytes in oglinda fiecare.

 

In cazul in care setez sa imi trimita prima data LSB, atunci pe osciloscop vad fedcba98_76543210 . 

 

 

Atasat este si codul scris, rescris si modificat de multe ori (scuzati pentru haosul din cod):

 

-mi-am facut niste variante de "16 biti" ca sa pot transmite / intelege ce se transmite.

- iesire DAC-ului am conectat-o la un ADC din uC sa vad daca apare ceva, dar nu era ce trebuie.

$regfile = "m128def.dat"$crystal = 8000000$hwstack = 40$swstack = 16$framesize = 32Config Lcdpin = Pin , Rs = Portd.5 , E = Portd.4 , Db4 = Portd.3 , Db5 = Portd.2 , Db6 = Portd.1 , Db7 = Portd.0Config Lcd = 20 * 4Cursor Off NoblinkConfig Spi = Hard , Interrupt = Off , Data Order = Lsb , Master = Yes , Polarity = High , Phase = 0 , Clockrate = 4 , Noss = 0'Config Spi = Soft , Dout = Portb.2 , Clock = Portb.1 , Ss = Portb.0 , Mode = 3SpiinitConfig Portb = OutputConfig Adc = Single , Prescaler = Auto , Reference = AvccConfig Porte.1 = InputDdre = &B00000000Alias Buton As Pine.1Dim Val_16 As WordDim W As WordDim Z As SingleDim Varianta As ByteDim Buton As WordVarianta = 0DoIf Buton = 1 ThenDoLoop Until Buton = 0   Incr Varianta   If Varianta > 3 Then      Varianta = 0   End IfEnd IfIf Varianta = 0 Then   Val_16 = &B00000000_00000000   Waitus 1   Spiout Val_16 , 2   Waitms 10End IfIf Varianta = 1 Then   Val_16 = &B10000000_11100000   Waitus 1   Spiout Val_16 , 2   Waitms 10End IfIf Varianta = 2 Then   Val_16 = &B11001111_00000000   Waitus 1   Spiout Val_16 , 2   Waitms 10End IfIf Varianta = 3 Then   Val_16 = &B00000000_11111111   Waitus 1   Spiout Val_16 , 2   Waitms 10End IfWaitms 100W = Getadc(2)Z = W / 1023Z = Z * 5Locate 1 , 1Lcd VariantaLocate 2 , 1Lcd Val_16Locate 4 , 1Lcd Fusing(z , "#.################")Loop
Link spre comentariu

in configuratia DATA ORDER = MSB:

 De ce MSB? Mie din poza imi iese LSB (DB0). 

val_16 = &b01234567_89abcdef In cazul in care setez sa imi trimita prima data LSB, atunci pe osciloscop vad fedcba98_76543210 .

Dupa parerea mea, asta e varianta corecta.Asta daca interpretez eu corect rezultatul de la osciloscop. Editat de Liviu M
Link spre comentariu

Atunci ai postat poza gresita.

Sorry, poza e buna, ochii sunt defecti. :rade:

Ai dreptate, e MSB FIRST.

 

val_16 = &b01234567_89abcdef

 

constat ca rezultatul nu este cel asteptat, si pe osciloscop vad: 76543210_fedcba98 , adica cei doi bytes in oglinda fiecare.

 

In cazul asta, esti sigur ca pe osciloscop nu vezi &b89abcdf_01234567? Ca eu varianta asta as putea-o intelege, pe cea pe care ai scris-o tu mai sus nu.

Editat de Liviu M
Link spre comentariu

Ai dreptate:

 

Am transmis : Val_16 = &B10000000_11100000

Am vazut:                        &B11100000_10000000

 

Cu galben este clock-ul

Cu albastru este Data Out de la uC.

 

post-224932-0-75388800-1432834617_thumb.gif

 

Nu inteleg cum as putea atunci sa fac sa ii transmit mereu xx00 + 12 biti dintr-o variabila.  :26  .... intentionez sa reglez tensiunea dintr-o sursa liniara ...

Link spre comentariu

E exact cum am banuit. Microcontrollerul fiind pe 8 biti, cei 16 biti de date sunt salvati in doua locatii, la adresa A octetul LS si la adresa A+1 octetul MS.

Cum spiout trimite cate un octet o data, incepe cu adresa A si termina cu adresa A+1, fiecare din octeti trimis MSB first.

Solutia? Pui octetii de trimis intr-un array, in ordinea in care-ti trebuie.

dim deTrimis () as bytedeTrimis(0) = msBytedeTrimis(1) = lsBytespiout(deTrimis, 2)

Sau faci cum ai facut pana acum, iti "construiesti" comenzile cum iti trebuie. Cu avantajul ca acum stii de ce. :rade:

Link spre comentariu

Bun, acum am inteles motivul pentru care datele se transferau asa, insa nu stiu cum voi face ca informatia mea pe 12 biti sa o combin cu inca 4 biti (&bxx00 - normal mode) , sa le impart in 2 bytes si sa ii trimit unu dupa celalalt...

 

Ca idee, pana acuma mi-am facut pentru sursa mult dorita o parte de cod care sa incrementeze/decrementeze doua variabile de tip integer dintr-un encoder + 1 buton din care le schimb intre ele (tensiune si curent)....iar acele doua variabile cumva va trebui sa le formatez si sa le trimit pe SPI.....dar cea mai grea intrebare: cum ?

 

Ca si principiu, dupa cate am citit pana acum (in 2 ore) mi-am facut o idee, insa nu stiu daca am inteles corect:

     - o matrice pe 2 bytes

     - primii 4 biti ii pun 0000 - pentru normal mode

     - cumva va trebui sa scot din variabila mea de tip integer ultimii 12 biti , pe care sa ii pun in matrice in continuarea celor 4

     - pe urma transmit primii 8 biti, pe urma ceilalti 8 biti ramasi

 

Cam asa ceva ar trebui facut ? Sau am luat-o departe pe camp deja ? :)

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