mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik STM32 - Mit USART String-Input den CCR (PWM-Timer) setzen


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: Nikita J. (nikita_j)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Hallo zusammen,

Board: STM32F4-Discovery
Bib: STM32
IDE: Atolic Truestudio

Aufgabe:
möchte durch USART-Schnittstelle vom PC an STM32 die Parameter für 
PWM-Signal (Servo-Motoren) senden. Der STM32 soll string auslesen evtl. 
in int umwandeln und CCR1, CCR2, CCRn.. Wert verändern/stellen.

Aktueller Stand:

USART Interrupt
void USART2_IRQHandler() {
  if (USART_GetITStatus(USART2, USART_IT_RXNE) == SET) {
    USART_ClearITPendingBit(USART2, USART_IT_RXNE);
    static int cnt = 0;
    char input = USART2->DR;

    if ((input != '\n') && (cnt < MAX_WORDLEN)) {
      received_str[cnt++] = input;
    } else {
      received_str[cnt] = '\0';
      cnt = 0;
      USART2_Send(USART2, received_str);
//      if(received_str){
//
//      }
    }
  }

}

USART string senden
void USART2_Send(USART_TypeDef *USARTx, volatile char *str) {
  while (*str) {
    while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);
    USART_SendData(USARTx, *str);
    *str++;
  }
}

Frage:
Wie kann ich "received_str" zerlegen? z.B. ich sende vom Computer 
MP11500
dies soll interpretiert werden als: CCP1 auf Wert 1500 setzen oder 
MP31000: CCP3 auf Wert 1000 setzen.
Wie kann ein Beispielcode dafür aussehen?

Vielen Dank!
Grüß, Nik

Autor: Nop (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Du kannst erstmal gucken, ob der String mit "MP" beginnt. Dann machst Du 
einen switch-case auf das nächste Zeichen, das '1', '2', '3' oder so 
sein kann. Aufgepaßt, '1' ist nicht der integer 1.

Die Zahlenumwandlung kannst Du mit atoi() machen, was einen String 
erwartet. Der Wert kommt ab Positon 3, also value = 
atoi(received_str+3).

Das als Anregungen.

Autor: Nop1 (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
sscanf

Autor: pegel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nop1 schrieb:
> sscanf

Den finde ich auch gut. ;)
#include "stdio.h"
#include "string.h"
#include "stdint.h"

uint8_t Zeichenkette [] = {"MP12345"};
void main()
{
  printf("\nZerlegung von: %s \n",Zeichenkette);
  uint8_t Laenge = strlen(Zeichenkette);
  printf("Laenge der Zeichenkette: %i\n",Laenge);


  if (Zeichenkette[0]=='M' & Zeichenkette[1]=='P'){
    printf("MP Stimmt\n");

    uint8_t  Kanal = Zeichenkette[2]-'0';
    printf("Kanal: %d\n",Kanal);

    uint8_t buffer[10];
    int PWM_Wert;

    for(int i=3,j=0;i<Laenge;i++,j++) {
      buffer[j]=Zeichenkette[i];
    }

    sscanf(buffer,"%d",&PWM_Wert);
    //printf("buffer: %s\n",buffer);

    printf("PWM_Wert: %d\n",PWM_Wert);
  }
}

Autor: Bülent C. (mirki)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Diese ganze string Bearbeitung auf einem uC ist doch murks. Sende per 
uart doch gleich die hex Werte der Zahlen. Größere Werte kannst du doch 
zerlegen und zusammen führen.
Will dir damit nur sagen, daß du Dir erstmal grundlegende Gedanken über 
das protokol machen solltest.
Ein Byte als qualifier und dann payload plus am Ende ein Trennzeichen.

Autor: W.S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nikita J. schrieb:
> Aktueller Stand:
>
> USART Interruptvoid USART2_IRQHandler() {
> ...
>     if ((input != '\n') && (cnt < MAX_WORDLEN)) {
>       received_str[cnt++] = input;

Du schreibst Murks.

Trenne doch die logschen Ebenen voneinander, sonst verhedderst du dich 
noch viel mehr.

Wie man sowas richtig macht, kannst du in der Lernbetty nachlesen, 
alternativ in diversen geposteten Quellen von mir.

Sene- und Empfangs-Verfahren:
- der Interrupthandler behandelt die Hardware: er sendet Zeichen aus dem 
Sende-Ringpuffer und empfängt Zeichen, die er in den Empfangs-Ringpuffer 
schreibt. Er bewertet die Inhalte NICHT.

- die von außen sichtbaren Funktionen des seiellen Treibers nehmen zu 
sendende Zeichen entgegen und stopfn sie in den Sende-Ringpuffer und sie 
geben empfangene Zeichen aus dem Empfangs-Ringpuffer an die aufrufenden 
Programmteile. Sie befassen sich NICHT mit der Hardware und sie bewerten 
auch die Inhalte NICHT.

Kommando-Verfahren:
Variante A:
Es gibt ein Kommandoprogramm, das eine Funktion enthält, welche aus der 
Grundschleife zyklisch aufgerufen wird. Diese Funktion fragt den 
seriellen Treiber ab, ob Empfangszeichen vorliegen, sortiert diese in 
einen Kommandopuffer und sendet ein Echo der Zeichen zurück. Sie kann 
auch diverse Editierfunktionen haben. Ist der Puffer voll oder ist ein 
Enter (CR oder LF oder was auch immer) erkannt, dann ruft sie die 
eigentliche Kommandofunktion auf, welche die Kommandozeile analysiert 
und entsprechend ausführt.

Variante B:
Es gibt ein Kommandoprogramm, das eine Funktion enthält, welche aus der 
Grundschleife zyklisch aufgerufen wird. Diese Funktion fragt den 
seriellen Treiber ab, ob Empfangszeichen vorliegen, wertet das aktuelle 
Zeichen aus und führt die zugehörigen Funktionen aus.

Diese Variante B ist nicht für HMI geeignet, aber für schnelle 
Maschinenkommunikation. Mal ein Beispiel für nen Plotter:
120.5X92.0YD200X20YU
macht nen Strich von x=120.5, y=92 nach x=200, y=20

W.S.

Autor: Nikita J. (nikita_j)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen herzlichen Dank für eure Vorschläge! Ich werde mich an diesen 
Wochenende dies ausprobieren!

Grüße, Nik

Autor: Andreas S. (igel1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nikita J. schrieb:
> Vielen herzlichen Dank für eure Vorschläge! Ich werde mich an diesen
> Wochenende dies ausprobieren!
>
> Grüße, Nik

Bitte poste einmal Deine Ergebnisse, denn Du fertig bist - ich wollte 
auch schon einmal immer so etwas programmiert haben.

Viele Grüße

Igel1

Autor: pegel (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Mit dem sscanf geht es sogar noch eleganter mit einer formatierten 
Zerlegung, wobei der letzte Wert auch eine variable Länge haben kann.

Siehe Anhang.

Autor: pegel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit Leerzeichen zwischen den Werten im String kann man sich auch die 
Längenangabe sparen.

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.