Hallo Leute, kann mir vielleicht jemand sagen, ob folgendes mit einem STM32F103C8 funktioniert? ich möchte für einen zwei Phasen Boostwandler (für einen MPPT Tracker) zwei PWMs per STM32F103 erzeugen. Diese sollen das selbe Ton zu Toff verhalten haben, aber zueinander um eine halbe Periode versetzt sein. Das einzige, was ich bis jetzt gefunden habe ist, das man Totzeiten bei komplementären PWM Ausgängen einbauen kann, aber ich habe ja keine komplementären. Geht das überhaupt bei dem STM32F103? Danke
Sunnyboy schrieb: > aber ich habe ja keine komplementären. Hast Du. Du weißt es nur nicht. Bei 90° Phasenverschiebung ist das Pegel-Vorzeichen doch egal. Es bleiben immer zwei um 90° verschobene Rechtecksignale.
:
Bearbeitet durch User
Wenn Du um 180° verschiebst, brauchst Du keine zwei PWM. Da reicht eine und ein Inverter.
Walter T. schrieb: > Hast Du. Du weißt es nur nicht. Bei 90° Phasenverschiebung ist das > Pegel-Vorzeichen doch egal. Es bleiben immer zwei um 90° verschobene > Rechtecksignale. Irgendwie verstehe ich die Aussage nicht. Könntest du das noch einmal erklären?
Bei STM32F103 sehe ich nur die Möglichkeit 2 Timer gleich zu konfigurieren und vor dem Starten das TIMx_CNT Register bei einem Timer mit 0 zu laden und beim anderen mit dem gewünschten Versatz. Alle weiteren Aktionen, wie Tastverhältnis setzen z.B., müssen dann natürlich auf beiden Timern gemacht werden. Wenn du es dir noch aussuchen kannst, nimm den STM32F334. Der hat einen wesentlich besseren Timer (HRTIM) für diesen Zweck.
temp schrieb: > Bei STM32F103 sehe ich nur die Möglichkeit 2 Timer gleich zu > konfigurieren und vor dem Starten das TIMx_CNT Register bei einem Timer > mit 0 zu laden und beim anderen mit dem gewünschten Versatz. Super, das war es! Riesigen Dank! :) Ich lasse jetzt einfach (erst einmal zum generellen testen) Timer 2 & 3 @ 100kHz bei 72MHz Systemtakt laufen und habe TIM2_CNT einfach um den halbe Periode gesetzt. Somit ist er genau um eine halbe Periode versetzt. temp schrieb: > Wenn du es dir noch aussuchen kannst, > nimm den STM32F334. Ich hab hier noch eine handvoll von den STM32 Blue Pills mit eben den 103ern liegen. Ich benutze zwar das Arduino Zeugs nicht, aber die Dinger sind einfach unschlagbar günstig. Für <2€ ein "ready to use" Board. Und für den selben Preis gibt es auch ein paar ST-Links, von denen auch welche habe.
Ich verstehe das Problem wohl immer noch nicht. TIM1 und TIM8 haben eine dead time - Funktion (Register OCx und OCxN), deren Polarität sich frei wählen läßt. Zwei phasenstarre, um 90° versetzte PWM sollten damit ohne Klimmzüge möglich sein.
:
Bearbeitet durch User
Ich noch einmal :-( Mich hat das mit TIM1 im complementair Mode nicht in ruhe gelassen... Also was ich hinbekommen habe ist den ersten Kanal (T1C1 @PA8) zu erzeugen und den zweiten (T1C1N @PB13) zu invertieren. Aber wenn ich das Register CNT beschreibe bekomme ich keinen Deadtime-Versatz hin... es ändert nicht einmal etwas. Kann mir da noch jemand weiter helfen? Und ja, dies ist jetzt auf die Schnelle in "Arduino-Syntax" geschrieben - Asche auf mein Haupt!
1 | #define PWM_OUT PA8 //PWM output
|
2 | #define PWM_OUT_COMP PB13 //complementary output
|
3 | |
4 | void setup() |
5 | {
|
6 | pinMode(PC13, OUTPUT); |
7 | HardwareTimer timer1 = HardwareTimer(1); |
8 | timer1.setPrescaleFactor(1); |
9 | timer1.setPeriod(10); //100kHz |
10 | |
11 | pinMode(PWM_OUT, PWM); |
12 | pinMode(PWM_OUT_COMP, PWM); |
13 | |
14 | timer_dev *t = TIMER1; //refers t to Timer 1 |
15 | timer_reg_map r = t->regs; |
16 | |
17 | r.adv->CNT = 360; << hat gänzlich keine Auswirkung! 360 ist die Hälfte der Periode von 720 |
18 | |
19 | bitSet(r.adv->CCER,0); // enable CC1E |
20 | bitSet(r.adv->CCER,2); // enable CC1NE |
21 | bitSet(r.adv->CCER,3); // invert CC1NE |
22 | |
23 | pwmWrite(PWM_OUT, 300); // |
24 | }
|
Da wäre es sinnvoll zu wissen, in welchen Registern pwmWrite() herumschreibt.
Hier wäre die Implementation dazu zu finden: https://github.com/bobc/maple-asp/blob/master/Arduino/hardware/maple-asp/Maple/cores/maple/pwm.cpp
Sunnyboy schrieb: > Hier wäre die Implementation dazu zu finden: Dann wäre es interessant, zu wissen, in welchen Registern timer_set_compare() herumschreibt.
Ich finde es schlicht weg nicht - irgendwie undurchsichtig :-( Welche müssten es denn sein? Dann setzte ich diese per Hand.
Sunnyboy schrieb: > Welche müssten es denn sein? Dann setzte ich diese per Hand. Irgendwie fühle ich mich jetzt in Zugzwang, weil ich vorher auch schon geantwortet habe, und ich muß gestehen: Ich weiß es nicht. Ich nutze nicht bare metal, sondern die Standard Peripheral Library. Deren Implementierungsbeispiele wären also auch meine erste Anlaufstelle. Da sieht das Beispiel "TIM\ComplementarySignals" ziemlich nach dem aus, was Du vorhast.
Servus, der Beitrag ist zwar schon etwas älter, aber ich habe auch ein kleines Problem mit soetwas. Ich möchte auf einem STM32F103 eine Vollbrücke ansteuern und mit Phasenverschiebung regeln. Ich habe auf einem Blue Pill Board TIM1 im output compare programmiert; CH1 CH1N und CH2 CH2N, die Phasenverschiebung zwischen CH1 und CH2 mach ich mit CCR1 und CCR2. Über den ADC werden zwei Poti Werte eingelesen, eines für die Phasenverschiebung und eines für die Frequenz zum einstellen. Zuätzlich sind noch 2 Hall Sensoren zur Stromüberwachung verbaut. Das Ganze funktioniert auch schon ziemlich gut...nur ein kleines Problem: Der Phasenversatz lässt sich über das Poti super einstellen, aber hin und wieder springen die Phasen umher. Also...wenn die Phasenverschiebung z. B. 0 sein sollte, kann es sein dass die auf einmal auf 100% springt, oder wenn so ca. 20% eingestellt sind, springt sie dann auf 80%...und auch wieder zurück. Ich bekomme auch immer Warnungen, immer wenn der ADCWerte[3] ausgelesen wird: "array subscript is above array bound" Was kann das bedeuten??? Vielen Dank schon mal! /* USER CODE BEGIN Header */ /** ************************************************************************ ****** * @file : main.c * @brief : Main program body ************************************************************************ ****** * @attention * * <h2><center>© Copyright (c) 2019 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 "ssd1306.h" #include "fonts.h" #include "math.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ volatile uint16_t ADCWerte[3]; volatile uint16_t shift; volatile uint16_t frequenz; volatile uint16_t i = 0; char potiwert[12]; char potiwert2[12]; char shiftwert[12]; char frequenzwert[12]; char sensorwert1[12]; char sensorwert2[12]; char offsetwert1[12]; char offsetwert2[12]; double poti; double poti2; double sensor1; double sensor2; double s1offset; double s2offset; double strommax1 = 200; // +/- maximalwert Strom1 bei Abschaltung (Rohwert) double strommax2 = 200; // +/- maximalwert Strom2 bei Abschaltung (Rohwert) /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ ADC_HandleTypeDef hadc1; DMA_HandleTypeDef hdma_adc1; I2C_HandleTypeDef hi2c1; DMA_HandleTypeDef hdma_i2c1_rx; DMA_HandleTypeDef hdma_i2c1_tx; TIM_HandleTypeDef htim1; /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_DMA_Init(void); static void MX_TIM1_Init(void); static void MX_ADC1_Init(void); static void MX_I2C1_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* 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_DMA_Init(); MX_TIM1_Init(); MX_ADC1_Init(); MX_I2C1_Init(); /* USER CODE BEGIN 2 */ SSD1306_Init(); SSD1306_Clear(); HAL_ADC_Start (&hadc1); HAL_ADCEx_Calibration_Start(&hadc1); HAL_ADC_Start_DMA(&hadc1, (uint32_t*) ADCWerte, 4); //ADC -> DMA start HAL_Delay(100); s1offset = ADCWerte[2]; //Sensorwert1 offset aus Array auslesen s2offset = ADCWerte[3]; //Sensorwert2 offset aus Array auslesen HAL_Delay(100); frequenz = ((ADCWerte[1]*0.293)+450)-1; //frequenz berechnen 20-80 kHz shift = (frequenz*ADCWerte[0])/4096; //Phasenverschiebung berechnen i = shift; // i = berechneter Wert Phasenverschiebung für Softstart shift = 0; sensor1 = ADCWerte[2]; //Sensorwert1 aus Array auslesen sensor2 = ADCWerte[3]; //Sensorwert2 aus Array auslesen HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET); //Enable pin ein HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET); //Enable pin ein HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_1); //start Timer1 CH1 HAL_TIMEx_OCN_Start(&htim1, TIM_CHANNEL_1); //start Timer1 CH1N HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_2); //start Timer1 CH2 HAL_TIMEx_OCN_Start(&htim1, TIM_CHANNEL_2); //start Timer1 CH2N //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++ //Softstart: TIM1->ARR= frequenz; //counter period (frequenz) aktualisieren TIM1->CCR2 = shift;// Phasenverschiebung aktualisieren HAL_Delay(1000); for(shift=0; shift<=i; shift++) { shift = shift+5; TIM1->CCR2 = shift; sprintf (shiftwert, "%4d", shift); SSD1306_GotoXY (5,10); SSD1306_Puts ("shift", &Font_7x10, 1); SSD1306_GotoXY (55,10); SSD1306_Puts (shiftwert , &Font_7x10, 1); SSD1306_UpdateScreen(); //display HAL_Delay(0.01); } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (ADCWerte[2] <= (s1offset+strommax1) && ADCWerte[2] >= (s1offset-strommax1) && ADCWerte[3] <= (s2offset+strommax2) && ADCWerte[3] >= (s2offset-strommax2)) //Hall-sensorwerte für Überstromüberwachung { //shift=0; frequenz = ((ADCWerte[1]*0.293)+450)-1; //frequenz berechnen 20-80 kHz shift = (frequenz*ADCWerte[0])/4096; //Phasenverschiebung berechnen TIM1->ARR = frequenz; //counter period (frequenz) aktualisieren TIM1->CCR2 = shift;// Phasenverschiebung aktualisieren poti = ADCWerte[0]; //Potiwert shift aus Array auslesen poti2 = ADCWerte[1]; //Potiwert Frequenz aus Array auslesen //sensor1 = ADCWerte[2]; //Sensorwert1 aus Array auslesen //sensor2 = ADCWerte[3]; //Sensorwert2 aus Array auslesen //HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET); //Enable pin ein //HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET); //Enable pin ein sprintf (potiwert, "%4d", ADCWerte[0]); //Poti Rohwert sprintf (potiwert2, "%4d", ADCWerte[1]); //Poti2 Rohwert sprintf (potiwert, "%5.3f [V]", ((poti/4096)*3.3)); //Poti Spannung [V] sprintf (potiwert2, "%5.3f [V]", ((poti2/4096)*3.3)); //Poti2 Spannung [V] sprintf (shiftwert, "%4d %%", ((shift*100)/frequenz)); sprintf (frequenzwert, "%5.2f kHz", ((72000000/2/(double)frequenz)/1000)); sprintf (offsetwert1, "%4.0f", s1offset); sprintf (offsetwert2, "%4.0f", s2offset); //verschiedene Ausgaben des 1. Sensors //sprintf (sensorwert1, "%4.0f", sensor1); //Sensor1 Rohwerte sprintf (sensorwert1, "%4.0f", (ADCWerte[2]-s1offset)); //Sensor1 Rohwerte mit Offset //sprintf (sensorwert1, "%6.4f [V]", ((sensor1/4096)*3.3)); //Sensor1 Spannung [V] //sprintf (sensorwert1, "%6.4f [V]", (((sensor1/4096)*3.3)-1.7000)); //Sensor1 Spannung mit Offset [V] //sprintf (sensorwert1, "%4.0f [mV]", ((sensor1/4096)*3.3)*1000); //Sensor1 Spannung [mV] //sprintf (sensorwert1, "%4.0f [Gs]", ((((1000-(-1000))/(4.0-1.0))*((sensor1/4096)*3.3)-1.0)+(-1000))); //Sensor1 Magnetfussdichte [Gauss] //sprintf (sensorwert1, "%6.3f [T]", ((((sensor1-2100)/4096)*3.3)*(1000/1.5))/10000); //Sensor1 Magnetfussdichte [T] //sprintf (sensorwert1, "%4.1f [A]", (((((sensor1-2100)/4096)*3.3)*(1000/1.5))/10000)*4998556*0.0014); //Sensor1 Strom [A] // verschiedene Ausgaben des 2. Sensors //sprintf (sensorwert2, "%4.0f", sensor2); //Sensor2 Rohwerte sprintf (sensorwert2, "%4.0f", (ADCWerte[3]-s2offset)); //Sensor2 Rohwerte mit Offset //sprintf (sensorwert2, "%6.4f [V]", ((sensor2/4096)*3.3)); //Sensor2 Spannung [V] //sprintf (sensorwert2, "%6.4f [V]", (((sensor2/4096)*3.3)-1.7000)); //Sensor2 Spannung mit Offset [V] //sprintf (sensorwert2, "%4.0f [mV]", ((sensor2/4096)*3.3)*1000); //Sensor2 Spannung [mV] //sprintf (sensorwert2, "%4.0f [Gs]", ((((1000-(-1000))/(4.0-1.0))*((sensor2/4096)*3.3)-1.0)+(-1000))); //Sensor2 Magnetfussdichte [Gauss] //sprintf (sensorwert2, "%6.3f [T]", ((((sensor2-2100)/4096)*3.3)*(1000/1.5))/10000); //Sensor2 Magnetfussdichte [T] //sprintf (sensorwert2, "%4.1f [A]", (((((sensor2-2100)/4096)*3.3)*(1000/1.5))/10000)*4998556*0.0014); //Sensor2 Strom [A] SSD1306_GotoXY (5,0); SSD1306_Puts ("Poti1", &Font_7x10, 1); SSD1306_GotoXY (55,0); SSD1306_Puts (potiwert, &Font_7x10, 1); SSD1306_GotoXY (5,10); SSD1306_Puts ("Poti2", &Font_7x10, 1); SSD1306_GotoXY (55,10); SSD1306_Puts (potiwert2, &Font_7x10, 1); SSD1306_GotoXY (5,20); SSD1306_Puts ("shift", &Font_7x10, 1); SSD1306_GotoXY (62,20); SSD1306_Puts (shiftwert , &Font_7x10, 1); SSD1306_GotoXY (5,30); SSD1306_Puts ("freq", &Font_7x10, 1); SSD1306_GotoXY (55,30); SSD1306_Puts (frequenzwert , &Font_7x10, 1); SSD1306_GotoXY (5,41); SSD1306_Puts ("H1:", &Font_7x10, 1); SSD1306_GotoXY (30,41); SSD1306_Puts (sensorwert1, &Font_7x10, 1); SSD1306_GotoXY (70,41); SSD1306_Puts ("H2:", &Font_7x10, 1); SSD1306_GotoXY (95,41); SSD1306_Puts (sensorwert2, &Font_7x10, 1); SSD1306_GotoXY (5,52); SSD1306_Puts ("o1:", &Font_7x10, 1); SSD1306_GotoXY (30,52); SSD1306_Puts (offsetwert1, &Font_7x10, 1); SSD1306_GotoXY (70,52); SSD1306_Puts ("o2:", &Font_7x10, 1); SSD1306_GotoXY (95,52); SSD1306_Puts (offsetwert2, &Font_7x10, 1); SSD1306_UpdateScreen(); //display /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++ // Bei Überstromerkennung ueberstrom: HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_RESET); //Enable pin aus HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET); //Enable pin aus HAL_ADC_Stop_DMA(&hadc1); //ADC -> DMA stop HAL_TIM_OC_Stop(&htim1, TIM_CHANNEL_1); //stop Timer1 CH1 HAL_TIMEx_OCN_Stop(&htim1, TIM_CHANNEL_1); //stop Timer1 CH1N HAL_TIM_OC_Stop(&htim1, TIM_CHANNEL_2); //stop Timer1 CH2 HAL_TIMEx_OCN_Stop(&htim1, TIM_CHANNEL_2); //stop Timer1 CH2N SSD1306_ToggleInvert(); SSD1306_UpdateScreen(); HAL_Delay(500); goto ueberstrom; //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++ /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; /** Initializes the CPU, AHB and APB busses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != 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_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC; PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV8; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); } } /** * @brief ADC1 Initialization Function * @param None * @retval None */ static void MX_ADC1_Init(void) { /* USER CODE BEGIN ADC1_Init 0 */ /* USER CODE END ADC1_Init 0 */ ADC_ChannelConfTypeDef sConfig = {0}; /* USER CODE BEGIN ADC1_Init 1 */ /* USER CODE END ADC1_Init 1 */ /** Common config */ hadc1.Instance = ADC1; hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE; hadc1.Init.ContinuousConvMode = ENABLE; hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.NbrOfConversion = 4; if (HAL_ADC_Init(&hadc1) != HAL_OK) { Error_Handler(); } /** Configure Regular Channel */ sConfig.Channel = ADC_CHANNEL_0; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } /** Configure Regular Channel */ sConfig.Channel = ADC_CHANNEL_1; sConfig.Rank = ADC_REGULAR_RANK_2; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } /** Configure Regular Channel */ sConfig.Channel = ADC_CHANNEL_2; sConfig.Rank = ADC_REGULAR_RANK_3; sConfig.SamplingTime = ADC_SAMPLETIME_28CYCLES_5; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } /** Configure Regular Channel */ sConfig.Channel = ADC_CHANNEL_3; sConfig.Rank = ADC_REGULAR_RANK_4; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN ADC1_Init 2 */ /* USER CODE END ADC1_Init 2 */ } /** * @brief I2C1 Initialization Function * @param None * @retval None */ static void MX_I2C1_Init(void) { /* USER CODE BEGIN I2C1_Init 0 */ /* USER CODE END I2C1_Init 0 */ /* USER CODE BEGIN I2C1_Init 1 */ /* USER CODE END I2C1_Init 1 */ hi2c1.Instance = I2C1; hi2c1.Init.ClockSpeed = 400000; hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; hi2c1.Init.OwnAddress1 = 0; hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 = 0; hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c1) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN I2C1_Init 2 */ /* USER CODE END I2C1_Init 2 */ } /** * @brief TIM1 Initialization Function * @param None * @retval None */ static void MX_TIM1_Init(void) { /* USER CODE BEGIN TIM1_Init 0 */ /* USER CODE END TIM1_Init 0 */ TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0}; /* USER CODE BEGIN TIM1_Init 1 */ /* USER CODE END TIM1_Init 1 */ htim1.Instance = TIM1; htim1.Init.Prescaler = 0; htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = 1200; htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim1.Init.RepetitionCounter = 0; htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_OC_Init(&htim1) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) { Error_Handler(); } sConfigOC.OCMode = TIM_OCMODE_TOGGLE; sConfigOC.Pulse = 0; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET; sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET; if (HAL_TIM_OC_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } sConfigOC.Pulse = 600; if (HAL_TIM_OC_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK) { Error_Handler(); } sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE; sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE; sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_1; sBreakDeadTimeConfig.DeadTime = 50; sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE; sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH; sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE; if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN TIM1_Init 2 */ /* USER CODE END TIM1_Init 2 */ HAL_TIM_MspPostInit(&htim1); } /** * Enable DMA controller clock */ static void MX_DMA_Init(void) { /* DMA controller clock enable */ __HAL_RCC_DMA1_CLK_ENABLE(); /* DMA interrupt init */ /* DMA1_Channel1_IRQn interrupt configuration */ HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn); /* DMA1_Channel6_IRQn interrupt configuration */ HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn); /* DMA1_Channel7_IRQn interrupt configuration */ HAL_NVIC_SetPriority(DMA1_Channel7_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA1_Channel7_IRQn); } /** * @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_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1|GPIO_PIN_15, GPIO_PIN_RESET); /*Configure GPIO pin : PA0 */ GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /*Configure GPIO pins : PB1 PB15 */ GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_15; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); } /* 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****/
Hat keiner eine Antwort? PS: es hat nix mit dem gefälschten Stm32 aus dem anderen Beitrag zu tun, ich hab hier zwar auch einen gefälschten chip, aber es ist kein Unterschied erkennbar, wenn ichs auf einen orig stm32f103c8t6 aufspiele.
und wenn ich ccr1=0 und ccr2=200 zum beispiel fest vergebe und die ccr2 aktualisierung über den ADC auskommentiere, funktionierts. es muss wohl was mit dem adc/dma zu tun haben?!
Beitrag von Sascha, nicht den PA0 zu benutzen hat funktioniert! Beitrag "Ungenauigkeit beim STM32 ADC"
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.