Sari la conținut

Cateva pareri despre o viitoare aplicatie cu microcontrollere


Postări Recomandate

Sunt 8 relee, adica un port intreg, asta inseamna 1byte de date, valorile fiind de 1-255 avem nevoie de 255 diferite date pe 8 biti, nui mare treaba.

Valoare de 1-255 se foloseste pentru indexare, tabelul este defapt un vector de date si gata.

De exemplu unsigned char output_transform_tabel[] = {3, 7, 9, 12, ...}

  • Răspunsuri 58
  • Created
  • Ultimul Răspuns

Top Posters In This Topic

Top Posters In This Topic

Posted Images

De exemplu unsigned char output_transform_tabel[] = {3, 7, 9, 12, ...}

 

Puteti sa detaliati putin! Am spus ca vreau sa ajut putin la dezvoltarea programului si poate poate reusim cu toti punand mana de la mana.

 

unsigned char output_transform_tabel[] = {3, 7, 9, 12, ...} ???????????????

 

Cu A1...A8 am notat porturile de la iesire uC care vor comanda releele 1...8. In partea dreapta am notat tensiunea care se doreste sau se tasteaza. Totusi, pentru ca s-a mai discutat aspectul asta, cum facem ADUNAREA. Spre exemplu, tastezi 29 sau 129, cum citeste uC asta? De fapt, cred ca am mai intrebat!!!

 

A1 A2 A3 A4 A5 A6 A7 A8

1 1 0 0 0 0 0 0 0

2 0 1 0 0 0 0 0 0

3 1 1 0 0 0 0 0 0

4 0 0 1 0 0 0 0 0

5 1 0 1 0 0 0 0 0

6 0 1 1 0 0 0 0 0

7 1 1 1 0 0 0 0 0

8 0 0 0 1 0 0 0 0

9 1 0 0 1 0 0 0 0

10 0 1 0 1 0 0 0 0

11 1 1 0 1 0 0 0 0

12 0 0 1 1 0 0 0 0

13 1 0 1 1 0 0 0 0

14 0 1 1 1 0 0 0 0

15 1 1 1 1 0 0 0 0

16 0 0 0 0 1 0 0 0

17 1 0 0 0 1 0 0 0

18 0 1 0 0 1 0 0 0

19 1 1 0 0 1 0 0 0

20 0 0 1 0 1 0 0 0

21 1 0 1 0 1 0 0 0

22 0 1 1 0 1 0 0 0

23 1 1 1 0 1 0 0 0

24 0 0 0 1 1 0 0 0

25 1 0 0 1 1 0 0 0

26 0 1 0 1 1 0 0 0

27 1 1 0 1 1 0 0 0

28 0 0 1 1 1 0 0 0

29 1 0 1 1 1 0 0 0

30 0 1 1 1 1 0 0 0

31 1 1 1 1 1 0 0 0

32 0 0 0 0 0 1 0 0

...................................................................

256 1 1 1 1 1 1 1 1

 

 

In programarea in C instructiunea de realizare a tabelului e de forma asta:

 

tabel [nr. rand] [nr. coloana] = 
{
{1	0	0	0	0	0	0	0}
{0	1	0	0	0	0	0	0}
............................
{1	1	1	1	1	  1	   1	  1}
}

 

Dar eu ma gandeam la o cautare a pointerilor dintr-un tabel, utilizand o instructiune de genul:

 

unsigned char output_transform_tabel [] = {....}
{ char *tensiune_tastatura;

tensiune_tastatura = sir;
while (*sir)
{
*sir = toupper (*sir);
sir++;
}
return (tensiune_tastatura)

 

Sau mai bine apelam la look-up ca in Excel ? Dar sa vedem ce spune si domnu donpetru!!! scratch_one-s_head.gif

 

Toate cele bune tuturor

@dan

Editat de dan_e

Bun, vad ca trebuie sa explic in detalii, aveti tensiuni intre 1-255 asta inseamna defapt 7 biti -7relee, daca ploturile au tensiuni 1,2,4,8,16,32,64,128V adica puterile lui 2 nu trebuie nici un algoritm si nici look up table pur si simplu se scrie pe port valoare citita de la tastatura. Fiind vorba de 7biti, bitul 0va ramane liber recomand ca acel releu sa fie legat in serie cu iesirea si comandat numai dupa ce a fost configurat iesire,ca un output enable.

 

Look-up table era indicat daca configuratie releelor ar fi fost mai complicata, vad ca nu ati inteles cum se foloseste si ce rol are un look up table, fiind vorba de o configuratie statica nu are rost sa recalculezi de fiecare data printr-un algoritm, valorile se introduc intr-un tabel si numai indexare se calculeaza, na bun cum implementam aici? Foarte simplu: valoare citita de la tastatura este indexul tabelului, adica tabelul are 256 locatii de 8 biti fiecare locatie are configuratia de relee pentru valoare de tensiune respectiva si se acceseaza cu valoare citita de la tastatura de ex. key=getkey() portd=tabel(key). In cazul prezent prima varianta este cea buna, dar se poate experimenta si cu look-up table.

Bun, vad ca trebuie sa explic in detalii, aveti tensiuni intre 1-255 asta inseamna defapt 7 biti -7relee, daca ploturile au tensiuni 1,2,4,8,16,32,64,128V adica puterile lui 2 nu trebuie nici un algoritm si nici look up table pur si simplu se scrie pe port valoare citita de la tastatura. Fiind vorba de 7biti, bitul 0va ramane liber recomand ca acel releu sa fie legat in serie cu iesirea si comandat numai dupa ce a fost configurat iesire,ca un output enable.

Aceasta metoda cred ca presupune mentinerea in permanenta in starea "conectat" a releului aferent infasurarii transformatorului de 1V! Adica, cand punem sub tensiune montajul, acesta automat ne va indica 1V urmand ca din tastatura sa setam o valoare imediat superioara. Dar oare o sa putem sa anulam acel volt ? Mai exact, atunci cand dorim 0V la iesire! In plus, mai e o problema aici, sa exemplific: daca tastam 7, valoarea in binar atribuita porturilor este 111, altfel spus: Port.B0=1; Port.B1=1; Port.B2=1; Port.B3...Port.B7=0. Cum setam in acest caz Port.B3...Port.B7=0 ? Sa definim toate porturile in zero la inceputul programului ? Apoi, un alt aspect care merita atentie: cum facem ca uC-ul sa "adune", adica cand tastam 4 si imediat dupa aceea 7 sa "vada" 47 ? Dupa altgoritmul prezentat "pe 7biti" acesta presupune - sa ma corectati daca gresesc - ca atunci cand tastam 4, porturile de iesire automat sa se configureze pentru 4V dar cand imediat dupa aceea dorim sa tastam 7, uC sa sterga 4 si sa configureze iesirile pentru 7V. Adica exista pericolul sa nu putem seta tensiunii mai mari de 9V ? Cu siguranta exista o solutie la asta dar... cum ?

Cum am spus si anterior trebuie un releu legat in serie cu iesirea, un fel de output enable si asa se poate seta 0V, si o alta chestie PORTB = 7; va rezulta 0b00000111 adica 7, nu vad problema :) nu inteleg nici problema cu "adunarea" pe o tastatura 4x3 sunt si 2 taste # si * de ex. # se poate folosi ca enter, se tasteaza valoare 123 si # pentru validare, simplu ca buna ziua si pe port PORTB = 123 daca trebuie adunare PORTB = PORTB+25;

Prea multa filozofie prea putina practica ...

 

Aceasta metoda cred ca presupune mentinerea in permanenta in starea "conectat" a releului aferent infasurarii transformatorului de 1V! Adica, cand punem sub tensiune montajul, acesta automat ne va indica 1V urmand ca din tastatura sa setam o valoare imediat superioara. Dar oare o sa putem sa anulam acel volt ? Mai exact, atunci cand dorim 0V la iesire! In plus, mai e o problema aici, sa exemplific: daca tastam 7, valoarea in binar atribuita porturilor este 111, altfel spus: Port.B0=1; Port.B1=1; Port.B2=1; Port.B3...Port.B7=0. Cum setam in acest caz Port.B3...Port.B7=0 ? Sa definim toate porturile in zero la inceputul programului ? Apoi, un alt aspect care merita atentie: cum facem ca uC-ul sa "adune", adica cand tastam 4 si imediat dupa aceea 7 sa "vada" 47 ? Dupa altgoritmul prezentat "pe 7biti" acesta presupune - sa ma corectati daca gresesc - ca atunci cand tastam 4, porturile de iesire automat sa se configureze pentru 4V dar cand imediat dupa aceea dorim sa tastam 7, uC sa sterga 4 si sa configureze iesirile pentru 7V. Adica exista pericolul sa nu putem seta tensiunii mai mari de 9V ? Cu siguranta exista o solutie la asta dar... cum ?

Practica se poate pune in aplicare dar asta de abia dupa ce ne-am lamurit "filozofic" asupra problemei. Pana acum s-au trasat cateva supozitii dar nimic concret care sa fie aplicat practic sau pe baza caruia sa scriem un program. Spunem ca stim ceva, palpam problema, dar solutia concreta se lasa asteptata. Dar pana @Laci doreste sa-si expuna mai concret solutia, inclusiv un exemplu pe un compilator personal cu care lucreaza, am sa va expun "algoritmul propriu" (ramane de vazut, in zilele ce urmeaza, daca se poate implementa).

 

Ma gandeam, apropo de altgoritm, ca valoarea citita de la tastatura sa fie inclusa intr-o bucla (in C++) do {... while(), unde pentru inceput, din sirul de constante 1, 2, 4, 8, 16, 32, 64, 128 (fiecare constanta atribuita unui port de iesire de la B0...B7), sa se aleaga valoarea imediat inferioara valorii tastate.

 

Spre exemplu, sa presupunem ca se tasteaza 123, semnificand 123V, atunci kp=123. In sirul anterior mentionat, valoarea imediat inferioara aceste valori este 64, atunci kp-64=59. Deoarece 64 reprezinta portul B6, atunci daca restul este mai mare sau egal cu zero (59>0), portul B6 va fi in 1 logic (ceea ce inseamna ca va c-da releul aferent infasurarii de 64V). Apoi, deoarece rezultatul este pozitiv, bucla continua si compara rezultatul cu sirul de constante si alege iar valoarea imediat inferioara rezultatului, mai exact 32. Vom avea 59-32=27. Deoarece 27>0, portul.5 va fi in 1 logic (idem c-da releu 32V). In continoare vom avea: 27-16=11 (Port B4 = 1logic - c-da releu 16V); 11-8=3 (Port B3 = 1logic - c-da releu 8V); 3-2=1 (Port B1 = 1logic - c-da releu 2V) si 1-1=0 (Port B0 = 1logic - c-da releu 1V).

Daca adunam "porturile"=64+32+16+8+2+1=123, tocmai tensiunea de iesire care am tastat-o.

Ar mai fi de lamurit problema cu inregistrarea Kp>9. Mai exact, cand tastam 10, 135 etc, uC sa atribuie kp valoarea aceasta.

 

In ceea ce priveste solutia formulata mai sus cu cei 7 sau 8biti, imi este putin neclara!

 

Oricum, problema, cel putin din punctul meu de vedere este in studiu. Dar pana la solutionarea ei, cel putin din partea mea, astept sa citesc explicatiile lui edy, care se lasa asteptate!

Am o idee de comanda a releelor (calculul matematic introdus al datelor introduse de la tastatura). Revin cu explicatii.

Numai bine

Eu lucrez in C, cu compilator avr-gcc, algoritmul descris e ok, dar nu este nevoie de asa ceva. Scriu cateva randuri de cod sa vedeti cat de simplu este de facut:

// sa zicem ca portb va fii folosit pentru comanda reelor

 

#define KEY_NOT_PRESSED 0x0F

 

unsigned char key, key_buff;

 

int main(void)

{

unsigned short output_value=0;

//....

 

DDRD = 0xff; //setat ca iesire

PORTD= 0; // pentru siguranta...

key=KEY_NOT_PRESSED;

key_buff=KEY_NOT_PRESSED;

//....

 

while(1) //bucla main

{

//..

 

if((key!=key_buff)&&(key!=KEY_NOT_PRESSED) ) // daca a fost apasat o alta tasta

{

switch(key)

{

case '#': //enter

PORTD = output_value;

break;

 

case '*': //clear

output_value = 0;

break;

 

default:

output_value = ((output_value*10)+key)&0xFF; //limitare la maximum 255

 

};

 

//activare buzzer pentru 10-30ms

 

}//if((key!=key_buff)&&(key!=KEY_NOT_PRESSED) ) // daca a fost apasat o alta tasta

 

key_buff=key;

 

}//while(1) //bucla main

 

}//int main(void)

 

// intrerupere de timer de 1-10ms

ISR(...)

{

//..

 

key=GetKey(); //citire tastatura

 

//..

}

 

Cam asta ar fii partea de comanda a releelor, mai este citirea efectiva a tastaturii, comanda buzzerului, si comanda releului de siguranta

Afirmatia asta:

// sa zicem ca portb va fii folosit pentru comanda reelor

si cu asta:

DDRD = 0xff; //setat ca iesire

PORTD= 0; // pentru siguranta...

key=KEY_NOT_PRESSED;

key_buff=KEY_NOT_PRESSED;

...si asta:

Cam asta ar fii partea de comanda a releelor, mai este citirea efectiva a tastaturii, comanda buzzerului, si comanda releului de siguranta

Este "un cod" care nu are nicio legatura cu comanda releelor, care conform afirmatii anterioare ar trebui sa se faca pe portul.B, dar in cod se fac niste bucle care adreseaza - eronat - probabil si bine daca ar fi fost scris corect toata partea de cod care intereseaza - port D. Mai intreb, inca o data, pentru ca @Laci spunea (in vorbe) la un moment dat mai sus asta, cum se transforma valoarea citita de la tastatura in cod binar la iesirile portul uC considerat ca iesire ? In codul de mai sus, e un fel de "harcea-parcea". E ca si cum ai fi la bucatarie si ai vrea sa faci mancare, dar nu stii exact ce trebuie dar stii cam ce ar trebui sa iasa, dar arunci ingredientele in oala de-a valma. Imi pare nespus de rau, dar cam asa e structurat codul de mai sus.

 

Mai astept si alte review-uri. Daca nu exista, nu este nicio problema, putem sa nu mai consideram acest proiect "Open Source"?! Am ajuns la observatia sau afirmatia asta dupa ultimile interventii ale "utilizatorilor initiati in microcontrolere de aici"!

 

Numai bine

Imi cer scuze, eram destul de grabit, pentru ca eram in concediu dar am zis ca daca am inceput discutia sa nu am pauze de cateva zile.

In comentariu am pomenit de portb si in cod am scris portd, dar am fost consecvent si am folosit numai portd in cod, asa ca va rog frumos partea cu harcea pacea nu cred ca este adecvat. Am vrut sa explic, eventual sa atasez un cod care face citirea tastaturii(ca am facut destule aplicatii cu tastaturi), dar in momentul de fata ma retrag din discutie si de pe forum. Nu stiu cum vi sa parut codul sursa, eu am formatat cu space-uri acuma ca dupa submit apare asa, eu nu am nici o vina. Am cativa ani buni de experienta in dezvoltarea aplicatiilor embedded si consider ca stiu despre ce vorbesc, insa nu vreau sa-mi pierd vremea cu astfel de discutii, numai bine.

 

P.S. Va ma spun inca odata portd sau portd sau oricare port intreg cu 8pini adica registru de 8 biti daca se scrie o valoare in decimal sau hexa, sau octal sau orice alta reprezentare pe port apare in binar. Acuma ca vrei sa accesezi fiecare bit in parte si sa faci un algoritm(se poate mult mai simplu) este problema ta, dar am spus ca nu are nici un rost. Nu ma credeti? se poate citi pdf-ul sau se poate simula in avr studio o simpla scriere pe port.

@Laci,

 

Imi cer scuze daca te-ai simtit lezat de afirmatiile mele anterioare legate de codul scris de tine mai sus. Mai mult ca sigur ar fi trebuit sa ma limitez in a spune numai ce era de spus (mai putin "chestia" cu harcea-parcea), dar nefiind in concediu, si "stresat" cu problemele zilnice, uite ca se mai intampla sa spui mai mult decat trebuie. Inca o data scuze!

 

Referitor la subiectul acestui topic, stiu ca orice valoare in decimal sau hexa, reprezentata la iesirile un port pe 8 biti va apare sub forma binara. Dar poate nu am fost suficient de inteles. Ma interesa ca atunci cand tastam pe keypad doua valori succesive, portul respectiv - considerat iesire pt. comanda releelor - sa vada ("in binar") valoare respectiva? Am inteles ca nu este o problema in acest sens daca tastam numerele de la 0...9, dar ma interesa cum procedem atunci cand tastam 23 spre exemplu. Am vazut ceva in acest sens, in codul expus de tine mai sus, dar... e cam neclar (ar trebui reexplicata partea respectiva)!

Ok, am inteles intrebarea, adica odata tastat 6 si 7 cum "deplasezi 6 cu un loc spre stanga", am facut asa:

output_value = ((output_value*10)+key)&0xFF;

 

Sa luam in detalii, in output_value este valoare veche care la inceput este 0,

de la tastatura se citeste un numar 0..9, (acum nu pot sa scriu formula frumos cum este definit

un numar intrun format arbitrar ca editorul nu suporta)

Un numar in format zecimal 234 este definit asa: (10^2)*4+(10^1)*3+(10^0)*4

 

Deci output_value = 0 se citeste 4 => output_value = 0*10+4 => 4

se mai citeste 3 => output_value = 4*10+3 => 43

si se mai citeste 2 => output_value = 43*10+2 => 432,

 

Totul fiind intro bucla se adun valorile ponderat pana cand se apasa # cand se scrie efectiv pe port,

la apasarea * cand se sterge output_value este indicat si stergerea valori portului, am omis acest lucru.

 

Dar cum se vede am depasit 255 valoare maxima reprezentata pe 8 biti, daca scriem pe port sau atribuim unei variabile de 8 biti

se pierde byte-ul semnificativ(432 = 0x01B0) si va ramane valoarea 0xB0 = 176;

 

((output_value*10)+key)&0xFF => sterge byte-ul semnficativ, defapt face acelasi lucru ca si cand scriem o variabila de 16bit in 8bit,

este redundant, dar eu totdeauna limitez asa cand este cazul ca sa fie sigur.

Referitor la program: nu ar mai usor ca sa facem conversia zecimal - binar iar rezultatul pe 8 biti sa-l trimitem direct portului pe care sunt conectate cele 8 relee? Adica, in momentul in care se introduce tensiunea de la tastatura avem grija ca valoarea sa nu depaseasca 255 (mesaj de eroare), dupa care facem conversia dec-bin si gata. Eu zic ca ar fi mai simplu.

@edy_wheazel: arhitectura micro controllelor, procesoarelor, circuitelor digitala se bazeaza pe logica booleana, datele sunt in format binar. Cand vorbim de un controller pe 8biti cum este si familia avr de la atmel avem un data bus care are latime de 8biti, registri sunt de 8biti. Un port digital este defapt un registru fiecare bit este reprezentat fizic de un pin, nu trebuie sa faci conversie zecimal binar pentru ca poti sa scrii direct o valoare de 1 byte(8biti) pe port.

Insa ai dreptate ca in registrii se scriu numai valori in format hexazecimal, insa in C poti sa scii direct in zecimal pentru ca compilator face conversia in hexa.

@edy_wheazel: arhitectura micro controllelor, procesoarelor, circuitelor digitala se bazeaza pe logica booleana, datele sunt in format binar. Cand vorbim de un controller pe 8biti cum este si familia avr de la atmel avem un data bus care are latime de 8biti, registri sunt de 8biti. Un port digital este defapt un registru fiecare bit este reprezentat fizic de un pin, nu trebuie sa faci conversie zecimal binar pentru ca poti sa scrii direct o valoare de 1 byte(8biti) pe port.

Insa ai dreptate ca in registrii se scriu numai valori in format hexazecimal, insa in C poti sa scii direct in zecimal pentru ca compilator face conversia in hexa.

 

Cunosc arhitectura uC.

Am observat insa faptul ca la o simpla conversie dec-bin rezulta exact tensiunea necesara. Adica, sa spunem ca avem nevoie de 22Volti, asta inseamna in binar 01101000, exact aclansarea releelor 2(2V), 3(4V) si 5(16V), insumate (inseriate) rezulta 22V. De aceea ziceam sa facem doar aceasta conversie si sa o trimitem portului.

 

In asamblare se pot introduce date in registrii si in binar, si in hexa si in zecimal, se schimba "prefixul" cu care sunt introduse. De exemplu, daca vreau sa introduc intr-un registru valoarea 9A pot sa o scriu 0x9A (hexa) sau 0b10011010 (binar).

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
  • Navigare recentă   0 membri

    • Nici un utilizator înregistrat nu vede această pagină.

×
×
  • Creează nouă...

Informații Importante

Folosim cookie-uri și tehnologii asemănătoare pentru a-ți îmbunătăți experiența pe acest website, pentru a-ți oferi conținut și reclame personalizate și pentru a analiza traficul și audiența website-ului. Înainte de a continua navigarea pe www.tehnium-azi.ro te rugăm să fii de acord cu: Termeni de Utilizare.

ATENTIE !!! Functionarea Tehnium Azi depinde de afisarea de reclame.

Pentru a putea accesa in continuoare site-ul web www.tehnium-azi.ro, va rugam sa dezactivati extensia ad block din browser-ul web al vostru. Dupa ce ati dezactivat extensia ad block din browser dati clic pe butonul de mai jos.

Multumim.

Apasa acest buton dupa dezactivarea extensiei Adblock