allez001 Postat Octombrie 25, 2016 Partajează Postat Octombrie 25, 2016 (editat) Salutare .... intampin o problema simpla pe care nu stiu sa o rezolv. pe mikroC imi merge acest program, in MPLAB v3.40 , compilator xc8 nu. MPLAB nu vrea sa il compileze.... insa daca pun in locul variabilelor valorile direct calculate merge. #include <htc.h>#include <xc.h>#include"header.h" // aici sunt configuratiile registrilor si #pragma ... void main() { const long f = 512 ; // Frecventa const long t = 500000/f ; // obtine timpii de frecventa in microsecunde while(1){ GP2 = 1 ; __delay_us( t ); GP2 = 0 ; __delay_us( t ); } } Editat Octombrie 25, 2016 de allez001 Link spre comentariu
mars01 Postat Octombrie 25, 2016 Partajează Postat Octombrie 25, 2016 (editat) Salut! 1. Daca incluzi xc.h numai trebuie sa incluzi htc.h. Mai mult decat atat, aceasta incluziune a header-ului xc.h ar trebui facuta in fisierul tau "header.h" preferabil folosind si un "guard": #ifndef HEADER_H#define HEADER_H #include <xc.h>/* cod*/#endif iar in programul principal incluzi doar fisierul "header.h" 2. In XC8, _delay_us(x) are nevoie de urmatoarea directiva de preprocesor: #define _XTAL_FREQ 8000000 unde 8000000 = 8MHz este frecventa oscilatorului (setezi valoarea la frecventa la care lucreaza uC-ul tau) 3. Te referi la constantele acelea? Ideea de constanta este ca este ... constanta ... Nu poti schimba valoarea unei constante ... Scapa de "const" din fata lor si o sa iti compileze programul. Oricum, ar trebui sa iti mearga si asa cum este acum ... dar daca intentionezi sa schimbi "f" in timpul executiei programului (run time) atunci "t" nu poate fi constanta si evident nici "f" (cu exceptia situatiei cand folosesti un pointer ca sa modifici valoarea stocata la adresa lui "f" dar aceasta este ...). Editat Octombrie 25, 2016 de mars01 Link spre comentariu
allez001 Postat Octombrie 26, 2016 Autor Partajează Postat Octombrie 26, 2016 (editat) _XTAL_FREQ; o am definita, am facut cum ati spus... totusi nu vrea Nu pot renunta la constante.... pentru ca " delay_us" vrea neaparat valoare constanta. Si exact aici se pare ca este problema, la o privire mai atenta in log-ul de compilare. newmain2.c:18: error: (1387) inline delay argument must be constantnewmain2.c:20: error: (1387) inline delay argument must be constant Deci inseamna ca , constantele mele nu sunt interpretate ca si constante. Dar oare dece ? Si mergand pe ideea asta, in loc de variante constante am incercat cu definitii ( #define...). si cu #define merge . .............. #define freq 512 #define t 500000/freq ...................... Dar unde este problema ? De ce constantele nu sunt constante ?? Editat Octombrie 26, 2016 de allez001 Link spre comentariu
mars01 Postat Octombrie 26, 2016 Partajează Postat Octombrie 26, 2016 (editat) Bug de compilator. Presupun ca versiunea de compilator folosita este cea curenta adica XC8 v1.38, in varianta FREE. Educated guess: controller-ul folosit este PIC12F675. Cand se compileaza in varianta FREE sau STANDARD apare eroarea postata mai sus. Cand se compileaza in varianta PRO totul este OK. Solutie: 1. se folosesc directivele #define 2. se creaza o functie de delay care ar arata cam asa: void micro_delay( unsigned long x) { while (x--) __delay_us(1);} In acest fel constantele alea pot fi si variabile. Programul ar putea arata asa: // CONFIG#pragma config WDTE = OFF // Watchdog Timer (WDT disabled)#pragma config CP = OFF // Code Protect (Code protection off)#pragma config MCLRE = OFF // Master Clear Enable (GP3/MCLR pin fuction is digital I/O, MCLR internally tied to VDD)#include <xc.h>#define _XTAL_FREQ 4000000void micro_delay( unsigned long x) { while (x--) __delay_us(1);}void main() { const unsigned long f = 512 ; // Frecventa const unsigned long t = 500000/f ; // obtine timpii de frecventa in microsecunde while(1){ GP2 = 1; micro_delay(t); GP2 = 0; micro_delay(t); } } LE: la o asa frecventa mica de lucru, vor fi erori folosinf functia de mai sus pentru ca la un Fosc = 4MHz, vor fi 1.000.000 instructiuni pe secunda adica 1 instructiune pe microsecunda. Functia va avea un overhead de cativa cicli de ceas iar ulterior fiecare delay de 1us va necesita o scadere a lui x plus o comparatie data de while() ceea ce conduce la cel putin 3 cicli de ceas consumati adica 3 microsecunde (comparatia necesita 2 cicli de ceas). Deci eroare masiva. La frecvente mai mari de lucru va fi OK. Editat Octombrie 26, 2016 de mars01 Link spre comentariu
Liviu M Postat Octombrie 26, 2016 Partajează Postat Octombrie 26, 2016 Daca folosesti alte nume (cu sanse mai mici de a fi "luate") in loc de t si f, tot asa face?Ma gandesc sa nu fie astea definite pe cine stie unde, ca prea au nume de "sistem international".LE Iar am scris inainte sa citesc tot. Marius are explicatii mai bune. Link spre comentariu
allez001 Postat Octombrie 28, 2016 Autor Partajează Postat Octombrie 28, 2016 (editat) @Liviu M. Am schimbat si numele si nici asa nu a vrut. @Mars01. Am incercat si cu functia aceea void micro_delay(..), si nici asa nu a vrut. Am schimbat si compilatorul, am gasit pe net XC8 v1.34 PRO... si nici asa nu a vrut, Insa in log-ul de compilare xc8 PRO genereaza apare alta eroare newmain2.c:18: error: (712) can't generate code for this expression Si am zis ca tot omul sa vad ce am la linia 18. si ce sa vezi const long time = 500000/freq ; Asa ca mi-a venit ideea sa nu mai fac aceea impartire in cadrul constantei. Bun .... dar de impartire tot am nevoie, asa ca am mutat-o mai jos. astfel codul devine: const long freq = 512 ; const long time = 500000 ; GP2= 1 ; __delay_us( time/freq ) ; GP2= 0 ; __delay_us( time/freq ) ; Si asa ii place... MULTUMESC PENTRU AJUTOR !!! PS: acea informatie cu diferentele dintre varianta free si PRO a fost de mare ajutor .......... altfel nu stiam ce are. Ulterior am mai citit pe un forum, cum ca XC8 free ar face codul mai mare decat PRO care este optimizat mai bine Editat Octombrie 28, 2016 de allez001 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