Forum: Mikrocontroller und Digitale Elektronik Uart schickt falsche Werte


von Mark (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Leute

Heute habe ich mich fast den ganzen Tag mit der Uart beschäftigt und 
leider ist es so, dass ich das Problem immer noch nicht verstanden habe.
Ich bräuchte dringend euren Rat.

In meinem Programm habe ich die Uart folgendermassen initialisiert.
1
void UART_Init()
2
{
3
  
4
  GPIO_InitTypeDef GPIO_InitStruct;
5
  
6
  __HAL_RCC_USART1_CLK_ENABLE();                                  // enable clock uart
7
  __HAL_RCC_GPIOB_CLK_ENABLE();                                 // enable clock gpio
8
  
9
  /**USART1 GPIO Configuration    
10
  PB6     ------> UART1_TX
11
  PB7     ------> UART1_RX 
12
  */
13
  GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
14
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
15
  GPIO_InitStruct.Pull = GPIO_NOPULL;
16
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
17
  GPIO_InitStruct.Alternate = GPIO_AF0_USART1;
18
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
19
  
20
  huart1.Instance = USART1;
21
  huart1.Init.BaudRate = 9600;
22
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
23
  huart1.Init.StopBits = UART_STOPBITS_1;
24
  huart1.Init.Parity = UART_PARITY_NONE;
25
  huart1.Init.Mode = UART_MODE_TX;
26
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
27
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
28
  huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
29
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_DMADISABLEONERROR_INIT;
30
  huart1.AdvancedInit.DMADisableonRxError = UART_ADVFEATURE_DMA_DISABLEONRXERROR;
31
  if (HAL_UART_Init(&huart1) != HAL_OK)
32
  {
33
    _Error_Handler(__FILE__, __LINE__);
34
  }
35
}

Im main folgendes getestet:

1
  UART_HandleTypeDef huart1;
2
uint8_t array1[] = {'2', '3'};
3
HAL_UART_Transmit(&huart1, array1, 2, 10);

Irgendwie schicke ich da nur 165er und ein paar andere Zeichen 
zwischendurch.

Dann habe ich die selben Einstellungen im CubeMX durchgeführt und bin 
auf folgenden Code. Dieser funktioniert und ich schicke da die richtigen 
Zeichen.
Der Code, der funktioniert ist:
1
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
2
{
3
4
  GPIO_InitTypeDef GPIO_InitStruct;
5
  if(huart->Instance==USART1)
6
  {
7
  /* USER CODE BEGIN USART1_MspInit 0 */
8
9
  /* USER CODE END USART1_MspInit 0 */
10
    /* Peripheral clock enable */
11
    __HAL_RCC_USART1_CLK_ENABLE();
12
  
13
    /**USART1 GPIO Configuration    
14
    PA10     ------> USART1_RX
15
    PB6     ------> USART1_TX 
16
    */
17
    GPIO_InitStruct.Pin = GPIO_PIN_10;
18
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
19
    GPIO_InitStruct.Pull = GPIO_NOPULL;
20
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
21
    GPIO_InitStruct.Alternate = GPIO_AF1_USART1;
22
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
23
24
    GPIO_InitStruct.Pin = GPIO_PIN_6;
25
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
26
    GPIO_InitStruct.Pull = GPIO_NOPULL;
27
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
28
    GPIO_InitStruct.Alternate = GPIO_AF0_USART1;
29
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
30
31
  /* USER CODE BEGIN USART1_MspInit 1 */
32
33
  /* USER CODE END USART1_MspInit 1 */
34
  }
35
36
}
37
38
static void MX_USART1_UART_Init(void)
39
{
40
41
  huart1.Instance = USART1;
42
  huart1.Init.BaudRate = 9600;
43
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
44
  huart1.Init.StopBits = UART_STOPBITS_1;
45
  huart1.Init.Parity = UART_PARITY_NONE;
46
  huart1.Init.Mode = UART_MODE_TX;
47
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
48
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
49
  huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
50
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_DMADISABLEONERROR_INIT;
51
  huart1.AdvancedInit.DMADisableonRxError = UART_ADVFEATURE_DMA_DISABLEONRXERROR;
52
  if (HAL_UART_Init(&huart1) != HAL_OK)
53
  {
54
    _Error_Handler(__FILE__, __LINE__);
55
  }
56
57
}
Die Clocks habe ich soweit eingeschaltet bei meinem Code und finde 
einfach keinen Fehler.
Ich habe die Bits im Debugger verglichen. Alles sind die gleichen bis 
auf das BRR Register, welcher anstatt die DIV_Mantissa und DIV_Fraction.
Die sind bei meinem Code 0x009C für DIV_Mantissa anstatt 0x0034
und 0x04 für DIV_Fraction anstatt 0x01.
Aber die Baudrate habe ich gleich eingestellt.

Ich wäre um Hilfe sehr dankbar.

von Stefan F. (Gast)


Lesenswert?

Um welchen Mikrocontroller geht es?

von Mark (Gast)


Lesenswert?

Stefanus F. schrieb:
> Um welchen Mikrocontroller geht es?

Sorry, wollte ich gerade machen, du warst aber schneller.

STM32FO72c8

von nuJa (Gast)


Lesenswert?

hi,

irgendwie wie fällt mir da auf den ersten Blick auf:

:GehtNicht
  /**USART1 GPIO Configuration
  PB6     ------> UART1_TX
  PB7     ------> UART1_RX
  */
  GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;

:Geht
  /**USART1 GPIO Configuration
  PA10     ------> USART1_RX
  PB6     ------> USART1_TX
  */
  GPIO_InitStruct.Pin = GPIO_PIN_10;


 cu

von Stefan F. (Gast)


Lesenswert?

> Alles sind die gleichen bis auf das BRR Register, welcher
> anstatt die DIV_Mantissa und DIV_Fraction.

Ich verstehe diesen Satz nicht, kannst du den mal vervollständigen?


Wenn letztendlich das BRR Register das einzige anders konfigurierte ist, 
dann liegt dort wohl offensichtlich der Fehler. Immerhin ist dieses ja 
für die Baudrate zuständig und genau die scheint falsch zu sein.

Der Wert in diesem Register hängt doch sicher von der Konfiguration des 
Taksystems ab. Bist du ganz sicher, dass auch dort alles gleich ist?

Kannst du das Timing vom TxD Pin mal mit einem Oszilloskop oder Logic 
Analyzer messen?

von Mark (Gast)


Lesenswert?

nuJa schrieb:
> hi,
>
> irgendwie wie fällt mir da auf den ersten Blick auf:
>
> :GehtNicht
>   /**USART1 GPIO Configuration     PB6     ------> UART1_TX
>   PB7     ------> UART1_RX  */
>   GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
>
> :Geht
>   /**USART1 GPIO Configuration     PA10     ------> USART1_RX
>   PB6     ------> USART1_TX  */
>   GPIO_InitStruct.Pin = GPIO_PIN_10;
>
>  cu

Ja, stimmt.
Ich brauche nur den Tx Kanal.

verlangter Satz:
Alle Bits sind gleich gesetzt USART1 bis auf das BRR Register, welcher 
sich in der DIV_Mantissa und DIV_Fraction unterscheidet.
Die im Bild angezeigten BRR Werte sind die beim funktionierenden Code.
Meine weichen davon ab.



> Wenn letztendlich das BRR Register das einzige anders konfigurierte ist,
> dann liegt dort wohl offensichtlich der Fehler. Immerhin ist dieses ja
> für die Baudrate zuständig und genau die scheint falsch zu sein.
>
> Der Wert in diesem Register hängt doch sicher von der Konfiguration des
> Taksystems ab. Bist du ganz sicher, dass auch dort alles gleich ist?


Meinst du die Bits vom System Init?

> Kannst du das Timing vom TxD Pin mal mit einem Oszilloskop oder Logic
> Analyzer messen?

Kann ich morgen gleich mal machen. Die Bits vom Taktsystrm an, wenn wir 
beide vom Gleichen sprechen.

Danke Stefan
Bis morgen

von nuJa (Gast)


Lesenswert?

du hast die Frage nach dem verwendeten µC noch nicht beantwortet...

von nuJa (Gast)


Lesenswert?

wenn es ein stm32 ist
gilt für BRR:
"USART1->BRR = (SystemCoreClock / 115200);"

Rückwärts gerechnet SystemCoreClock= 9600 x 115200
Das ergibt 1,10592 Ghz....

von nuJa (Gast)


Lesenswert?

Mark schrieb:
> Sorry, wollte ich gerade machen, du warst aber schneller.
>
> STM32FO72c8

Sorry,
hab ich nicht gesehen...

von nuJa (Gast)


Lesenswert?

Wenn du nicht mehr gemacht hast.

:GehtNicht
void UART_Init()
{

  GPIO_InitTypeDef GPIO_InitStruct;

  __HAL_RCC_USART1_CLK_ENABLE();                                  // 
enable clock uart
  __HAL_RCC_GPIOB_CLK_ENABLE();                                 // 
enable clock gpio

  /**USART1 GPIO Configuration
  PB6     ------> UART1_TX
  PB7     ------> UART1_RX
  */
  GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF0_USART1;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

:Geht


hast du dein Problem zwischen :GehtNicht und :Geht



  huart1.Instance = USART1;

von Mark (Gast)


Lesenswert?

nuJa schrieb:
> wenn es ein stm32 ist
> gilt für BRR:
> "USART1->BRR = (SystemCoreClock / 115200);"
>
> Rückwärts gerechnet SystemCoreClock= 9600 x 115200
> Das ergibt 1,10592 Ghz....

Das vermute ich eher als deine 2. Vermutung. Wie Stefan auch gesagt hat.
Ich werde das mit dem systemclock auch morgen anschauen.
Das mit dem GPIO, da wuesste ich nicht was da zwischen Geht nicht und 
geht falsch sein sollte.
Aber danke dir

von Stefan F. (Gast)


Lesenswert?

Mark schrieb:
>> Der Wert in diesem Register hängt doch sicher von der Konfiguration des
>> Taksystems ab. Bist du ganz sicher, dass auch dort alles gleich ist?
>
> Meinst du die Bits vom System Init?

Ich meine zum Beispiel das RCC Register. Also die ganzen 
Clock-Multiplexer, Prescaler und PLL Settings.

von Mark (Gast)


Lesenswert?

Stefanus F. schrieb:
> Mark schrieb:
>>> Der Wert in diesem Register hängt doch sicher von der Konfiguration des
>>> Taksystems ab. Bist du ganz sicher, dass auch dort alles gleich ist?
>>
>> Meinst du die Bits vom System Init?
>
> Ich meine zum Beispiel das RCC Register. Also die ganzen
> Clock-Multiplexer, Prescaler und PLL Settings.

Hallo Stefan,

ohne jetzt die Signale gemessen zu haben, habe ich folgendes zuerst 
versucht.
Du hattest Recht, mit dem RCC.
Ich habe mal bei dem funktionierenden Code nachgesehen und habe 
festgestellt, dass der interne Clock HSI RC 8MHz verwendet wird. Damit 
funktioniert es auch.

Was bei mir aber ist, dass ich fälschlicherweise einen 4MHz Quarz statt 
8MHz drauf habe. Das sollte aber kein Problem darstellen, weil ich ja 
mit der PLL Source den Takt auf 48MHz hoch multiplizieren kann. Aber 
damit geht es nicht.
Da frage ich mich nun schon ein wenig warum das so ist und ob ich da 
trotzdem irgendwas falsch eingestellt habe.
Ich habe es mit diesen Varianten versucht. mit Intern funktioniert es.
1
MHZ_4
2
/**
3
  * @brief System Clock Configuration
4
  * @retval None
5
  */
6
void SystemClock_Config(void)
7
{
8
  RCC_OscInitTypeDef RCC_OscInitStruct;
9
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
10
11
    /**Initializes the CPU, AHB and APB busses clocks 
12
    */
13
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
14
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
15
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
16
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
17
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6;
18
  RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;
19
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
20
  {
21
    _Error_Handler(__FILE__, __LINE__);
22
  }
23
24
    /**Initializes the CPU, AHB and APB busses clocks 
25
    */
26
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
27
                              |RCC_CLOCKTYPE_PCLK1;
28
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
29
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
30
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
31
32
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
33
  {
34
    _Error_Handler(__FILE__, __LINE__);
35
  }
36
37
    /**Configure the Systick interrupt time 
38
    */
39
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
40
41
    /**Configure the Systick 
42
    */
43
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
44
45
  /* SysTick_IRQn interrupt configuration */
46
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
47
}
48
49
INTERN
50
51
void SystemClock_Config(void)
52
{
53
54
  RCC_OscInitTypeDef RCC_OscInitStruct;
55
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
56
  RCC_PeriphCLKInitTypeDef PeriphClkInit;
57
58
    /**Initializes the CPU, AHB and APB busses clocks 
59
    */
60
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
61
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
62
  RCC_OscInitStruct.HSICalibrationValue = 16;
63
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
64
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
65
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6;
66
  RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;
67
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
68
  {
69
    _Error_Handler(__FILE__, __LINE__);
70
  }
71
72
    /**Initializes the CPU, AHB and APB busses clocks 
73
    */
74
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
75
                              |RCC_CLOCKTYPE_PCLK1;
76
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
77
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
78
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
79
80
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
81
  {
82
    _Error_Handler(__FILE__, __LINE__);
83
  }
84
85
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
86
  PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK1;
87
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
88
  {
89
    _Error_Handler(__FILE__, __LINE__);
90
  }
91
92
    /**Configure the Systick interrupt time 
93
    */
94
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
95
96
    /**Configure the Systick 
97
    */
98
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
99
100
  /* SysTick_IRQn interrupt configuration */
101
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
102
}
103
MHZ_8
104
105
void SystemClock_Config(void)
106
{
107
108
  RCC_OscInitTypeDef RCC_OscInitStruct;
109
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
110
  RCC_PeriphCLKInitTypeDef PeriphClkInit;
111
112
    /**Initializes the CPU, AHB and APB busses clocks 
113
    */
114
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
115
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
116
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
117
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
118
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6;
119
  RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;
120
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
121
  {
122
    _Error_Handler(__FILE__, __LINE__);
123
  }
124
125
    /**Initializes the CPU, AHB and APB busses clocks 
126
    */
127
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
128
                              |RCC_CLOCKTYPE_PCLK1;
129
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
130
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
131
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
132
133
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
134
  {
135
    _Error_Handler(__FILE__, __LINE__);
136
  }
137
138
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
139
  PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK1;
140
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
141
  {
142
    _Error_Handler(__FILE__, __LINE__);
143
  }
144
145
    /**Configure the Systick interrupt time 
146
    */
147
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
148
149
    /**Configure the Systick 
150
    */
151
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
152
153
  /* SysTick_IRQn interrupt configuration */
154
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
155
}
156
157
#endif

Hier die Einstellung für 4MHz
1
C-Code

von Stefan F. (Gast)


Lesenswert?

Der Schubs in die richtige Richtung ist mir gelungen, weiter weiss ich 
allerdings nicht, denn ich bin weder mit der HAL noch mit diesem 
konkreten µC Modell vertraut.

Nur so viel noch:
Die Taktfrequenz kannst du sicher mit einer blinkenden LED 
kontrollieren. Außerdem kannst du den Wert der Variable 
"SystemCoreClock" ausgeben. Ich würde beides mal tun.

von Mark (Gast)


Lesenswert?

Stefanus F. schrieb:
> Der Schubs in die richtige Richtung ist mir gelungen, weiter weiss
> ich
> allerdings nicht, denn ich bin weder mit der HAL noch mit diesem
> konkreten µC Modell vertraut.
>
> Nur so viel noch:
> Die Taktfrequenz kannst du sicher mit einer blinkenden LED
> kontrollieren. Außerdem kannst du den Wert der Variable
> "SystemCoreClock" ausgeben. Ich würde beides mal tun.

Ok, vielen Dank dafür
Ich werde es bei Gelegenheit gleich prüfen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.