Forum: Mikrocontroller und Digitale Elektronik STM32 Eingänge einlesen und auswerten


von AR (Gast)


Lesenswert?

Hallo zusammen,

ich bin etwas am Verzweifeln. Ich arbeite mit einem STM32F103ZET6 Board 
und habe es geschafft, die an den Ausgängen angeschlossenen LED´s zum 
leuchten zu bringen. Ich weiß auch ungefähr, wie ich einen Port als 
Eingang initialsieren muß. Aber ich weiß nicht, wie ich den Pin dann 
auswerten soll. Wir können mit userem Board mithilfe des Hyperterminals 
über RS232 auch zugreifen, um z.Bsp. Ausgänge zu schalten. Doch leider 
exisieren noch keine Befehle, um Eingänge zu schalten/abzufragen, 
geschweige denn später mal mit VS-Studio und WinForms was damit 
anzustellen. Hat jemand eine Idee, wie man sowas am Besten angeht, oder 
eine gute Lektüre ?

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Am besten denjenigen fragen, der das Programm für den STM32 geschrieben 
hat.

von AR (Gast)


Lesenswert?

wie wertet man gerenell einen eingang aus ? man kann ja die led, die an 
einem pin leuchtet, auch wieder einlesen und auswerten

von AR (Gast)


Lesenswert?

unser board hat z.bsp. 8 eingänge und ausgänge. man könnte doch das 
programm so ab ändern, wenn ich in meinem Programm in VS eine Checkbox 
aktiviere und die entsprechende LED am Ausgang auf dem Board leuchtet, 
zusätzlich noch eine andere, definierte LED leuchtet, oder nicht ?

von Andreas W. (geier99)


Lesenswert?

AR schrieb:
> wie wertet man gerenell einen eingang aus ? man kann ja die led, die an
> einem pin leuchtet, auch wieder einlesen und auswerten

In dem Du das IDR-Register vom entsprechen Port einliest und prüfst ob 
das Bit gesetzt ist.Beispiel:
 (GPIOA->IDR & (1<<PinNr)          //  0 oder 2^PinNr
oder
 ((GPIOA->IDR & (1<<PinNr)) >> PinNr  //liefert 0 oder 1.

Das ganze kann man dann noch schön in Makros verpacken :-)

von AR (Gast)


Lesenswert?

Ich habe ja die outputs mit z.Bsp. "DO0((outputs&(1<<0)));" usw. 
definiert. Muß das IDR anstelle des outputs in dem Fall ?

von Andreas W. (geier99)


Lesenswert?

AR schrieb:
> Ich habe ja die outputs mit z.Bsp. "DO0((outputs&(1<<0)));" usw.
> definiert. Muß das IDR anstelle des outputs in dem Fall ?

ich dachte du wolltest Eingänge einlesen.

von AR (Gast)


Lesenswert?

ja, möchte ich auch. die frage ist ja, ob ich die eingänge ungefähr 
genauso definieren muß wie die ausgänge.....

von Andreas W. (geier99)


Lesenswert?

ja, zb. im Modus:
GPIO_Mode_IN_FLOATING  // Eingang offen
oder
GPIO_Mode_IPU          // Eingang  mit Pullup
oder
GPIO_Mode_IPD          // Eingang mit PullDown

anstatt z.B.
GPIO_Mode_Out_PP

Der Rest bleibt gleich. Du must halt nur im GPIOx->CRx Register den 
richtigen mode einstellen.

PS: IDR ist das Input Data Register.

von AR (Gast)


Lesenswert?

und wie würde dann eine if abfrage z.bsp. aussehen ? evtl so:

if

(GPIOA->IDR & (1<<02) == 1)
{
     dann tue irgendwas...........
}

oder wie ?

von Andreas W. (geier99)


Lesenswert?

AR schrieb:
> und wie würde dann eine if abfrage z.bsp. aussehen ? evtl so:
>
> if
>
> (GPIOA->IDR & (1<<02) == 1)
> {
>      dann tue irgendwas...........
> }
>
> oder wie ?
fast richtig :-)

 ((GPIOA->IDR & (1<<02))>> 0x02 == 1)

oder

 (GPIOA->IDR & (1<<02) == 4)

von AR (Gast)


Lesenswert?

Das mit (GPIOA->IDR & (1<<02) == 4) verstehe ich nicht so richtig. Wenn 
man nur 0 oder 1 erhalten kann, kann doch da niemals eine 4 stehen, oder 
? Nur 0 oder 1 könnte da stehen......

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Was willst Du denn nun programmieren, den PC in einem PC Programm?
Oder schreibst Du ein Programm für den Prozessor?

Lese mal ein paar Toutorials über C Programmierung und vor allem was der 
Operator "<<" bedeutet.

Und dann lese in der Definition was für ein Datentyp die Variable 
"GPIOA->IDR" hat nach.

von Flo (Gast)


Lesenswert?

die frage ist auch,
arbeitest du mit der pheripherie standart library,
oder mit register direktzugriffen?

eingänge auslesen ist nicht schwierig,
dafür gibs ein extra register.

mit der pherstdlib kannst du auch die eingänge einzelnt
oder als port abfragen

alles in allem mal den datasheet zur pheripherie vom stm32
rausholen, um die funktionsweise üerhaupt zu verstehen
(für gpio aktivierung muss man zum beispiel auch noch die entsprechende 
clock aktivieren, also nicht ganz so trivial wie bei avrs)

von Andreas W. (geier99)


Lesenswert?

AR schrieb:
> Das mit (GPIOA->IDR & (1<<02) == 4) verstehe ich nicht so richtig. Wenn
> man nur 0 oder 1 erhalten kann, kann doch da niemals eine 4 stehen, oder
> ? Nur 0 oder 1 könnte da stehen......



 (1<<2) = 4  ==>  GPIOA->IDR & 4 ==> das kann nur 0 oder 4 werden

ansonsten die Tipps von meinem Vorgänger befolgen.
http://www.mikrocontroller.net/articles/Bitmanipulation

von AR (Gast)


Lesenswert?

Hallo,

ich bins nochmal,

wenn ich möchte, dass bei PortF der Ausgang z.Bsp. 1 ist, soll bei PortF 
automatisch Ausgang 7 aktiviert werden.

    if((GPIOF->IDR & (1<<05))>> 0x05 == 1)
        {
             ((GPIOF->IDR & (1<<07))>> 0x07 == 1);
        }

Doch wird die Zeile "((GPIOF->IDR & (1<<07))>> 0x07 == 1);" blau 
unterstrichen nach dem compileren mit dem Hinweis: value computed is not 
used.

von AR (Gast)


Lesenswert?

obiges thema hat sich erledigt. inzwischen ist ein neues problem 
aufgetaucht und zwar möchte ich mit:

   uint8_t ucStatus = 0;

ucStatus = GPIO_ReadOutputDataBit(GPIOF,GPIO_Pin_10);
    if(ucStatus == 32)
        {
             GPIOE->BSRR = GPIO_Pin_1;
        }

den zustand eines ausganges abfragen und wenn dieser 1 ist, dann soll 
pin 1 an port e gesetzt werden.

wie frägt man eine 8bit variable ab ? mache ich das so richtig ? glaube 
eher nicht ;-)

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

if(GPIOF->ODR & GPIO_Pin_10)
        {
             GPIOE->BSRR = GPIO_Pin_1;
        }

von AR (Gast)


Lesenswert?

danke für die schnelle antwort,

was bedeutet ->odr

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Siehe Doku
RM0008 Reference_Manual
von ST

von AR (Gast)


Lesenswert?

der eingang wird so aber leider nicht gesetzt

von AR (Gast)


Lesenswert?

ich meinte, der ausgang pin 1

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Der Ausgang GPIOF->ODR, GPIO_Pin_10 muss auch erst gesetzt sein

von AR (Gast)


Lesenswert?

dann haben wir uns missverstanden,

ich gebe z.bsp. am ausgang pin10 24v rein, wird runtergeteilt auf 3,3v 
und dann gehts über eingang pin9 zum stm. wenn am ausgang pin10 die 24v 
anliegen, sollte an port3 pin 1 gesetzt werden.

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Gut, dann lerne mal den Unterschied zwischen Ausgang und Eingang.

Wenn Du die Doku von hier:
Beitrag "Re: STM32 Eingänge einlesen und auswerten"
liest, dann weißt Du auch wie man einen Eingang liest.

Wir sind hier alle so kleinlich.

von AR (Gast)


Lesenswert?

wie würde denn so ein eingang in eine 8bit variable z.bsp. abgespeichert 
werden ? was würde in der variable drinstehen

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Der gesamte Eingangsport hat schon mal 16 Bit.
Also nochmal, Doku lesen.

von AR (Gast)


Lesenswert?

ja, aber in der doku steht ja nichts drin, wie ich die variable weiter 
verwerte. if(ucStatus == 0x80) dieser ansatz ist denke ich ja falsch, 
oder

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Da könnte dieser Tipp weiterhelfen:
Beitrag "Re: STM32 Eingänge einlesen und auswerten"

von AR (Gast)


Lesenswert?

Juhuuu, ich habs hinbekommen...

if((GPIOC->IDR & (1<<13))>> 13 == 1)
        {
             GPIOE->BSRR = GPIO_Pin_1;
        }

so funktioniert es wie ich es haben möchte. Aber was icch nicht 
begreife, warum man mit (1<<13) bitweise von 1 dann 13 mal nach links 
verschiebt und dann wieder mit >> 13mal zurück, das verstehe ich 
nicht...

von AR (Gast)


Lesenswert?

das ganze funktioniert aber nur, wenn die 24v am eingang schon anliegen, 
während das board eingeschlten wird. wenn ich die 24v erst später 
einstecke, geht der ausgang trotzdem nicht an

von AR (Gast)


Lesenswert?

ok, habe es noch in die haupt while schleife gepackt und jetzt gehts. 
danke, super forum

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Das ist die Kurzform:

if (GPIOC->IDR & GPIO_Pin_13)

schneller, effizienter, ohne schieben, klar und verständlich.

von AR (Gast)


Lesenswert?

hallo,

jemand hat mal die ausgänge als z.bsp. "DO0((outputs&(1<<0)))" für 
outputs deklariert, sodass man mit einem stringvergleich über teraterm 
die eingänge per rs232 ein und ausschalten kann. wie könnte so eine 
definition für eingänge aussehen ?
ich möchte mal später das ganze in c# mit winforms integrieren.

von Walter S. (avatar)


Lesenswert?

Die Natur hat hat ja durch trial and error sogar uns Menschen 
hervorgebracht, also warum sollte man nicht auch auf diese Weise ein 
Programm schreiben können,
dauert halt ein paar Jährchen ....

von Reinhard B. (brainstorm)


Lesenswert?

Hallo AR,

Du weißt ja jetzt wie man Ausgänge setzt und Eingänge einliest. Wenn du 
diese Funktionen über den UART nutzen willst, dann musst du dir dazu ein 
Protokoll überlegen. Beim Empfangen kannst du das dann - wie du selbst 
schon richtig erkannt hast - z. B. per Stringvergleich zerpflücken und 
die entsprechenden Aktionen ausführen.

Aber etwas Hirnschmalz wirst du da selber reinstecken müssen. Würde mich 
wundern, wenn sich jemand findet, der dir das bis ins Detail vorbetet. 
Vielleicht findest du ja irgendwo ein anderes Projekt, bei dem 
irgendetwas über UART gesteuert wird und kannst dir dort was abschaun.

mfg

von AR (Gast)


Lesenswert?

kann mir mal jemand bitte erklären, was daran falsch ist an dem befehl:

#define  RELAIS(a)    {if(a>0)?(GPIOE->BSRR  |= GPIO_Pin_6) 
else(GPIOE->BRR  |= GPIO_Pin_6);}

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Das Fragezeichen muss weg

von AR (Gast)


Lesenswert?

genau. so gehts jetzt:


#define  RELAIS(a)    {if(a>0)GPIOE->BSRR  |= GPIO_Pin_6; else 
GPIOE->BRR  |= GPIO_Pin_6;}

von ar (Gast)


Lesenswert?

Habe mich nun mit dem Einlesen der Eingänge beschäftigt. Habe Sie in 
Ride7 definiert und kann nun über Stringvergleich im Hyperterminal 
abfragen, ob der entsprechende Eingang gesetzt ist oder nicht. Ich 
blicke aber immer noch nicht, wie ich diesen String dann über UART an 
meine C# WinForms Anwendung senden kann und dort ein Ereignis auslösen 
?? Kann mir bitte jemand weiterhelfen ????

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

In der STM32F10x_StdPeriph_Lib_V3.5.0 von ST (Downloadbar bei ST) gibt 
es 12 Demo-Programme wie man einen UART nutzen kann.
Darunter sogar eines "HyperTerminal_Interrupt".

Arbeite mal die Demos alles durch.

von ar (Gast)


Lesenswert?

Ist das Lib nicht mehr verfügbar ?

Aber wenn ich im Hyperterminal die Eingänge bereits abfragen kann, dann 
müßte ich doch in C# den Befehl "nur" senden und wieder empfangen. Es 
soll der Zustand eines bestimmten I/O Ports abgefragt werden und dann in 
WinForms z.Bsp. eine PictureBox "aufleuchten".

von ar (Gast)


Lesenswert?

Hab das Lib gefunden. Muß es mal anschauen, blick da noch ned so ganz 
durch

von ar (Gast)


Lesenswert?

ich komm irgendwie nicht weiter....

von Noname (Gast)


Lesenswert?

Um offen zu sein wundert mich das nicht.
Deine Fragen und Codebeispiele deuten darauf hin das Dir wesentliche 
Grundlagen fehlen, Datenblattstudium nur rudimentär erfolgt ist und Du 
sehr wenig Erfahrung hast.

Das nächste was Du tun solltest ist aus meiner Sicht:
1. Lerne Fragen vollständig und verständlich zu formulieren. Bei einem 
"ich komm irgendwie nicht weiter...." können wir allenfalls mitfühlend 
den Kopf neigen, Dich aber nicht weiterbringen. Wir müssen wissen, wo es 
hakt.

2. Lies ein C-Buch und das Datenblatt. Solche Code-Snippets wie
1
#define  RELAIS(a)    {if(a>0)GPIOE->BSRR  |= GPIO_Pin_6; else
2
GPIOE->BRR  |= GPIO_Pin_6;}
deuten auf einen Mangel in mindestens einer Hinsicht hin.
Das Datenblatt erklärt eindeutig, das BSRR resp. BRR jeweils eines oder 
mehrere derjenigen Bits löschen oder setzen die im Registerwert auf 1 
stehen. Das verodern ist unnötig, da beim lesen sowieso alle Bits auf 0 
stehen.

Nun, das ist alles kein Beinbruch und soll Dich nicht entmutigen. Jeder 
fängt mal an und macht dabei Fehler. Aber gib Dir bitte ein wenig mehr 
Mühe. Mir kommst Du wie ein Schüler vor, der gerade versucht den 
Lernaufwand zu minimieren.

von ar (Gast)


Lesenswert?

Hab mal einiges durchgelesen und versucht mich schlauer zumachen. Ich 
glaube, mit dem folgenden Beispiel was ich gefunden habe komme ich 
weiter, nur funktioniert es bei mir noch nicht so richtig:

        private void timer1_Tick(object sender, EventArgs e)
        {

            string input = "";
            string[] lesen;


            lesen = new string[8];

            serialPort.WriteLine("in 0\r\n");

            bool flag = false;
            do
            {
                input = serialPort.ReadExisting();
                flag = input.Contains("in 0 = 1");
            }
            while (flag != true);

            MessageBox.Show("Richitg");
            textBox2.Text = input;

        }

von Youssef (Gast)


Angehängte Dateien:

Lesenswert?

hallo zusammen

kann jemand von Ihnen vielleicht mir erklären. Was bedeutet eigentlich 
diese Zeile ((GPIOC ->IDR& 0x80)==0x00) und die Beide Termen CR1, CR2

LCD_Glass_Init () ;                      //LCD Initialisierung
LCD_Glass_Clear () ;
GPIOC ->DDR =0x00;
GPIOE -> DDR =0xFF;
GPIOC ->CR1 =0x00;
GPIOE ->CR2 = 0xFF;
While (1) {

      If
  ((GPIOC ->IDR& 0x80)==0x00)
      {
      LCD_Glass_DisplayString (“EIN”);
      Delay_ms(100) ;
     }

Else

{
      LCD_Glass_DisplayString (“AUS”);
      Delay_ms(100) ;
}
}
}


Danke

von m.n. (Gast)


Lesenswert?

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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.