Sari la conținut
ELFORUM - Forumul electronistilor

MPLAB X 3.40 Problema Variabile


allez001

Postări Recomandate

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 de allez001
Link spre comentariu
  • Răspunsuri 5
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • allez001

    3

  • mars01

    2

  • Liviu M

    1

Top autori în acest subiect

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 de mars01
Link spre comentariu

_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 constant
newmain2.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 de allez001
Link spre comentariu

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 de mars01
Link spre comentariu

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

@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. :freaza: 

 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... :inger

 

 

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 de allez001
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