AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR... |
23.01.2013, 14:04
|
|
Почётный гражданин KAZUS.RU
Регистрация: 26.11.2011
Адрес: Анапа
Сообщений: 1,620
Сказал спасибо: 284
Сказали Спасибо 129 раз(а) в 111 сообщении(ях)
|
xmega чтение температурного сенсора
Пытался осилить по даташитам и апноутам - не смог, нагуглил и дополнил (чтобы совсем не юзать атмеловские драйвера) такой вот код
Код:
|
//Чтение температуры и сенсоров
uint8_t ReadCalibrationByte( uint8_t index )
{
uint8_t result;
/* Load the NVM Command register to read the calibration row. */
NVM_CMD = NVM_CMD_READ_CALIB_ROW_gc;
result = pgm_read_byte(index);
/* Clean up NVM Command register. */
NVM_CMD = NVM_CMD_NO_OPERATION_gc;
return( result );
}
int32_t ReadECUtemp(void)
{
int32_t degrees_x10;
float kelvin_per_adc_x10;
uint8_t reff;
reff = ReadCalibrationByte( offsetof(NVM_PROD_SIGNATURES_t, TEMPSENSE0) );
reff = reff + (ReadCalibrationByte( offsetof(NVM_PROD_SIGNATURES_t, TEMPSENSE1)) ‹‹8);
kelvin_per_adc_x10 = ((273 + 85)*10) / (float)reff; // reference is ADC reading at 85C, scaled by 10 to get units of 0.1C
ADCA.CALL = ReadCalibrationByte( offsetof(NVM_PROD_SIGNATURES_t, ADCACAL0) );
ADCA.CALH = ReadCalibrationByte( offsetof(NVM_PROD_SIGNATURES_t, ADCACAL1) );
ADCA.CTRLB = ADC_RESOLUTION_12BIT_gc; // 12 bit conversion
ADCA.REFCTRL = ADC_REFSEL_INT1V_gc | ADC_TEMPREF_bm; // internal 1V bandgap reference + Temp Sensor enable
ADCA.PRESCALER = ADC_PRESCALER_DIV256_gc; // peripheral clk/256 (32MHz/256=125kHz)
ADCA.CH1.CTRL = ADC_CH_INPUTMODE_INTERNAL_gc | ADC_CH_GAIN_1X_gc; // Internal Temp Sensor
ADCA.CH1.MUXCTRL = ADC_CH_MUXINT_TEMP_gc;
ADCA.CTRLA |= ADC_ENABLE_bm;// enable adc
ADCA_CTRLA |= ADC_CH1START_bm; // Start conversion
while ((ADCA.CH1.INTFLAGS & 0x01) != 0x01);
degrees_x10 = ADCA.CH1.RES;
degrees_x10 *= kelvin_per_adc_x10;
degrees_x10 -= 2730;
return (degrees_x10);
} |
Он в комнатной температуре возвращает значения около 32XXX, оно плавает слегка. В принципе, похоже на правду, но хотелось бы как то проверить.. как?
|
|
|
|
23.01.2013, 15:38
|
|
Почётный гражданин KAZUS.RU
Регистрация: 26.11.2011
Адрес: Анапа
Сообщений: 1,620
Сказал спасибо: 284
Сказали Спасибо 129 раз(а) в 111 сообщении(ях)
|
Re: xmega чтение температурного сенсора
Ну, почти тот же вопрос. Выяснить через ADC напряжение на пине относительно GND и внутреннего 1v опорного.
Код:
|
float Result;
ADCA.CALL = ReadCalibrationByte( offsetof(NVM_PROD_SIGNATURES_t, ADCACAL0) );
ADCA.CALH = ReadCalibrationByte( offsetof(NVM_PROD_SIGNATURES_t, ADCACAL1) );
ADCA.CTRLA |= ADC_ENABLE_bm;// enable adc
ADCA.CTRLB = ADC_RESOLUTION_12BIT_gc; // 12 bit conversion
ADCA.REFCTRL = ADC_REFSEL_VCC_gc; //1.6v internal vcc
ADCA.PRESCALER = ADC_PRESCALER_DIV128_gc; // peripheral clk/128 (32MHz/128=250kHz)
ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc; // single ended
//выбор пина
switch (_ch)
{
case 0:
ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN0_gc;
break;
case 1:
ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN1_gc;
break;
case 2:
ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN2_gc;
break;
case 3:
ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN3_gc;
break;
case 4:
ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN4_gc;
break;
}
ADCA.CH0.CTRL |= ADC_CH_START_bm;
while(!(ADCA.CH0.INTFLAGS));
Result = ADCA.CH0.RES;
ADCA.CTRLA &= ~ADC_ENABLE_bm;// disable adc
return (Result * 16 / 4096); |
Запрашиваю пин PA1. На нем, да и на остальных по расчетам 5-9 в, прыгает местами. остальные висят в воздухе, но на PA1 напряжение фиксированное.
Ориентируюсь на опорное 1.6в (написано в описании к дефайну - интернал 1.6в вцц)
Где я ошибся?
|
|
|
|
23.01.2013, 15:44
|
|
Почётный гражданин KAZUS.RU
Регистрация: 20.03.2007
Адрес: "Братское кольцо враждебности", т.е. ближайшее заМКАДье.
Сообщений: 6,789
Сказал спасибо: 2,912
Сказали Спасибо 3,120 раз(а) в 2,111 сообщении(ях)
|
Re: xmega чтение температурного сенсора
Сообщение от whoim
|
Он в комнатной температуре возвращает значения около 32XXX, оно плавает слегка. В принципе, похоже на правду, но хотелось бы как то проверить.. как?
|
Поставьте на чип кружку (с плоским дном) с горячей водой или с тающим льдом.
Сообщение от whoim
|
Запрашиваю пин PA1. На нем, да и на остальных по расчетам 5-9 в, прыгает местами. остальные висят в воздухе, но на PA1 напряжение фиксированное.
|
Вопрос непонятен, а выделенное жирным - просто бред. Оно не должно быть выше питания (3.6 В макс.) больше чем на 0.2-0.3 вольта.
Последний раз редактировалось ForcePoint; 23.01.2013 в 18:08.
Причина: Орфография
|
|
|
|
24.01.2013, 09:39
|
|
Почётный гражданин KAZUS.RU
Регистрация: 26.11.2011
Адрес: Анапа
Сообщений: 1,620
Сказал спасибо: 284
Сказали Спасибо 129 раз(а) в 111 сообщении(ях)
|
Re: xmega чтение температурного сенсора
ForcePoint, это в перерасчете на резисторы и битность
а сравнивание идет с опорным 1.6в
в общем - что то тут не так а что именно не могу понять, вроде все верно..
|
|
|
|
24.01.2013, 09:40
|
|
Почётный гражданин KAZUS.RU
Регистрация: 26.11.2011
Адрес: Анапа
Сообщений: 1,620
Сказал спасибо: 284
Сказали Спасибо 129 раз(а) в 111 сообщении(ях)
|
Re: xmega чтение температурного сенсора
ADC_CH_INPUTMODE_SINGLEENDED_gc;
я правильно понимаю, что этот параметр - без усилений, измерение на пине относительно GND МК?
Код:
|
/* Input mode */
typedef enum ADC_CH_INPUTMODE_enum
{
ADC_CH_INPUTMODE_INTERNAL_gc = (0x00‹‹0), /* Internal inputs, no gain */
ADC_CH_INPUTMODE_SINGLEENDED_gc = (0x01‹‹0), /* Single-ended input, no gain */
ADC_CH_INPUTMODE_DIFF_gc = (0x02‹‹0), /* Differential input, no gain */
ADC_CH_INPUTMODE_DIFFWGAIN_gc = (0x03‹‹0), /* Differential input, with gain */
} ADC_CH_INPUTMODE_t; |
Последний раз редактировалось whoim; 24.01.2013 в 10:14.
|
|
|
|
24.01.2013, 10:16
|
|
Почётный гражданин KAZUS.RU
Регистрация: 26.11.2011
Адрес: Анапа
Сообщений: 1,620
Сказал спасибо: 284
Сказали Спасибо 129 раз(а) в 111 сообщении(ях)
|
Re: xmega чтение температурного сенсора
Фишка еще в одном. Поставил подряд несколько вызовов ADC с разных каналов и следом же температуру. Она стала прыгать...
|
|
|
|
24.01.2013, 10:50
|
|
Почётный гражданин KAZUS.RU
Регистрация: 26.11.2011
Адрес: Анапа
Сообщений: 1,620
Сказал спасибо: 284
Сказали Спасибо 129 раз(а) в 111 сообщении(ях)
|
Re: xmega чтение температурного сенсора
Возвращает прыгающий бред и по температурному сенсору. Ничего не понимаю. Все что изменилось - 1.1в пришло на PA1.
Вот тот же код для вычисления температуры:
Код:
|
//Чтение температуры и сенсоров
uint8_t ReadCalibrationByte( uint8_t index )
{
uint8_t result;
/* Load the NVM Command register to read the calibration row. */
NVM_CMD = NVM_CMD_READ_CALIB_ROW_gc;
result = pgm_read_byte(index);
/* Clean up NVM Command register. */
NVM_CMD = NVM_CMD_NO_OPERATION_gc;
return( result );
}
int16_t ReadECUtemp(void)
{
int16_t degrees_x10;
float kelvin_per_adc_x10;
uint8_t reff;
reff = ReadCalibrationByte( offsetof(NVM_PROD_SIGNATURES_t, TEMPSENSE0) );
reff = reff + (ReadCalibrationByte( offsetof(NVM_PROD_SIGNATURES_t, TEMPSENSE1)) ‹‹8);
kelvin_per_adc_x10 = ((273 + 85)*10) / (float)reff; // reference is ADC reading at 85C, scaled by 10 to get units of 0.1C
ADCA.CTRLA |= ADC_ENABLE_bm;// enable adc
ADCA.CALL = ReadCalibrationByte( offsetof(NVM_PROD_SIGNATURES_t, ADCACAL0) );
ADCA.CALH = ReadCalibrationByte( offsetof(NVM_PROD_SIGNATURES_t, ADCACAL1) );
ADCA.CTRLB = ADC_RESOLUTION_12BIT_gc; // 12 bit conversion
ADCA.REFCTRL = ADC_REFSEL_INT1V_gc | ADC_TEMPREF_bm; // internal 1V bandgap reference + Temp Sensor enable
ADCA.PRESCALER = ADC_PRESCALER_DIV256_gc; // peripheral clk/256 (32MHz/256=125kHz)
ADCA.CH1.CTRL = ADC_CH_INPUTMODE_INTERNAL_gc | ADC_CH_GAIN_1X_gc; // Internal Temp Sensor
ADCA.CH1.MUXCTRL = ADC_CH_MUXINT_TEMP_gc;
ADCA_CTRLA |= ADC_CH1START_bm; // Start conversion
while ((ADCA.CH1.INTFLAGS & 0x01) != 0x01);
degrees_x10 = ADCA.CH1.RES;
degrees_x10 *= kelvin_per_adc_x10;
degrees_x10 -= 2730;
return (degrees_x10);
} |
Что не так???
|
|
|
|
24.01.2013, 12:16
|
|
Почётный гражданин KAZUS.RU
Регистрация: 10.05.2003
Адрес: Москва
Сообщений: 2,528
Сказал спасибо: 737
Сказали Спасибо 1,927 раз(а) в 799 сообщении(ях)
|
Re: xmega чтение температурного сенсора
Сообщение от whoim
|
Она стала прыгать
|
Читайте на тему "Медианный фильтр" и "фильтр Гаусса"
алгоритм реализации в инете есть.
__________________
Опыт - это школа, в которой человек узнает, каким дураком он был раньше.
|
|
|
|
24.01.2013, 12:25
|
|
Почётный гражданин KAZUS.RU
Регистрация: 26.11.2011
Адрес: Анапа
Сообщений: 1,620
Сказал спасибо: 284
Сказали Спасибо 129 раз(а) в 111 сообщении(ях)
|
Re: xmega чтение температурного сенсора
get_ADC завелось верно. Нужно очищать флаг прерывания после конвертации
Цитата:
|
while(!(ADCA.CH0.INTFLAGS));
ADCA.CH0.INTFLAGS=ADC_CH_CHIF_bm;
|
также ADC_REFSEL_VCC_gc означает VCC/1.6 = 2.06v в моем случае.
Температура по прежнему скачет от 0 до 65500 ))
|
|
|
|
24.01.2013, 12:26
|
|
Почётный гражданин KAZUS.RU
Регистрация: 26.11.2011
Адрес: Анапа
Сообщений: 1,620
Сказал спасибо: 284
Сказали Спасибо 129 раз(а) в 111 сообщении(ях)
|
Re: xmega чтение температурного сенсора
DK,
Сообщение от whoim
|
Температура по прежнему скачет от 0 до 65500 ))
|
так что..
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 01:05.
|
|