mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AD-Wandler von AT89C51: Impulsbreite mit zwei Potis einstellen


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Francis C. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
hallo Z'me,

me voici de nouveau...

die Impulsbreite eines Rechtecksignal soll ueber zwei Trimm-Potis 
einstellbar sein. Der Bereich der Einstellung liegt zw. 1ms - 256ms, 
sowohl fuer die negative (t_n) Impulsbreite  als auch fuer die positive 
(t_p) Impulsbreite.
Wobei t_n + t_p die gesamte Impulsbreite formen, sollen sie jedoch 
unabhaengig/getrennt betrieben.

Meine Probleme:
1- Wie kann ich t_n und t_p getrennt betreiben, denn, wenn ich nur t_n 
(poti) einstelle, bekomme ich den Wert2 ausgegeben?
2- nur die Werte (1 u. 2) werden ausgegeben, obwohl ich sie 
Zeiteinstellung berechenet habe und ausgeben moechte

Im Anhang das Beispiel des Herstellers (seite 155) und ein PrintScreen 
anbei mein C-Code
/*** Einbinden von Include-Dateien ***/
#include <stdio.h>                  // Standard Ein-/Ausgabefunktionen
#include <at89c51cc03.h>            // CC03er-Grundregister


/*** Festlegung der benoetigen SFRs ***/
//near unsigned char P_1  @  0x90;    // Port P1 als Ganzes festlegeen, d.h. der komplette
                                   



/********************************************************************************************/
/*** Start des Hauptprogramms ***************************************************************/
/********************************************************************************************/

void main (void)     // Start des Hauptprogramms
{
    /*Definition der benoetigten Variablen*/
    unsigned int wert1;// Variable zur Berechnung des A/D-Wandler Ergebnisses an Poti 1-->t_p 
    unsigned int wert2;// Variable zur Berechnung des A/D-Wandler Ergebnisses an Poti 2-->t_n
    unsigned int t_p;//fuer die positive Imspulsbreite
    unsigned int t_n;//fuer die negative Impulsbreite   

    /**************************************************************/
    /*  Initialisierung der seriellen Schnittstelle 0 des CC03ers */
    /*  Schnittstellenparameter: 9600Baud, 8 Datenbit, 1 Stopp-Bit*/
    /*  asynchroner Betrieb                                       */
    /**************************************************************/

    SCON=0x52;
    TMOD |=0x20;
    TH1=0xfd;
    TR1=1;
    TI=1;

    /* Punkt 2, Analog-/Digital-Wandler initialisieren! */
    ADCF = 0xc0;        // Portpin P1.6 und P1.7 als Analogeingaenge definieren
    ADCON = 0x20;       // ADC einschalten --> ADEN = 1

    /* Bildschirm loeschen und Cursor auf Home-Position */
    printf("\x1b\x48\x1b\x4a");

    /* Bildschirm-Ueberschrift */
    printf("Programm zuer Einstellung einer Impulsbreite\n");
    printf("==================================================\n\n");
    //printf("\n\n\n***********Menu*************\n");
    printf("\n\n\n   positive Impulsbreite am Port P1.6, Bereich 1- 256ms!");
    printf("\n\n   negative Impulsbreite am Port P1.7, Bereich 1- 256ms!");

    //ADCON &= 0xf8;// alle Kanaele auf null setzen

    while(1)
    {
 
        if ((ADCON |= 0x06))   // Kanal 6 ausgewaehlt
        {
            printf("\n\n\n Port P1_6 wird ausgegeben: \n");
            ADCON = (ADCON | 0x08);                     // Einmalige Wandlung des ADUs starten!
            while((ADCON & 0x10) == 0);                 // Warte bis A/D-Wandlung beendet ist!
            ADCON = ADCON & 0xef;                       // Wandlungsendebit ADEOC auf log. 0 setzen!
            wert1 = ((ADDH << 2) + (ADDL & 0x03));       // Ergebnisregister auslesen u. zusammenbauen!
            t_p = (256 / 1024) * wert1;                  // positive Impulsbreite berechnen!
            if (wert1 == 0) t_p = 1;         // Wenn Wert ist null, t_p ist 1 ms (niedrigste Impulsbreite)
            if (wert1 > 1024) t_p = 256;     // Wenn Wert groesser 1024, t_p ist 256 ms (hoechstte Impulsbreite)
            printf("\x1b\x59\x2c\x34 %u    ", wert1);    // Cursor positionieren und Ergebnis in Dezimal ausgeben
            printf("\x1b\x59\x32\x34 %u ms    ", t_p);   // als positive Impulsbreite ausgeben!
            _wait_ms(2000);           
        }

        if (ADCON |= 0x07)//Wenn ADU eingeschalten und Kanal 7 ausgewaehlt
        {
            printf("\n\n\n Port P1_7 wird ausgegeben: \n");
            ADCON = (ADCON | 0x08);                     // Einmalige Wandlung des ADUs starten!
            while((ADCON & 0x10) == 0);                 // Warte bis A/D-Wandlung beendet ist!
            ADCON = ADCON & 0xef;                       // Wandlungsendebit ADEOC auf log. 0 setzen!
            wert2 = ((ADDH << 2) + (ADDL & 0x03));       // Ergebnisregister auslesen u. zusammenbauen!
            t_n = (256 / 1024) * wert2;                  // positive Impulsbreite berechnen!
            if (wert2 == 0) t_n = 1;         // Wenn Wert ist null, t_p ist 1 ms (niedrigste Impulsbreite)
            if (wert2 > 1024) t_n = 256;     // Wenn Wert groesser 1024, t_p ist 256 ms (niedrigste Impulsbreite)
            printf("\x1b\x59\x2c\x34 %u    ", wert2);    // Cursor positionieren und Ergebnis in Dezimal ausgeben
            printf("\x1b\x59\x32\x34 %u ms    ", t_n);   // als positive Impulsbreite ausgeben!
            _wait_ms(2000);           
        }
    }

    /* Endlosschleife zum ordnungsgemaessen Abschluss des Programms ist
       hier nicht mehr notwendig, da ja das Programm selber als End-
       losschleife laeuft !
    */

}

/********************************************************************************************/
/*** Ende des Hauptprogramms, d.h. Ende des gesamten Programms! *****************************/
/********************************************************************************************/

Autor: Francis C. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke und Gruss

Autor: Nop (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist Dir bewußt, daß (256 / 1024) in C eine Integer-Division ist und das 
Ergebnis des Ausdrcukes somit immer 0 ist?

Autor: Francis C. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bonsoir Messieurs,

Nop schrieb:
> Ist Dir bewußt, daß (256 / 1024) in C eine Integer-Division ist
> und das
> Ergebnis des Ausdrcukes somit immer 0 ist?

Danke fuer den Hinweis. Ich habe es rausgenommen.

Es funktioniert ein Stueck weit. Aber ich bekomme:

 -maximum 250 ms anstatt 256 ms, was die hoechst positive Impulsbreite 
anbelangt
 -minimum 0 ms anstatt 1 ms, was die niedrigst positive Impulsbreite 
anbelangt

Noch einen Hinweis von euch, bitte?


Ich habe mein Programm wie folgt komplett neu umgeschrieben:
/*** Einbinden von Include-Dateien ***/
#include <stdio.h>                  // Standard Ein-/Ausgabefunktionen
#include <at89c51cc03.h>            // CC03er-Grundregister


/*** Festlegung der benoetigen SFRs ***/
//nicht noetig, da im include vorhanden
                                   



/********************************************************************************************/
/*** Start des Hauptprogramms ***************************************************************/
/********************************************************************************************/

void main (void)     // Start des Hauptprogramms
{
    /*Definition der benoetigten Variablen*/
    unsigned char t_p;//Variable zur Ermittlung des A/D-Wandler Ergebnisses an Poti 1-->t_p
              //positive Impulsbreite
    unsigned char t_n;//Variable zur Ermittlung des A/D-Wandler Ergebnisses an Poti 1-->t_p
              //negative Impulsbreite

    /**************************************************************/
    /*  Initialisierung der seriellen Schnittstelle 0 des CC03ers */
    /*  Schnittstellenparameter: 9600Baud, 8 Datenbit, 1 Stopp-Bit*/
    /*  asynchroner Betrieb                                       */
    /********************Punkt 2***********************************/

    SCON=0x52;
    TMOD |=0x20;
    TH1=0xfd;
    TR1=1;
    TI=1;

    /* Punkt 3: Analog-/Digital-Wandler initialisieren! */
    ADCF = 0xc0;        // Portpin P1.6 und P1.7 als Analogeingaenge definieren
    ADCON = 0x20;       // ADC einschalten --> ADEN = 1

    /* Punkt 4: Bildschirm loeschen und Cursor auf Home-Position */
    printf("\x1b\x48\x1b\x4a");

    /* Punkt 5: Bildschirm-Ueberschrift */
    printf("Programm zuer Einstellung einer Impulsbreite\n");
    printf("==================================================\n");
    printf("\n\n\n Der AD-Wandler wird im 8 Bits Modus betrieben.");
    printf("\n\n   positive Impulsbreite t_p am Port P1.6, Bereich 1- 256ms!");
    printf("\n\n   negative Impulsbreite t_n am Port P1.7, Bereich 1- 256ms!");
    printf("");

    ADCON &= 0xf8;// alle Kanaele auf null setzen
 
       while(1)
       {
            if((ADCON & 0xfe)!=0xff)
            {            
                ADCON &= 0xf8;  //alle Kanaele freimachen
                ADCON |= 0x06;  //Kanal 6 auswaehlen
                ADCON |= 0x08;  //AD-Wandler starten--> ADSST = 1
                while((ADCON & 0x10) == 0);     // Warte bis A/D-Wandlung beendet ist!
                ADCON = ADCON & 0xef;           // Wandlungsendebit ADEOC auf log. 0 setzen!
                t_p = ADDH;       // Ergebnisregister auslesen

                printf("\n\n\n die positive Impulsbreite t_p ist: ");
                printf("\x1b\x59\x32\x34 %u ms    ", t_p);   // als positive Impulsbreite ausgeben!
                
                //Um im Bereich 1 - 256ms sicher zu bleiben
                if (t_p <1) t_p = 1;
                if (t_p >256) t_p = 256;
            }

                
            if((ADCON & 0xff)!=0xfe)
            {
                ADCON &= 0xf8;  //alle Kanaele freimachen
                ADCON |= 0x07;  //Kanal 6 auswaehlen          
                ADCON |= 0x08;  //AD-Wandler starten-->ADSST = 1 
                while((ADCON & 0x10) == 0);     // Warte bis A/D-Wandlung beendet ist!
                ADCON = ADCON & 0xef;           // Wandlungsendebit ADEOC auf log. 0 setzen!
                t_n = ADDH;     // Ergebnisregister auslesen
                                    //und um eins erhoehen
                                    //damit die Impulsbreite im Bereich bleibt

                printf("\n\n\n die negative Impulsbreite t_n ist: ");
                printf("\x1b\x59\x32\x34 %u ms    ", t_n);   // als negative Impulsbreite ausgeben!

                //Um im Bereich 1 - 256ms sicher zu bleiben
                if (t_n <1) t_n = 1;
                if (t_n >256) t_n = 256;

            }
            _wait_ms(2000);
        }
       

    /* Endlosschleife zum ordnungsgemaessen Abschluss des Programms ist
       hier nicht mehr notwendig, da ja das Programm selber als End-
       losschleife laeuft !
    */

}

/********************************************************************************************/
/*** Ende des Hauptprogramms, d.h. Ende des gesamten Programms! *****************************/
/********************************************************************************************/

Autor: tommy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Francis C. schrieb:
> if (t_p >256) t_p = 256;

t_p ist unsigned char und kann Werte von 0 bis 255 annehmen.

Autor: tommy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
bist Du weiter gekommen?

t_n betrifft das natürlich auch.

a la prochaine

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.

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