Hier will ich mit einer kurzen Notiz einen USB nach TTL Konverter vorstellen.

Im Elektronikfachhandel gibts ja recht häufig fertige USB-Seriell Wandler, aber die wandeln halt USB in die übliche RS232 Pegel um, d.h. ca. +12V für eine 1 und -12V für eine 0. Diese Spannungspegel sind natürlich immer dann ungeeignet wenn man Microcontrollerschaltungen an PCs anschliessen will und mit diesen "einfache" Daten austauschen will. Dann benötigt man eben TTL-Logikpegel die 3.3V oder 5V betragen.

Diese Wandlung übernimmt komplett ein integrierter Baustein von FTDI den FT233RL. Ich verwende die nachfolgenden Platinen immer dann, wenn man seriell mit einem PC und einer Schaltung kommunizieren will und die Kommunikation debuggen muss.

Ein einfaches Telnet (oder früher : Hyperterm) reicht dann aus um serielle Daten auszugeben oder eben einzulesen.

 

Die Schaltung besitzt noch zwei LEDs auf der Platine die dann auch optisch anzeigen ob Daten übertragen werden - und zwar getrennt für Rx und Tx.Dies ist hilfreich wenn man nicht genau weiß ob die Software alles richtig macht.

Zusätzlich kann man mit einem Jumper noch umschalten ob man 3.3V oder 5V Logikpegel haben möchte. Auch habe ich die GND und Betriebsspannung für kleinere Schaltungen gleich herausgeführt. Mit 4 Leitungen kann man so z.B. einfache ZigBEE-Bausteine oder auch mal ein Heizungsinterface direkt anschliessen.

Bezüglich der Host-Software gibts noch einen schwergewichtigenVorteil der FTDI Chips. In jedem Windows und Linux sind die passenden Treiber für einen virtuellen COM-Port eingebaut, sodass man mit jeder Programiersprache direkt darauf zugreifen kann.

Es gibt gleiche Schaltungen direkt in einem USB Stecker eingebaut, die haben jedoch zumeist keine LED-Anzeige ob Daten übertragen werden.

Wer die Schaltung nachbauen will hier sind die Downloadlinks:

Als wichtige Komponente für meine Home-Alarmanlage benötigte ich einen RFID-Reader. Zur Auswahl stand ein HF-Reader mit 13.56MHz oder LF-Reader mit 125kHz. Für das Ein- oder Ausschalten der Alarmanlage erscheinen mir beide Technologien völlig ausreichend.

Für die Erfassung und Decodierng von LF-Tags mit 125kHz gibt es fertige Chips, die zwar schon relativ alt aber preiswert sind. Als Rawdecoder eignet sich z.B. der EM4095 von EM-Microelectronics.

Nachfolgend die Schaltbilder und Platinenpläne.

 

Als Empfangsspule habe ich übrigens die Spule des Linearmotors für die Kopfpositionierung einer alten Festplatte zweckentfremdet. Die hatte mit 200uH in etwa die benötigte Induktivität.Es gibt aber mittlerweile genügend Angebote im Netz.

Der Demod-Ausgang des RFID-Decoders wird mit dem EXTINT Eingang PA0/D2 des Olimexino-Boards verbunden.

Achtung ! Man muss einen Pegelwandler - im einfachsten Fall einen Spannungsteiler (3.3kOhm und 4.7kOhm)- dazwischenschalten da der EM4095 5V TTL-Ausgang hat, aber der STM32 auf dem Olimexino-Board 3.3V TTL-Eingang erwartet.

STM32 Ein- und Ausgabe von digital Informationen

Hier sind die wesentlichen Befehle zur Ein- und Ausgabe von digitalen Werten beim STM32 Prozessor beschrieben.

Hier am Beispiel des STM32F107VC Prozessors. Die Port-Bits fangen bei Pin_0(!) an. GPIO_Pin_0 ist der Prozessorpin 15.

Bitausgabe

Setzen eines einzelnen Bitregisters direkt: (Pin6) auf Port C:

Bit 6 auf logisch 1 setzen: GPIOC->BSRR = GPIO_Pin_6;

Bit 6 auf logisch 0 setzen: GPIOC->BRR = GPIO_Pin_6;

Bit 6 invertieren: GPIOC->ODR ^= GPIO_Pin_6;

oder alternativ die Orginalfunktionen der STM Lib.

Bit 6 auf logisch 1 setzen: GPIO_SetBits(GPIOC,GPIO_Pin6)

Bit 6 auf logisch 0 setzen: GPIO_ResetBits(GPIOC,GPIO_Pin6)

Bit 6 und Bit 9 auf logisch 0 setzen: GPIO_ResetBits(GPIOC, GPIO_Pin6|GPIO_Pin9)

Die direkten Funktionen sind naturgemäß erheblich schneller. Allerdings müsste sich jemand den erzeugten Assembler Code anschauen ob es wirklich so ist.

Portausgabe

Die IO-Ports des STM32 sind jeweils 16 bit breit. Wenn man also einen ganzen Port beschreiben will muss man auch eine Funktion verwenden die 16 Bit variablen verwendet. Dies ist:

Write complete port : GPIO_Write(GPIOC,val);

wobei val eine 16bit variable uint16_t val

sein muss. Oder wieder einzelne Bits setzen mit folgendem Befehl:

GPIO_Write(GPIOC, GPIO_Pin6 | GPIO_Pin9);

Um den Zustand eines Ausgangsports zurückzulesen (weil man nicht weiß wie er gerade gesezt ist) kann man folgende Funktion verwenden:

uint16_t val;

val = GPIO_ReadOutputData(GPIOC, GPIO_Pin6 | GPIO_Pin9);

Achtung diese Funktion liest nur die (!) Setzregister NICHT den Ausgangszustand.

Biteingabe

Einlesen des kompletten Port C:

port_data = GPIO_ReadInputData(GPIOC);

Achtung: Beim Lesen eines Bits kann es passieren dass anscheinend nichts gelesen wird oder das Bit nicht erkannt wird. Die Ursache liegt in den vielfältigen Programmiermöglichkeiten die der STM32 bietet. Man muss vor der Verwendung definieren welche Art der Input sein soll. Hier die dazu benötigten Flags:

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // Pin Floating
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //Pin with pull up R
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //Pin with pull down R

Pin Floating ist z.B. sinnvoll wenn man externe Widerstände in anderen Schaltungsteilen hat.

Nachfolgend noch ein einfaches Demoprogramm.

/* Wolfram Koerver
 * STM32 Example for OLIMEX STM32P107 Test Board
 * Toggle green and yellow LEDs Test Program this is the "hello world for electronics"
 * 1.1.2013
 */

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"

void init_GPIO(void);

void delay_nus(uint32_t nus);

int main(void)
{
	init_GPIO();
    while(1)
    {
		/* Toggle LEDs which connected to PC6 and PC7 ; Green/Yellow LEDs from Olimex Board*/
		GPIOC->ODR ^= GPIO_Pin_6;						// invert pin
		delay_nus (100000);								// delay a short time
		GPIOC->ODR ^= GPIO_Pin_7;						// toggle other LED
		delay_nus (100000);
    }
}

void init_GPIO(void)
{
    /* Initialize GPIO Structure, configure clock on peripheral bus
     * Enable GPIO Pins for LED which are connected to PC6,7*/
    /* Configure the GPIO_LED pin  PC6 = Green LED PC7 = Yellow LED
     * Configure direction and clock speed*/

	GPIO_InitTypeDef  GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
}

/***************************************************************************//**
 * @brief     delay in n us
 * @param[in] n:delay value
 * @return    None
*******************************************************************************/
void delay_nus(uint32_t nus)
{
 uint32_t temp;
 SysTick->LOAD = nus * 11;
 SysTick->VAL = 0x00;
 SysTick->CTRL = 0x01 ;
 do
 {
  temp=SysTick->CTRL;

 }while(temp&0x01&&!(temp&(1<<16)));
 SysTick->CTRL = 0x00;
 SysTick->VAL = 0X00;
}