SoftwareSerial ekvivalent för STM32?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

SoftwareSerial ekvivalent för STM32?

Inlägg av Al_Bundy »

I Arduino-miljön så kan man använda ett bibliotek som heter SoftwareSerial för att bestämma en RX ingång och en TX utgång från slumpmässiga GPIO pinnar. Sedan finns det något som heter HardwareSerial, som jag tror är det samma. Rätta mig om jag har fel.

Men finns det något ekvivalent SoftwareSerial för STM32 också? Jag har nämligen en UART function skriven i C som är anpassad för både Windows och Linux. För Windows ser den ut så här:

Kod: Markera allt

#include <windows.h>
#include <Setupapi.h>

HANDLE serial_handle;

int uart_open(char *port) {
	char str[20];

	snprintf(str, sizeof(str) - 1, "\\\\.\\%s", port);
	serial_handle = CreateFileA(str, GENERIC_READ | GENERIC_WRITE,
			FILE_SHARE_READ | FILE_SHARE_WRITE,
			NULL, OPEN_EXISTING, 0, //FILE_FLAG_OVERLAPPED,
			NULL);

	if (serial_handle == INVALID_HANDLE_VALUE) {
		return -1;
	}

	return 0;
}
void uart_close() {
	CloseHandle(serial_handle);
}

int uart_tx(int len, unsigned char *data) {
	DWORD r, written;
	while (len) {

		r = WriteFile(serial_handle, data, len, &written,
		NULL);
		if (!r) {
			return -1;
		}
		len -= written;
		data += len;
	}

	return 0;
}
int uart_rx(int len, unsigned char *data, int timeout_ms) {
	int l = len;
	DWORD r, rread;
	COMMTIMEOUTS timeouts;
	timeouts.ReadIntervalTimeout = MAXDWORD;
	timeouts.ReadTotalTimeoutMultiplier = 0;
	timeouts.ReadTotalTimeoutConstant = timeout_ms;
	timeouts.WriteTotalTimeoutMultiplier = 0;
	timeouts.WriteTotalTimeoutConstant = 0;

	SetCommTimeouts(serial_handle, &timeouts);
	while (len) {
		r = ReadFile(serial_handle, data, len, &rread,
		NULL);

		if (!r) {
			l = GetLastError();
			if (l == ERROR_SUCCESS)
				return 0;
			return -1;
		} else {
			if (rread == 0)
				return 0;
		}
		len -= rread;
		data += len;
	}

	return l;
}
För Linux ser den ut så här:

Kod: Markera allt

#include <stdio.h>
#include <termios.h>
#include <fcntl.h>
#include <unistd.h>

int serial_handle;

int uart_open(char *port) {
	struct termios options;
	int i;

	serial_handle = open(port, (O_RDWR | O_NOCTTY /*| O_NDELAY*/));

	if (serial_handle < 0) {
		return -1;
	}

	/*
	 * Get the current options for the port...
	 */
	tcgetattr(serial_handle, &options);

	/*
	 * Set the baud rates to 115200...
	 */
	cfsetispeed(&options, B115200);
	cfsetospeed(&options, B115200);

	/*
	 * Enable the receiver and set parameters ...
	 */
	options.c_cflag &= ~(PARENB | CSTOPB | CSIZE | CRTSCTS | HUPCL);
	options.c_cflag |= (CS8 | CLOCAL | CREAD);
	options.c_lflag &= ~(ICANON | ISIG | ECHO | ECHOE | ECHOK | ECHONL | ECHOCTL
			| ECHOPRT | ECHOKE | IEXTEN);
	options.c_iflag &= ~(INPCK | IXON | IXOFF | IXANY | ICRNL);
	options.c_oflag &= ~(OPOST | ONLCR);

	//printf( "size of c_cc = %d\n", sizeof( options.c_cc ) );
	for (i = 0; i < sizeof(options.c_cc); i++)
	options.c_cc[i] = _POSIX_VDISABLE;

	options.c_cc[VTIME] = 0;
	options.c_cc[VMIN] = 1;

	/*
	 * Set the new options for the port...
	 */
	tcsetattr(serial_handle, TCSAFLUSH, &options);

	return 0;
}
void uart_close() {
	close(serial_handle);
}

int uart_tx(int len, unsigned char *data) {
	ssize_t written;

	while (len) {
		written = write(serial_handle, data, len);
		if (!written) {
			return -1;
		}
		len -= written;
		data += len;
	}

	return 0;
}
int uart_rx(int len, unsigned char *data, int timeout_ms) {
	int l = len;
	ssize_t rread;
	struct termios options;

	tcgetattr(serial_handle, &options);
	options.c_cc[VTIME] = timeout_ms / 100;
	options.c_cc[VMIN] = 0;
	tcsetattr(serial_handle, TCSANOW, &options);

	while (len) {
		rread = read(serial_handle, data, len);

		if (!rread) {
			return 0;
		} else if (rread < 0) {
			return -1;
		}
		len -= rread;
		data += len;
	}

	return l;
}
I Arduino så skulle detta se ut så här:

Kod: Markera allt


#include "dinHeaderFil.h"

SoftwareSerial mySerial(1,0); // RX, TX

int uart_open() {
        mySerial.begin(9600); 
}
void uart_close(){
       mySerial.end();
}

int uart_tx(uint8_t* data, uint8_t len) {
       size_t written;

	while (len) {
		written = mySerial.write(data, len);
		if (!written) {
			return -1;
		}
		len -= written;
		data += len;
	}

 	return 0;
}

int uart_rx(uint8_t* data, uint8_t len) {
       int l = len;
       size_t rread;

       while (len) {
		rread = mySerial.read(data, len);

		if (!rread) {
			return 0;
		} else if (rread < 0) {
			return -1;
		}
		len -= rread;
		data += len;
	}

	return l;
}

Väldigt enkel C kod som direkt talar med hårdvaran. Men jag skulle behöva skriva om dessa så att dom passar med STM32. Har ni några förslag?
Senast redigerad av Al_Bundy 15 maj 2019, 19:36:01, redigerad totalt 2 gånger.
Användarvisningsbild
AndLi
Inlägg: 17044
Blev medlem: 11 februari 2004, 18:17:59
Ort: Knivsta
Kontakt:

Re: SoftwareSerial ekvivalent för STM32?

Inlägg av AndLi »

Du har fel...
Varför vill du inte använda harvard uart/serial på stm32an?

Softwareserial är något man tar till i nödfall när man har slut på hårdvaru uarts.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: SoftwareSerial ekvivalent för STM32?

Inlägg av Al_Bundy »

Harvard :o

Hur gör man då? :) Skulle helst vilja använda USB porten för avläsning till datorn också. Men softwareserial måste väll ändå fungera OK, eller finns det risk att det inte riktigt fungerar?
snigelen
Inlägg: 815
Blev medlem: 8 maj 2009, 11:02:14
Ort: Lund

Re: SoftwareSerial ekvivalent för STM32?

Inlägg av snigelen »

AndLi menar nog hårdvaru-USART. Men det var en ganska kul felskrivning eftersom stm32 är en typisk harward-arkitektur.

Hur man gör? Läser manualen eller googlar och hoppas på tur (det är MÅNGA som gjort detta före dig).
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: SoftwareSerial ekvivalent för STM32?

Inlägg av Al_Bundy »

Att använda RX och TX utgångarna på en STM32 finns massvis med filmer och manualer om. Men att använda godtyckliga GPIO pinnar, vet jag inte hur man gör.
snigelen
Inlägg: 815
Blev medlem: 8 maj 2009, 11:02:14
Ort: Lund

Re: SoftwareSerial ekvivalent för STM32?

Inlägg av snigelen »

Det finns ofta ett par alternativa RX/TX för varje USART, så det är ju inte så svårt att få det att passa in. Går det inte det så är det nog lämpligast att gå tillbaks till ruta ett. Vilka resuser behövs? Vilka resurser finns på tänkt MCU? Räcker det till så kan man ju fördela dessa resurser på lämpligt sätt.

Går det verkligen inte att få ihop det med vald MCU så bör man kanske titta på någon annan. Absolut sista nödfall skulle väl vara att välja en mjukvaruimplementation. Det är inte direkt jättesvårt att åstadkomma om man vet hur kommunikationen fungerar. Säkert någon annan som gjort det och delat med sig dessutom.

Edit: det är inte jätteenkelt med Rx.
Användarvisningsbild
rvl
Inlägg: 5719
Blev medlem: 5 april 2016, 14:58:53
Ort: Helsingfors

Re: SoftwareSerial ekvivalent för STM32?

Inlägg av rvl »

Det finns tre att välja på i F401 och de har ett par alternativa pinpar. Ctr-klick i Cube om man inte orkar läsa datablad...
usart.png
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
snigelen
Inlägg: 815
Blev medlem: 8 maj 2009, 11:02:14
Ort: Lund

Re: SoftwareSerial ekvivalent för STM32?

Inlägg av snigelen »

Bara för att jag är uttråkad...

Så har kan man implementera soft send av en byte (eller hur många bitar man nu vill ha i sin "frame").

Skicka strartbit.
Vänta 1/baud
skicka varje bit med 1/baud tidsavstånd mellan varje.
skicka minst en stopp-bit.

Lämpligen slår man av avbrott innan och återställer (till vad det var) efteråt.
Fördelen med hårdvaru-USART är att den sköter allt, oavsett vad MCU'n har för sig för övrigt (avbrott, DMA, bla, bla bla).

För att ta emot en byt kan man t.ex.

Aktivera ett externt interrupt för att detektera startbiten.
När startbiten kommit, aktivera ett timerinterrupt med 1/2 1/baud.
I detta timerinterrupt, håll reda på vilken bit som behandlats, lagra dem. Vid vartannat interrupt efter det första.
Kolla att det faktiskt är en stopp-bit till sist, aktivera ext.int, avaktivera timer int.
"Rapportera" resultatet eller eventuell frame-error (saknad stopp-bit).

Stor fördel med hårdvaru-USART är att allt detta sköts av hårdvara, oavsett vad MCU'n har för sig för övrigt. Mjukvaru-Rx är lite känslig för (relativt) långa avbrott. Det går kanske att avhjälpa med input capture men då blir det lite mer jobb. Hårdvaru-USART samplar dessutom varje bit ett antal gånger och väljer majoritetsresultatet som slutresultat för varje bit.

Sedan, vare sig det är hård- errer mjuk implementation så bör man nog använda en FIFO-buffer på Rx, och kanske Tx också.
Användarvisningsbild
Wedge
Inlägg: 1026
Blev medlem: 8 juli 2012, 17:33:33

Re: SoftwareSerial ekvivalent för STM32?

Inlägg av Wedge »

SoftwareSerial på STM32 :
https://www.stm32duino.com/viewtopic.php?t=6

Orkar inte läsa hela, men rätt tidigt i tråden verkar många vara inne på att det är meningslöst med en mjukvarulösning med så många hårdvaruportar tillgängliga. Så deras SoftwareSerial är en wrapper kring en hårdvaruporten... :)
Användarvisningsbild
Icecap
Inlägg: 26105
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: SoftwareSerial ekvivalent för STM32?

Inlägg av Icecap »

Mjukvara-serieport är till att börja med inte så sinnessjukt smart - men i nödfall kan det fungera.

Men att vilja ha en UART-funktion via mjukvara för att de lediga hårdvara-UART inte är på rätt pinnar är rakt av fel på ett nivå som är ganska högt.

Men vill du använda USB är det väl bara att sätta upp de nödvändiga register och peta in rätt mjukvara så att det fungerar.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: SoftwareSerial ekvivalent för STM32?

Inlägg av Al_Bundy »

Jag får leta rätt på rätt GPIO pinnar och börja programmera och sätta register.

Finns det inte så att man kan tala med USB Data+ och Data- på t.ex. Arduino, Teensy, STM32?
Rick81
Inlägg: 746
Blev medlem: 30 december 2005, 13:07:09

Re: SoftwareSerial ekvivalent för STM32?

Inlägg av Rick81 »

Jo det går köra USB med stm32 men ge sig på att koda USBstacken är inte rekommendera för nybörjare. Dock finns det färdig STM32 exempel kod för HID dvs mus/tangentbord samt USB mass storage kod. Har själv gjort detta för stm32f1. Fick dock aldrig Virtual COM att funka.

Dock är en UART USB så mycket enklare att jobba med och de kostar 2 dollar/st på ex https://www.electrodragon.com/product/c ... module-v2/
så det brukar jag använda för generell kommunikation mellan stm32 och PC.
Skriv svar