Sari la conținut
ELFORUM - Forumul electronistilor

Exercitii programare de la zero


Vizitator ciocanaru

Postări Recomandate

In primul rand am gresit linia:

if (RA0_bit == 1) last_RA0 == 1;

Corect este:

if (RA0_bit == 1) last_RA0 = 1; 

Ok Iulian am sa explic ce am facut.

 

Am facut referire la 17 secunde deoarece, aproximativ 17 secunde dureaza executia atat a functiei lights_on() cat si a functiei lights_off().

De ce 17 secunde?

Ca doar mai sunt si alte instructiuni in afara de cele 17 delay-uri de cate 1 secunda ...

Pai acele instructiuni suplimentare dureaza atat de putin incat putem aproxima ca durata de executia a fiecareia din cele doua functii amintite este de cca 17 secunde.

 

Acum, in ce consta protectia.

In stare default butonul nu este apasat adica RA2_bit este HIGH (este egal cu 1).

 

Atunci din tot ce este in bucla while(1) se executa doar:

if (RA0_bit == 1) last_RA0 = 1;

si rezultatul acestei linii este ca atata timp cat butonul este neapasat, adica RA0_bit este HIGH, variabila last_RA0 va avea valoarea 1

last_RA0 = 1

Al 2-lea if nu se executa din cauza ca, conditia nu este indeplnita deoarece cum spuneam butonul este neapasat, deci RA0_bit este HIGH

 

La un moment dat apasam butonul RA0. 

Linia:

if (RA0_bit == 1) last_RA0 = 1;

nu se mai executa, dar in continuare last_RA0 = 1 de la ultima trecere prin bucla. Corect? Corect.

 

Acum insa se va executa al 2 lea if pentru last_RA0 este 1 de data trecuta si acum RA0_bit este LOW. Indiferent ca se sting luminile sau se aprind, la finalul if-ului al 2 lea se executa linia:

last_RA0 = 0;

Si in cazul in care tinem butonul apasat in continuu pentru acele 17 secunde cat dureaza (relativ) executia celui de-al doilea if, cand se incepe din nou o trecere prin bucla while(1), avem un last_RA0 = 0 de la finalul trecerii anterioare prin bucla, prima linie:

if (RA0_bit == 1) last_RA0 = 1;

nu se executa, pentru ca noi avem butonul apasat deci RA0_bit este LOW (adica 0) deci in continuare last_RA0 ramane cu valoarea zero, ceea ce face ca al-2-lea if sa nu se execute pentru ca, conditia sa nu este indeplinita partial, adica last_RA0 sa fie egal cu 1.

 

Si tot asa pana dam drumul la buton, cand tot ce am descris incepe din nou.

Editat de mars01
Link spre comentariu

Am inteles acum ; nu ma asteptam la aceasta varianta . Ma gandeam ca 17 secunde e o perioada cam lunga si as fi vrut sa o scurtez ulterior , poate si de-asta ma asteptam ca aceasta protectie sa fie implementata altfel . 

 

Totusi , aceasta modificare nu e esentiala asa ca gasesc programul mai mult decat suficient pentru ce-mi trebuie mie .

 

Mai am o nelamurire legata de registrul ADCON1 :

 

 

 

ADCON1 poate avea valoarea: 4 sau 5 sau 6 sau 7. Toate aceste valori ne asigura ca RA2 este un I/O digital.

 

 

Care este diferenta intre ADCON1=6 si ADCON1=7 ?

 

Posted Image

Link spre comentariu

Am facut montajul pe o placa de test si am cateva probleme .

 

Cu softul care are implementata protectia la ramanerea blocata a intrerupatorului , ledurile nu se sting : se aprind si raman aprinse . am incercat varianta fara acea protectie si acolo ledurile se aprind si se sting ...dar nu toate . Sau mai exact cateva leduri se aprind dar nu raman aprinse .

 

Ledurile cuplate la pinii :RD2, RD3,RC5, RC6,RD5,RD6 se aprind dar nu raman aprinse . 

 

De asemenea montajul n-a miscat nimic pana cand nu am pus un cristal de 4Mhz ; initial am incercat cu 20Mhz si apoi cu 10 Mhz . N-ar fi trebuit sa mearga si cu un cristal de 20 Mhz ?

 

https://youtu.be/osLYjoornbI

Link spre comentariu

Am schimbat softul ca sa poata fi folosit pentru 17F877A (16F74 nu este in lista Proteus), am micsorat durata functiei delay de la 1secunda la 0.1 secunde ca sa se vada mai rapid.

 

Rezultat simulare Proteus:

Posted Image

 

Daca nu este o problema de harddware atunci ar putea sa fie ceva registri neconfigurati ... Posteaza aici registrii CONFIG ca sa ne uitam peste ei.

 

LE:

Programul folosit este ca mai jos. Am pus un #define pentru delay ca sa pot schimba "dintr-un foc" delay-ul peste tot fara sa stau sa editez toate delay-urile acelea ...

*Declaram doua constante ON si OFF */#define ON  1#define OFF 0#define delay 100void lights_on() {  RD2_bit = ON;    //aprindem becul  delay_ms(delay);  // intarziere de o secunda  RD3_bit = ON;  delay_ms(delay);  RC5_bit = ON;  delay_ms(delay);  RC6_bit = ON;  delay_ms(delay);  RC7_bit = ON;  delay_ms(delay);  RD4_bit = ON;  delay_ms(delay);  RD5_bit = ON;  delay_ms(delay);  RD6_bit = ON;  delay_ms(delay);  RD7_bit = ON;  delay_ms(delay);  RB0_bit = ON;  delay_ms(delay);  RB1_bit = ON;  delay_ms(delay);  RB2_bit = ON;  delay_ms(delay);  RB3_bit = ON;  delay_ms(delay);  RB4_bit = ON;  delay_ms(delay);  RB5_bit = ON;  delay_ms(delay);  RB6_bit = ON;  delay_ms(delay);  RB7_bit = ON;  delay_ms(delay);}void lights_off() {  RD2_bit = OFF;    //Stingem becul  delay_ms(delay);  // intarziere de o secunda  RD3_bit = OFF;  delay_ms(delay);  RC5_bit = OFF;  delay_ms(delay);  RC6_bit = OFF;  delay_ms(delay);  RC7_bit = OFF;  delay_ms(delay);  RD4_bit = OFF;  delay_ms(delay);  RD5_bit = OFF;  delay_ms(delay);  RD6_bit = OFF;  delay_ms(delay);  RD7_bit = OFF;  delay_ms(delay);  RB0_bit = OFF;  delay_ms(delay);  RB1_bit = OFF;  delay_ms(delay);  RB2_bit = OFF;  delay_ms(delay);  RB3_bit = OFF;  delay_ms(delay);  RB4_bit = OFF;  delay_ms(delay);  RB5_bit = OFF;  delay_ms(delay);  RB6_bit = OFF;  delay_ms(delay);  RB7_bit = OFF;  delay_ms(delay);}void main() {  unsigned char stare_lumini = OFF; // variabila care tine minte starea curenta a luminilor  unsigned char last_RA0 = 1;       // variabila care tine minte starea anterioara a butonului    /************** INITIALIZARE***************************/  ADCON0 = 0;          //dezactivam ADC  ADCON1 = 7;          //port A and E pins are digital I/O    TRISA = 0b00000001;  //facem INTRARE din pinul 2 adica RA0; aici vom avea switch-ul conectat  TRISB = 0b00000000;  //facem portul B B0-B7 ,iesire  TRISC = 0b00011111;  //RC 5-7 setati ca iesiri  TRISD = 0b00000011;  //RD 2-7 setati ca iesiri    PORTB = 0b00000000;  //pornim cu becurile de pe PORTB stinse  PORTC = 0b00000000;  //pornim cu becurile de pe PORTC stinse  PORTD = 0b00000000;  //pornim cu becurile de pe PORTD stinse  /**************SFARSIT INITIALIZARE********************/  while(1) {      if (RA0_bit == 1) last_RA0 = 1;        if (RA0_bit == 0 && last_RA0 == 1) {   //daca intrarea este LOW si luminile sunt oprite      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        if (stare_lumini == OFF) {          lights_on();          stare_lumini = ON;        }        else {          lights_off();          stare_lumini = OFF;        }      }      last_RA0 = 0;    }  }} 
Editat de mars01
Link spre comentariu

Pentru quarz peste 4MHz, la oscilator trebuie selectat, conform foii de catalog, HS nu XT. Ma rog, nu scrie chiar asa, da' din tabelele de la paginile 121-122 cam asa se intelege.

LE Cre'ca am amestecast topicurile, m-am uitat in datasheetul lui 16F873.

Editat de Liviu M
Link spre comentariu

Cum a spus si Liviu.

Pagina 91, 92 in datasheet-ul de aici: http://ww1.microchip.com/downloads/en/DeviceDoc/30325b.pdf

Atentie la condensatorii folositi si daca montajul este facut pe breadboard pot aparea probleme daca cristalul nu este aproape de controler.

 

4MHz este exact limita maxima pentru setarea XT.

Pentru cuarturile cu frecventa mai mare trebuie folosita setarea HS si condensatorii de pe langa cuartz sa aiba valoarea de cca 15pF.

 

LE: Pentru un program ca acesta eu as fi folosit un PIC12F675 cu doi, trei  registri HC595. Costul total ar fi cca 6 lei si scapi si de nevoia de oscilator extern etc.

Editat de mars01
Link spre comentariu

Am selectat HS cu doi condensatori de 15pf si acum merge si cu un cristal de 20 Mhz ...dar merge ca si pana acum : adica jumatate da, jumatate nu :) .

 

Vreau sa folosesc 16f74 pentru ca am vreo trei bucati care stau degeaba si pe care am vrut sa le folosesc ; practic n-aveam neaparat nevoie de acest sistem de iluminare , eu am vrut sa folosesc undeva aceste memorii ...pana ce nu devin (mult) prea batrane .

 

Pana la urma o sa fac cablajul si o sa folosesc de acolo doar pinii care lucreaza cum trebuie si asta e : o sa pun mai putine becuri decat aveam de gand .

 

Asta este a doua placa de test pe care fac incercari ; pe prima am schimbat-o pentru ca m-am gandit ca poate am pe undeva o problema de contact .N-a fost cazul : exact acelasi lucru s-a intamplat pe ambele variante . Am trei memorii si le-am incercat pe toate , deci nici acolo nu e problema . 

Editat de iuli09
Link spre comentariu

Hm, eu as incerca sa vad ce alte functii sunt multiplexate cu pinii care nu merg si as incerca sa le dezactivez inca o data (in afara de porturile analogice - si nu e cazul aici, celelalte functii extra trebuie activate de mana, nu dezactivate de mana).

In cazul pinilor enumerati pentru portul C, functiile suplimentare sunt RS232 sau SPI. Incearca sa le dezactivezi pe astea, vezi ce iese.

In cazul portului D, acesta poate fi utilizat ca PSP. Vezi in descrierea registrului TRISE ce e aia si cum se dezactiveaza (faci 0 bitul TRISE_4 - PSPMODE).

Link spre comentariu

iuli09, mai exact care dintre pini nu se activeaza?

 

Incearca si cu programul acesta de facut blink:

#define ON	1void main() {    /************** INITIALIZARE***************************/  ADCON0 = 0;          //dezactivam ADC  ADCON1 = 7;          //port A and E pins are digital I/O    TRISA = 0b00000001;  //facem INTRARE din pinul 2 adica RA0; aici vom avea switch-ul conectat  TRISB = 0b00000000;  //facem portul B B0-B7 ,iesire  TRISC = 0b00011111;  //RC 5-7 setati ca iesiri  TRISD = 0b00000011;  //RD 2-7 setati ca iesiri    PORTB = 0b00000000;  //pornim cu becurile de pe PORTB stinse  PORTC = 0b00000000;  //pornim cu becurile de pe PORTC stinse  PORTD = 0b00000000;  //pornim cu becurile de pe PORTD stinse  /**************SFARSIT INITIALIZARE********************/  while(1) {	  RD2_bit = ON; 	  RD3_bit = ON;	  	  RC5_bit = ON;		  RC6_bit = ON;	  	  RC7_bit = ON;		  RD4_bit = ON;	  	  RD5_bit = ON;	  RD6_bit = ON; 	  RD7_bit = ON;	  RB0_bit = ON;	  RB1_bit = ON;	  RB2_bit = ON;	  RB3_bit = ON;	  RB4_bit = ON;	  RB5_bit = ON;	  RB6_bit = ON;	  RB7_bit = ON;	  	  delay_ms(500); 	  	  RD2_bit = OFF;    //Stingem becurile	  RD3_bit = OFF;	  RC5_bit = OFF;	  RC6_bit = OFF;	  RC7_bit = OFF;	  RD4_bit = OFF;	  RD5_bit = OFF;	  RD6_bit = OFF;	  RD7_bit = OFF;	  RB0_bit = OFF;	  RB1_bit = OFF;	  RB2_bit = OFF;	  RB3_bit = OFF;	  RB4_bit = OFF;	  RB5_bit = OFF;	  RB6_bit = OFF;	  RB7_bit = OFF;	  	  delay_ms(500);  }} 
Link spre comentariu

RD2, RD3,RC5, RC6,RD5,RD6 -acestia sunt pinii care "fac figuri"

 

Am incercat deja sa pun bitul 4 din TRISE in zero , am pus tot TRISE in zero de fapt si degeaba .

 

Am incercat si eu sa anulez diverse functii ale acestor pini dar ori n-am reusit sa fac asta ori nu e acolo poblema pentru ca nu s-a rezolvat nimic . 

 

Cateva chestii interesante : 

 

- softul pe care l-a postat ieri Mars01 , cel cu protectia de 17 secunde , n-a functionat (ledurile nu se stingeau ) , insa cu cel postat azi cel unde singura modificare pe care am vazut-o eu este "#define delay 100"  , ledurile se sting , in felul lor dar se sting .

 

-daca nu montez ledurile si actionez butonul si de-abia pe urma incep sa "plantez" leduri , acestea raman aprinse ,chiar si cele care inainte se stingeau . Mai putin RD2 ...ala nu ramane aprins orice as face .

 

O sa iau maine la puricat datasheetul si o sa anulez orice functie mi se pare ca ar avea legatura cu pinii buclucasi . 

 

O sa vad si daca gasesc un alt programator pe care sa-l incerc ; acum folosesc o clona Pickit2 si softul dedicat pentru PicKit.

Editat de iuli09
Link spre comentariu

17 LED-uri * 20 mA (sper ca ai pus si rezistori de limitare a curentului in serie cu fiecare LED) = 340 mA. 

S-ar putea sa fie prea mult pentru controller ... 5V*0.34A = 1.70W consum din chip.

 

Si cred de aici este problema. Incearca sa limitezi curentul mai mult prin LED-uri. Foloseste rezistori serie cu fiecare LED  de sa zicem cca 560 ... 680 ohmi sau foloseste tranzistori/IC_driver pentru comanda LED-urilor.

 

LE: Atentie ce scrie in poza relativ la pinul MCLR.

 

Posted Image

Editat de mars01
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