STM32F429 Discovery ADC (Analog to Digital Convertor)
Transcription
STM32F429 Discovery ADC (Analog to Digital Convertor)
NAME SURNAME: NUMBER: CEN 425 Embedded Systems STM32F429 Discovery ADC (Analog to Digital Convertor) In many embedded projects, we have to deal with signals directly from nature, like temperature, pressure, current. Theses signals are analog by default and in most of cases we use sensors that converts these analog signals to analog electrical voltage to be injected in the microcontroller to do some work. Unfortunately, microcontrollers are digital and just can't deal with analog signals so these signals must be converted again to digital signals that is comprehensible by the microcontroller. For this purpose, microcontroller's manufacturers usually incorporate an ADC into the microcontroller. ADC is actually stands for Analog to Digital Converter. This module is omnipresent in most of microcontrollers. ADC converts analog voltage to digital number, that can be used in microcontrollers. STM32F4xx MCUs have up to 3 ADCs of which every has 19 channels. 16 external channels, connected to IO pins 3 internal channels The 12-bit ADC is a successive approximation analog-to-digital converter. It has up to 19 multiplexed channels allowing it to measure signals from 16 external sources, two internal sources, and the VBAT channel. The A/D conversion of the channels can be performed in single, continuous, scan or discontinuous mode. The result of the ADC is stored into a left or right-aligned 16-bit data register. The analog watchdog feature allows the application to detect if the input voltage goes beyond the user-defined, higher or lower thresholds. ADC main features • 12-bit, 10-bit, 8-bit or 6-bit configurable resolution. • Interrupt generation at the end of conversion, end of injected conversion, and in case of analog watchdog or overrun events. • Single and continuous conversion modes. • Scan mode for automatic conversion of channel 0 to channel ‘n’. • Discontinuous mode. • Dual/Triple mode (on devices with 2 ADCs or more). • Configurable DMA data storage in Dual/Triple ADC mode. • Configurable delay between conversions in Dual/Triple interleaved mode • ADC conversion type (refer to the datasheets) • ADC supply requirements: 2.4 V to 3.6 V at full speed and down to 1.8 V at slower speed. • ADC input range: VREF– ≤ VIN ≤ VREF+. • DMA request generation during regular channel conversion. Now that we have the ADC configured, we need to read the temperature. For now we will just use the debugger to read the value of the sensor. But first we need to read the data then convert it to a temperature. To find the formula for the conversion of the data, we can look at the reference manual for the STM32F4. The formula is Temperature (in °C) = {(VSENSE – V25) / Avg_Slope} + 25 Where: V25 = VSENSE value for 25° C Avg_Slope = average slope of the temperature vs. VSENSE curve (given in mV/°C or μV/°C) Looking at the data sheet for the specific STM32F407VG processor the following values are found V25 = 0.76V = 760 mV. Avg_Slope = 2.5 mV/°C Read the conversion value Value and converted into voltage Vsense, Vsense = Value × 3300/4095 (mV). Temp = [( Vsense– 760) / 2500] + 25); ADC_InitTypeDef Struct Reference Data Fields FunctionalState uint32_t uint32_t uint32_t uint8_t uint32_t FunctionalState ADC_ContinuousConvMode ADC_DataAlign ADC_ExternalTrigConv ADC_ExternalTrigConvEdge ADC_NbrOfConversion ADC_Resolution ADC_ScanConvMode FunctionalState ADC_InitTypeDef::ADC_ContinuousConvMode Specifies whether the conversion is performed in Continuous or Single mode. This parameter can be set to ENABLE or DISABLE. uint32_t ADC_InitTypeDef::ADC_DataAlign Specifies whether the ADC data alignment is left or right. This parameter can be a value of ADC_data_align. uint32_t ADC_InitTypeDef::ADC_ExternalTrigConv Select the external event used to trigger the start of conversion of a regular group. This parameter can be a value of ADC_extrenal_trigger_sources_for_regular_channels_conversion. uint32_t ADC_InitTypeDef::ADC_ExternalTrigConvEdge Select the external trigger edge and enable the trigger of a regular group. This parameter can be a value of ADC_external_trigger_edge_for_regular_channels_conversion. uint8_t ADC_InitTypeDef::ADC_NbrOfConversion Specifies the number of ADC conversions that will be done using the sequencer for regular channel group. This parameter must range from 1 to 16. uint32_t ADC_InitTypeDef::ADC_Resolution Configures the ADC resolution dual mode. This parameter can be a value of ADC_resolution. 2 FunctionalState ADC_InitTypeDef::ADC_ScanConvMode Specifies whether the conversion is performed in Scan (multichannels) or Single (one channel) mode. This parameter can be set to ENABLE or DISABLE. void ADC_Init (ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct) Initializes the ADCx peripheral according to the specified parameters in the ADC_InitStruct. Note: This function is used to configure the global features of the ADC ( Resolution and Data Alignment), however, the rest of the configuration parameters are specific to the regular channels group (scan mode activation, continuous mode activation, External trigger source and edge, number of conversion in the regular channels group sequencer). Parameters: ADCx: Where x can be 1, 2 or 3 to select the ADC peripheral. ADC_InitStruct: Pointer to an ADC_InitTypeDef structure that contains the configuration information for the specified ADC peripheral. Return values: None. void ADC_Cmd (ADC_TypeDef* ADCx,FunctionalState NewState) Enables or disables the specified ADC peripheral. Parameters: ADCx: Where x can be 1, 2 or 3 to select the ADC peripheral. NewState: New state of the ADCx peripheral. This parameter can be: ENABLE or DISABLE. Return values: None. void ADC_TempSensorVrefintCmd (FunctionalState NewState) Enables or disables the temperature sensor and Vrefint channels. Parameters: NewState: New state of the temperature sensor and Vrefint channels. This parameter can be: ENABLE or DISABLE. Return values: None. void ADC_RegularChannelConfig (ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime) Configures for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. Parameters: ADCx: Where x can be 1, 2 or 3 to select the ADC peripheral. ADC_Channel: The ADC channel to configure. This parameter can be one of the following values: ADC_Channel_0: ADC Channel0 selected ADC_Channel_1: ADC Channel1 selected ADC_Channel_2: ADC Channel2 selected ADC_Channel_3: ADC Channel3 selected ADC_Channel_4: ADC Channel4 selected ADC_Channel_5: ADC Channel5 selected ADC_Channel_6: ADC Channel6 selected ADC_Channel_7: ADC Channel7 selected ADC_Channel_8: ADC Channel8 selected ADC_Channel_9: ADC Channel9 selected ADC_Channel_10: ADC Channel10 selected ADC_Channel_11: ADC Channel11 selected ADC_Channel_12: ADC Channel12 selected ADC_Channel_13: ADC Channel13 selected ADC_Channel_14: ADC Channel14 selected ADC_Channel_15: ADC Channel15 selected ADC_Channel_16: ADC Channel16 selected ADC_Channel_17: ADC Channel17 selected ADC_Channel_18: ADC Channel18 selected Rank: The rank in the regular group sequencer. This parameter must be between 1 to 16. ADC_SampleTime: The sample time value to be set for the selected channel. This parameter can be one of the following values: ADC_SampleTime_3Cycles: Sample time equal to 3 cycles ADC_SampleTime_15Cycles: Sample time equal to 15 cycles ADC_SampleTime_28Cycles: Sample time equal to 28 cycles ADC_SampleTime_56Cycles: Sample time equal to 56 cycles ADC_SampleTime_84Cycles: Sample time equal to 84 cycles ADC_SampleTime_112Cycles: Sample time equal to 112 cycles ADC_SampleTime_144Cycles: Sample time equal to 144 cycles ADC_SampleTime_480Cycles: Sample time equal to 480 cycles Return values: None. 3 void ADC_SoftwareStartConv (ADC_TypeDef* ADCx) Enables the selected ADC software start conversion of the regular channels. Parameters: ADCx: Where x can be 1, 2 or 3 to select the ADC peripheral. Return values: None. FlagStatus ADC_GetFlagStatus (ADC_TypeDef* ADCx, uint8_t ADC_FLAG) Checks whether the specified ADC flag is set or not. Parameters: ADCx: Where x can be 1, 2 or 3 to select the ADC peripheral. ADC_FLAG: Specifies the flag to check. This parameter can be one of the following values: ADC_FLAG_AWD: Analog watchdog flag ADC_FLAG_EOC: End of conversion flag ADC_FLAG_JEOC: End of injected group conversion flag ADC_FLAG_JSTRT: Start of injected group conversion flag ADC_FLAG_STRT: Start of regular group conversion flag ADC_FLAG_OVR: Overrun flag Return values: The new state of ADC_FLAG (SET or RESET). uint16_t ADC_GetConversionValue (ADC_TypeDef* ADCx) Returns the last ADCx conversion result data for regular channel. Parameters: ADCx: Where x can be 1, 2 or 3 to select the ADC peripheral. Return values: The Data conversion value. 4 Laboratory Task: Write the required C program code given as below Connect 5 LEDs to the pins 11-12-13-14-15 of the port F of the STM32F429ZI Disco Board. Don’t forget the GND connection and resistors. Add the “Temperature” and “ADC1” variables to the watch window to observe the result. Examine the operation of your experimental setup. Note some values of “Temperature” (or ADC_TypeDef*) from watch window. After that change ADC_InitDef.ADC_DataAlign = ADC_DataAlign_Left; and observe and note the changes. Than, change ADC_InitDef.ADC_DataAlign = ADC_DataAlign_Left; and observe and note the changes. After recovering the change, observe the current “Temperature” value and using the given formulations calculate the measured temperature value. Write down your own observations. #include "stm32f4xx.h" #include "stm32f4xx_gpio.h" #include "stm32f4xx_rcc.h" #include "stm32f4xx_tim.h" #include "stm32f4xx_adc.h" GPIO_InitTypeDef GPIO_InitDef; //Structure for analog pin ADC_InitTypeDef ADC_InitDef; //Structure for ADC confguration void GPIO_Config() { //Clock configuration RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); GPIO_InitDef.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_InitDef.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitDef.GPIO_OType = GPIO_OType_PP; GPIO_Init(GPIOF, &GPIO_InitDef); } void ADC_Config() { //Clock configuration //The ADC1 is connected the APB2 peripheral bus RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //ADC structure configuration ADC_DeInit(); ADC_InitDef.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitDef.ADC_Resolution = ADC_Resolution_12b; ADC_InitDef.ADC_ContinuousConvMode = ENABLE; ADC_InitDef.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; ADC_InitDef.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_InitDef.ADC_NbrOfConversion = 1; 5 ADC_InitDef.ADC_ScanConvMode = DISABLE; ADC_Init(ADC1, &ADC_InitDef); //Initialize ADC with the previous configuration //Enable ADC conversion ADC_Cmd(ADC1, ENABLE); //Select the channel to be read from ADC_RegularChannelConfig(ADC1, ADC_Channel_17, 1, ADC_SampleTime_28Cycles); } void Delay(uint32_t nCount) { while(nCount--) { } } uint16_t readADC1(uint8_t channel) { ADC_SoftwareStartConv(ADC1); //Start the conversion while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); //Processing the conversion return ADC_GetConversionValue(ADC1); //Return the converted data } int main() { GPIO_Config(); ADC_Config(); ADC_TempSensorVrefintCmd(ENABLE); do { unsigned int Temperature = readADC1(17); if ( Temperature>500 ) { GPIO_SetBits(GPIOF, GPIO_Pin_11); } if ( Temperature>750 ) { GPIO_SetBits(GPIOF, GPIO_Pin_12); } if ( Temperature>1000 ) { GPIO_SetBits(GPIOF, GPIO_Pin_13); } if ( Temperature>1250) { GPIO_SetBits(GPIOF, GPIO_Pin_14); } if ( Temperature>1500) { GPIO_SetBits(GPIOF, GPIO_Pin_15); } Delay(1000000); } while (1); } 6