Sari la conținut
ELFORUM - Forumul electronistilor

Programarea uC-urilor Atmel


ole

Postări Recomandate

  • 2 săptămâni mai târziu...

Salutare!

Acum 2 zile m-am apucat sa citesc cate ceva despre LCD 2x16 si comunicarea lor cu un microcontroler.Dupa ce am inteles cum stau treburile m-am apucat sa fac cateva functii :Send_Message,Send_Character, Go_to_Position(x,y),Check_if_is_Busy ,Send_Command si Init_Lcd.Dupa am vrut sa fac o functie care sa-mi afiseze pe ecran un numar ,iar pentru asta am folosit itoa(x,y,z).Pana aici totul este ok.Acum vreau sa afisez si numere cu maxim 2 zecimale,iar pentru asta am gasit o functie dtostrf(x,y,z,w).

Problema este ca aceasta functie "papa" cam mult din resurse.Fara sa o apelez tot programul cu functiile mele create ocupa doar 7.7% din Flash,iar cand vreau sa transform sa zicem 3,14 intr-un sir de caractere si apelez aceasta functie dtostrf(),memoria flash ajunge la 25.4%,destul de mult pentru o amarata de functie.

Exista alta modalitate de a afisa numere cu virgula,desigur fara a folosi aceasta functie.

Eu m-am gandit la ceva .Ce parere aveti?

#int main(void){  char mes[2]; float a=3.14,c; int b; b=a; //b o sa fie =3 c=(a-b)*100; //(3,14-3)*100=0.14*100=14 itoa(b,mes,10); Send_Message(mes); Send_Character('.'); itoa(c,mes,10); Send_Message(mes);}
Link spre comentariu

Nu ma ajuta si pe mine nimeni?

De exemplu cea de sus merge pentru anumite numere ,la altele sa zic asa 32,11 imi arata 32,10.Aveti idee ce as putea sa-i fac sa merga ,sau o alta idee total diferita de a mea?

Link spre comentariu

Merge mai bine daca-l faci pe c (si pe b, de altfel) char?

Oricum, sunt sanse ca diferentele sa fie erori de reprezentare.

 

PS O alta varianta de calcul pentru c ar fi

char c = a % 1;

da' nu cred ca e mai buna ca varianta ta.

Link spre comentariu

Am incercat cu char c,b;  ,dar tot la fel in loc de 32,14 imi arata 32,13 ,dar acum mi-am dat seama ca o asemenea eroare e practic destul de mica si chiar nu conteaza,deci nu ma deranjeza. 

Problema este alta acum ,am creat o functie in care am pus codul de mai ,se numeste Send_decimal_Number(float number); si merge foarte bine ,dar acea variabila number de tip float imi ocupa 13% din memorie,deci tot cam pe la 20% ajung si eu nu prea vreau sa depasesc 10% ,vreau sa fac un fel de librarie ,dar nu vreau sa depasesc 10% din memoria lui ATmega8.

Link spre comentariu

Asta e , daca vrei program mic trebuie sa eviti variabile tip float , adica calculul cu virgula . De exemplu nu scrii 3,14 ci 314 , la sfarsit descompui rezultatul in parte intreaga si rest si pui tu virgula pentru afisare normala pe lcd , si alte artificii in functie de operatiile matematice dorite , informatii sunt pe net .

Editat de Depanatoru
Link spre comentariu

Incearca ca aici:

c=(a-b)*100;

sa scrii:

c=(a-b)*1000;

Oricum, este recomandat sa multiplici variabila de tip "float" cu o putere a lui 10, si sa te folosesti de variabile tip "int" sau "uint" pentru a afisa numarul dorit, neuitand sa pui virgula in conformitate cu factorul de multiplicare ales.

Link spre comentariu

Am facut asa:

void Send_decimal_Number(unsigned int zenumber){  unsigned int a;  a=zenumber%100;  zenumber/=100;  Send_Number(zenumber,10);  if(a>9)  Send_Message(",");  else  Send_Message(",0");  Send_Number(a,10);}

Merge destul de bine imi afiseaza orice numar cu doua zecimale ,de exemplu vreau sa afisez a=2,34 b=a*100; pe ecran Send_decimal_Number(b); si merge,deci orice variabila cu zecimale inainte sa o afisez o inmultesc cu 100 si nu am probleme.De exemplu daca citesc o valoare ADC=255; a=((255*100)/1023)*5 =>a=120 .Cand afisez a pe ecran apare 1,20.Deci este perfect si m-am si incadrat in cei 10%, am 6,5%. :rgtrwgtre

Eu am facut aceasta biblioteca pe 8biti si acum vreau sa fac si una pentru 4biti si am vazut ca pentru a initializa lcd-ul trebuie sa trimit doua comenzi :prima 1100 1100 si a doua 1100 0100 https://www.youtube.com/watch?v=1_nVScZG0J4 ,si nu am gasit nimic in pdf despre acest lucru ,ma ajutati putin?

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

Am vazut un tutorial pe youtube legat de un lcd 2x16 in 8bit  si la o functie 

void Data_in(void){  LcdControl|=(1<<Enable);  asm volatile("nop");  asm volatile("nop");  LcdControl&=~(1<<Enable);}

apare acel    asm volatile("nop");  .Am cautat pe net ce inseamna si nu am gasit un raspuns concret.Dupa cum cred eu este un fel de "delay",dar care nu stiu cum lucreaza.

Imi puteti spune si mie ce este si cum functioneaza?

Link spre comentariu

"nop" este o instructiune in limbaj de asamblare si ii "spune" microcontroller-ului sa nu execute nimic "No OPeration". Practic, pe o perioada de un impuls de ceas uC sta (poti sa o interpretezi si ca o intarziere egala cu valoarea perioadei unui impuls de ceas).

Link spre comentariu

De exemplu daca uC ruleaza la o frecventa de 1Mhz perioada o sa fie 0,001ms si el practic daca am de doua ori asm volatile("nop") o sa stea "degeaba" 0.002ms.

Am inteles bine?

Multumesc mult nico_2010  :ewryt45w .

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