2019-09-29 09:56 AM
I have STM32F303CCTX custom board.
IO Pin PB8 has a timer that triggers a gpio high for 200us and resets for 300us. creates a 1.8KHz wave with about 35% duty using plain timer mode. Timer IRQ handler also fires the adc conversion on pin PB0.
It continuously keeps running with no values for over a minute. Then suddenly exits to second for loop with the scans(mostly invalid values).
main.c
#define ADC_ARRY_SIZE 30
uint16_t adc_vals[ADC_ARRY_SIZE] = {0};
uint16_t adc_val = 0;
uint32_t adc_zero_count = 0;
uint32_t index_no = 0;
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
adc_val = HAL_ADC_GetValue(&hadc3);
if((adc_val != 0) && (index_no < ADC_ARRY_SIZE))
adc_vals[index_no++] = adc_val;
else if(adc_val == 0)
adc_zero_count++;
}
void set_pwm2_duty(uint32_t duty_count)
{
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, duty_count);
}
int main(void)
{
adc_val = 0;
adc_zero_count = 0;
index_no = 0;
adc_buffer_full = false;
int i;
//Generated code begin
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC3_Init();
MX_TIM2_Init();
MX_TIM6_Init();
//generated code end
set_laser_pwm_duty(3000);
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOGPIOB, GPIO_PIN_8, GPIO_PIN_SET);
HAL_TIM_Base_Start_IT(&htim6);//start pulse timer
adc_trigger = true;
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(index_no >= 30)
break;
HAL_Delay(1);
}
HAL_TIM_Base_Stop(&htim6);//start blink timer
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);
HAL_ADC_Stop_IT(&hadc3);
for(i=0;i<ADC_ARRY_SIZE;i++)
ladc_vals[i] = adc_vals[i];
for(;;);
}
Solved! Go to Solution.
2019-10-22 06:36 PM
The issue in ADC setup. The sampling cycles were too low at 1.5 cycles. It needed at least 19 cycles to get a non zero value.
2019-09-29 10:07 AM
If index_no is modified in an interrupt you should define it as volatile.
2019-09-29 11:07 AM
How are we supposed to debug this?
It won't advance the pointer for an indeterminate time if the ADC returns zero.
How do you know these are invalid values? Do have some plot or independent capture of the signals you can align?
A more rational approach to this is to use DMA into the array, and trigger the ADC directly with the TIM
2019-09-30 09:19 AM
I did put break point on timer irq handler and it never fired. That seems to be the main issue.
As for debug, it's quite simple. The task is to get periodic adc samples which is where the timer comes to focus. You can attach a dc supply to a Single ended adc channel and set it up to give 10 mV at 25 mA.
2019-09-30 09:20 AM
Tried it. Same issue.
2019-09-30 09:26 AM
This assumes I'm interested in racking this up and testing it, the code's not even buildable.
My point would be to supply enough of your experimental data that one could look at what's happening from afar, and not have to repeat and understand observations I might not be able to reproduce in 2 minutes or less.
2019-09-30 10:52 AM
Here is a simple timer code where the callback doesnt work. Apparntly the IRQ handler in the stm32f3xx_it.c does get called. Most of it is system generated.
Main.c
Here is a simple timer code where the callback doesnt work. Apparntly the IRQ handler in the stm32f3xx_it.c does get called. Most of it is system generated.
main.c
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* 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 ---------------------------------------------------------*/
TIM_HandleTypeDef htim6;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM6_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void HAL_TIM_Period_ElapsedCallBack(TIM_HandleTypeDef *htim)
{
//if(htim != &htim6)
// return;
GPIO_PinState pulse_state;
pulse_state = HAL_GPIO_ReadPin(PULSE_GPIO_Port, PULSE_Pin);
if(pulse_state == GPIO_PIN_SET)
{
HAL_GPIO_WritePin(PULSE_GPIO_Port, PULSE_Pin, GPIO_PIN_RESET);
__HAL_TIM_SET_AUTORELOAD(&htim6, 2560);
}
else
{
HAL_GPIO_WritePin(PULSE_GPIO_Port, PULSE_Pin, GPIO_PIN_SET);
__HAL_TIM_SET_AUTORELOAD(&htim6, 1430);
}
HAL_TIM_Base_Start_IT(&htim6);
}
/* 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_TIM6_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim6);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* 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};
/** 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_MUL3;
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();
}
}
/**
* @brief TIM6 Initialization Function
* @param None
* @retval None
*/
static void MX_TIM6_Init(void)
{
/* USER CODE BEGIN TIM6_Init 0 */
/* USER CODE END TIM6_Init 0 */
TIM_MasterConfigTypeDef sMasterConfig = {0};
/* USER CODE BEGIN TIM6_Init 1 */
/* USER CODE END TIM6_Init 1 */
htim6.Instance = TIM6;
htim6.Init.Prescaler = 9;
htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
htim6.Init.Period = 1439;
htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM6_Init 2 */
/* USER CODE END TIM6_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_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5|PULSE_Pin, GPIO_PIN_RESET);
/*Configure GPIO pins : PB5 PULSE_Pin */
GPIO_InitStruct.Pin = GPIO_PIN_5|PULSE_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);
}
/* 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(char *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 */
main.h
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32f3xx_hal.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
/* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions prototypes ---------------------------------------------*/
void Error_Handler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */
/* Private defines -----------------------------------------------------------*/
#define PULSE_Pin GPIO_PIN_8
#define PULSE_GPIO_Port GPIOB
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
#ifdef __cplusplus
}
#endif
#endif /* __MAIN_H */
2019-09-30 10:54 AM
2019-09-30 11:20 AM
2019-10-22 06:36 PM
The issue in ADC setup. The sampling cycles were too low at 1.5 cycles. It needed at least 19 cycles to get a non zero value.