WebSites    Projekte    CCD_ControllerCommandDispatcher

STM32F103-CommandDispatcher

Übersicht


  •  STM32F103CommandDispatcher unter der VSCode-Entwicklungsoberfläche
  •  Code für MicroController STM32F103C8T6 (BluePill)
  •  Analyse / Response und Ausführung von UART-ASCII-Commands
  •  Senden von System-Events zum PC-Client
  •  Minimale Version: nur Berücksichtigung von System- und Led-Commands

Download

  •  2212261851_Stm32CommandDispatcher_01V05.zip

Bestandteile


  •  main.cpp :
//
#include "Define.h"
#include "Helper.h"
#include "Pin.h"
#include "Led.h"
#include "SerialUart.h"
#include "Command.h"
#include "System.h"
//
extern Character BufferLine[];
//
CSerialUart UartA(PIN_SERIALA_RX, PIN_SERIALA_TX);
CSerialUart* PUartSystem;
CLed LedSystem(PIN_LEDSYSTEM, true);
CCommand Command;
CSystem System;


void Error(const char* text)
{
    sprintf(BufferLine, "!Error: %s!\r\n", text);
    UartA.Write(BufferLine);
}

void setup() 
{
    PUartSystem = &UartA;
    //
    LedSystem.Open(sldOff);
    UartA.Open(115200);
    delay(330);
    UartA.Write("\r\n");
    UartA.Write("**************************\r\n");
    UartA.Write("* Stm32CommandDispatcher *\r\n");
    UartA.Write("**************************\r\n");
    UartA.Write("* Version: 01V01         *\r\n");
    UartA.Write("* Date...: 221206        *\r\n");
    UartA.Write("* Time...: 1845          *\r\n");
    UartA.Write("* Author.: OMdevelop     *\r\n");
    UartA.Write("**************************\r\n");
    //
    OnSystemHelp();
    //
    System.Open(1000);
}

void loop() 
{
    if (UartA.Execute())
    {
        if (UartA.ReadLine(BufferLine))
        {
            if (Command.Analyse(BufferLine))
            {
                if (false == Command.Execute())
                {
                    Error("Invalid Command-Execution");
                }
            }
        }
    }
    System.Execute();
    LedSystem.Execute();    
}
//
  •  Command.cpp :
//
#include "Define.h"
#include "Helper.h"
#include "Pin.h"
#include "Led.h"
#include "SerialUart.h"
#include "Command.h"
//
extern Character BufferLine[];
extern CSerialUart UartA;
extern CLed LedSystem;
extern CCommand Command;
//
CCommand::CCommand(void)
{
    FCommand[0] = 0x00;
     FParameterCount = 0;
     FParameterA[0] = 0x00;
     FParameterB[0] = 0x00;
     FParameterC[0] = 0x00;
     FParameterD[0] = 0x00;
}
//
char* CCommand::GetCommand(void)
{
    return FCommand;
}
byte CCommand::GetParameterCount(void)
{
    return FParameterCount;
}
char* CCommand::GetParameterA(void)
{
    return FParameterA;
}
char* CCommand::GetParameterB(void)
{
    return FParameterB;
}
char* CCommand::GetParameterC(void)
{
    return FParameterC;
}
char* CCommand::GetParameterD(void)
{
    return FParameterD;
}
//
Boolean CCommand::Analyse(char* pline)
{
    const char* TOKEN_RXD = " \r\n\t";    
    char* Token;
    FCommand[0] = 0x00;
    FParameterCount = 0;
    FParameterA[0] = 0x00;
    FParameterB[0] = 0x00;
    FParameterC[0] = 0x00;
    FParameterD[0] = 0x00;
    Token = strtok(pline, TOKEN_RXD);
    if (NULL != Token)
    {
        strcpy(FCommand, Token);
        strupr(FCommand);
        FParameterCount = 0;
        Token = strtok(NULL, TOKEN_RXD);
        if (NULL != Token)
        {
            strcpy(FParameterA, Token);
            FParameterCount = 1;
            Token = strtok(NULL, TOKEN_RXD);
            if (NULL != Token)
            {
                strcpy(FParameterB, Token);
                FParameterCount = 2;
                Token = strtok(NULL, TOKEN_RXD);
                if (NULL != Token)
                {
                    strcpy(FParameterC, Token);
                    FParameterCount = 3;
                    Token = strtok(NULL, TOKEN_RXD);
                    if (NULL != Token)
                    {
                        strcpy(FParameterD, Token);
                        FParameterCount = 4;
                    }
                }
            }
        }
    }    
    return (0 < strlen(FCommand));
}
//--------------------------------
// System
//--------------------------------
Boolean CCommand::AnalyseSystemHelp(void)
{ // Parameter -
    return OnSystemHelp(true);
}
Boolean CCommand::AnalyseSystemAbort(void)
{ // Parameter -
    return OnSystemAbort();
}
Boolean CCommand::AnalyseSystemReset(void)
{ // Parameter -
    return OnSystemReset();
}
Boolean CCommand::AnalyseSystemRefreshInterval(void)
{ // Parameter -
    if (GetParameterCount() < 1)
        return false;    
    UInt32 TI = atol(GetParameterA());
    return OnSystemRefreshInterval(TI);
}
//--------------------------------
// LedSystem
//--------------------------------
Boolean CCommand::AnalyseLedSystemOn(void)
{ // Parameter -
    return OnLedSystemOn();
}
Boolean CCommand::AnalyseLedSystemOff(void)
{ // Parameter -
    return OnLedSystemOff();
}
Boolean CCommand::AnalyseLedSystemInvert(void)
{ // Parameter -
    return OnLedSystemInvert();
}
Boolean CCommand::AnalyseLedSystemBlink(void)
{ // ParameterA:count ParameterB:ontime[ms] ParameterC:offtime[ms]
    if (GetParameterCount() < 3)
        return false;    
    UInt32 BC = atol(GetParameterA());
    UInt32 TO = atol(GetParameterB());
    UInt32 TF = atol(GetParameterC());
    return OnLedSystemBlink(BC, TO, TF);
}
//
Boolean CCommand::Execute(void)
{ // []0..4
    //--------------------------------
    // System
    //--------------------------------
    if (0 == strcmp("H", FCommand))
    {
        return AnalyseSystemHelp();
    }
    if (0 == strcmp("A", FCommand))
    {
        return AnalyseSystemAbort();
    }
    if (0 == strcmp("R", FCommand))
    {
        return AnalyseSystemReset();
    }
    if (0 == strcmp("SRI", FCommand))
    {
        return AnalyseSystemRefreshInterval();
    }
    //--------------------------------
    // LedSystem
    //--------------------------------
    if (0 == strcmp("LSO", FCommand))
    {
        return AnalyseLedSystemOn();
    }
    if (0 == strcmp("LSF", FCommand))
    {        
        return AnalyseLedSystemOff();
    }
    if (0 == strcmp("LSI", FCommand))
    {        
        return AnalyseLedSystemInvert();
    }
    if (0 == strcmp("LSB", FCommand))
    {        
        return AnalyseLedSystemBlink();
    }
    return false;    
}
//
  •  CommandAnalysis.cpp :
//
#include "Define.h"
#include "Helper.h"
#include "Pin.h"
#include "Led.h"
#include "SerialUart.h"
#include "Command.h"
#include "System.h"
//
extern Character BufferLine[];
//
extern CSerialUart UartA;
extern CLed LedSystem;
extern CCommand Command;
extern CSystem System;
//
//--------------------------------
//  System
//--------------------------------
Boolean OnSystemHelp(bool response)
{   
    if (response)
    {
        Response("H");
    }        
    UartA.WriteLine("# Help : System");
    UartA.WriteLine("# H - This Help");
    UartA.WriteLine("# A - Abort");
    UartA.WriteLine("# R - Reset");
    UartA.WriteLine("# SRI  - System Refresh Interval ime[ms]");
    UartA.WriteLine("# Help : LedSystem");
    UartA.WriteLine("# LSO - SetOn");
    UartA.WriteLine("# LSF - SetOff");
    UartA.WriteLine("# LSI - Invert");
    UartA.WriteLine("# LSB    - Blink ount Timen[ms] TimeOf[ms]");
    return true;
}
Boolean OnSystemAbort(void)
{   
    Response("A");
    // abort all FSMs
    LedSystem.Abort();
    return true;
}
Boolean OnSystemReset(void)
{   
    Response("R");
    delay(1000);
    NVIC_SystemReset();
    return true;
}
Boolean OnSystemRefreshInterval(UInt32 time)
{   
    sprintf(BufferLine, "SRI %lu", time);
    Response(BufferLine);    
    System.SetRefreshInterval(time); 
    return true;
}
//--------------------------------
//  LedSystem
//--------------------------------
Boolean OnLedSystemOn(void)
{   
    LedSystem.Set(sldOn);       
    Response("LSO");
    return true;
}
Boolean OnLedSystemOff(void)
{
    LedSystem.Set(sldOff);
    Response("LSF");
    return true;
}
Boolean OnLedSystemInvert(void)
{
    LedSystem.Invert();
    Response("LSI");
    return true;
}
Boolean OnLedSystemBlink(UInt32 count, UInt32 timeon, UInt32 timeoff)
{
    sprintf(BufferLine, "LSB %i %i %i", count, timeon, timeoff);
    Response(BufferLine);    
    return LedSystem.Blink(count, timeon, timeoff);
}
  •  Led.cpp :
//
#include "Led.h"

//
#include "Define.h"
#include "Helper.h"
#include "SerialUart.h"
//
extern char LineBuffer[];
extern CSerialUart UartA;

CLed::CLed(int pin, bool inverted)
{
    FState = sldOff;
    FPin = pin;
    FInverted = inverted;
    FCount = 0;
    FTimeOn = 1;
    FTimeOff = 1;
    FTicksPreset = millis();
}
//
void CLed::Open(EStateLed state)
{
    pinMode(FPin, OUTPUT);
    Set(state);
}
//
void CLed::Abort(void)
{
    FCount = 0;
    FTimeOn = 1;
    FTimeOff = 1;
    Set(sldOff);
}
//
void CLed::Set(EStateLed state)
{
    FState = state;
    if (FInverted)
    {
        if (sldOn == FState)
        {
            digitalWrite(FPin, LOW);
            Event("LSO");
        }
        else
        {
            digitalWrite(FPin, HIGH);
            Event("LSF");
        }
    }
    else
    {
        if (sldOn == FState)
        {
            digitalWrite(FPin, HIGH);
            Event("LSO");
        }
        else
        {
            digitalWrite(FPin, LOW);
            Event("LSF");
        }
    }
}
//
EStateLed CLed::Get(void)
{    
    return FState;
}
//
EStateLed CLed::Invert(void)
{
    if (sldOff == Get())
    {
        Set(sldOn);
    }
    else
    {
        Set(sldOff);
    }
    return Get();
}
//
Boolean CLed::Blink(UInt32 count, UInt32 timeon, UInt32 timeoff)
{
    FCount = max((UInt32)1, count);
    FTimeOn = timeon;
    FTimeOff = timeoff;
    FTicksPreset = millis();
    Set(sldOn);
    return true;
}

void CLed::Execute(void)
{
    if (0 < FCount)
    {
        if ((sldOn == Get()) && (FTicksPreset + FTimeOn) <= millis())
        {
            Set(sldOff);
        } 
        else
        if ((sldOff == Get()) && (FTicksPreset + FTimeOn + FTimeOff) <= millis())
        {
            FTicksPreset = millis();
            FCount--;
            if (0 < FCount)
            {
                Set(sldOn);
            }
        }
    }
}
  •  SerialUart.cpp :
//
#include "SerialUart.h"
//
CSerialUart::CSerialUart(int pinrxd, int pintxd)
{
    FPinRxD = pinrxd;
    FPinTxD = pintxd;
    FPUart = new HardwareSerial(FPinRxD, FPinTxD);
    FRxCharacter = 0x00;
    FRxIndex = 0;
}

void CSerialUart::Open(int baudrate)
{
    FPUart->begin(baudrate);
    FRxIndex = 0;
}
//
void CSerialUart::WriteLine(void)
{
    FPUart->print("\r\n");
}
void CSerialUart::WriteLine(const char* value)
{
    FPUart->print(value);
    FPUart->print("\r\n");
}
void CSerialUart::Write(const char* value)
{
    sprintf(FTxBuffer, "%s", value);
    FPUart->print(FTxBuffer);
}
void CSerialUart::Write(char* value)
{
    sprintf(FTxBuffer, "%s", value);
    FPUart->print(FTxBuffer);
}
void CSerialUart::Write(Int8 value)
{
    sprintf(FTxBuffer, "%i", value);
    FPUart->print(FTxBuffer);
}
void CSerialUart::Write(UInt8 value)
{
    sprintf(FTxBuffer, "%u", value);
    FPUart->print(FTxBuffer);
}
void CSerialUart::Write(Int16 value)
{
    sprintf(FTxBuffer, "%i", value);
    FPUart->print(FTxBuffer);
}
void CSerialUart::Write(UInt16 value)
{
    sprintf(FTxBuffer, "%u", value);
    FPUart->print(FTxBuffer);
}
void CSerialUart::Write(Int32 value)
{
    sprintf(FTxBuffer, "%i", value);
    FPUart->print(FTxBuffer);
}
void CSerialUart::Write(UInt32 value)
{
    sprintf(FTxBuffer, "%u", value);
    FPUart->print(FTxBuffer);
}
void CSerialUart::Write(Float32 value)
{
    sprintf(FTxBuffer, "%.3f", value);
    FPUart->print(FTxBuffer);
}
void CSerialUart::Write(Double64 value)
{
    sprintf(FTxBuffer, "%.6f", value);
    FPUart->print(FTxBuffer);
}
//
Boolean CSerialUart::ReadCharacter(Character &character)
{
    character = FRxCharacter;
    FRxCharacter = 0x00;
    return true;
}
Boolean CSerialUart::ReadLine(PCharacter pcharacter)
{
    strcpy(pcharacter, FRxBuffer);
    FRxIndex = 0;
    FRxBuffer[FRxIndex] = 0x00;
    return (0 < strlen(pcharacter));
}
//
Boolean CSerialUart::Execute(void)
{
    if (FPUart->available())
    {
        FRxCharacter = FPUart->read();
        if ((TOKEN_CR == FRxCharacter) ||
            (TOKEN_LF == FRxCharacter))
        {
            FRxBuffer[FRxIndex] = 0x00;
            FRxIndex = 0;
            return (0 < strlen(FRxBuffer));
        }
        else
        {
            FRxBuffer[FRxIndex] = FRxCharacter;
            FRxIndex++;
            FRxBuffer[FRxIndex] = 0x00;
        }
    }
    return false;
}
  •  Helper.cpp :
//
#include "Define.h"
#include "Helper.h"
#include "SerialUart.h"
//
extern CSerialUart UartA;
//
char BufferLine[SIZE_BUFFERLINE];

void Response(const char* text)
{
    UartA.Write(":");
    UartA.Write(text);
    UartA.Write("\r\n");
}

void Event(const char* text)
{
    UartA.Write("!");
    UartA.Write(text);
    UartA.Write("\r\n");
}
  •  System.cpp :
//
#include "Define.h"
#include "Helper.h"
#include "Led.h"
#include "SerialUart.h"
#include "System.h"
//
extern Character BufferLine[];
extern CSerialUart* PUartSystem;
extern CLed LedSystem;
//
CSystem::CSystem(void)
{
    FRefreshInterval = INIT_REFRESHINTERVAL;
}
    
void CSystem::Open(UInt32 interval)
{
    FRefreshInterval = interval;
}    
//
void CSystem::SetRefreshInterval(UInt32 time)
{
    FRefreshInterval = time;
}
//
void CSystem::Execute(void)
{   
    if (FTicksPreset < millis()) 
    {
        FTicksPreset = millis() + FRefreshInterval;
        sprintf(BufferLine, "!SYS %lu %u", millis(), (int)LedSystem.Get());
        PUartSystem->WriteLine(BufferLine);
    }
}

Signalfluss

Modul main.cpp :
  •  Zentrales Programm mit setup() und loop()
  •  Globale Error()-Routine (Uart-Ausgabe)
  •  setup() : Ausgabe Program-Header, Ausgabe Help
  •  loop() : Analyse der eingehenden Uart-Daten und Ausführung der Commands

Module Command.cpp mit Class CCommand:
  •  Splitting Command/ParameterCount/ParamterA/B/C/D
  •  Analyse Commands SystemHelp/Abort/Reset/RefreshInterval
  •  Analyse Commands SystemLedOn/Off/Invert/Blink
  •  Execution aller eingehenden Commands (Execute())

Module CommandAnalysis.cpp :
  •  zu Command.cpp ergänzendes Modul mit Callback-OnExecute-Funktionen:
     OnSystemHelp() / OnSystemAbort() / OnSystemReset()
     OnSystemRefreshInterval(UInt32 time) / OnLedSystemOn() / OnLedSystemOff()
     OnLedSystemInvert() / OnLedSystemBlink(UInt32 count, UInt32 timeon, UInt32 timeoff)

Module Led.cpp mit Class CLed:
  •  Constructor mit Vorgabe von Pin und Invert-State
  •  Initialisierung mit Open()
  •  Get()- und Set()(On/Off)-Funktionen
  •  Blink(UInt32 count, UInt32 timeon, UInt32 timeoff)-Routine
  •  Main: Permanenter Aufruf der Execute-Funktion (für Blink)
  •  Abort() der Blink()-Funktion

Module SerialUart.cpp mit Class CSerialUart:
  •  Constructor mit Vorgabe von RxD- und TxD-Pin
  •  Initialisierung mit Open()
  •  Write()-Funktionen mit unterschiedlichen Aufruf-Parametern
  •  ReadCharacter()-Funktion mit Character-Rückgabe-Parameter
  •  ReadLine()-Funktion mit Line-Rückgabe-Parameter
  •  Main: Permanenter Aufruf der Execute-Funktion (Poll RxD)

Modul Helper.cpp :
  •  Uart-Ausgabe der Response()- und Event()-Routine

Module System.cpp mit Class CSystem:
  •  Class CSystem : Periodischer System-Refresh über Uart zum PC
  •  Class CSystem : Vorgabe der Refresh-Periode [ms]

WebSites    Projekte    CCD_ControllerCommandDispatcher