Inhaltsverzeichnis

Tipps und Tricks

Hardware Design

Impdanze-Kalkulator
LT-Spice Tutorials

STM32

Tutorials

Programmierung / KEIL Compiler (MDK µ-Vision)

Als erstes sollte man sich das mal durchlesen:
MDK5 getting started
CMSIS-Driver (Keil)
Tools von ST
- ( Clock-Konfigurations Tool (Excel), … )
Keil - Migrate ARM Compiler 5 to ARM Compiler 6
STVP-STM32 - ST Visual Programmer STM32

Die alte Datei am besten vorher sichern. Da das ganze Handling für die Einstellungen der Farben in der Keil IDE sehr umständlich ist, habe ich obige Vorlage erstellt.

Hinweis: In dieser Datei sind auch meine Templates gespeichert (z.B. für doxygen Blöcke)

Und so sieht es aus :-)

Ansicht global.prop (obiger Link kann direkt gedownloaded werden)

Debugging / Simulator

Nun erscheinen für den STM32F103 beim Debuggen unter Peripherals komfortablere Menüeinträge für die Peripeherie.
Wie dies auch für den STM32F105 funktioniert, habe ich noch nicht rausgefunden.
 Peripherie Module im Klartext beim Debuggen (nur STM32F103)

In der DLL konnte ich folgende Parameter (somit werden wohl bloss diese Prozessoren unterstützt) finden:

'STM32F101T6', 'STM32F101RD','STM32F103T6', 'STM32F101ZE'
'STM32F101T8', 'STM32F101RE','STM32F103T8', 'STM32F103RE'
'STM32F101C6', 'STM32F101V8','STM32F103C6', 'STM32F103V8'
'STM32F101C8', 'STM32F101VB','STM32F103C8', 'STM32F103VB'
'STM32F101CB', 'STM32F101VC','STM32F103CB', 'STM32F103VC'
'STM32F101R6', 'STM32F101VD','STM32F103R6', 'STM32F103VD'
'STM32F101R8', 'STM32F101VE','STM32F103R8', 'STM32F103VE'
'STM32F101RB', 'STM32F101ZC','STM32F103RB', 'STM32F103ZC'
'STM32F101RC', 'STM32F101ZD','STM32F103RC', 'STM32F103ZD'
'STM32F101RD', 'STM32F101ZE','STM32F103RD', 'STM32F103ZE'
'ST_bare'    
'CortexM3' 
'STM32F217IG'

Debug Settings Keil

Target Settings Keil - Hinweise

Hinweis das Makro PROZESSOR_FAMILY_STM32LXX wird von mir im Header definiert, wenn ich einen STM32L1xx Type verwende:

//#define PROZESSOR_FAMILY_STM32LXX      // Makro zum aktivieren, dass die STM32LXX-Variante
                                         // verwendet werden soll 

Tipps zu Timer Konfigurationen (PWM)

Timer Codebook

und noch ein Beispiel für die PWM initialisierung von 4 PWM-Kanäle:

header.h:

//! PWM Timer2 Period um auf die 960 Hz zu kommen.
#define TIMER2_PWM_PERIOD (0x208D)    // (0x109E)

typedef enum extern_inputs_name_en {
    EXTERN_MOTOR_1    
,   EXTERN_MOTOR_2    
,   EXTERN_MOTOR_3    
,   EXTERN_MOTOR_4    
    
,   EXTERN_COUNTS_MOTOR_INPUTS    
} extern_inputs_name_t;



typedef volatile struct pwmStatus_st {
    struct pwm_st {
        u32 dutyCycle;
        u32 newDutyCycle;    // wenn wahr dann neuen Wert setzen
        
    } pwm[EXTERN_COUNTS_MOTOR_INPUTS];
    
    struct pwm_timer_st {
        u16 CCRx_Val ;     // Wert für die Peridodendauer vom Timer2 Channel x   (1-4) 
        void (*pTimSetCompare)(TIM_TypeDef* TIMx, uint16_t compare);                    // Zeiger auf die TIM_SetCompare Funktion
        void (*pTimOcInit)(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);     // Zeiger auf die OCxInit Funktion
        void (*pTimOcPreload)(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); 
    } pwm_timer[EXTERN_COUNTS_MOTOR_INPUTS]; 
} pwmStatus_t;

extern pwmStatus_t  pwmStatus;
extern pwmStatus_t* const pPwmStatus;



main.c:

//! PWM Statusflags über den PWM-Systemzustand
pwmStatus_t  pwmStatus =    {

                                {
                                    { PWM_DEFAULT_DUTY_CYCLE,1 }
,                                   { PWM_DEFAULT_DUTY_CYCLE,1 }                             
,                                   { PWM_DEFAULT_DUTY_CYCLE,1 }                            
,                                   { PWM_DEFAULT_DUTY_CYCLE,1 }   
                                } 
,                               {
                                    { 0x00 , TIM_SetCompare1, TIM_OC1Init, TIM_OC1PreloadConfig }     //CCR, TimeSetCompare(), TIM_OCxInit(), 
,                                   { 0x00 , TIM_SetCompare2, TIM_OC2Init, TIM_OC2PreloadConfig } 
,                                   { 0x00 , TIM_SetCompare3, TIM_OC3Init, TIM_OC3PreloadConfig }    
,                                   { 0x00 , TIM_SetCompare4, TIM_OC4Init, TIM_OC4PreloadConfig }
                                }
                            };

pwmStatus_t* const pPwmStatus = &pwmStatus;




/**
  * @brief  Timer2 Kanäle 1-4 für das PWM Ausgangssignal initialisieren
  *  
  *  PWM-Frequenz 940 Hz für alle Kanäle
  *  PORT A1  (T2.1n)
  *  PORT A2  (T2.2n)
  *  PORT A3  (T2.3n)
  *  PORT A4  (T2.4n)
  * @param  u16 defaultTast
  * @retval None
  */

 void vInitTimer2PWM(u32 defaultTast) {
    u32 i;

    // TIM2 clock enable  für das Licht PWM-Signal Test
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
                            
    // Timer2 Konfiguration PBA2
    // Tim2-CLK= auf 4 Mhz festlegen
    // Time base configuration
    // PWM Frequenz soll (f= 940 Hz) sein:
    // allgemein:   f=TimerCLK/(ARR+1)  ==> ARR=(4 MHz/940Hz)-1 =     4254,32 = 4254 = 109E        0x14F1
                                     // ==> ARR=(8 MHz/940Hz)-1 =     8509,64 = 8510 = 213E
    PrescalerValue = (vu16) (SystemCoreClock / TIMER2_CLOCK) - 1;  // 17    (8 für ( Mhz)

    TIM_TimeBaseStructure.TIM_Period = TIMER2_PWM_PERIOD ;          // 0x109E ==> PWM = 940 Hz
    TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;           // Timer1 Clk=4 MHz
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;         // keine weiterer Teiler
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;     // Vorwärtszähler
    //TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;              // Nur bei Timer1 und Timer8

    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);   
     
    // TIM1 Channel3 duty cycle = (TIM1_CCR3/ TIM1_ARR)* 100 = 25%
     
    for(i=0;  i<EXTERN_COUNTS_MOTOR_INPUTS;i++) {
        pPwmStatus->pwm_timer[i].CCRx_Val = SetPWM_Tast(defaultTast);
        
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        //TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
        TIM_OCInitStructure.TIM_Pulse = pPwmStatus->pwm_timer[i].CCRx_Val;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
        
        pPwmStatus->pwm_timer[i].pTimOcInit(TIM2, &TIM_OCInitStructure);
        pPwmStatus->pwm_timer[i].pTimOcPreload(TIM2, TIM_OCPreload_Enable);
    }
     
/*  nicht notwendig
    // Update registers
    TIM1->EGR |= (1 << TIM_EGR_UG);
*/

    TIM_ARRPreloadConfig(TIM2, ENABLE);

   /* TIM2 enable counter */
    TIM_Cmd(TIM2, ENABLE);

  // Main Output Enable  //nur bei Timer 1, 8
  //  TIM_CtrlPWMOutputs(TIM2, ENABLE);

}

sonstige Keil Tipps

Keil / STM32CubeIDE

ST-Standard Peripherie Lib

Und noch ein paar Tipps:

STM32F1 HAL

UM 1850 - Description of STM32F1 HAL and Low-layer drivers

App-Notes ST

App-Notes von Keil

Die ST-LINK/V2-1 auf den NUCLEO und Discovery-Boards können auf ein J-Link OB geflasht werden.
Die Anleitung von Segger ist hier:
ST-LINK zu J-Link von Segger

STM32 Bootloader Projekte

Diverse andere Projekte verwenden auch den Tiny-USB Stack um für Ihren eigenen Bootloader:

Normalerweise verwende ich mein JTAG Standardkabel (und Belegung) um die ST's zu programmieren.
Da ich immer wieder danach gefragt werde, hier mal die einfachste Variante (SWD Schnittstelle) hier werden nur 4 Verbindungen benötigt. Die Spannungsversorgung des Prozessors mache ich immer mit dem USB Verbindungskabel.

SWD Schnittstelle

ST-LINK ←→ Interface (meine STM32 Hardware)

 1 ---- Vdd -----2
 4 ---- GND ---- 4
 7 ---- TMS ---- 8  (SWDIO)
 9 ---- TCK ---- 7  (SWCLD)
 

Und hier noch ein Bild: SWD Verbindungen

JTAG Schnittstelle

ST-Utility - Klone

Dieser USB-Stick Klone hat den Vorteil, dass er auch die Versorgungsspannung liefert. Dafür ist er halt etwas langsamer und unterstützt nur das SWD-Schnittstelle. Dieses Teil hatte ich mir nur für Testzwecke zu gelegt.

ST-Klone ←→ Interface (meine STM32 Hardware)

 1 ---- Reset ---- 1  (optional)
 2 ---- SWDIO ---- 8  (TMS)
 4 ---- GND   ---- 4
 6 ---- SWCLK ---- 7  (TCK)
 7 ---- +3,3V ---- 2  (+3,3V MCU)

STM32 Discovery Boards

STM32-VL-DISCOVERY (STM32F100RB)

Sehr einfaches Eval-Board. Hat im Prinzip nur zwei LEDs und einen Taster als Input. Ist aber für kurze Tests gut geeignet

LEDS

die beiden anderen LEDS (LD1, LD2) sind fest verdraht und sind für PC-Board Kommunikation (LD1) und Power LED (LD2) vorbehalten.

Taster

Hinweis zu STM32CubeIde und Debugging - In den neueren Versionen wird das Debugging dieses Board nicht unterstützt (wegen ST-LINK V1 auf dem Board). Deswegen verwende ich dann den BMP, d.h.:

verbinden.

STM32F429I-DISCO1

Moving Tux Demo

Ich habe die „Moving Tux Demo“ mal probeweise auf dem Disco1-Board installiert. Eine kurze Beschreibung von den Abweichungen der Installation und die binär Dateien findet ihr hier:

GDB Tipps

Da bei der MovinTux Demo auch OpenOCD installiert wird kann man auch den GDB von den ARM-Tools aus dem openOCD Ordner verwenden. Als erstes muss aber der ST-Link GDB-Server mit:

STLinux

ST bietet noch folgendes an:

TouchGFX Designer

Habe ich mit dem 429 Discoveryboard getetstet. Hinweise um den Bildschirm zu um 90° zu drehen:

Hier mein erstes Testprojekt für das Lüftermenü:

STM32 unter Linux


Step-by-Step: STM32 Development Environment with OpenOCD and Visual Studio Code (Linux)


32 Runtime Libs unter Ubuntu 16.04
install all dev and docs


VS-Code unter Ubuntu installieren

Unter Ubuntu am besten folgende vorgehensweise (auch für 18.04):

curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
sudo mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg
sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main" > /etc/apt/sources.list.d/vscode.list'

sudo apt update
sudo apt install code

Hat den Vorteil das man auch immer die aktuellste Version mittels apt updaten kann. Ab 18.04 ist VS-Code als Package im Software-Center enthalten, aber halt nicht immer ganz aktuell

Tipps zu Busmaster

CAN-Simulationen

Hinweis ab der Version V3.0 hat sich die STCAN_MSG Struktur geändert (vereinfacht). Deshalb müssen bestehende Simulationen angepasst werden. Die automatisch Konvertierung beim Importieren einer älteren Version hat bei mir nicht funktioniert. Eventuell lags daran, dass meine Simulationen schon etwas älter sind und im Header die Busmaster Version: BUSMASTER VERSION [1.7.1] angegeben war.
Hier nun die neu Struktur:

class STCAN_MSG
{
  unsigned int    id;        
  bool            isExtended; 
  bool            isRtr;    
  unsigned char   dlc;      
  unsigned char   cluster;
  unsigned char   data[64];
  unsigned long   timeStamp;
  bool            isCanfd;

  // To set data
  bool byteAt(int index, unsigned char val);
  bool wordAt(int index, unsigned short val);
  bool longAt(int index, unsigned long val);

  // To get data
  unsigned char  byteAt(int index);
  unsigned short wordAt(int index);
  unsigned long longAt(int index);
};
*Cluster ist die CAN-Kanalnummer vom Interface

Meine CAN Simulationen für Busmaster V3.1.0

VS Code Busmaster Settings für die Busmaster Simulationen

Da der integrierte Code Editor vom Busmaster grausam ist, habe ich jetzt eine Lösung gefunden um den Visual Studio Code Editor für die Busmaster Knoten Simulation zu verwenden inkl. der IntelliSense Funktionalität und compilieren des Quellcodes direkt aus VS Code herraus.

Hier folgt nun eine kurze Beschreibung wie man den Visual Studio Editor konfigurieren kann damit man für die Busmaster Simulationen die IntelliSense zur Verfügung steht und man auch direkt unter VS Code compilieren kann, d.h. direkt die DLL Datei für den Busmaster erzeugen kann.
Hier für müssen 2 Konfigurations Dateien angelegt werden:

Durch den angepassten „problemMatcher“ werden auch die Fehlermeldungen beim Compilieren in das Problemfenster übernommen, und man kann mit einem Mausklick direkt zur fehlerhaften Zeile springen.
Legendlich der Dateiname ist dann in der alten WIN/MSDOS Schreibweise.

Hier folgt nun eine kurze Beschreibung der wichtigsten Einträge:

Hinweis: Die Pfade bei den markierten Zeilen müssen eventuell angepasst werden.

Hinweis: OBD_Simulatormake ist das vom Busmaster erzeugte Makefile für den Compiler und der Name muss an das eigene Simulations-Projekt angepasst werden.


Tipps zu Doku-Wiki

SyntaxHigligther 4

SyntaxHighlighter 4 on Github

<sxh [brush][; options]>
... code/text ...
</sxh>

Beispiel mit Markierung bestimmter Zeilen:

#define CIRCBUF_DEF(x,y) uint8_t x##_space[y]; circBuf_t x = { x##_space,0,0,y}
 
CIRCBUF_DEF(cb, 32);
 
int circBufPush(circBuf_t *c, uint8_t data)
{
    int next = c->head + 1;
    if (next >= c->maxLen)
        next = 0;
 
    // Cicular buffer is full
    if (next == c->tail)
        return -1;  // quit with an error
 
    c->buffer[c->head] = data;
    c->head = next;
    return 0;
}
 
int circBufPop(circBuf_t *c, uint8_t *data)
{
    int next;
    // if the head isn't ahead of the tail, we don't have any characters
    if (c->head == c->tail)
        return -1;  // quit with an error
 
    *data = c->buffer[c->tail];
    c->buffer[c->tail] = 0;  // clear the data (optional)
 
    next = c->tail + 1;
    if(next >= c->maxLen)
        next = 0;
 
    c->tail = next;
 
    return 0;
}


Tipps zu Raspberry

pi1_tipps
pi3_tipps
Upgrade von Rpi2 zu Rpi3 - System Upgrade von einer Rpi2 SD-Karte auf 3

I²C Schnittstelle und Raspi - Beispiele mit Python

I2C-Sniffer

pigpio

Raspi-Sniffer

Git: push over ssh:

cd my-project
git remote add origin ssh://user@host/mnt/foo/bar/my-project.git
git push origin master 

HW Design Eagle

Hier sind ein paar Links zu Eagle Libs für HW Erweiterungen für den Raspi

SD-Karte klonen

Mit diesem kleine Windowstool kann man die kompletter SD-Karte inkl. aller Partitionen klonen:

Hinweis: Eventuell muss man auf der Ziel SD-Karte vorher alle bestehende Partitioinen und das Volume mit dem Festplattenmanager löschen, falls es zu write Fehlern kommt (bei Roadkil's Diskimage war dies bei mir erforderlich)

Unter „Linux“ kann man auch „dd“ verwenden um die komplette SD-Karte oder einzelne Partitionen zu klonen.

# Ein Image von einer einzelnen Partion auf sdf erstellen:
sudo dd if=/dev/sdf1 of=/home/myusername/raspberry_root-backup-sdf1-2017-05-10.img

# komplettest Image erstellen:
sudo dd if=/dev/sdf of=/home/myusername/raspberry-backup-sd_card_2017-05-10.img

Image mounten

Die obige erstellten Images können als „Loop Device“ eingebunden werden:

obiges kann mit:

sudo losetup --find --show -P minix203.img

vereinfacht werden, da hier das Image direkt an das erste freie Loop-Device verbunden wird.

SD-Karte formatieren

SD-Kart Formater


Fail2ban Tipps

einzelne Fiterregeln (jails) kann man in der shell prüfen:

fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf 

oder mit Ausgabe der Logzeile:

fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf  --print-all-matched

Hinweis: immer den kompletten Pfad zur Konfigurationsdatei verwenden

Fail2Ban Filter und Jails Konfiguration

Weitere Tipps:

 fail2ban-client status 
 fail2ban-client status ssh             # zeigt alle IPs an die von "SSH" gebannt wurden
 fail2ban-client get ssh banned         # gibt ein Array der gebannte IPs von "SSH" zurück
 fail2ban-client unban xxx.xxx.xxx.xx   # IP für alle Jails wieder freigeben.

ESP32 Pico Kit

Get Started with ESP32-Pico-Kit

ESP32 CAM DEV

Hier eine kurze Beschreibung vom Modul:
ESP32-CAM Dev Board

OCTAVE

Für meine Tests wurde die Version V4.2.1 verwendet. Mit der nachträglichen Installation des Signal Moduls:
pkg install D:\Downloads\chrome\signal-1.3.2.tar.gz
(signal-1.3.2.tar.gz, von Signal Package von Sourceforge)
danach muss das Modul noch mit:
pkg load signal
geladen werden.

FIR-Filter Design

FIR-Filter mit Octave/Matlab

Testfile bitte in *.m umbennenen fir_first_test.m

Octave Beispiele

GIT Extensions

Probleme

Git

Git Submodule

 git submodule add ssh://andreas@geier99.de/opt/git/Projekte/Tools/diagLogger.git Andreas/diagLogger

Damit dies funktioniert, muss ein eventuell vorhandener Ordner „diagLogger“ aus dem Index erst gelöscht werden. Beim Pull wird dann auch das diaglogger geklont(oder gepullt)

Obiges Beispiel legt ein Submodul in ein bestehendes geklontes Git-Repository an (eventuell vorher den Ordner vom Submodul löschen)

Obiger Befehl legt auch die Datei .gitmodules an:

[submodule "Andreas/diagLogger"]
        path = Andreas/diagLogger
        url = ssh://andreas@geier99.de/opt/git/Projekte/Tools/diagLogger.git

Git Konsole Tipps

Java

Creating an Updater in Java

Decompiler

OpenOCD mit Buspirate

vscode esp

USB Driver