riciu Postat Ianuarie 23, 2016 Autor Partajează Postat Ianuarie 23, 2016 hai ca usor usor , incep sa ies din ceata. Cu desene in fata, cu explicatiile voastre scoase la imprimanta, cu cele din data sheet, parca incep sa ma misc pe drumul drept si sa prind curaj. Multumesc mai ales lui mars01 ca are un stil bun de a explica, dar si explicatiile celorlalti devin pe inteles incet incet. Link spre comentariu
mars01 Postat Ianuarie 23, 2016 Partajează Postat Ianuarie 23, 2016 (editat) Continuare Variabile (basic) Ziceam de program, dar sa termin ce vreau sa spun despre variabile. Nu am de gand sa epuizez aici tot subiectul variabilelor si al tipurilor de variabile. Vreau insa sa mentionez ca mai exista si alte genuri de variabile cum ar fi: enumerari, structuri, stringuri, arii si pointeri (ariile si pointerii sunt enumerati unul langa celalalt pentru ca exista o relatie de "rudenie" intre ei). Poate vom discuta si despre aceste genuri de variabile dar mai tarziu deoarece nu sunt esentiale pentru moment. Cand ajungem la functii vom discuta si despre ce inseamna variabile locale si ce inseamna variabile globale, variabile statice. Cand vom discuta de librarii, fisiere header, atingem si ce inseamna cuvantul cheie "extern". Lucruri pe care poate veti vrea sa le atingeti in studiu sunt asa numitii "qualifiers" const si volatile. Cand ajungem la intreruperi o sa vorbim despre volatile. Stiu ca las mai multe intrebari decat raspunsuri, dar sincer nu pot altfel. Vorbeam anterior de asa numitele variabile "constante". Cand in C se declara o variabila constanta, hai sa ii spunem constanta (pentru ca se bat cap in cap conceptele de variabil cu constant), noi facem automat si initializarea constantei cu ceva. Fie cu un numar, fie cu un string de caractere. Despre stringuri discutam mai tarziu. O variabila normala o poti pur si simplu declara (tot timpul la inceputul sectiunii de program cel putin asta spune ANSI) asa: int x; Dar in acest moment in locatia de memorie unde este variabila x poate sa fie orice valoare. Daca am tipari variabila x (adica valoarea din ea) ar putea sa apara orice. Evident acest "orice" poate fi in intervalul -32768 ... 32767. De ce? Pentru ca intr-o variabila tip INT nu poti pune alte valori decat in acest interval. In orice caz, daca am vrea sa stim sigur ce este in variabila pentru mai tarziu (poate facem o comparatie cu ea sau mai stiu eu ce) atunci trebuie sa o intializam cu, ceva. Poate zero de ex: x = 0; Sau putem face declaratie simultan cu initializarea: int x = 0; In cazul contantei, este obligatoriu ca odata cu declaratia sa faci si initializarea. const int y = 0; O variabila normala poate fi modificata in program. Acum poate x = 0, mai tarziu x = -1 si mai tarziu x poate fi 5000. Etc O constanta, odata definita si initializata numai poate fi modificata. Deloc. Daca incerci sa o modifici in program primesti o eroare. Remarcati cuvantul cheie: const Cu el ii spunem programului (si programatorului care citeste programul) ca variabila declarata ca si const, pe nume y, este o constanta care va ramane cu acea valoare tot timpul. La ce te ajuta constantele atunci? Mai intai programatorului ii este mai usor sa tina cont de logica programului. Cand vede "const" in program stie ca acea "variabila" este o constanta si ca nu se modifica. In al doilea rand este mai usor de inteles cand zici asa: const unsigned int pin_corect = 1234; Si pe urma cand testezi in program: unsigned int pin_introdus = ...if (pin_introdus == pin_corect) { // daca pinul introdus este cel corect, adica pin_corect care este 1234// fa ceva}else { // altfel//fa altceva} Variabila pin_introdus poate fi o variabila care stocheaza o valoare introdusa la un cifru. Este mult mai sugestiv cand comparam cu "pin_corect" pentru ca denumirea "pin_corect" deja ne spune ca sectiunea de cod dintre urmatoarele acolade va reflecta succesul. Daca am testa ceva de genul: unsigned int pin_introdus = ...if (pin_introdus == 1234) { // daca pinul introdus 1234// fa ceva}else { // altfel//fa altceva} In acest caz, daca programul este suficient de mare, ai putea spune: "ce naiba este 1234? oare este codul corect sau doar o varianta care poate imi blocheaza definitiv intrarea" Se vede utilitatea de a compara cu un nume si nu direct cu un numar ... In plus, daca acest cod "pin_corect" este folosit in mai multe locuri in program si sa zicem ca vrem sa il modificam, in loc sa cautam prin tot programul dupa 1234 si sa schimbam peste tot sa zicem in 7777, cand folosim o constanta atunci este suficient sa modificam declaratia (de fapt partea de initializare din declaratie) la inceputul programului din: const unsigned int pin_corect = 1234; in const unsigned int pin_corect = 7777; si tadaa, modificarea se propaga peste tot in program, acolo unde este folosita constanta pin_corect. La un moment dat o sa discutam si despre directiva preprocesor "#define" care face cam acelasi lucru. Cu avantaje si dezavantaje. Mai vreau sa spun un singur lucru: TYPE CASTING. O sa mai vorbim ulterior dar in mare vreau sa amintesc acum despre aceasta. Spuneam anterior ca o variabila are o adresa in memorie si cand ii declaram tipul (signed int, char, unsigned long etc etc) stabilim si cati biti sunt rezervati la acea locatie (de ex pentru unsigned char va amintiti, se alocau 8biti si astfel se puteau pune in aceasta variabila valori de la 0 la 255. numai valori pozitive, nu? deoarece este unsigned ...) Dar ce te faci cand incerci sa aduni doua variabile ca mai jos: unsigned int y = 2100;unsigned char z = 33;unsigned int suma;suma = y + z; Variabila y este tip unsigned int (deci se stocheaza pe 16bit). Variabila z este de tip unsigned char (deci se stocheaza pe 8bit). Variabila suma este tip unsigned int (deci tot pe 16bit stocata). Cand le aduni pe y si z este ca si cum aduni mere cu pere. Ori aceasta nu se poate face dpdv logic. In acest caz se pot intampla doua situatii: 1. daca lasam pur si simplu codul ca atare, compilatorul va face un casting implicit. Ce inseamna aceasta? Inseamna ca atunci cand compilatorul vede ca aduna un tip de variabila stocata pe mai putini biti (unsigned char este stocata pe 8biti) cu un tip de varibila stocata pe mai multi biti (unsigned int este stocata pe 16biti), el va "promova" variabila cu biti mai putini in tipul variabilei cu mai multi biti. Cu alte cuvinte, compilatorul cu de la sine putere, ia decizia si il face pe unsigned char z intr-un unsigned int, muta valoarea 33 in noul spatiu de 16 biti (ca doar este unsigned int acum), aduna pe y si pe z (acum au amandoua acelasi tip si se poate face adunarea) si pune valoarea rezultata (2133) in variabila suma. 2. sau facem noi casting explicit, ca si programatori. Adica: unsigned int y = 2100;unsigned char z = 33;unsigned int suma;suma = y + (unsigned int)z; Remarcati "(unsigned int)" in fata lui z. Prin aceasta ii spunem compilatorului, ca in acest caz particular, sa trateze variabila tip unsigned char z ca pe un unsigned int. (cu consecintele de rigoare, spatiu stocare format din 16bit ...) In mare (informativ) cam asta este type casting-ul. Editat Ianuarie 23, 2016 de mars01 Link spre comentariu
riciu Postat Ianuarie 23, 2016 Autor Partajează Postat Ianuarie 23, 2016 mars01, ai spus la CONFIGURATION WORDS ca " bit 1 si bit 0 FOSC1:FOSC0 = 01 adica bit 1 = 0 iar bit 0 = 0." DAR BIT 0 NU TREBUIA SA FIE 1 CA SA IASA CUM AI SPUS TU EGAL CU 01 ? apoi "Foarte IMPORTANT. Ii spunem astfel controllerului ca am optat sa ii conectam un cuartz (adica un High Speed Oscillator) pe pinii dedicati (pinii 13 si 14)" DACA ALEGEM OSCILATOR HS, DATASHEETUL SPUNE CA TREBUIE SA-I PUNEM VALOAREA 10, DECI AR VENI BIT1=1 SI BIT0 = 0. AM INTELES BINE SAU NU? Link spre comentariu
djvas Postat Ianuarie 23, 2016 Partajează Postat Ianuarie 23, 2016 Ai inteles bine. Pentru HS avem FOSC1=1 si FOSC0=0. Link spre comentariu
mars01 Postat Ianuarie 23, 2016 Partajează Postat Ianuarie 23, 2016 (editat) M-ai prins doua greseli una dupa alta. Daca as putea edita as edita acel paragraf dar din pacate odata scris, dupa ce trece perioada de gratie de cca 1 ora nu se mai poate edita. Ma bucur ca ai prins greseala, arata ca incerci sa intelegi si depui efort personal fara ca doar sa copiezi. Bravo tie! Editat Ianuarie 23, 2016 de mars01 Link spre comentariu
mars01 Postat Ianuarie 24, 2016 Partajează Postat Ianuarie 24, 2016 (editat) Stiu ca nu am tratat aproape nimic din ce inseamna decizii in C dar iata un program care face urmatoarele: - configuram pinul 2 al controlerului, RA0, ca si intrare digitala si conectam aici un switch la GND si un rezistor de cca 4.7K catre VDD - configuram pinul 33 al controlerului, RB0, ca si iesire digitala si conectam aici un LED Daca intrarea RA0 trece din HIGH in LOW adica switchul este apasat, se face un debouncing (voi explica maine ce este cu debouncing-ul) la buton, se aprinde LED-ul si se intra intr-o bucla de tip while(expresie) in care se va sta cca 10minute. Dupa iesirea din bucla while se stinge LED-ul si se ia de la capat programul, asteptand o apasare de switch (adica intrarea RA0 sa devina LOW). void main() { /*declaram o variabila numita timp, de tip unsigned int - deci poate lua valori intre 0 si 65535 Aceasta variabila va tine in ea numarul de zeci de milisecunde care va constitui perioada de temporizare. Initializam aceasta variabila cu val 60000 care corespunde la 60000 cicluri de 10ms adica 10minute */ unsigned int timp = 6000; /*Declaram doua constante ON si OFF ca sa ne fie mai usor de inteles programul*/ const unsigned char ON = 1; const unsigned char OFF = 0; /************** INITIALIZARE***************************/ CMCON = 0b00000111; //dezactivam comparator ADCON0 = 0; //dezactivam ADC CVRCON = 0; //dezactivam referinta variabila de tensiune TRISA = 0b00000001; //facem INTRARE din pinul2 adica RA0; aici vom avea switch-ul conectat TRISB = 0b00000000; //facem IESIRE din pinul 33 adica RB0; aici vom avea LED-ul conectat PORTB = 0b00000000; //pornim cu LED-ul atasat pe pinul33 stins. Adica RB0 = LOW; /**************SFARSIT INITIALIZARE********************/ /*urmeaza bucla infinita Cat timp 1 este egal cu 1(si 1 este egal cu 1 tot timpul) executa ce este intre acolade */ while(1 == 1) { if (RA0_bit == 0) { //daca intrarea este LOW delay_ms(10); //asteptam 10 milisecunde if (RA0_bit == 0) { //daca intrarea inca mai este LOW atunci chiar ca avem o apasare reala de switch RB0_bit == ON; //aprindem LED-ul while (timp != 0) { //cat timp timpul este diferit de zero //variabila timp va scadea cu o unitate pentru fiecare 100ms care trec timp = timp - 1; // sau se poate scrie timp--; delay_ms(10); //aceasta este intarzierea esentiala pentru cronometrarea timpului cat LED-ul sta aprins } //timpul cat LED-ul trebuie sa stea ON a trecut si acum facem LED-ul OFF RB0_bit == OFF; } } }} Si o varianta care difera prin faptul ca, in timp ce se sta in bucla de temporizare si se asteapta trecerea celor 10 minute, daca cumva intrarea RA0 unde este conectat switch-ul devine LOW (adica switch-ul este apasat) atunci temporizarea este resetata si se va relua asteptarea de la inceput. void main() { /*declaram o variabila numita timp, de tip unsigned int - deci poate lua valori intre 0 si 65535 Aceasta variabila va tine in ea numarul de zeci de milisecunde care va constitui perioada de temporizare. Initializam aceasta variabila cu val 60000 care corespunde la 60000 cicluri de 10ms adica 10minute */ unsigned int timp = 6000; /*Declaram doua constante ON si OFF ca sa ne fie mai usor de inteles programul*/ const unsigned char ON = 1; const unsigned char OFF = 0; /************** INITIALIZARE***************************/ CMCON = 0b00000111; //dezactivam comparator ADCON0 = 0; //dezactivam ADC CVRCON = 0; //dezactivam referinta variabila de tensiune TRISA = 0b00000001; //facem INTRARE din pinul2 adica RA0; aici vom avea switch-ul conectat TRISB = 0b00000000; //facem IESIRE din pinul 33 adica RB0; aici vom avea LED-ul conectat PORTB = 0b00000000; //pornim cu LED-ul atasat pe pinul33 stins. Adica RB0 = LOW; /**************SFARSIT INITIALIZARE********************/ /*urmeaza bucla infinita Cat timp 1 este egal cu 1(si 1 este egal cu 1 tot timpul) executa ce este intre acolade */ while(1 == 1) { if (RA0_bit == 0) { //daca intrarea este LOW delay_ms(10); //asteptam 10 milisecunde if (RA0_bit == 0) { //daca intrarea inca mai este LOW atunci chiar ca avem o apasare reala de switch RB0_bit == ON; //aprindem LED-ul while (timp != 0) { //cat timp timpul este diferit de zero /*Urmatoarele doua conditii if(expresie) se folosesc pentru ca daca cumva in timpul de asteptare mai apasam cumva pe buton, timpul trecut se reseteaza si temporizarea o ia de la inceput*/ if (RA0_bit == 0) { //daca intrarea este LOW delay_ms(10); //asteptam 10 milisecunde if (RA0_bit == 0) { //daca intrarea inca mai este LOW atunci chiar ca avem o apasare reala de switch timp = 60000; //resetam timpul la valoarea initiala, 60000 * 10ms = 600000ms = 600sec = 10minute } } //variabila timp va scadea cu o unitate pentru fiecare 100ms care trec timp = timp - 1; // sau se poate scrie timp--; delay_ms(10); //aceasta este intarzierea esentiala pentru cronometrarea timpului cat LED-ul sta aprins } //timpul cat LED-ul trebuie sa stea ON a trecut si acum facem LED-ul OFF RB0_bit == OFF; } } }} Maine discutam pe marginea programului si incerc sa explic fiecare linie a programului (apar si chestii noi cum este RB0_bit, RA0_bit, conditia if(expresie) etc). CONFIGURATION WORDS raman la fel cum i-am explicat anterior si se configureaza la crearea proiectului. Editat Ianuarie 24, 2016 de mars01 Link spre comentariu
spark Postat Ianuarie 24, 2016 Partajează Postat Ianuarie 24, 2016 @mars01_o intrebare te rog_ce inseamna ""mapare"" momentan citesc online despre C++ , termenul mapare apare si la tine poate se lipeste ceva de mine Link spre comentariu
mars01 Postat Ianuarie 24, 2016 Partajează Postat Ianuarie 24, 2016 @core este cel cu maparea. Poate te ajuta el dar va trebui sa dai mai multe detalii legate de context. La modul general, maparea a ceva corespunde cu conceptul de asociere a doua sau mai multe "lucruri" si/sau crearea unei structuri ordonate. Link spre comentariu
spark Postat Ianuarie 24, 2016 Partajează Postat Ianuarie 24, 2016 ok merci_am gasit si eu ceva ""traducere"" (mai betonata ) mapare = organizare Link spre comentariu
bobinatorul Postat Ianuarie 24, 2016 Partajează Postat Ianuarie 24, 2016 (editat) Intrebare: Cand stingem ledul scriem RB0_bit == OFF; dar putem scrie si PORTB=0b00000000; ??? in cazul in care nu sunt declarate variabilele? Editat Ianuarie 24, 2016 de bobinatorul Link spre comentariu
Liviu M Postat Ianuarie 24, 2016 Partajează Postat Ianuarie 24, 2016 Cand stingem ledul scriem RB0_bit == OFF; dar putem scrie si PORTB=0b00000000; ??? == nu modifica valoarea, == e operatie de "testare". Si da, daca scriai PORTB = 0b00000000 il faceai 0 pe RB0, dar odata cu el si pe ceilalti 7 biti ai portului. De obicei porturile au mai multi pini folositi, asa ca de obicei nu e cea mai buna idee sa modifici tot portul odata. Link spre comentariu
bobinatorul Postat Ianuarie 24, 2016 Partajează Postat Ianuarie 24, 2016 Multumesc pentru raspuns si in special lui mars01. Sper sa nu rup firul topicului dar aceasta reprezinta "mascarea"bitilor? Link spre comentariu
ratza Postat Ianuarie 24, 2016 Partajează Postat Ianuarie 24, 2016 @mars01_o intrebare te rog_ce inseamna ""mapare"" momentan citesc online despre C++ , termenul mapare apare si la tine poate se lipeste ceva de mine E vorba despre modul în care structurezi memoria. De exemplu, adresele vectorilor de întrerupere pot fi în cod (flash) sau în RAM. Cînd faci maparea sau remaparea, trebuie să ţii cont de cîtă memorie e folosită şi de către cine. Chestia asta se face manual sau automat în linker file, în funcţie de compilator. Alt exemplu ar putea fi memoria paginată, fiecare pagină avînd o dimensiune oarecare. Un alt exemplu e organizarea memoriei: flash, EEPROM şi RAM, toate începînd de la adresa logică 0x0000. În mod normal s-ar suprapune, dar adresele fizice sînt altele. Intrebare: Cand stingem ledul scriem RB0_bit == OFF; dar putem scrie si PORTB=0b00000000; ??? in cazul in care nu sunt declarate variabilele? Se poate masca folosind PORTB astfel: // Ştergerea bituluiPORTB &= ~0x01;// Setarea bituluiPORTB |= 0x01;// Verificare bit setatif ((PORTB & 0x01) == 0x01)// Verificare bit ştersif ((PORTB & 0x01) == 0x00)// Metode mai elegante de a seta, şterge şi verifica un bit#define TRUE 1#define FALSE 0#define SET_BIT(var, b) var |= (1 << b)#define CLR_BIT(var, b) var &= ~(1 << b)#define IS_BIT_CLR(var, b) (var & (1 << b))?FALSE:TRUE#define IS_BIT_SET(var, b) (var & (1 << b))?TRUE:FALSE Link spre comentariu
Vezi Muti Postat Ianuarie 24, 2016 Partajează Postat Ianuarie 24, 2016 mars01, corecteaza postarea #66. RB0_bit == ON; //aprindem LED-ul ??? ai scapat "==" in loc de "=" cam peste tot. intra lumea in ceata. Link spre comentariu
Liviu M Postat Ianuarie 24, 2016 Partajează Postat Ianuarie 24, 2016 dar aceasta reprezinta "mascarea"bitilor? Mascarea bitilor inseamna modificarea anumitor biti intr-un grup (octet, word...), cu pastrarea celorlalti nemodificati (prin folosirea unor operatii speciale si masti potrivite). La operatiile de mascare se folosesc operatiile logice pe biti (bitwise, prin cartile in engleza). Nu stiu sigur daca astea-s toate, dar eu cel mai des am folosit AND (SI, &), OR (SAU, |), NOT (negare, ~), XOR (^). AND se foloseste cand vrem sa facem bitii 0 (X AND 0 = 0, X AND 1 = X), OR cand vrem sa facem bitii 1 ( X OR 1 = 1, X OR 0 = X), NOT cand vrem sa negam toti bitii (~0000 = ~1111), XOR cand vrem sa negam anumiti biti (X XOR 1 = !X, X XOR 0 = X). Exemple. Considerand X = 0b11001100, ca sa obtinem: - 0b11000000 facem AND cu masca 0b11110011 (1 unde nu vrem sa modificam, 0 unde vrem) => 0b11001100 & 0x11110011 = 0b11000000 - 0b11001111 facem OR cu masca 0b00000011 (0 unde nu vrem sa modificam, 1 unde vrem) - 0b00110011 facem NOT X - o iesire (sa zicem bitul 3) care sa-si modifice starea intr-o bucla, la fiecare trecere prin bucla - folosim XOR cu masca 0x00001000. Link spre comentariu
Postări Recomandate
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 contAutentificare
Ai deja un cont? Autentifică-te aici.
Autentifică-te acum