Forum: Mikrocontroller und Digitale Elektronik STM32 HAL U(S)ART Problem


von Nico (Gast)



Lesenswert?

Hallo zusammen,

ich bin aktuell dabei, mit einem STM32 und einem externen 16 bit ADC ein 
Hamamatsu Mikro-Spektrometer auszulesen. Das klappt soweit auch ganz 
gut, leider habe ich Probleme damit, die Daten aus dem STM 
herauszubekommen. Geplant war, jeweils ein Spektrum einzulesen und 
anschließend die Daten per U(S)ART zur weiteren Verarbeitung auszugeben.

Klingt eigentlich ganz simpel. Solange ich in der Hauptschleife des 
Programms nichts per U(S)ART ausgebe, klappt das auch wunderbar, im 
Debugger stehen auch plausible Werte im Array. Sobald ich jedoch die 
Werte (ohne oder mit Delays davor oder danach) per U(S)ART ausgebe, 
zerhackt es mir das Timing komplett und es kommt (logischerweise) nur 
Rauschen im seriellen Terminal an, da nun nicht mehr das Spektrum 
abgetastet wird, sondern nur Rauschen.

Ich bin momentan überfragt, bin mir aber sehr sicher, dass es ein ganz 
offensichtlicher Fehler ist.

Anbei zwei Fotos vom Oszillogramm (einmal ohne UART Transmit und daher 
mit mehr oder weniger übereinanderliegendem "Abtasttakt" und Spektrum, 
so soll es aussehen) und einmal mit UART Transmit und komplett relativ 
zum Spektrum verschobenen "Abtasttakt".

von Nico (Gast)


Lesenswert?

Code folgt in Kürze.

von Nico (Gast)


Lesenswert?

main.c:

/* USER CODE BEGIN Header */
/**
  ************************************************************************ 
******
  * @file           : main.c
  * @brief          : Main program body
  ************************************************************************ 
******
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause 
license,
  * the "License"; You may not use this file except in compliance with 
the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ************************************************************************ 
******
  */
/* USER CODE END Header */

/* Includes 
------------------------------------------------------------------*/
#include "main.h"

/* Private includes 
----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "ADS8860.h"
#include "globalvars.h"
/* USER CODE END Includes */

/* Private typedef 
-----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define 
------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro 
-------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables 
---------------------------------------------------------*/
SPI_HandleTypeDef hspi1;

TIM_HandleTypeDef htim3;

UART_HandleTypeDef huart4;
USART_HandleTypeDef husart1;

/* USER CODE BEGIN PV */
extern volatile int triggered;
volatile int triggered;
uint16_t spektrum[288];
/* USER CODE END PV */

/* Private function prototypes 
-----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI1_Init(void);
static void MX_USART1_Init(void);
static void MX_TIM3_Init(void);
static void MX_UART4_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code 
---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

#ifdef _GNUC_
  #define PUTCHAR_PROTOTYPE int__io__putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif

PUTCHAR_PROTOTYPE
{
  HAL_USART_Transmit(&husart1, (uint8_t *)&ch, 1, 0xFFFF);
  return ch;
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
  //uint16_t adc = 0;
  uint16_t werte[288];
  /* USER CODE END 1 */


  /* MCU 
Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the 
Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_SPI1_Init();
  MX_USART1_Init();
  MX_TIM3_Init();
  MX_UART4_Init();
  /* USER CODE BEGIN 2 */
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
  printf("\n\r UART Test Passed~ \n\r");
  ads8860_Init();
  /* USER CODE END 2 */



  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    // Sende Startpuls an Spektrometerbaustein
    HAL_GPIO_WritePin(ST_GPIO_Port, ST_Pin, GPIO_PIN_SET);
    for (uint16_t i = 0; i < 10000; i++) {
      __nop();
    }
    HAL_GPIO_WritePin(ST_GPIO_Port, ST_Pin, GPIO_PIN_RESET);
    for (uint16_t i = 0; i < 10000; i++) {
      __nop();
    }

    for (uint16_t i=0;i<288;i++) {
      werte[i] = ADS8860_ReadValue();
    }

    HAL_Delay(10);

    printf("%d\n", werte[150]);

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  /** Initializes the CPU, AHB and APB busses clocks
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 180;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Activate the Over-Drive mode
  */
  if (HAL_PWREx_EnableOverDrive() != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != 
HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief SPI1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_SPI1_Init(void)
{

  /* USER CODE BEGIN SPI1_Init 0 */

  /* USER CODE END SPI1_Init 0 */

  /* USER CODE BEGIN SPI1_Init 1 */

  /* USER CODE END SPI1_Init 1 */
  /* SPI1 parameter configuration*/
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
  hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SPI1_Init 2 */

  /* USER CODE END SPI1_Init 2 */

}

/**
  * @brief TIM3 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM3_Init(void)
{

  /* USER CODE BEGIN TIM3_Init 0 */

  /* USER CODE END TIM3_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};

  /* USER CODE BEGIN TIM3_Init 1 */

  /* USER CODE END TIM3_Init 1 */
  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 8;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 50;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != 
HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 25;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != 
HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM3_Init 2 */

  /* USER CODE END TIM3_Init 2 */
  HAL_TIM_MspPostInit(&htim3);

}

/**
  * @brief UART4 Initialization Function
  * @param None
  * @retval None
  */
static void MX_UART4_Init(void)
{

  /* USER CODE BEGIN UART4_Init 0 */

  /* USER CODE END UART4_Init 0 */

  /* USER CODE BEGIN UART4_Init 1 */

  /* USER CODE END UART4_Init 1 */
  huart4.Instance = UART4;
  huart4.Init.BaudRate = 1000000;
  huart4.Init.WordLength = UART_WORDLENGTH_8B;
  huart4.Init.StopBits = UART_STOPBITS_1;
  huart4.Init.Parity = UART_PARITY_NONE;
  huart4.Init.Mode = UART_MODE_TX_RX;
  huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart4.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart4) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN UART4_Init 2 */

  /* USER CODE END UART4_Init 2 */

}

/**
  * @brief USART1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART1_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  husart1.Instance = USART1;
  husart1.Init.BaudRate = 115200;
  husart1.Init.WordLength = USART_WORDLENGTH_8B;
  husart1.Init.StopBits = USART_STOPBITS_1;
  husart1.Init.Parity = USART_PARITY_NONE;
  husart1.Init.Mode = USART_MODE_TX;
  husart1.Init.CLKPolarity = USART_POLARITY_LOW;
  husart1.Init.CLKPhase = USART_PHASE_1EDGE;
  husart1.Init.CLKLastBit = USART_LASTBIT_DISABLE;
  if (HAL_USART_Init(&husart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */

  /* USER CODE END USART1_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOF_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOG_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4|GPIO_PIN_7, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(ST_GPIO_Port, ST_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : PF0 */
  GPIO_InitStruct.Pin = GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

  /*Configure GPIO pins : PA4 PA7 */
  GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pin : ST_Pin */
  GPIO_InitStruct.Pin = ST_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(ST_GPIO_Port, &GPIO_InitStruct);

  /* EXTI interrupt init*/
  HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI0_IRQn);

}

/* USER CODE BEGIN 4 */
/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return 
state */

  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line 
number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and 
line number,
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, 
line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF 
FILE****/

von Nico (Gast)


Lesenswert?

ADS8860.c:

#include "ADS8860.h"
#include "globalvars.h"

static void DIN_Set(void)
{
  HAL_GPIO_WritePin(DIN_Port, DIN_Pin, GPIO_PIN_SET);
}

static void CONVST_Reset(void)
{
  HAL_GPIO_WritePin(CONVST_Port, CONVST_Pin, GPIO_PIN_RESET);
}

static void CONVST_Set(void)
{
  HAL_GPIO_WritePin(CONVST_Port, CONVST_Pin, GPIO_PIN_SET);
}

uint16_t ADS8860_ReadValue(void)
{
  DIN_Set();
  CONVST_Set();
  delay_600ns();
  CONVST_Reset();
  uint16_t val;
  /*HAL_SPI_Receive(&ADS8860_SPI_Port, &readBuffer, 8, 0xFFFF);
  adcReadBuffer = readBuffer;
  readBuffer = 0;
  HAL_SPI_Receive(&ADS8860_SPI_Port, &readBuffer, 8, 0xFFFF);
  adcReadBuffer = adcReadBuffer << 8;
  adcReadBuffer |= readBuffer;*/
  /*HAL_SPI_Receive(&ADS8860_SPI_Port, buffer, 2, 1);
  adcReadBuffer = ((uint16_t) buffer[0] << 8) | ((uint16_t) 
buffer[1]);*/
  /*HAL_SPI_Receive(&ADS8860_SPI_Port, &adcReadBuffer, 16, 0xFFFF);*/

  HAL_SPI_Receive(&ADS8860_SPI_Port, (uint8_t *)&val, 1, 10);

  HAL_GPIO_WritePin(SCLK_Port, SCLK_Pin, GPIO_PIN_RESET);
  HAL_GPIO_WritePin(DOUT_Port, DOUT_Pin, GPIO_PIN_RESET);
  return val;
}

void delay_600ns(void)
{
  for (uint8_t i = 0; i < 10; i++)
    __nop();

}

void delay_ticks(int n)
{
  for (uint8_t i = 0; i < n; i++)
    __nop();

}

void ads8860_Init(void)
{
  DIN_Set();
  CONVST_Reset();
}

von Ruediger A. (Firma: keine) (rac)


Lesenswert?

Wo wird die RCC clock für den U(S)ART enabled?

von Nico (Gast)


Lesenswert?

Ich habe mal alles in ein Github Repo geladen: 
https://github.com/neitmedia/spectrodue

Ich habe das Projekt mit STM32CubeMX generiert und der U(S)ART 
funktioniert ja auch einwandfrei, ich kann problemlos mit 1000000 Baud 
Daten senden.

Ich zweifle also daran, dass da noch irgendein RCC aktiviert werden 
muss, wenn die Übertragung als solches funktioniert. Das einzige Problem 
ist wie gesagt dieses dann auftretende Timingproblem in der 
Hauptschleife.

Die SPI-Kommunikation geht dann völlig kaputt.

von Ruediger A. (Firma: keine) (rac)


Lesenswert?

ok sorry, habe ich missverstanden. Der UART ist offensichtlich ok.

Das nächste wonach man gucken sollte ist ob die SPI HAL Funktionen 
irgendwie fortwährend Interrupts disablen.

von Nico (Gast)


Lesenswert?

Danke für den Tipp! Wie kann ich das denn am Besten prüfen?

von Paul (Gast)


Lesenswert?

uint16_t temp;


HAL_UART_Transmit(&huart1, &temp, 2, 1000);

Klappt bei mir auf der Blue Pill
Wichtig ist das "&" vor der Variable, sonst kommt bei mir auch nur 
Bullshit raus.

von Nico (Gast)


Lesenswert?

Ich habe printf auf den U(S)ART umgebogen, hier:

PUTCHAR_PROTOTYPE
{
  HAL_USART_Transmit(&husart1, (uint8_t *)&ch, 1, 0xFFFF);
  return ch;
}

An sich funktioniert ja sowohl der U(S)ART als auch die 
SPI-Kommunikation mit dem ADC. Ich kann sogar in der Initfunktion etwas 
auf den USART schreiben und danach problemlos SPI Kommunikation machen, 
nur wenn ich innerhalb der Hauptschleife zuerst paar GPIOs setze, dann 
paar __nop()s ausführe und anschließend noch ein paar GPIOs setze, dann 
SPI_Receive mache und anschließend den abgerufenen Wert per UART 
ausgebe, zerhackt es mit das Timing komplett.

von Nico (Gast)


Lesenswert?

/* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    // Sende Startpuls an Spektrometerbaustein
    HAL_GPIO_WritePin(ST_GPIO_Port, ST_Pin, GPIO_PIN_SET);
    for (uint16_t i = 0; i < 10000; i++) {
      __nop();
    }
    HAL_GPIO_WritePin(ST_GPIO_Port, ST_Pin, GPIO_PIN_RESET);
    for (uint16_t i = 0; i < 10000; i++) {
      __nop();
    }

    for (uint16_t i=0;i<288;i++) {
      werte[i] = ADS8860_ReadValue();
    }

    HAL_Delay(10);

    printf("%d\n", werte[150]); <-- mit dieser Zeile ist das Timing 
kaputt, ohne diese Zeile klappt alles wunderbar. Siehe Oszillogramme.

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

von Ruediger A. (Firma: keine) (rac)


Lesenswert?

Hm, sind die USARTS in der HAL interupt getrieben oder busy wait 
getrieben? Wie liegen die Interruptprioritäten? An welcher Stelle wird 
an USART4 geschrieben?

Was passiert, wenn Du das printf aufspaltest in

{
    unsigned char aData[20];
    sprintf(aData,"%d\n");
    printf(aData);
}

sehr wahrscheinlich wird das Timing erst beim printf in die Hecken gehen 
(der Test nur, um das Problem sicher auf den USART1 einzugrenzen).

Ich würde die Ausgabe von printf an die ITM statt an einen USART 
ausgeben, das ist in jedem Fall wesentlich weniger invasiv.

: Bearbeitet durch User
von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Nico schrieb:
> for (uint16_t i=0;i<288;i++) {
>       werte[i] = ADS8860_ReadValue();
>     }

Das sieht für mich nach der klassischen Aufgabe für einen 
Timerinterrupt, oder, noch besser, wenn man die Pinwackelei in den Griff 
bekommt, nach einem Job für DMA aus, gleich nachdem klar ist, das es 
nicht zu einem Konflikt in den GPIOs kommt.
Ich wünschte, das HAL nicht so eine Plappertasche wäre, dann wäre es 
etwas übersichtlicher. Mein Ansatz aber wäre, eine der beiden Aufgaben 
deutlich in den Hintergrund zu schieben, oder automatisch zu bearbeiten. 
USART müsste auf jeden Fall gehen, wenn sich die Pins nicht ins Gehege 
kommen.

Nico schrieb:
> printf("%d\n", werte[150]);
Du möchtest aber wirklich nur Zelle 150 ausgeben? printf kann übrigens 
selber ganz schön dauern, wenn du da eine grosse Version benutzt.

: Bearbeitet durch User
von m.n. (Gast)


Lesenswert?

Ruediger A. schrieb:
> Wie liegen die Interruptprioritäten?

Außer EXTI0 finde ich keinen weiteren Interrupt, der zudem auch noch die 
(default) höchste Priorität hat.

Matthias S. schrieb:
> Ich wünschte, das HAL nicht so eine Plappertasche wäre, dann wäre es
> etwas übersichtlicher.

Hinzu kommt, daß das ganze Programm wohl auch keine Struktur hat.
Erklärende Kommentare fehlen.

von Nico (Gast)


Lesenswert?

Ja, Timer-Interrupt und DMA wäre auf jeden Fall eine Idee für eine 
spätere Implementation.

Mir gings jetzt erstmal darum, überhaupt ein Spektrum rauszubekommen. Es 
ist auch erstmal völlig egal, wie lange es dauert, die Spektren 
rauszuschreiben, hauptsache ich habe da mal was in der Hand.

Ich hatte es schonmal per Timer-Interrupt probiert, aber da ging 
überhaupt nichts, da hat er erst gar keine SPI-Kommunikation gemacht, 
wenn ich in der ISR versucht habe, das ADS8860_ReadValue() auszuführen.

Und wie gesagt, im Debugger stehen ja jetzt schonmal die richtigen 
Werte, wäre nur schön, wenn ich die per UART irgendwie standardisiert 
nach draußen bekäme.

Ja, das mit der 150 ist korrekt, das war nur zum Test. Selbst das klappt 
ja nicht. Selbst wenn ich was statisches rausprinte, das Timing ist 
sofort im Eimer.

Für den undokumentierten Code muss ich mich entschuldigen, man sieht 
leider sehr, dass da bisher nur rumgetestet wurde.

von NichtWichtig (Gast)


Lesenswert?

Seriellen Buffer anlegen und dort rein schreiben.
Schreib- und LeseIndex entsprechend mitführen.

Denn Buffer dann Zeichenweise in der Hauptschleife OHNE HAL senden.
Immer wenn USART verfügbar ist das nächste Zeichen transmitten
Wenn nicht frei nicht transmitten und weiter in der loop.

Braucht 2 Zeilen welche man in der HAL Transmit findet.
Abfrage ob frei
Transfer des nächsten Zeichen

von NichtWichtig (Gast)


Lesenswert?

Und in der main-loop kein HAL_Delay(10) einbauen sondern die CPU pennen 
legen, der SysTick wird in spätestens jede ms wecken.

Das Pennenlegen läßt sich dann Fallweise noch unterdrücken wenn 1ms nix 
tuen unerwünscht ist.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Es wäre sicher sinnvoll, mal der USART auf den Zahn zu fühlen, indem du 
ohne den HAL Kram auf sie zugreifst:
1
void uart_put(char data){
2
 while ((USART1->SR & USART_FLAG_TXE) == 0);
3
 USART1->DR = data;
4
}

von Nico (Gast)


Lesenswert?

Matthias S. schrieb:
> void uart_put(char data){
>  while ((USART1->SR & USART_FLAG_TXE) == 0);
>  USART1->DR = data;
> }

Auf die Art und Weise habe ich jetzt zumindest mal Daten rausgeplottet. 
Sieht schon ganz gut aus - ich werde dennoch nicht ohne Interrupts/DMA 
auskommen.

Vielen Dank allen, die sich hier beteiligt haben!

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Nico schrieb:
> Auf die Art und Weise habe ich jetzt zumindest mal Daten rausgeplottet.

Immerhin. Das ist einer der Gründe, warum ich HAL kein bisschen mag. Ich 
hätte mein derzeitiges Projekt damit niemals hinbekommen, bei dem beide 
USB Cores, TFT, ADCs und diverse andere Peripherie zusammen arbeiten 
müssen.
Da ist mir die SPL doch deutlich lieber.

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.