Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F10x Внутренний датчик температуры
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
bullit
Добрый день!
Процессор STM32F103c8t6.
Столкнулся с проблемой что по 16 каналу (TempSense) ADC1 значение не меняется, как процек не грей!
Код инициализации:
CODE
RCC_ADCCLKConfig(RCC_PCLK2_Div4);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 , ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);

// Enable ADC1 reset calibration register
ADC_ResetCalibration(ADC1 );
// Check the end of ADC1 reset calibration register
while (ADC_GetResetCalibrationStatus(ADC1 ));

// Start ADC1 calibration
ADC_StartCalibration(ADC1 );
// Check the end of ADC1 calibration
while (ADC_GetCalibrationStatus(ADC1 ));

ADC_InitTypeDef ADC_InitStructure;
/* ADC1 configuration ------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);

ADC_TempSensorVrefintCmd(ENABLE);
/* ADC1 regular channels configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_239Cycles5 );

ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);

NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 7;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);


Код запуска конвертирования (запускаем раз в секунду):
Код
ADC_SoftwareStartConvCmd(ADC1, ENABLE);

Код прерывания:
Код
adcdata = ADC_GetConversionValue(ADC1);
adcVolt  = adcdata*3.3/4096;
diffVolt =   0.76 - adcVolt;
temp1  = diffVolt / (2.5/1000);//0.00025;
temp2 = temp1 +25;
ADC_ClearITPendingBit(ADC1, ADC_IT_EOC );


adcdata постоянно равен 1738 +/- 10 едениц. Код тестировался на 2-3 процеках значения теже. Явно в коде, но что не пойму!
nx6310
Попробуй калибровку АЦП сделать после её инициализации. Еще в даташите написано что время конвертирования должно быть 17,1 мкs (Select a sample time of 17.1 µs)
_basile
А накрен его вообще использовать?
Для измерения мощности, потребляемой кристаллом?
Я, конечно, "сильно извиняюсь", но ARM - все же не MSP430.

Цитата(nx6310 @ Jan 10 2013, 12:39) *
Попробуй калибровку АЦП сделать после её инициализации. Еще в даташите написано что время конвертирования должно быть 17,1 мкs (Select a sample time of 17.1 µs)
Tahoe
Цитата(_basile @ Jan 10 2013, 22:05) *
А накрен его вообще использовать? Для измерения мощности, потребляемой кристаллом?

Ну вот у меня прям сейчас пример есть. STM32 рулит драйвером BLDC, точность в 1 градус не требуется, но знать, пусть примерно, температуру девайса в целом, полезно. А нагрев, в основном, будет идти именно от драйвера. Так что не стОит делать умозаключения, не подумав. wink.gif
bullit
Плотность электроники очень большая, закрытый корпус.
На других платах с мк F4 температуру показывает до 65 гр. Ц.

Перепроверил все настройки, менял местами калибровку- не помогает.

nx6310
Тактирование Альтернативных функций включено?

Попробуй
Код
ADC_TempSensorVrefintCmd(ENABLE);и ADC_Cmd(ADC1, ENABLE);

поставить после
Код
ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_239Cycles5 );
bullit
Нет, не помогло.
Не понятно еще насчёт калибровки: страница 215 рефмануал на 101-107 серию (CD00171190)
Цитата
Before starting a calibration the ADC must have been in power-off state (ADON bit = ‘0’) for at least two ADC clock cycles.

Не понятно нужно калибровку проводить в выключенном состоянии или просто выключить АЦП на время 2 клоков, затем снова включить.
Если просто выключить - то калибровка не проходит, естесно.

А вообще вопрос назревает: а кто нибудь измерял температуру кристалла внутренним датчиком температуры?
nx6310
Я включаю термодатчик, потом включаю АЦП. потом калибрую.

Код
RCC->APB2ENR |= RCC_APB2Periph_ADC1;
ADC1->SQR1|=0x200000; //3 канала
ADC1->SQR3|=(16<<10)+(9<<5)+8;// 1-й замер 8-й канал, 2- замер 9 канал, 3 замер-16 канал температуры
ADC1->SMPR1|=6<<18;// 16 канал замер 71,5 циклов
ADC1->SMPR2|=0x2d<<24;// каналы 8 и 9 7,5 циклов
ADC1->CR1|=0x100; //включение skan mode
ADC1->CR2|=0x009E0100; //включение термодатчика и DMA
ADC1->CR2|=1;//включение АЦП
ADC1->CR2|=8; //сброс калибровок
while(ADC1->CR2&8);// ожидание сброса калибр. регистров
ADC1->CR2|=4; //начало калибровки
while(ADC1->CR2&4);// ожидание конца калибровки
ADC1->CR2&=~1;//выключение АЦП
RCC->APB2ENR &= ~RCC_APB2Periph_ADC1;
bullit
Заработало! Будем выяснять почему до неработало!
nx6310
обязательно напиши причину wink.gif
bullit
ну что тут сказать... дело было не в бабине....)
Из-за не внимательности коэффициенты для расчёта температуры стояли от F4 серии (они отличаются). Отсюда и все непонятки появлялись!
Выкладываю код в окончательном виде (для f10x и f4xx):
CODE
#if defined (STM32F10X_LD) || defined (STM32F10X_LD_VL) || defined (STM32F10X_MD) ||
defined (STM32F10X_MD_VL) || defined (STM32F10X_HD) || defined (STM32F10X_CL)

RCC_ADCCLKConfig(RCC_PCLK2_Div4);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 , ENABLE);

ADC_InitTypeDef ADC_InitStructure;
//ADC1 configuration ------------------------------------------------------
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);


// ADC1 regular channels configuration
ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_239Cycles5 );
ADC_TempSensorVrefintCmd(ENABLE);


// Enable ADC1
ADC_Cmd(ADC1, ENABLE);


// Enable ADC1 reset calibration register
ADC_ResetCalibration(ADC1 );
// Check the end of ADC1 reset calibration register
while (ADC_GetResetCalibrationStatus(ADC1 ));

// Start ADC1 calibration
ADC_StartCalibration(ADC1 );
// Check the end of ADC1 calibration
while (ADC_GetCalibrationStatus(ADC1 ));

/* ADC3 regular channel12 configuration *************************************/
//ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_3Cycles );

ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);

NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);

#else
#ifdef STM32F4XX

ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

/* ADC Common Init **********************************************************/
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div8;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);

/* ADC3 Init ****************************************************************/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);

/* ADC3 regular channel12 configuration *************************************/
ADC_RegularChannelConfig(ADC1, ADC_Channel_TempSensor, 1, ADC_SampleTime_3Cycles );

ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);

NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

/* Enable ADC3 */
ADC_Cmd(ADC1, ENABLE);

// разрешение прерывания по завершению преобразования
ADC_RegularChannelConfig(ADC1, ADC_Channel_TempSensor, 1, ADC_SampleTime_480Cycles);

ADC_TempSensorVrefintCmd(ENABLE);
#else
#error *** Не выбран процессор ***
#endif
#endif


Обработчик прерывания:
CODE
#if defined (STM32F10X_LD) || defined (STM32F10X_LD_VL) || defined (STM32F10X_MD) || defined (STM32F10X_MD_VL) ||
defined (STM32F10X_HD) || defined (STM32F10X_CL)
float tempera2;
void ADC1_2_IRQHandler(void)
{
adcdata = ADC_GetConversionValue(ADC1 );
tempera2 = (1.43 - adcdata * 0.00080586) / 0.0043 + 25;

CPUTempSense = 25+(1775 - adcdata )*18736/100000;

ADC_ClearITPendingBit(ADC1, ADC_IT_EOC );
}

#else
#ifdef STM32F4XX

void ADC_IRQHandler(void)
{
adcdata = ADC1 ->DR;
CPUTempSense = 25 + (adcdata - 943) * 3223 / 10000;
ADC_ClearITPendingBit(ADC1, ADC_IT_EOC );
}
#else
#error *** Не выбран процессор ***
#endif
#endif


PS читайте даташиты внимательней меньше будет проблем))
Всем спасибо!
nx6310
TEMP_STM=((1.43-(ADC[temp]*0.00080566))/0.0043)+25;
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.