2022-11-03 01:45 AM
#include "main.h"
#define ADC_BUF_LEN 9000
uint8_t adc_buf[ADC_BUF_LEN];
uint8_t ch = 0;
ADC_HandleTypeDef hadc;
DMA_HandleTypeDef hdma_adc;
TIM_HandleTypeDef htim2;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_ADC_Init(void);
static void MX_TIM2_Init(void);
/* USER CODE BEGIN PFP */
static void ADC_Select_CH0 (void);
static void ADC_Select_CH4 (void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC_Init();
MX_TIM2_Init();
/* USER CODE BEGIN 2 */
HAL_ADC_Start_DMA(&hadc, (uint32_t*)adc_buf, ADC_BUF_LEN);
// start pwm generation
if(HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_4) != HAL_OK)
Error_Handler();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
}
static void MX_ADC_Init(void)
{
hadc.Instance = ADC1;
hadc.Init.OversamplingMode = DISABLE;
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
hadc.Init.Resolution = ADC_RESOLUTION_8B;
hadc.Init.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ContinuousConvMode = DISABLE;
hadc.Init.DiscontinuousConvMode = ENABLE;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
hadc.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T2_TRGO;
hadc.Init.DMAContinuousRequests = ENABLE;
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();
}
ADC_ChannelConfTypeDef sConfig = {0};
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
/**
* @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 = 4000;
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_UPDATE;
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_4) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM2_Init 2 */
/* USER CODE END TIM2_Init 2 */
}
/**
* 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);
}
void ADC_Select_CH0 (void)
{
ch =0;
ADC_ChannelConfTypeDef sConfig = {0};
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = ADC_RANK_NONE;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
if(HAL_ADCEx_Calibration_Start(&hadc, ADC_SINGLE_ENDED) != HAL_OK)
Error_Handler();
}
void ADC_Select_CH4 (void)
{
ch =4;
ADC_ChannelConfTypeDef sConfig = {0};
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_RANK_NONE;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
if(HAL_ADCEx_Calibration_Start(&hadc, ADC_SINGLE_ENDED) != HAL_OK)
Error_Handler();
}
void HAL_ADC_ConvHalfCpltCallback (ADC_HandleTypeDef * hadc){
}
void HAL_ADC_ConvCpltCallback (ADC_HandleTypeDef * hadc)
{
HAL_ADC_Stop_DMA(hadc);
// start pwm generation
if(HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_4) != HAL_OK)
Error_Handler();
uint16_t min = 4000;
uint16_t max = 0;
for (uint16_t i =0;i<1000;i++)
{
if (adc_buf[i] > max)
{
max = adc_buf[i];
}
else if (adc_buf[i] < min)
{
min = adc_buf[i];
}
}
if(max - min < 20 & ch == 0){ //320 20
ADC_Select_CH4();
}
else if(max - min > 237 & ch == 4){ //3800 237
ADC_Select_CH0();
}
else{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_14);
}
HAL_ADC_Start_DMA(hadc, (uint32_t*)adc_buf, ADC_BUF_LEN);
if(HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_4) != HAL_OK)
Error_Handler();
}
Board: B-L072Z-LRWAN ( STM32L072CZY)
I am trying to record audio at 8kHz with 8 bits (using DMA and timer2)
I use 2 amplifiers with different amplification connected too PA0 and PA4
PA4 (amplification 10x of PA0)
I am trying to set my ADC to sample channel 0 and if that value is to small switch to channel 4
The values i get from this code are incorrect, for debugging i tried setting the DMA to HALFWORD and the buffer to uint16_t and the values the ADC returned after switching ones to channel 4 became 12bit resolution
2022-11-03 06:05 AM
Cube is primarily intended to provide quick solution for typical problems, mainly through clicking in CubeMX. Whenever you try something the auhors did not deem typical, Cube gets into your way.
In other words, Cube is open source, you can try to find and fix the issue yourself primarily by reading out and checking the ADC registers content; or just throw it away and write it normally.
JW