Please help advice.
I am fighting several days with option ADC.
I am using 2 channels ADC IN0 and IN1 on STM32L010RB microcontroler via HAL library.
If checking apart then everything are good but when I am checking together it I have all time the same problem: first channel rewrite data on second channel and I have the same data on IN0 and IN1 in terminal
Function for select IN0.
#include "main.h"
#include <stdio.h>
#include <string.h> //Library for work with string
/* USER CODE BEGIN Includes */
char Tx_Data[31] = {0};
volatile uint32_t Axis[2] = {0};
ADC_HandleTypeDef hadc;
UART_HandleTypeDef huart2;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_ADC_Init(void);
void ADC_Select_CH0(void)
{
ADC_ChannelConfTypeDef sConfig_0 = {0};
/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig_0.Channel = ADC_CHANNEL_0;
sConfig_0.Rank = 0;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig_0) != HAL_OK)
{
Error_Handler();
}
}
void ADC_Select_CH1(void)
{
ADC_ChannelConfTypeDef sConfig_1 = {0};
/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig_1.Channel = ADC_CHANNEL_1;
sConfig_1.Rank = 1;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig_1) != HAL_OK)
{
Error_Handler();
}
}
void ADC_Check_CH0(void)
{
HAL_ADC_Start(&hadc); // start ADC
HAL_ADC_PollForConversion(&hadc, 100);
Axis[0] = HAL_ADC_GetValue(&hadc);
HAL_ADC_Stop(&hadc);
}
void ADC_Check_CH1(void)
{
HAL_ADC_Start(&hadc); // start ADC
HAL_ADC_PollForConversion(&hadc, 100);
Axis[1] = HAL_ADC_GetValue(&hadc);
HAL_ADC_Stop(&hadc);
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_ADC_Init();
HAL_ADCEx_Calibration_Start(&hadc, ADC_SINGLE_ENDED); // simple channel
while(1)
{
/* USER CODE END WHILE */
ADC_Select_CH0();
ADC_Check_CH0();
ADC_Select_CH1();
ADC_Check_CH1();
sprintf(Tx_Data, "Axis X: %d;\nAxis Y: %d;\r\n\n\n", (int)Axis[0], (int)Axis[1]);
HAL_UART_Transmit(&huart2, (uint8_t*)Tx_Data, strlen(Tx_Data), 1000);
}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_8;
RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses 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_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
static void MX_ADC_Init(void)
{
hadc.Instance = ADC1;
hadc.Init.OversamplingMode = DISABLE;
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.SamplingTime = ADC_SAMPLETIME_79CYCLES_5;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ContinuousConvMode = ENABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.DMAContinuousRequests = DISABLE;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.LowPowerFrequencyMode = DISABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
if (HAL_ADC_Init(&hadc) != HAL_OK)
{
Error_Handler();
}
}
static void MX_USART2_UART_Init(void)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = 9600;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
}
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
HAL_GPIO_WritePin(Green_LED_GPIO_Port, Green_LED_Pin, GPIO_PIN_RESET);
GPIO_InitStruct.Pin = SW_Button_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(SW_Button_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = Green_LED_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(Green_LED_GPIO_Port, &GPIO_InitStruct);
}
void Error_Handler(void)
{
__disable_irq();
while (1)
{
}
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)
{
}
#endif /* USE_FULL_ASSERT */
enter image description here
I am working with an stm32 f767zit and I am trying to generate PWM signals to control servos, but they are not generating correctly. I followedd the tutorial from here Deep Blue Embedded and was able to generate the PWM signals just fine on an stm32 f103rb, but I switched to the f767zit because I needed more PWM outputs. I have already looked at the HAL documentation and for both and compared them and as far as I can tell there are not any differences in how the pwm signals should be generated.
I have done several projects with the stm32 boards but I am still sort of a noob. I have looked for many hours for a solution but I can not find one. Sorry if this is actually just something simple and basic that I am missing.
Here are screen shots of the pwm outputs. as you can see the f103rb generates them normally, sguare waves at 50hz and 3.3v peaks. The pwm signals on the f767 are made up of lots of spikes and have peaks at 10mV. Although, they do seem to be generating at the correct pulse length
PWM Output of f103rb
PWM Output of f767
In my code all I am trying to do is initalize the servos and the set them to a positon. There are 12 servos and they are using timers 1-4. The specific channels and pins can be seen in the Servo configuration code. My main code initializes all of the perifrials and then calls initServos() which calls SERVO_init() for each servo in SERVO_CfgParam. Then my main loop calls SERVO_moveto(). I am only moving one servo in the main code but I have tested every pin that I am using and get the same results.
I used the same meathod and code for controlling 3 servos on my f013rb without any problems. I cannot figure out what difference there is on the f767zit.
Main Code
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_USART3_UART_Init();
MX_USB_OTG_FS_PCD_Init();
MX_SPI1_Init();
MX_TIM1_Init();
MX_TIM2_Init();
MX_TIM3_Init();
MX_TIM4_Init();
/* USER CODE BEGIN 2 */
initServos();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
SERVO_MoveTo(11,90);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
Servo configuration.
typedef struct
{
GPIO_TypeDef * SERVO_GPIO;
uint16_t SERVO_PIN;
TIM_TypeDef* TIM_Instance;
uint32_t* TIM_CCRx;
uint32_t PWM_TIM_CH;
uint32_t TIM_CLK;
float MinPulse;
float MaxPulse;
}SERVO_CfgType;
const SERVO_CfgType SERVO_CfgParam[SERVO_NUM] =
{
// Servo Motor 1 Configurations
{
GPIOE,
GPIO_PIN_9,
TIM1,
&TIM1->CCR1,
TIM_CHANNEL_1,
72000000,
0.65,
2.3
},
// Servo Motor 2 Configurations
{
GPIOE,
GPIO_PIN_11,
TIM1,
&TIM1->CCR2,
TIM_CHANNEL_2,
72000000,
0.65,
2.3
},
// Servo Motor 3 Configurations
{
GPIOE,
GPIO_PIN_13,
TIM1,
&TIM1->CCR3,
TIM_CHANNEL_3,
72000000,
0.65,
2.3
},
// Servo Motor 4 Configurations
{
GPIOE,
GPIO_PIN_14,
TIM1,
&TIM1->CCR4,
TIM_CHANNEL_4,
72000000,
0.65,
2.3
},
// Servo Motor 5 Configurations
{
GPIOA,
GPIO_PIN_15,
TIM2,
&TIM2->CCR1,
TIM_CHANNEL_1,
72000000,
0.65,
2.3
},
// Servo Motor 6 Configurations
{
GPIOB,
GPIO_PIN_10,
TIM2,
&TIM2->CCR2,
TIM_CHANNEL_3,
72000000,
0.65,
2.3
},
// Servo Motor 7 Configurations
{
GPIOB,
GPIO_PIN_11,
TIM2,
&TIM2->CCR4,
TIM_CHANNEL_4,
72000000,
0.65,
2.3
},
// Servo Motor 8 Configurations
{
GPIOC,
GPIO_PIN_6,
TIM3,
&TIM3->CCR1,
TIM_CHANNEL_1,
72000000,
0.65,
2.3
},
// Servo Motor 9 Configurations
{
GPIOC,
GPIO_PIN_7,
TIM3,
&TIM3->CCR2,
TIM_CHANNEL_2,
72000000,
0.65,
2.3
},
// Servo Motor 10 Configurations
{
GPIOC,
GPIO_PIN_8,
TIM3,
&TIM3->CCR3,
TIM_CHANNEL_3,
72000000,
0.65,
2.3
},
// Servo Motor 11 Configurations
{
GPIOC,
GPIO_PIN_9,
TIM3,
&TIM3->CCR4,
TIM_CHANNEL_4,
72000000,
0.65,
2.3
},
// Servo Motor 12 Configurations
{
GPIOB,
GPIO_PIN_6,
TIM4,
&TIM4->CCR1,
TIM_CHANNEL_1,
72000000,
0.65,
2.3
}
};
Servo initialization function
void SERVO_Init(uint16_t au16_SERVO_Instance)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
TIM_HandleTypeDef htim;
uint32_t PSC_Value = 0;
uint32_t ARR_Value = 0;
//DWT_Delay_Init();
/*--------[ Configure The Servo PWM GPIO Pin ]-------*/
if(SERVO_CfgParam[au16_SERVO_Instance].SERVO_GPIO == GPIOA)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
}
else if(SERVO_CfgParam[au16_SERVO_Instance].SERVO_GPIO == GPIOB)
{
__HAL_RCC_GPIOB_CLK_ENABLE();
}
else if(SERVO_CfgParam[au16_SERVO_Instance].SERVO_GPIO == GPIOC)
{
__HAL_RCC_GPIOC_CLK_ENABLE();
}
else if(SERVO_CfgParam[au16_SERVO_Instance].SERVO_GPIO == GPIOD)
{
__HAL_RCC_GPIOD_CLK_ENABLE();
}
else if(SERVO_CfgParam[au16_SERVO_Instance].SERVO_GPIO == GPIOE)
{
__HAL_RCC_GPIOE_CLK_ENABLE();
}
GPIO_InitStruct.Pin = SERVO_CfgParam[au16_SERVO_Instance].SERVO_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(SERVO_CfgParam[au16_SERVO_Instance].SERVO_GPIO, &GPIO_InitStruct);
/*--------[ Calculate The PSC & ARR Values To Maximize PWM Resolution ]-------*/
/* Those Equations Sets The F_pwm = 50Hz & Maximizes The Resolution*/
PSC_Value = (uint32_t) (SERVO_CfgParam[au16_SERVO_Instance].TIM_CLK / 3276800.0);
ARR_Value = (uint32_t) ((SERVO_CfgParam[au16_SERVO_Instance].TIM_CLK / (50.0*(PSC_Value+1.0)))-1.0);
/*--------[ Configure The Servo PWM Timer Channel ]-------*/
/*--[Check The Timer & Enable Its Clock]--*/
if(SERVO_CfgParam[au16_SERVO_Instance].TIM_Instance == TIM1)
{
__HAL_RCC_TIM1_CLK_ENABLE();
}
else if(SERVO_CfgParam[au16_SERVO_Instance].TIM_Instance == TIM2)
{
__HAL_RCC_TIM2_CLK_ENABLE();
}
else if(SERVO_CfgParam[au16_SERVO_Instance].TIM_Instance == TIM3)
{
__HAL_RCC_TIM3_CLK_ENABLE();
}
else if(SERVO_CfgParam[au16_SERVO_Instance].TIM_Instance == TIM4)
{
__HAL_RCC_TIM4_CLK_ENABLE();
}
htim.Instance = SERVO_CfgParam[au16_SERVO_Instance].TIM_Instance;
htim.Init.Prescaler = PSC_Value;
htim.Init.CounterMode = TIM_COUNTERMODE_UP;
htim.Init.Period = ARR_Value;
htim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
HAL_TIM_Base_Init(&htim);
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
HAL_TIM_ConfigClockSource(&htim, &sClockSourceConfig);
HAL_TIM_PWM_Init(&htim);
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim, &sMasterConfig);
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_PWM_ConfigChannel(&htim, &sConfigOC, SERVO_CfgParam[au16_SERVO_Instance].PWM_TIM_CH);
/*--------[ Calculate & Save The Servo Pulse Information ]-------*/
gs_SERVO_info[au16_SERVO_Instance].Period_Min = (uint16_t) (ARR_Value * (SERVO_CfgParam[au16_SERVO_Instance].MinPulse/20.0));
gs_SERVO_info[au16_SERVO_Instance].Period_Max = (uint16_t) (ARR_Value * (SERVO_CfgParam[au16_SERVO_Instance].MaxPulse/20.0));
/*--------[ Start The PWM Channel ]-------*/
HAL_TIM_PWM_Start(&htim, SERVO_CfgParam[au16_SERVO_Instance].PWM_TIM_CH);
}
Moving the servo
/* Moves A Specific Motor To A Specific Degree That Can Be Float Number */
void SERVO_MoveTo(uint16_t au16_SERVO_Instance, float af_Angle)
{
uint16_t au16_Pulse = 0;
au16_Pulse = ((af_Angle*(gs_SERVO_info[au16_SERVO_Instance].Period_Max - gs_SERVO_info[au16_SERVO_Instance].Period_Min))/180.0)
+ gs_SERVO_info[au16_SERVO_Instance].Period_Min;
*(SERVO_CfgParam[au16_SERVO_Instance].TIM_CCRx) = au16_Pulse;
}
GPIO and timer intitializations
/**
* #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_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, LD1_Pin|LD3_Pin|LD2_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(USB_PowerSwitchOn_GPIO_Port, USB_PowerSwitchOn_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin : USER_Btn_Pin */
GPIO_InitStruct.Pin = USER_Btn_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(USER_Btn_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : RMII_MDC_Pin RMII_RXD0_Pin RMII_RXD1_Pin */
GPIO_InitStruct.Pin = RMII_MDC_Pin|RMII_RXD0_Pin|RMII_RXD1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pins : RMII_REF_CLK_Pin RMII_MDIO_Pin RMII_CRS_DV_Pin */
GPIO_InitStruct.Pin = RMII_REF_CLK_Pin|RMII_MDIO_Pin|RMII_CRS_DV_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pins : LD1_Pin LD3_Pin LD2_Pin */
GPIO_InitStruct.Pin = LD1_Pin|LD3_Pin|LD2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pin : RMII_TXD1_Pin */
GPIO_InitStruct.Pin = RMII_TXD1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
HAL_GPIO_Init(RMII_TXD1_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : USB_PowerSwitchOn_Pin */
GPIO_InitStruct.Pin = USB_PowerSwitchOn_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(USB_PowerSwitchOn_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : USB_OverCurrent_Pin */
GPIO_InitStruct.Pin = USB_OverCurrent_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(USB_OverCurrent_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : RMII_TX_EN_Pin RMII_TXD0_Pin */
GPIO_InitStruct.Pin = RMII_TX_EN_Pin|RMII_TXD0_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
}
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 = 65535;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_OnePulse_Init(&htim1, TIM_OPMODE_SINGLE) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
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_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
{
Error_Handler();
}
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 0;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.BreakFilter = 0;
sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;
sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;
sBreakDeadTimeConfig.Break2Filter = 0;
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);
}
/**
* #brief TIM2 Initialization Function
* #param None
* #retval None
*/
static void MX_TIM2_Init(void)
{
/* USER CODE BEGIN TIM2_Init 0 */
/* USER CODE END TIM2_Init 0 */
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
/* USER CODE BEGIN TIM2_Init 1 */
/* USER CODE END TIM2_Init 1 */
htim2.Instance = TIM2;
htim2.Init.Prescaler = 0;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 65535;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM2_Init 2 */
/* USER CODE END TIM2_Init 2 */
HAL_TIM_MspPostInit(&htim2);
}
/**
* #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_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 = 0;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 65535;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
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 = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM3_Init 2 */
/* USER CODE END TIM3_Init 2 */
HAL_TIM_MspPostInit(&htim3);
}
/**
* #brief TIM4 Initialization Function
* #param None
* #retval None
*/
static void MX_TIM4_Init(void)
{
/* USER CODE BEGIN TIM4_Init 0 */
/* USER CODE END TIM4_Init 0 */
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
/* USER CODE BEGIN TIM4_Init 1 */
/* USER CODE END TIM4_Init 1 */
htim4.Instance = TIM4;
htim4.Init.Prescaler = 0;
htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
htim4.Init.Period = 65535;
htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_PWM_Init(&htim4) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM4_Init 2 */
/* USER CODE END TIM4_Init 2 */
HAL_TIM_MspPostInit(&htim4);
}
Let me know if there is any more information that you need.
I think your problem might be due to the alternate function mapping. The F767 datasheet has a table on p.89 listing what values you should put into the GPIOn.AFR registers (GPIO_InitStruct.Alternate in the HAL - I assume) to get the right peripheral on the pin. It looks like your timer channels for those pins are all AF1, and you haven't defined which AF to use in your SERVO_Init routine. It's probably a good idea to fill in every member of the struct, even if you think it's unnecessary, just to make sure you don't miss anything deceptively important.
I am having a strange problem. I have a board with 2 UART interfaces (STM32F217) and I am using DMA to receive the data on both UARTs (USART1 and USART2).
USART2 works perfectly. I can send and receive data through it no problem, but I am having a problem with USART1. It only works properly the first transfer. If it just worked once and then stopped then I'd be ok, since it probably means that I just need to add the function for USART1 interruption and call its IRQHandler But my problem is that the next times it receives the data, but it drops the first few bytes (randomly ... sometimes drops 2 sometimes drops up to 6 bytes and it's not like it's a fast protocol, it has a 1s timeout).
Here is my workflow:
- Initialize UART;
Call Receive_DMA;
Protocol has variable size, it depends on the first bytes so I configured a fixed 256 circular receive transfer (maximum size for header + data) and check how many bytes have been received so far, if the amount matches the first byte then it's ok.
After error (did not receive entire packet, wrong CRC or timeout) or success then call
HAL_UART_DMAStop(&huart1);
and then
if(HAL_UART_Receive_DMA(&huart1, rx232buffer, 256) != HAL_OK) {
while(1);
}
This is done for both UARTs and one works perfectly and the other works well the first time and then starts dropping bytes.
Any idea of what could be the problem?
EDIT
Here's a version of my code. I wrote the functionality just now (inside main loop ... it's not exactly that but it works similar to that ... my code is kinda big and with many things not related to the communication so I just rewrote it like this ... as stated huart1 only works properly once and then drops bytes ... huart2 works fine .. huart1 is RS232 ... huart2 i RS485)
static void rxbuffer[256] = {0};
static void rx232buffer[256] = {0};
struct header {
int startWord;
int command;
int size;
};
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart1_rx;
DMA_HandleTypeDef hdma_usart1_tx;
DMA_HandleTypeDef hdma_usart2_rx;
DMA_HandleTypeDef hdma_usart2_tx;
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA2_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Stream5_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
/* DMA1_Stream6_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream6_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream6_IRQn);
/* DMA2_Stream2_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
/* DMA2_Stream7_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Stream7_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn);
}
static void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 57600;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
static void MX_USART2_UART_Init(void)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = 57600;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
int main(void)
{
int bytecount;
int bytecount232;
int rxlen485;
int rxlen232;
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
MX_USART2_UART_Init();
if(HAL_UART_Receive_DMA(&huart2, rxbuffer, 256) != HAL_OK) {
while(1);
}
if(HAL_UART_Receive_DMA(&huart1, rx232buffer, 256) != HAL_OK) {
while(1);
}
while(1) {
bytecount = __HAL_DMA_GET_COUNTER(&hdma_usart2_rx);
rxlen485 = 256 - bytecount;
bytecount232 = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
rxlen232 = 256 - bytecount232;
if(rxlen485 >= sizeof(struct header)) {
//start timer
struct header *pHeader = rxbuffer;
if(pHeader->size == rxlen485 - sizeof(struct header)) {
//do something
HAL_UART_DMAStop(&huart2);
if(HAL_UART_Receive_DMA(&huart2, rxbuffer, 256) != HAL_OK) {
while(1);
}
if(timeout) { // purely demonstrative ... the timeout part
//do something
HAL_UART_DMAStop(&huart2);
if(HAL_UART_Receive_DMA(&huart2, rxbuffer, 256) != HAL_OK) {
while(1);
}
}
}
if(rxlen232 >= sizeof(struct header)) {
struct header *pHeader = rxbuffer;
if(pHeader->size == rxlen232 - sizeof(struct header)) {
//do something
HAL_UART_DMAStop(&huart1);
if(HAL_UART_Receive_DMA(&huart1, rx232buffer, 256) != HAL_OK) {
while(1);
}
if(timeout) { // purely demonstrative ... the timeout part
//do something
HAL_UART_DMAStop(&huart1);
if(HAL_UART_Receive_DMA(&huart1, rx232buffer, 256) != HAL_OK) {
while(1);
}
}
}
}
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
__NOP();
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
__NOP();
}
void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart2);
/* USER CODE BEGIN USART2_IRQn 1 */
/* USER CODE END USART2_IRQn 1 */
}
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART2_IRQn 1 */
/* USER CODE END USART2_IRQn 1 */
}
//----- in another file--------
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(huart->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspInit 0 */
/* USER CODE END USART1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
PA11 ------> USART1_CTS
PA12 ------> USART1_RTS
*/
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART1 DMA Init */
/* USART1_RX Init */
hdma_usart1_rx.Instance = DMA2_Stream2;
hdma_usart1_rx.Init.Channel = DMA_CHANNEL_4;
hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_rx.Init.Mode = DMA_CIRCULAR;
hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
__HAL_LINKDMA(huart,hdmarx,hdma_usart1_rx);
/* USART1_TX Init */
hdma_usart1_tx.Instance = DMA2_Stream7;
hdma_usart1_tx.Init.Channel = DMA_CHANNEL_4;
hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_tx.Init.Mode = DMA_NORMAL;
hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
__HAL_LINKDMA(huart,hdmatx,hdma_usart1_tx);
/* USER CODE BEGIN USART1_MspInit 1 */
/* USER CODE END USART1_MspInit 1 */
}
else if(huart->Instance==USART2)
{
/* USER CODE BEGIN USART2_MspInit 0 */
/* USER CODE END USART2_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_USART2_CLK_ENABLE();
/**USART2 GPIO Configuration
PD5 ------> USART2_TX
PD6 ------> USART2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* USART2 DMA Init */
/* USART2_RX Init */
hdma_usart2_rx.Instance = DMA1_Stream5;
hdma_usart2_rx.Init.Channel = DMA_CHANNEL_4;
hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_rx.Init.Mode = DMA_CIRCULAR;
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart2_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
__HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);
/* USART2_TX Init */
hdma_usart2_tx.Instance = DMA1_Stream6;
hdma_usart2_tx.Init.Channel = DMA_CHANNEL_4;
hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_tx.Init.Mode = DMA_NORMAL;
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart2_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart2_tx) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
__HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);
HAL_NVIC_SetPriority(USART2_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
}
}
I have got a problem with the development of a i2c communication between a ATMega328 and a STM32 F302R8 controller.
Below the initialisation code of the st controller, generated by Cube.
void MX_I2C2_Init(void) {
hi2c2.Instance = I2C2;
hi2c2.Init.Timing = 0x2000090E;
hi2c2.Init.OwnAddress1 = 0;
hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c2.Init.OwnAddress2 = 0;
hi2c2.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c2) != HAL_OK) {
_Error_Handler(__FILE__, __LINE__);
}
/**Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE)
!= HAL_OK) {
_Error_Handler(__FILE__, __LINE__);
}
/**Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK) {
_Error_Handler(__FILE__, __LINE__);
}
HAL_I2C_MspInit(&hi2c2);
}
void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle) {
GPIO_InitTypeDef GPIO_InitStruct;
if (i2cHandle->Instance == I2C2) {
/* USER CODE BEGIN I2C2_MspInit 0 */
/* USER CODE END I2C2_MspInit 0 */
/**I2C2 GPIO Configuration
PA9 ------> I2C2_SCL
PA10 ------> I2C2_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* I2C2 clock enable */
__HAL_RCC_I2C2_CLK_ENABLE()
;
/* USER CODE BEGIN I2C2_MspInit 1 */
/* USER CODE END I2C2_MspInit 1 */
}
}
I added the HAL_I2C_MspInit(&hi2c2); call for setting the pins in the right mode.
The Function SerialMain part of a thread and will be called regularly.
void SerialMain(void const* arg) {
MX_USART1_UART_Init();
MX_I2C2_Init();
char *buffer = "Hello World! ";
int cnt = 0;
for (;;) {
cnt++;
if (HAL_I2C_Master_Transmit(&hi2c2, 8 , buffer, 13, 1000) != HAL_OK) { //PA9 SCL PA10 SDA
SerialError();
}
if (HAL_I2C_Master_Transmit(&hi2c2, 8 >> 1, &cnt, sizeof(cnt), 1000)
!= HAL_OK) { //PA9 SCL PA10 SDA
SerialError();
}
osDelay(10);
}
}
After trying to transmit the Hello World message the HAL_I2C_Master_Transmit will return HAL_TIMEOUT.
Does someone know why it returns HAL_TIMEOUT?
Does someone know how to transmit data successfully?
I'm trying to do a kind of "terminal" interaction with my STM32L476.
First of all I want to do a direct echo, when I recive data send it back for the same UART.
After, I want to put the echo in a task.
Question:
I'm implementing a hard-real time OS and want to leave UART operations to IDLE task, or very low priority task.
Is this a good way of doing things?
I can print using:
void uartPrint(UART_HandleTypeDef *huart, char _out[]){
HAL_UART_Transmit_DMA(huart, (uint8_t *) _out, strlen(_out));
}
But I don't receive, or the HAL_UART_RxCpltCallbackis not called never.
main.c
/
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32l4xx_hal.h"
#include "cmsis_os.h"
#include "dma.h"
#include "usart.h"
#include "spi.h"
#include "tim.h"
#include "gpio.h"
#include "display.h"
SPI_HandleTypeDef hspi1;
UART_HandleTypeDef hlpuart1;
uint8_t rxData;
void SystemClock_Config(void);
void MX_FREERTOS_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_LPUART1_UART_Init();
MX_SPI2_Init();
MX_TIM15_Init();
MX_FREERTOS_Init();
osKernelStart();
while (1){
}
}
/** System Clock Configuration*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit;
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLN = 20;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**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_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LPUART1;
PeriphClkInit.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure the main internal regulator output voltage
*/
if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure the Systick interrupt time
*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
/**Configure the Systick
*/
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 15, 0);
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM1) {
HAL_IncTick();
}
}
void _Error_Handler(char * file, int line)
{
while(1)
{
}
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
{
}
#endif
usart.c
#include "usart.h"
#include "gpio.h"
#include "dma.h"
/* USER CODE BEGIN 0 */
#include "cmsis_os.h"
#include "string.h"
uint8_t Uart1RxBuf [UART3_RX_TRAMA_LONG];
uint8_t RxBuffer;
uint8_t rxData;
/* USER CODE END 0 */
UART_HandleTypeDef hlpuart1;
DMA_HandleTypeDef hdma_lpuart_rx;
DMA_HandleTypeDef hdma_lpuart_tx;
/* LPUART1 init function */
void MX_LPUART1_UART_Init(void)
{
hlpuart1.Instance = LPUART1;
hlpuart1.Init.BaudRate = 115200;
hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;
hlpuart1.Init.StopBits = UART_STOPBITS_1;
hlpuart1.Init.Parity = UART_PARITY_NONE;
hlpuart1.Init.Mode = UART_MODE_TX_RX;
hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&hlpuart1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(uartHandle->Instance==LPUART1)
{
__HAL_RCC_LPUART1_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_LPUART1;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
hdma_lpuart_rx.Instance = DMA2_Channel7;
hdma_lpuart_rx.Init.Request = DMA_REQUEST_4;
hdma_lpuart_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_lpuart_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_lpuart_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_lpuart_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_lpuart_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_lpuart_rx.Init.Mode = DMA_NORMAL;
hdma_lpuart_rx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_lpuart_rx) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
__HAL_LINKDMA(uartHandle,hdmarx,hdma_lpuart_rx);
/* LPUART_TX Init */
hdma_lpuart_tx.Instance = DMA2_Channel6;
hdma_lpuart_tx.Init.Request = DMA_REQUEST_4;
hdma_lpuart_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_lpuart_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_lpuart_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_lpuart_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_lpuart_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_lpuart_tx.Init.Mode = DMA_NORMAL;
hdma_lpuart_tx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_lpuart_tx) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
__HAL_LINKDMA(uartHandle,hdmatx,hdma_lpuart_tx);
/* LPUART1 interrupt Init */
HAL_NVIC_SetPriority(LPUART1_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(LPUART1_IRQn);
/* USER CODE BEGIN LPUART1_MspInit 1 */
uartTaskStatus = INIT;
HAL_UART_Receive_DMA(&hlpuart1,&rxData,1);
/* USER CODE END LPUART1_MspInit 1 */
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
if(uartHandle->Instance==LPUART1)
{
__HAL_RCC_LPUART1_CLK_DISABLE();
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_0|GPIO_PIN_1);
HAL_DMA_DeInit(uartHandle->hdmarx);
HAL_DMA_DeInit(uartHandle->hdmatx);
HAL_NVIC_DisableIRQ(LPUART1_IRQn);
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
if(UartHandle -> Instance == hlpuart1.Instance){
HAL_UART_Transmit_DMA(&hlpuart1,&rxData,1);
}
}
void uartPrint(UART_HandleTypeDef *huart, char _out[]){
HAL_UART_Transmit_DMA(huart, (uint8_t *) _out, strlen(_out));
}
void UartTask(void const *argument){
char inBuffer[8];
for(;;){
switch(uartTaskStatus){
case ERR:
break;
case INIT:
uartPrint(&hlpuart1,"Uart Init: \r\n");
uartTaskStatus = READ;
break;
case READ:
break;
}
osDelay(100);
}
}
I'm not using yet the uart task, but here is where I create the task at freertos.c
osThreadDef(uartTask, UartTask, osPriorityNormal, 0, 128);
uartTaskHandle = osThreadCreate(osThread(uartTask), NULL);
The Uart Init: appears on my terminal.
When I debug, program never reaches the HAL_UART_RxCpltCallback.
Thanks!
EDIT 1:
DMA init!
void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA2_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel5_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);
/* DMA2_Channel6_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Channel6_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA2_Channel6_IRQn);
/* DMA2_Channel7_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Channel7_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA2_Channel7_IRQn);
}