// () PORTD_PIN1 GPIOD->MODER |= GPIO_MODER_MODER1_0; GPIOD->PUPDR |= GPIO_PUPDR_PUPDR1_0; GPIOD->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR1; // , 12 , 16- , 17 - VDDA, // 22 - , // , , , // EOC, EOC , http://chipspace.ru/stm32l-discovery-adc/ // 16() 17(vdda) // 22() , 2- vdda, 3- ADC1->CR2 |= (ADC_CR2_DELS_2 | ADC_CR2_CONT); ADC1->CR1 |= ADC_CR1_SCAN; // GPIOE.7 - GPIOE->MODER |= GPIO_MODER_MODER7; //3 ADC1->SQR1 |= ADC_SQR1_L_1; // ADC_IN 16 1 , 305 // ADC_IN 17 2 , 305 // ADC_IN 22 3 , 305 ADC1->SQR5 |= ADC_SQR5_SQ1_4 | ADC_SQR5_SQ2_0 | ADC_SQR5_SQ2_4 | ADC_SQR5_SQ3_1 | ADC_SQR5_SQ3_2 | ADC_SQR5_SQ3_4; // 16 17 22 301 279 ADC1->SMPR2 |= ADC_SMPR2_SMP16 | ADC_SMPR2_SMP17_2; ADC1->SMPR1 |= ADC_SMPR1_SMP22_2; // VDDA ADC->CCR |= ADC_CCR_TSVREFE; // DMA ADC1->CR2 |= (ADC_CR2_DMA | ADC_CR2_DDS); // DMA // - , . DMA1_Channel1->CCR &= ~DMA_CCR1_DIR; // . DMA1_Channel1->CCR &= ~DMA_CCR1_PINC; // . DMA1_Channel1->CCR |= DMA_CCR1_MINC; // - 16 . DMA1_Channel1->CCR |= DMA_CCR1_PSIZE_0; // - 16 DMA1_Channel1->CCR |= DMA_CCR1_MSIZE_0; // - (Very High) DMA1_Channel1->CCR |= DMA_CCR1_PL; DMA1_Channel1->CCR |= DMA_CCR1_CIRC;
#include "types.h" // #define SENSORTEMPERATURE_CHANNEL 0 #define VDDA_CHANNEL 1 #define TRIMMER_CHANNEL 2 class cAdc { public: explicit cAdc(const tU32 memoryBaseAddr, const tU8 measureCount); tBoolean switchOn(void); tBoolean startConversion(void); tBoolean isConversionReady(void); tF32 getValue(void) const; private: void initDma(const tU32 memoryBaseAddr, const tU8 measureCount); };
#include <stm32l1xx.h> // STM2 #include "adc.h" // #include "susuassert.h" //for ASSERT #include "bitutil.h" // SETBIT, CLRBIT #define ADC1_DR_ADDRESS ((tU32)0x40012458) /******************************************************************************* * Function: constructor * Description: DMA RAM, * ******************************************************************************/ cAdc::cAdc(const tU32 memoryBaseAddr, const tU8 measureCount) { ASSERT(measureCount != 0); this->initDma(memoryBaseAddr, measureCount); } /******************************************************************************* * Function: switchOn * Description: ******************************************************************************/ tBoolean cAdc::switchOn(void) { tBoolean result = FALSE; // , 299 CD00240194.pdf SETBIT(ADC1->CR2, ADC_CR2_ADON); result = tBoolean(CHECK_BIT_SET(ADC1->SR, ADC_SR_ADONS)); return result; } /******************************************************************************* * Function: startConversion() * Description: ******************************************************************************/ tBoolean cAdc::startConversion(void) { tBoolean result = FALSE; // , 299 CD00240194.pdf SETBIT(ADC1->CR2, ADC_CR2_SWSTART); result = tBoolean(CHECK_BIT_SET(ADC1->SR, ADC_SR_STRT)); return result; } /******************************************************************************* * Function: getValue() * Description: ******************************************************************************/ tF32 cAdc::getValue(void) const { tF32 result = ADC1->DR; return result; } /******************************************************************************* * Function: isConversionReady() * Description: ? ******************************************************************************/ tBoolean cAdc::isConversionReady(void) { tBoolean result = tBoolean(CHECK_BIT_SET(ADC1->SR, ADC_SR_EOC)); return result; } /******************************************************************************* * Function: initDma() * Description: DMA ******************************************************************************/ void cAdc::initDma(const tU32 memoryBaseAddr, const tU8 measureCount) { // - . DMA1_Channel1->CPAR = ADC1_DR_ADDRESS; // - RAM. DMA1_Channel1->CMAR = memoryBaseAddr; DMA1_Channel1->CNDTR = measureCount; // DMA SETBIT(DMA1_Channel1->CCR, DMA_CCR1_EN); }
#include "adc.h" // cAdc #define MEASUR_NUMBER (tU8) 3 class cAdcDirector { public: explicit cAdcDirector(void); void startConversion(void); __IO uint16_t channelValue[MEASUR_NUMBER]; // private: cAdc *pAdc; };
#include "adcdirector.h" // /******************************************************************************* * Function: constructor * Description: , RAM, * DMA . ******************************************************************************/ cAdcDirector::cAdcDirector(void) { this->pAdc = new cAdc((tU32)&channelValue[0], MEASUR_NUMBER); this->pAdc->switchOn(); } /******************************************************************************* * Function: startConversion * Description: , DMA * channelValue ******************************************************************************/ void cAdcDirector::startConversion(void) { this->pAdc->startConversion(); }
void main( void ) { // ButtonControllera // , . //, static tTaskHandle tasksToNotifyFromButton[BUTTON_TASKS_NOTYFIED_NUM]; cAdcDirector *pAdcDirector = new cAdcDirector(); pAdcDirector->startConversion(); cLedsDirector *pLedsDirector = new cLedsDirector(); oRTOS.taskCreate(pLedsDirector, LEDSDIRECTOR_STACK_SIZE, LEDSDIRECTOR_PRIORITY, "Leds"); tasksToNotifyFromButton[LEDS_TASK_HANDLE_INDEX] = pLedsDirector->taskHandle; cButtonsController *pButtonsController = new cButtonsController(tasksToNotifyFromButton, BUTTON_TASKS_NOTYFIED_NUM); oRTOS.taskCreate(pButtonsController, BUTTONSCONTROLLER_STACK_SIZE, BUTTONSCONTROLLER_PRIORITY, "Buttons"); oRTOS.startScheduler(); }
#include "types.h" // #include "adcdirector.h" // cAdcdirector class iVariable { public: explicit iVariable(const cAdcDirector *pAdcDirector); virtual tF32 calculate(void) = 0; tF32 getValue(void) const {return value;}; protected: const cAdcDirector *pAdcDirector; tF32 value; };
#include "ivariable.h" // #include "susuassert.h" // for ASSERT /******************************************************************************* * Function: constructor * Description: ******************************************************************************/ iVariable::iVariable(const cAdcDirector *pAdcDirector) { ASSERT(pAdcDirector != NULL); this->pAdcDirector = pAdcDirector; this->value = 0.0F; }
#include "types.h" // #include "adcdirector.h" // cAdcdirector #include "ifilter.h" // iFilter #include "iVariable.h" // iVariable class cTemperature : public iVariable, private iFilter { public: explicit cTemperature(cAdcDirector *pAdcDirector); tF32 calculate(void); };
#include "temperature.h" // // 110 - 30 ( ), 289 #define DELTA_110_30 80.0F // , 28 , 30 :) #define DEGREE_30 28.0F // 2 102 CD00277537.pdf #define TS_CAL2_ADDR 0x1FF8007C // 1 102 CD00277537.pdf #define TS_CAL1_ADDR 0x1FF8007A // VDDA 3.0 #define VDDA_CAL_ADDR 0x1FF80076 #define FILTER_CONST 20.0F /******************************************************************************* * Function: constructor * Description: ******************************************************************************/ cTemperature::cTemperature(cAdcDirector *pAdcDirector) : iVariable(pAdcDirector) { } /******************************************************************************* * Function: calculate * Description: ******************************************************************************/ tF32 cTemperature::calculate(void) { tF32 temperature = 0.0F; // tF32 vdda = 0.0F; // vdda // , 289 CD00240193.pdf // 102 CD00277537.pdf tF32 tsCal2 = (tF32)(*((tU32 *)(TS_CAL2_ADDR)) >> 16); tF32 tsCal1 = (tF32) (*((tU32 *)(TS_CAL1_ADDR ))); tF32 vddaCal = (tF32)(*((tU32 *)(VDDA_CAL_ADDR)) >> 16); temperature = (tF32)this->pAdcDirector->channelValue[SENSORTEMPERATURE_CHANNEL]; vdda = (tF32)this->pAdcDirector->channelValue[VDDA_CHANNEL]; // 3.0 VDDA, // vdda, // 289 CD00240193.pdf temperature = DELTA_110_30 * ((temperature * vddaCal)/vdda - tsCal1) / (tsCal2 - tsCal1) + DEGREE_30; this->value = this->filter(this->value, temperature, FILTER_CONST); return this->value; }
Source: https://habr.com/ru/post/261823/
All Articles