Moin,
ich versuche grade einen UART auf dem stm32f3 (discovery-board) in
Betrieb zu nehmen.
Funktioniert so mäßig
Der USB-TTL konverter ist mit einem PL2303 bestückt und mit dem µC via
RX/TX (twistedpair) und Ground verbunden.
Das Terminal zeigt leider nur quatsch an, aber immerhin scheint etwas
anzukommen.
Der STM32 ist per CMSIS auf 9600 Baud konfiguriert. Wenn ich ein 'U'
(01010101) sende kann ich auf dem DSO eine "Bitdauer" von ca. 325 µS
ablesen.
Das macht nach Adamriese doch ca. 3000 bit/s. Komisch!
....
Die CMSIS Funktion rechnet ja den entsprechenden Wert für das BRR aus.
Ich bin fast soweit meine eigene Unfähigkeit auf ST zu schieben, aber da
es bei anderen ja scheinbar funktioniert....bin ich ratlos.
Vielleicht hab ich ja nen denkfehler. Ich wäre um Hinweise dankbar.
µC Code (angepasstes Bsp. aus dem Netz) ist:
/* Includes */
#include <stddef.h>
#include <stdio.h>
#include <stm32f4xx_conf.h>
// Function prototypes
void MySystemInit(void);
void USART_SendString(char* data);
int i;
// Main
int main(void)
{
// Controller initialisieren
SystemInit();
// MySystemInit initialisiert die GPIO's und den USART
MySystemInit();
// Sende Zeichen über USART
for(i=0;i<=10;i++)
{
USART_SendData(UART4, 'U');
// Warte bis die Übertragung beendet ist
while(USART_GetFlagStatus(UART4, USART_FLAG_TC) == RESET);
}
/*
// Sende ein String über USART
USART_SendString("Lorem ipsum dolores...\n");
// Warte bis die Übertragung beendet ist
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
*/
// Hauptschleife des Programms
// Nichts tun...
while(1)
{
}
}
// Initialisierung aller Ports, welche für mein Projekt benötigt werden
void MySystemInit(void)
{
// InitStructs erstellen
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
USART_ClockInitTypeDef USART_ClockInitStructure;
// Clocks einschalten
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_UART4);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_UART4);
// USART1 RX-Pin initialisieren
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType= GPIO_OType_OD;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_Init(GPIOC, &GPIO_InitStructure);
// USART1 TX-Pin initialisieren
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOC, &GPIO_InitStructure);
// USART initialisieren
// Clocks
USART_ClockStructInit(&USART_ClockInitStructure);
USART_ClockInit(UART4, &USART_ClockInitStructure);
// 9600 Baud, 8Bit, No Parity, 1 StopBit, No FlowControl
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_HardwareFlowControl =
USART_HardwareFlowControl_None;
USART_Init(UART4, &USART_InitStructure);
// USART an schalten
USART_Cmd(UART4, ENABLE);
}
Bild vom DSO kann ich grad nicht anhängen, Signalfolge ist LHLHLHLHLHH
Das Terminalprogramm gibt ferner, nicht verwunderlicher Weise einen
Framingerror aus...
Schon mal herzlichen Dank für die Tips
1.
Wenn Deine Bitzeiten nicht stimmen, ueberpruef mal deinen Startup code.
Speziell die Initialisierung der System Clock.
Manchmal wenn man einfach Dateien irgendwo aus dem Netz kopiert stimmt
die Konfiguration nicht mit dem ueberein was man wirklich auf dem Board
hat.
2.
Das ganze PinConfig musst Du nicht machen, bei den STM32's reicht es RX
und TX auf AF zu stellen.
Bei mir tut folgender code seinen Dienst anstandslos.
Ist code von einem F0, also Pins anpassen falls Du den Code kopierst
Manfred Becker schrieb:> Hi Sven,>>> kennst du schon Uwe's Seite. Er hat fertige Librarys geschrieben die das> alles übernehmen:>> http://mikrocontroller.bplaced.net/wordpress/?page_id=609>> Viel Erfolg!> ManiB
Hi Manfred,
herzlichen Dank für den Link! Der Code funktioniert einwandfrei! Da für
STM32F4!!! geschrieben, konnte ich die Libs einbinden ohne eine einzige
Anpassung vorzunehmen. :) Top! So wie ich das sehe auch ansonsten eine
sehr lohnenswerte HP für alle die mit dem discoveryboard rumspielen!
Props an Uwe also :)
beste Grüße
Sven
Juergen G. schrieb:> 1.> Wenn Deine Bitzeiten nicht stimmen, ueberpruef mal deinen Startup code.> Speziell die Initialisierung der System Clock.> Manchmal wenn man einfach Dateien irgendwo aus dem Netz kopiert stimmt> die Konfiguration nicht mit dem ueberein was man wirklich auf dem Board> hat.
Hallo Jürgen,
danke genau daran hat's gelegen. In dem Startup code wurde von einem
25MHz Quarz ausgegangen, verbaut ist ein 8MHz Quarz :) LoL
Ich hab Deinen Code grad mal an den F4 angepasst. Neben der Anpassung
der Busses, muss scheinbar noch
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
aufgerufen werden. Der F4 hat anscheinend nur ein "GPIO alternate
function high register" (AFR), der F0 hingegen 2 (AFRH und AFRL). Es
werden aber trotzdem 2 Werte (geshiftet) und geschrieben.
Also herzlichen Dank nochmal!
Sven
Hier der angepasste Code mit 115200 Baud und USART2 an PA2/PA3
#include "stm32f4xx_conf.h"
void uart2_init(){
GPIO_InitTypeDef GPIO_InitStructure;
// USART clock activation
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// USART config
USART_InitTypeDef uInit;
USART_StructInit(&uInit);
uInit.USART_BaudRate = 115200;
uInit.USART_WordLength = USART_WordLength_8b;
uInit.USART_StopBits = USART_StopBits_1;
uInit.USART_Parity = USART_Parity_No;
uInit.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
uInit.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART2, &uInit);
// USART activate
USART_Cmd(USART2, ENABLE);
/*
// activate Interrupt channel
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// activate Interrupts
USART_ITConfig (USART1, USART_IT_RXNE, ENABLE);
*/
}
int main()
{
int i;
SystemInit();
uart2_init();
// Sende Zeichen über USART
for(i=0;i<=10;i++)
{
USART_SendData(USART2, 'U');
//Warte bis die Übertragung beendet ist
while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);
}
while(1)
{
}
}
Ja, das mit der GPIO_PinAFConfig ist richtig.
Ich hab den Code auf die Schnelle einfach aus einem bestehenden
(aelteren) Projekt kopiert, bei dem ein F0 verwendet wurde.
Diesen Code nehme ich (fast) immer als Basis fuer die STM32's, egal
welcher Kern.
Kleiner Nachtrag noch fuer die jenigen die oben geposteten Code
verwenden.
Da dieser Code auf Interrupts basiert, muss noch eine ISR geschrieben
werden die die Daten entsprechend "verdaut".