But what is your overall program flow?
With repect to
the actual programming of a function, subroutine etc. is a minor detail.
For the architecture it is important to know and/or define the flow of the data from the source (analog input) to the output (e.g. digital display) as well as to define the required data structures (e.g. how are you going to represent the input data and output data within the computer's memory?).
Also considerations like e.g.:
- Is data going to be copied between routines or are pointers (addresses) used? Both of which have advantages and disadvantages.
- Does the data qcquissition have to be continuous or can it be intermittently? Continuous operation will require additional buffering to be able to store new data without overwriting old data which is still being processed.
If you want help in programming the peripheral components of the stm32f429i, that's not architecture. You will find lots of sample code by Googling with the right keywords.
Currently I do not have time to learn about programming or the architecture of it as due to the timing given to complete the project all i can do is learn a few basics and try to implement it.
I am now trying to trigger ADC conversion using timer 2 every 125us and also to feed the data into DAC as i want to check if the ADC waveform is the same as the signal input. However there i an error in getting the DAC signal as the oscilloscope does not display the signal.
Below shows the code that i used:
#include "main.h"
#include "stlogo.h"
/** @addtogroup STM32F4xx_HAL_Examples
* @{
*/
/** @addtogroup BSP
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static uint8_t DemoIndex = 0;
#ifdef EE_M24LR64
uint8_t NbLoop = 1;
#endif /* EE_M24LR64 */
__IO uint8_t ubKeyPressed = RESET;
BSP_DemoTypedef BSP_examples[] = {
{ Touchscreen_demo, "TOUCHSCREEN", 0 },
{ LCD_demo, "LCD", 0 },
{ Log_demo, "LCD LOG", 0 },
{ MEMS_demo, "MEMS", 0 },
#ifdef EE_M24LR64
{ EEPROM_demo, "EEPROM", 0},
#endif /* EE_M24LR64 */
};
TIM_HandleTypeDef timhandle;
ADC_HandleTypeDef adchandle;
DAC_HandleTypeDef dachandle;
DMA_HandleTypeDef dmahandle;
uint32_t AdcBuf[ADC_BUFFER_LENGTH];
/* Private function prototypes -----------------------------------------------*/
static void SystemClock_Config(void);
void ADC_IRQHandler(void);
static void Error_Handler(void);
static void Init_Timer(void);
static void Init_ADC(void);
static void Init_DAC(void);
static void Init_DMA(void);
static void Init_LCD(void);
/* Private functions ---------------------------------------------------------*/
static void Init_Timer()
{
__TIM2_CLK_ENABLE();
timhandle.Instance = TIM2;
timhandle.Init.Prescaler = 0;
timhandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
timhandle.Init.Period = HAL_RCC_GetHCLKFreq() / (2*ADC_BUFFER_LENGTH);
timhandle.Init.CounterMode = TIM_COUNTERMODE_UP;
timhandle.Init.RepetitionCounter = 0;
HAL_TIM_Base_Init(&timhandle);
TIM_MasterConfigTypeDef masterConfig;
masterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
masterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&timhandle, &masterConfig);
}
static void Init_ADC(void)
{
__GPIOB_CLK_ENABLE();
GPIO_InitTypeDef gpioInit;
gpioInit.Pin = GPIO_PIN_0;
gpioInit.Mode = GPIO_MODE_ANALOG;
gpioInit.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &gpioInit);
HAL_NVIC_SetPriority(ADC_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC_IRQn);
__ADC1_CLK_ENABLE();
adchandle.Instance = ADC1;
adchandle.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2;
adchandle.Init.Resolution = ADC_RESOLUTION_12B;
adchandle.Init.ScanConvMode = DISABLE;
adchandle.Init.ContinuousConvMode = DISABLE;
adchandle.Init.DiscontinuousConvMode = DISABLE;
adchandle.Init.NbrOfDiscConversion = 0;
adchandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
adchandle.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T2_TRGO;
adchandle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
adchandle.Init.NbrOfConversion = 1;
adchandle.Init.DMAContinuousRequests = ENABLE;
adchandle.Init.EOCSelection = ADC_EOC_SINGLE_CONV; //DISABLE;
if (HAL_ADC_Init(&adchandle) != HAL_OK)
{
Error_Handler();
}
/*##-2- Configure ADC regular channel ######################################*/
/* Note: Considering IT occurring after each number of size of */
/* "uhADCxConvertedValue" ADC conversions (IT by DMA end */
/* of transfer), select sampling time and ADC clock with sufficient */
/* duration to not create an overhead situation in IRQHandler. */
ADC_ChannelConfTypeDef sAdcConfig;
sAdcConfig.Channel = ADC_CHANNEL_8;
sAdcConfig.Rank = 1;
sAdcConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
sAdcConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&adchandle, &sAdcConfig) != HAL_OK)
{
/* Channel Configuration Error */
Error_Handler();
}
}
static void Init_DAC(void)
{
__GPIOA_CLK_ENABLE();
GPIO_InitTypeDef gpioInit;
gpioInit.Pin = GPIO_PIN_4;
gpioInit.Mode = GPIO_MODE_ANALOG;
gpioInit.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &gpioInit);
__DAC_CLK_ENABLE();
dachandle.Instance = DAC;
if (HAL_DAC_Init(&dachandle) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
DAC_ChannelConfTypeDef sDacConfig;
sDacConfig.DAC_Trigger = DAC_TRIGGER_NONE;
sDacConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
if (HAL_DAC_ConfigChannel(&dachandle, &sDacConfig, DAC_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
}
static void Init_DMA(void)
{
__DMA2_CLK_ENABLE();
dmahandle.Instance = DMA2_Stream4;
dmahandle.Init.Channel = DMA_CHANNEL_0;
dmahandle.Init.Direction = DMA_PERIPH_TO_MEMORY;
dmahandle.Init.PeriphInc = DMA_PINC_DISABLE;
dmahandle.Init.MemInc = DMA_MINC_ENABLE;
dmahandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
dmahandle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
dmahandle.Init.Mode = DMA_CIRCULAR;
dmahandle.Init.Priority = DMA_PRIORITY_HIGH;
dmahandle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
dmahandle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
dmahandle.Init.MemBurst = DMA_MBURST_SINGLE;
dmahandle.Init.PeriphBurst = DMA_PBURST_SINGLE;
HAL_DMA_Init(&dmahandle);
__HAL_LINKDMA(&adchandle, DMA_Handle, dmahandle);
HAL_NVIC_SetPriority(DMA2_Stream4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream4_IRQn);
}
static void Init_LCD(void)
{
BSP_LCD_Init();
BSP_LCD_Clear(LCD_COLOR_WHITE);
BSP_LCD_SetTextColor(LCD_COLOR_BLUE);
BSP_LCD_DrawRect(20, 20, 320, 200 );
}
static void Error_Handler(void)
{
/* Turn LED5 on */
while (1)
{
}
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* padchandle)
{
uint32_t adc_value = HAL_ADC_GetValue(&adchandle);
__HAL_ADC_DISABLE_IT(&adchandle, ADC_IT_EOC);
HAL_DAC_SetValue(&dachandle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, adc_value);
static unsigned int index = 0;
AdcBuf[index] = adc_value;
index++;
if (index >= ADC_BUFFER_LENGTH)
{
index = 0;
}
if (index != 0) return;
BSP_LCD_FillRect(21, 21, 318, 198 );
for (int i = 0; i < 319; i++)
{
unsigned long y1 = 0, y2 = 0;
for (int j = i*25; j < (i+1)*25; j++)
{
y1 += AdcBuf[j];
y2 += AdcBuf[j+25];
}
y1 /= 512;
y2 /= 512;
BSP_LCD_DrawLine(20+i, y1, 20+i+1, y2);
}
}
void ADC_IRQHandler(void)
{
HAL_ADC_IRQHandler(&adchandle);
}
void DMA2_Stream4_IRQHandler()
{
HAL_DMA_IRQHandler(&dmahandle);
}
/**
* @brief Main program
* @param None
* @retval None
*/
int main(void)
{
HAL_Init();
SystemClock_Config();
BSP_LED_Init(LED3);
BSP_LED_Init(LED4);
Init_LCD();
Init_Timer();
Init_ADC();
Init_DAC();
Init_DMA();
HAL_ADC_Start_IT(&adchandle);
HAL_DAC_Start(&dachandle, DAC_CHANNEL_1);
HAL_TIM_Base_Start(&timhandle);
while (1)
{
}
return 0;
}
/**
* @brief System Clock Configuration
* The system Clock is configured as follow :
* System Clock source = PLL (HSE)
* SYSCLK(Hz) = 180000000
* HCLK(Hz) = 180000000
* AHB Prescaler = 1
* APB1 Prescaler = 4
* APB2 Prescaler = 2
* HSE Frequency(Hz) = 8000000
* PLL_M = 8
* PLL_N = 360
* PLL_P = 2
* PLL_Q = 7
* VDD(V) = 3.3
* Main regulator output voltage = Scale1 mode
* Flash Latency(WS) = 5
* @param None
* @retval None
*/
static void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
/* Enable Power Control clock */
__HAL_RCC_PWR_CLK_ENABLE()
;
/* The voltage scaling allows optimizing the power consumption when the device is
clocked below the maximum system frequency, to update the voltage scaling value
regarding system frequency refer to product datasheet. */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/* Enable HSE Oscillator and activate PLL with HSE as source */
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.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 360;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
/* Activate the Over-Drive mode */
HAL_PWREx_EnableOverDrive();
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
RCC_ClkInitStruct.ClockType =
(RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | 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;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
}
/**
* @brief Display main demo messages
* @param None
* @retval None
*/
static void Display_DemoDescription(void)
{
uint8_t desc[50];
/* Set LCD Foreground Layer */
BSP_LCD_SelectLayer(1);
BSP_LCD_SetFont(&LCD_DEFAULT_FONT);
/* Clear the LCD */
BSP_LCD_SetBackColor(LCD_COLOR_WHITE);
BSP_LCD_Clear(LCD_COLOR_WHITE);
/* Set the LCD Text Color */
BSP_LCD_SetTextColor(LCD_COLOR_DARKBLUE);
/* Display LCD messages */
BSP_LCD_DisplayStringAt(0, 10, (uint8_t*)"STM32F429I BSP", CENTER_MODE);
BSP_LCD_SetFont(&Font16);
BSP_LCD_DisplayStringAt(0, 35, (uint8_t*)"Drivers examples", CENTER_MODE);
/* Draw Bitmap */
BSP_LCD_DrawBitmap((BSP_LCD_GetXSize() - 80) / 2, 65, (uint8_t *)stlogo);
BSP_LCD_SetFont(&Font8);
BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 20, (uint8_t*)"Copyright (c) STMicroelectronics 2014", CENTER_MODE);
BSP_LCD_SetFont(&Font12);
BSP_LCD_SetTextColor(LCD_COLOR_BLUE);
BSP_LCD_FillRect(0, BSP_LCD_GetYSize() / 2 + 15, BSP_LCD_GetXSize(), 60);
BSP_LCD_SetTextColor(LCD_COLOR_WHITE);
BSP_LCD_SetBackColor(LCD_COLOR_BLUE);
BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() / 2 + 30, (uint8_t*)"Press USER Button to start:", CENTER_MODE);
sprintf((char *)desc, "%s example", BSP_examples[DemoIndex].DemoName);
BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() / 2 + 45, (uint8_t *)desc, CENTER_MODE);
}
/**
* @brief Check for user input
* @param None
* @retval Input state (1 : active / 0 : Inactive)
*/
uint8_t CheckForUserInput(void)
{
if (BSP_PB_GetState(BUTTON_KEY) == RESET)
{
while (BSP_PB_GetState(BUTTON_KEY) == RESET)
;
return 1;
}
return 0;
}
/**
* @brief Toggle LEDs
* @param None
* @retval None
*/
void Toggle_Leds(void)
{
static uint8_t ticks = 0;
if (ticks++ > 100)
{
BSP_LED_Toggle(LED3);
BSP_LED_Toggle(LED4);
ticks = 0;
}
}
/**
* @brief EXTI line detection callbacks.
* @param GPIO_Pin: Specifies the pins connected EXTI line
* @retval None
*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == KEY_BUTTON_PIN)
{
ubKeyPressed = SET;
}
}
#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 can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/