www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Erstes Programm in C (PIC18F2550)


Autor: PIC Nico (eigo) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe Heute mein erstes Programm in C geschrieben und dazu direkt mal 
eine Frage. Mein Programm macht nicht das was ich gerne möchte. 
Vielleicht hat jemand von euch mal 'ne Minute und kann sich den 
Quellcode anschauen.

Das Programm soll folgendes machen:

Wenn an PORTB 0xE0 anliegt (also PORTB 5,6 und 7 auf High liegen), dann 
soll eine LED geschaltet werden (über Transistor) und zwar PORTC,4.

Das wars auch schon. Ich habe als Takt einen 4Mhz Quarz gewählt also 
müsste die Konfiguration mit 'HS' doch stimmen.
Naja mal schaun was ihr dazu sagt, freue mich schon auf Rückmeldungen.

PS: Der PIC18F2550 hat 2x Vss... Muss ich die beide auf 0V ziehen?
Und was soll das bezwecken?

Lieben Gruß Nico

Autor: Jens PICler (picler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Betriebsspannungen und GNDs sollten ALLE angeschlossen werden. Außerdem 
ist bei einem 4MHz-Quarz die Einstellung XT die richtige, wenn ich mich 
nicht irre.

Autor: PIC Nico (eigo) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, danke für die schnelle Antowrt.

Also XT geht bis 4Mhz und HS ab 4Mhz von daher sollte das eigentlich so 
funktionieren. Aber ich werde den 2. Vss auf nochmal auf 0V ziehen mal 
sehen ob das was hilft...

Autor: PIC Nico (eigo) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also das hat nix gebracht leider..

Autor: PIC Nico (eigo) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Keiner? ... =/

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie wäre es mal mit einer Schleife in main.

Autor: PIC Nico (eigo) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Stefan,

ich habe doch unten in main return stehen, hab das grad nochmal 
verbessert durch return 0;

Oder meinst du jetzt was anderes?

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Verstehe dein Programm nicht. Lies dein Programm
nochmal durch und dann die Kommentare dahinter. Passt
irgendwie nicht zusammen.

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nicolas Meyertöns schrieb:
> Hallo Stefan,
>
> ich habe doch unten in main return stehen, hab das grad nochmal
> verbessert durch return 0;

und was hat return mit einer Schleife zu tun?

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kannst PORTC.4 nicht nehmen. Der ist für USB gedacht.
Und als Input deklariert. Siehe Datenblatt.
Nimm einen anderen Port.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nicolas Meyertöns schrieb:

> ich habe doch unten in main return stehen, hab das grad nochmal
> verbessert durch return 0;
>
> Oder meinst du jetzt was anderes?

Ja, meine ich.
Nach einem Reset wird dein Programm einmal durchlaufen, und was passiert 
dann? Was passiert nach dem return? Nun, das hängt vom Compiler ab, von 
leerer Endlosschleife über Software-Reset bis hin zum Absturz ist da 
alles möglich.

Autor: Fragender (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
jup.

normal sieht das so aus:

void main (void)
{
   StartUpCode(); // Initialisiere deine Register, Hardware usw.

   while(1)
   {
      // Das hier ist deine Hauptschleife, hier wird die Applikation ausgefuehert
     App();
   }
   return 1;
}

Autor: Hermann U. (Firma: !www.pcb-devboards.de) (gera82)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Wenn an PORTB 0xE0 anliegt (also PORTB 5,6 und 7 auf High liegen), dann
>soll eine LED geschaltet werden (über Transistor) und zwar PORTC,4.

Versuch mal so:
  void main(void)         // Anfang      
  { 

    TRISA = 0x00;        // PORTA ist als Output konfiguriert
 
    TRISB = 0xE0;        // PORTB,5,6,7 ist als Input konfiguriert
    TRISC = 0x00;        // PORTC ist als Output konfiguriert

    PORTC = 0x00;

  while (1)
    {            
       if(PORTB == 0xE0) {
        PORTCbits.RC4 = 1;
        }
        else {
        PORTCbits.RC4 = 0;
        }
    }
  }

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man kann PortC4 nicht als Ausgang definieren.
Datenblatt lesen.

Autor: PIC Nico (eigo) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, danke für die Antworten ich bin im Augenblick nicht an meinem 
Platz aber werde es dann mal ausprobieren.

>Verstehe dein Programm nicht. Lies dein Programm
>nochmal durch und dann die Kommentare dahinter. Passt
>irgendwie nicht zusammen.

Ja ich weiß die Kommentare sind noch veraltet, sorry das hab ich 
verpennt.
Ok wenn man PORTC nicht als Ausgang definieren kann dann werde ich da 
mal umstruckturieren.
  while (1)
    {            
       if(PORTB == 0xE0) {
        PORTCbits.RC4 = 1;
        }
        else {
        PORTCbits.RC4 = 0;
        }
    }

*PORTCbits.RC4 = 1* Der Befhel steuert nur ein einzelnes Bit an richtig?
*while (1)* Die 1 in der Klammer was für eine Bedingung stellt diese 
dar? Läuft der jetzt immer durch die While Schleife durch?

Autor: Marco Schulze (sharkman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das while stellt die endlosschleife dar.

mit der 1 legst du quasi den zustand true fest. dieser gilt immer und 
somit wird die schleife nicht abgebrochen.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Nicolas,
ich kann dir nur raten dir ein C - Buch zu kaufen, es aufmerksam zu 
lesen und die darin enthaltenen Beispiele durch zu denken und 
auszuprobieren.

Auch wenn du Anfänger bist, ein µController Programm ohne Endlosschleife 
zu schreiben, zeigt davon dass du einfach mal aufs geradewohl drauf 
losprogrammierst und du dann mit Fehlersuche viel mehr Zeit verschei.. 
als mit schreiben.
Das ist der falsche Weg!
Nicht böse gemeint, ich habe auch so angefangen wie du, aber recht 
schnell meine Rangehensweise geändert...
Wünsche dir noch viel Spass beim Lernen!


mfg

Autor: PIC Nico (eigo) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, danke für eure Antworten!

Also ich habe schon einiges in Assembler programiert. Von daher ich weiß 
schon, dass es einer Schleife beadarf. Ich habe nur angenommen, dass es 
bei dem Return dann im "main" von vorne los geht, habe sowas nämlich in 
einem Tutorial gelesen und wohl falsch interpretiert, denn dort hieß es:

>> So muss ein C - Programm mindestens aussehen!

Naja okay jetzt weiß ich es besser =) Man lernt doch nie aus :)

Autor: PIC Nico (eigo) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay habe jetzt mal wieder ein bisschen ausprobiert und festgestellt es 
lag tatsächlich am Pin, welcher nur als Input benutzt werden kann.

Aber jetzt geht es weiter... Ich bekomme die LED jetzt zum leuchten aber 
sobald ich irgendwas in Abhängigkeit der Eingänge (RB7,6,5) machen 
möchte läuft nix mehr so wie ich will.


Zunächst konfiguriere ich unter main die TRIS Register, dann geht es 
direkt in die Schleife wo eine Bedingung zu finden ist und zwar "PORTB 
&& 224" also wenn PORTB7,6 und 5 High haben (entspricht doch dez. 224), 
wenn das also eine 1 liefert (true) dann soll das Unterprogramm 
aufgerufen werden und die LED blinkt vor sich hin.

Ist die Bedingung nicht erfüllt, so wird einfach der Ausgang gelöscht.

So jetzt kommt das interessante: Beim Starten des PICs also bei 
Spannungszufuhr fängt die LED sofort an zu blinken obwohl RB7,6 und 5 
LOW sind! Komischerweise sind RB4,3,2 und 0 auf HIGH. Wobei es im 
Datenblatt eigentlich heisst, dass alle Pull-Ups beim POR disabled sind.

Zum testen habe ich das INTCON2 Register auch nochmal mit FF geflutet 
aber das hat auch nix geholfen. Ich habe mich jetzt auch nicht getraut 
die PINs auf Masse zu ziehen weil ich mir den PIC nicht weghauen möchte.

Vielleicht weiß ja jemand was ich übersehen habe.

PS: Alle Pins am PORTB sind offen bis eben auf meine Eingänge (7,6,5) 
aber dass sollte ja nicht weiter stören da ich sie doch als Output 
initialisiert habe...

/**********************************************************************************************/
//  Include Dateien
/**********************************************************************************************/
  
#include <p18cxxx.h>                   // Für den PIC - wird autom. erkannt
#include "delays.h"                    // Für die Warteschleife 

/**********************************************************************************************/
//  Konfiguration
/**********************************************************************************************/

#pragma config FOSC = HS
#pragma config PWRT = ON
#pragma config BOR = OFF
#pragma config WDT = OFF  
#pragma config LVP = OFF
#pragma config PBADEN = OFF
#pragma config VREGEN = OFF
#pragma config MCLRE = ON            
      
/**********************************************************************************************/
//  Unterprogramm
/**********************************************************************************************/

  void someLittleFunction(void)
  {
    LATCbits.LATC7 = 1;
    Delay10KTCYx(1);
    LATCbits.LATC7 = 0;
    Delay10KTCYx(1);
  }

/**********************************************************************************************/
//  Hauptprogramm
/**********************************************************************************************/

  void main(void)               // Anfang      
{ 

    TRISA = 0x00;                // PORTA ist als Output konfiguriert 
    TRISB = 0xE0;                // PORTB,5,6,7 ist als Input konfiguriert
    TRISC = 0x00;                // PORTC ist als Output konfiguriert          

  while(1) 
  { 
    if (PORTB && 224)
    {
      someLittleFunction();
    }
    else
    {
      LATCbits.LATC7 = 0;
    }
  }
  return(0);
}

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> wo eine Bedingung zu finden ist und zwar "PORTB
> && 224" also wenn PORTB7,6 und 5 High haben

In einem C-Buch den Unterschied zwischen & und && nachschlagen.

Autor: PIC Nico (eigo) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay hab ich eben, also && Vergleicht das ganze Byte als ganzes und & 
alle Bits einzelnd, richtig?

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ähm, nicht ganz. Weder &, noch && vergleichen irgendetwas. Beides sind 
Und-Verknüpfungen. & eine bitweise, && eine logische.

Autor: PIC Nico (eigo) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja okay aber so meinte ich es ja hab mich nur falsch Ausgedrückt =) 
Danke für deine schnelle Antwort..

Autor: RFr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ein geeignetes C-Buch ist m.E.:
H.Herold C Kompaktreferenz
isbn 3-8273-2286-3

Ich sehe mich veranlasst, zur Benutzung dieses Buches mit grossem 
Nachdruck zu raten!

Gruss

Robert

Autor: PIC Nico (eigo) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Robert,
danke für deinen Buch Tipp, das werde ich mir mal ansehen.
Ich habe trotzdem vorab jetzt schonmal eine kurze Frage!

Folgende Variablen habe ich als unsigned char deklariert:

"eins", "zwei" und "erg"

wobei "eins" den Wert 1 "zwei" den Wert 15 zugeordnet bekommt.
"erg" soll die Bitweise Operation & der beiden anderen Variablen sein!

Also müsste es doch so ablaufen:
eins |0|0|0|0|0|0|0|1| (1)
------------&-------------
zwei |0|0|0|0|1|1|1|1| (15)
------------=-------------
erg  |0|0|0|0|0|0|0|1| (1)

Also folgender Code...
/**********************************************************************************************/
//  Unterprogramm
/**********************************************************************************************/

  void someLittleFunction(void)
  {
    LATCbits.LATC7 = 1;
    Delay10KTCYx(1);
    LATCbits.LATC7 = 0;
    Delay10KTCYx(1);
  }


/**********************************************************************************************/
//  Hauptprogramm
/**********************************************************************************************/

  void main(void)               // Anfang      
{ 

    unsigned char eins, zwei, erg;
    erg = eins & zwei;
    eins = 1;
    zwei = 15;

    TRISA = 0x00;                // PORTA ist als Output konfiguriert 
    TRISB = 0xE0;                // PORTB,5,6,7 ist als Input konfiguriert
    TRISC = 0x00;                // PORTC ist als Output konfiguriert          

  while(1) 
  { 
    if (erg == 1)
    {
      someLittleFunction();
    }
    else
    {
      LATCbits.LATC7 = 0;
    }
  }
  return(0);

...müsste die Funktion "someLittleFunction" aufrufen, oder?
Vielen Dank schonmal vorweg.

LG

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>...müsste die Funktion "someLittleFunction" aufrufen, oder?

Nö, die Reihenfolge stimmt nicht. erg wird 0 sein.

Autor: PIC Nico (eigo) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also muss es so aussehen?
    unsigned char eins, zwei, erg;
    eins = 1;
    zwei = 15;
    erg = eins & zwei;

Ich habe mich erst gefragt ob es wohl wichtig ist, dass ich die 
Operation nach den beiden deklarationen schreibe.. mh..
Danke für die schnelle Antwort =)

Autor: PIC Nico (eigo) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gut das Programm läuft schon wollt mich jetzt gleich weiter versuchen!
Habe mir einiges über ADC durchgelesen und ein Programm geschrieben aber 
es ist natürlich wieder irgendwo der Wurm drin =)
void main(void)                   // Main wie bei Assemblar          
{                                   // Anfang
    int ADCw;
    int ADCe;
    ADCe = 1023;


    LATA = 0x00;                    // PORTA löschen (kann beim Start undef. Zustand annehmen)
    LATB = 0x00;                    // PORTB löschen (kann beim Start undef. Zustand annehmen)
    LATC = 0x00;                    // PORTC löschen (kann beim Start undef. Zustand annehmen)

    ADCON0 = 0x01;                  // AD Wandlung auf RA0
    ADCON1 = 0x0E;                  // RA0 ist ein Analog Eingang
    ADCON2 = 0x3E;                  // Left,Geschwindigkeit,Time

    
    TRISA = 0x01;                    // PORTA,0 ist als Input konfiguriert 
    TRISB = 0x00;                    // PORTB,7 ist als Output konfiguriert  
    TRISC = 0x00;                    // PORTC ist als Output konfiguriert    

    Delay10KTCYx(10);                // ADC Aquisition Time    

Bis hier hin stelle ich erstmal die Grundlegenden Parameter ein!

  while(1)                           // Endlosschleife muss vorhanden sein
  {                                 // Start ab jetzt kommt euer main Programmcode
  
  ADCON0 = 0x03;                    // Analog Digital Messung starten
  
  while (ADCON0 == 3)                // Warten bis der ADC fertig ist
    {
    

Hier soll der ADC gestartet werden und abgewartet werden, bis die 
Messung fertig ist.

  Delay10KTCYx(10);                  // ADC Aquisition Time


Hier ist dann wieder eine Verschnaufpause für den ADC.


      ADCw = ADRESH + ADRESL;


Hier möchte ich die beiden Ergebnis Register addieren.

  if (ADCw > ADCe)                  // Solange ADRESH größer als 128 ist 
    {
      LATCbits.LATC7 = 0;            // Bleibt der PORTC,7 aus
    }
  else
    {
      LATCbits.LATC7 = 1;            // Sonst geht er an!
    }

  }                                
}


Und hier soll entschieden werden ob LED an oder aus und zwar, wenn die 
Spannung über 2,5V liegt (1023) soll sie aus bleiben unter 2,5V soll sie 
an gehen.

Wo ist der Fehler?

Autor: Naja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>irgendwo der Wurm drin =)
>Wo ist der Fehler?

Ich sehe gleich drei.
1. Zuwenig C gelernt
2. Fehler ist nicht beschrieben.
3. Datenblatt nicht gelesen.

Autor: Sascha Focus (sascha_focus) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

du hast nen 10bit Analog Wert. Warum addierst du High/Lowbyte???

So sieht es bei mir aus:
void Setup_ADC(void)
{
  ADCON0bits.ADON=0;
  TRISAbits.TRISA0=1;
  ADCON2=0x3C;
  ADCON2bits.ADFM = 1;
  ADCON0bits.ADON=1;
}

unsigned int Read_ADC(unsigned char Channel)
{
  unsigned int ADWERT;
  switch(Channel)
    {
    case 0:
      ADCON0bits.CHS0=0;
      ADCON0bits.CHS1=0;
      ADCON0bits.CHS2=0;
      ADCON0bits.CHS3=0;
      break;
    case 1:
      ADCON0bits.CHS0=1;
      ADCON0bits.CHS1=0;
      ADCON0bits.CHS2=0;
      ADCON0bits.CHS3=0;
      break;
    case 2:
      ADCON0bits.CHS0=0;
      ADCON0bits.CHS1=1;
      ADCON0bits.CHS2=0;
      ADCON0bits.CHS3=0;
      break;
    case 3:
      ADCON0bits.CHS0=1;
      ADCON0bits.CHS1=1;
      ADCON0bits.CHS2=0;
      ADCON0bits.CHS3=0;
      break;
    case 4:
      ADCON0bits.CHS0=0;
      ADCON0bits.CHS1=0;
      ADCON0bits.CHS2=1;
      ADCON0bits.CHS3=0;
      break;
    case 5:
      ADCON0bits.CHS0=1;
      ADCON0bits.CHS1=0;
      ADCON0bits.CHS2=1;
      ADCON0bits.CHS3=0;
      break;
    case 6:
      ADCON0bits.CHS0=0;
      ADCON0bits.CHS1=1;
      ADCON0bits.CHS2=1;
      ADCON0bits.CHS3=0;
      break;
    case 7:
      ADCON0bits.CHS0=1;
      ADCON0bits.CHS1=1;
      ADCON0bits.CHS2=1;
      ADCON0bits.CHS3=0;
      break;
    case 8:
      ADCON0bits.CHS0=0;
      ADCON0bits.CHS1=0;
      ADCON0bits.CHS2=0;
      ADCON0bits.CHS3=1;
      break;
    case 9:
      ADCON0bits.CHS0=1;
      ADCON0bits.CHS1=0;
      ADCON0bits.CHS2=0;
      ADCON0bits.CHS3=1;
      break;
    case 10:
      ADCON0bits.CHS0=0;
      ADCON0bits.CHS1=1;
      ADCON0bits.CHS2=0;
      ADCON0bits.CHS3=1;
      break;
    case 11:
      ADCON0bits.CHS0=1;
      ADCON0bits.CHS1=1;
      ADCON0bits.CHS2=0;
      ADCON0bits.CHS3=1;
      break;
    case 12:
      ADCON0bits.CHS0=0;
      ADCON0bits.CHS1=0;
      ADCON0bits.CHS2=1;
      ADCON0bits.CHS3=1;
      break;
    default:
      ADCON0bits.CHS0=0;
      ADCON0bits.CHS1=0;
      ADCON0bits.CHS2=0;
      ADCON0bits.CHS3=0;
    }

  ADCON0bits.GO = 1;              // Start AD conversion
    while(ADCON0bits.NOT_DONE);     // Wait for conversion
  ADWERT=ADRESH;
  ADWERT=ADWERT<<8;
  ADWERT=ADWERT+ADRESL;
  return ADWERT;
}


Gruß Sascha

Autor: PIC Nico (eigo) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Sascha,

ich wollte eigentlich erstmal nur herrausfinden ist der Wert unter oder 
über 2,5V. Aber gut dann versuche ich es gleich vernünftig habe da aber 
noch eine Frage.


 >>while(ADCON0bits.NOT_DONE);
Fehlen hier nicht die beiden Klammern {} ?

>>ADWERT=ADRESH;
>>ADWERT=ADWERT<<8;
>>ADWERT=ADWERT+ADRESL;
>>return ADWERT;

Was genau machst du hier?

Autor: Sascha Focus (sascha_focus) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da wird aus den beiden 8Bit Werten ein 16Bit Wert gemacht, einfach 
schieben + addieren. Aus High/Lowbyte ein unsigned integer bilden.
Um auf auf 2.5V zu testen dann 512 als Wert nehmen, da dein AD von 
0-1023 geht.

Gruß Sascha

Autor: PIC Nico (eigo) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gut jetzt hab ich es fast, nur noch eine Kleinigkeit;

"Channel" legst du irgendwo anders im Programm fest, richtig?
Ich möchte zunächst nur 1 AD Pin benutzen und zwar RA0, also bräuchte 
ich nur schreiben:

ADCON0=0x01;

...denn die restlichen möchte ich ja eh nicht abfragen.

Autor: Sascha Focus (sascha_focus) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

soviel Speicher kostet der Code nicht.
So kannst du einfach mit dem Aufruf von Read_ADC(0) den Kanal 0 
aufrufen, oder Read_ADC(1) für Kanal 1. Ist später mal einfacher zu 
lesen....
Brauchst so halt nur schaun welchen AN-Pin du nimmst und nicht mehr 
schauen, wie du den einstellen mußt.


Gruß Sascha

Autor: PIC Nico (eigo) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja gut da hast du wohl recht! Jetzt noch 1 letzte Frage;

Wenn ich z.B. mein main Programm habe und dort drin dann
das UP oder Funktion Read_ADC(0) aufrufe, dann misst er ja den AN0
und speichert den in der uint ADWERT ab. Zum Schluss kommt dann ja
der Befehl Return ADWERT;

womit ich ja wieder in mein main Programm, mit dem Rückgabewert "ADWET", 
komme oder? Wenn ja, wenn ich nun den ADWERT unter main als Bedingung
einsetzte krieg ich nen Error weil der ADWERT unbekannt ist.

Wie kann ich das richtig stellen, muss ich zusätzlich den Wert unter
main auch nochmal deklarieren, dass es ein uint ist?

Schonmal 1000 dank für deine Hilfe hast mir echt gut geholfen =)

Autor: Sascha Focus (sascha_focus) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Variable ADWERT existiert nur local in der Funktion Read_ADC.
Deshalb auch der Aufruf mit ADCw=Read_ADC(0).
Es geht aber auch, wenn die AD-Funktionen in deiner main.c sind,
eine unsigned int ADWERT Variable anlegen.

#pragma udata
unsigned int ADWERT;
unsigned int ADCe;

#pragma code
void main(void)
{                                   // Anfang
    ADCe = 511;


    LATA = 0x00;                    // PORTA löschen (kann beim Start undef. Zustand annehmen)
    LATB = 0x00;                    // PORTB löschen (kann beim Start undef. Zustand annehmen)
    LATC = 0x00;                    // PORTC löschen (kann beim Start undef. Zustand annehmen)

    TRISB = 0x00;                    // PORTB,7 ist als Output konfiguriert  
    TRISC = 0x00;                    // PORTC ist als Output konfiguriert    

       Setup_ADC();
while(1)
 {
      Read_ADC(0);
  if (ADWERT > ADCe)                  // Solange ADRESH größer als 128 ist 
    {
      LATCbits.LATC7 = 0;            // Bleibt der PORTC,7 aus
    }
  else
    {
      LATCbits.LATC7 = 1;            // Sonst geht er an!
    }
 }                              
}


void Setup_ADC(void)
{
  ADCON0bits.ADON=0;
  TRISAbits.TRISA0=1;
  ADCON2=0x3C;
  ADCON2bits.ADFM = 1;
  ADCON0bits.ADON=1;
}

void Read_ADC(unsigned char Channel)
{
//  unsigned int ADWERT; // fällt weg, da global definiert!!!
  switch(Channel)
    {
    case 0:
      ADCON0bits.CHS0=0;
      ADCON0bits.CHS1=0;
      ADCON0bits.CHS2=0;
      ADCON0bits.CHS3=0;
      break;
    case 1:
      ADCON0bits.CHS0=1;
      ADCON0bits.CHS1=0;
      ADCON0bits.CHS2=0;
      ADCON0bits.CHS3=0;
      break;
    case 2:
      ADCON0bits.CHS0=0;
      ADCON0bits.CHS1=1;
      ADCON0bits.CHS2=0;
      ADCON0bits.CHS3=0;
      break;
    case 3:
      ADCON0bits.CHS0=1;
      ADCON0bits.CHS1=1;
      ADCON0bits.CHS2=0;
      ADCON0bits.CHS3=0;
      break;
    case 4:
      ADCON0bits.CHS0=0;
      ADCON0bits.CHS1=0;
      ADCON0bits.CHS2=1;
      ADCON0bits.CHS3=0;
      break;
    case 5:
      ADCON0bits.CHS0=1;
      ADCON0bits.CHS1=0;
      ADCON0bits.CHS2=1;
      ADCON0bits.CHS3=0;
      break;
    case 6:
      ADCON0bits.CHS0=0;
      ADCON0bits.CHS1=1;
      ADCON0bits.CHS2=1;
      ADCON0bits.CHS3=0;
      break;
    case 7:
      ADCON0bits.CHS0=1;
      ADCON0bits.CHS1=1;
      ADCON0bits.CHS2=1;
      ADCON0bits.CHS3=0;
      break;
    case 8:
      ADCON0bits.CHS0=0;
      ADCON0bits.CHS1=0;
      ADCON0bits.CHS2=0;
      ADCON0bits.CHS3=1;
      break;
    case 9:
      ADCON0bits.CHS0=1;
      ADCON0bits.CHS1=0;
      ADCON0bits.CHS2=0;
      ADCON0bits.CHS3=1;
      break;
    case 10:
      ADCON0bits.CHS0=0;
      ADCON0bits.CHS1=1;
      ADCON0bits.CHS2=0;
      ADCON0bits.CHS3=1;
      break;
    case 11:
      ADCON0bits.CHS0=1;
      ADCON0bits.CHS1=1;
      ADCON0bits.CHS2=0;
      ADCON0bits.CHS3=1;
      break;
    case 12:
      ADCON0bits.CHS0=0;
      ADCON0bits.CHS1=0;
      ADCON0bits.CHS2=1;
      ADCON0bits.CHS3=1;
      break;
    default:
      ADCON0bits.CHS0=0;
      ADCON0bits.CHS1=0;
      ADCON0bits.CHS2=0;
      ADCON0bits.CHS3=0;
    }

  ADCON0bits.GO = 1;              // Start AD conversion
    while(ADCON0bits.NOT_DONE);     // Wait for conversion
  ADWERT=ADRESH;
  ADWERT=ADWERT<<8;
  ADWERT=ADWERT+ADRESL;
//  return ADWERT;   //diese Zeile fällt dann weg!!!!
}



Hoffe mal, ich habe jetzt nix vergessen :)


Gruß Sascha

Autor: PIC Nico (eigo) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah gut, das hat mir noch gefehlt.Also wenn ich Variablen oberhalb meines 
Codes deklariere gelten sie global und ich kann sie überall abrufen.

Danke es funktioniert jetzt! Übrigens Deutschland (Damen) ist 
Europameister 6:2 gegen England gewonnen =) Schönen Abend noch..

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.