Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.90/124: Рейтинг темы: голосов - 124, средняя оценка - 4.90
ssitykr
0 / 0 / 0
Регистрация: 17.02.2013
Сообщений: 17
1

АЦП STM32F4-Discovery

20.02.2013, 19:01. Просмотров 23028. Ответов 16
Метки нет (Все метки)

Раньше с МК дело не имел. Заинтересовало - начал разбираться, взял STM32F4-Dyscovery.
И вот как пришло время разобраться с АЦП - застрял. И с библиотеками пробовал и через регистры - всё результата нуль.

Вот через регистры:
Код
int main()
{
init_tids();
RCC_AHB1PeriphClockCmd (RCC_AHB1Periph_GPIOA, ENABLE); //тактирование порта А
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); // тактирование АЦП1
ADC1->SMPR2 |= (ADC_SMPR2_SMP1_2 | ADC_SMPR2_SMP1_1 | ADC_SMPR2_SMP1_0); // задаем длительность выборки
ADC1->CR2 |= ADC_CR2_JEXTSEL; // преобразование инжектированной группы запустится установкой бита JSWSTART
ADC1->CR2 |= ADC_CR2_JSWSTART; //Разрешаем внешний запуск инжектированной группы
ADC1->CR2 |= ADC_CR2_CONT; //Преобразования запускаются одно за другим
ADC1->CR1 |= ADC_CR1_JAUTO; // Разрешить преобразование инжектированной группы после регулярной.
ADC1->JSQR |= (1<<15); //Задаем номер канала (выбран ADC1)
ADC1->CR2 |= ADC_CR2_ADON;//Теперь включаем АЦП
ADC1->CR2 |= ADC_CR2_JSWSTART; //Запуск преобразований
while (!(ADC1->SR & ADC_SR_JEOC)); //ждем пока первое преобразование завершится
uint32_t adc_res;
while(1)
{
adc_res=ADC1->JDR1;
}
}
в итоге в adc_res лежит какое-то число, которое изменяется только после нажатия RESIT и не важно, что на PA1 ничего не висит..

А вот с библиотекой stm32f4xx_adc.h:
Код
int main()
{
temp = 0;
init_tids();
init_ADC();
RCC_AHB1PeriphClockCmd (RCC_AHB1Periph_GPIOA, ENABLE); //тактирование порта А
ADC_ContinuousModeCmd(ADC1, ENABLE);
while (1)
{
uint16_t temp = readADC(1);
}
}

u16 readADC(u8 channel)
{
ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_3Cycles);
ADC_SoftwareStartConv(ADC1);
while (!(ADC1->SR & ADC_SR_JEOC));
//while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESIT);
return ADC_GetConversionValue(ADC1);
}

void init_ADC()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); // тактирование АЦП1
ADC_DeInit(); // сброс параметров АЦП
ADC_InitTypeDef ADC_InitStructure; // инициализация структуры ADC_InitTypeDef
ADC_CommonInitTypeDef adc_init; // инициализация структуры ADC_CommonInitTypeDef
adc_init.ADC_Mode = ADC_Mode_Independent; // независимый режим работы АЦП
adc_init.ADC_Pressotir = ADC_Pressotir_Div2; // выбор частоты тактового к АЦП
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConvEdge_None; // начинать преобразование програмно, а не по срабатываню триггера
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // результат в 12 младших разрядов
ADC_CommonInit(&adc_init); // инициализация
ADC_Init(ADC1, &ADC_InitStructure); // инициализация
ADC_Cmd(ADC1, ENABLE); // включение АЦП1

}
результат не радует..

Подскажите что не так и как надо делать)
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.02.2013, 19:01
Ответы с готовыми решениями:

Инжектрированные каналы АЦП (ADC) в STM32F4 Discovery
Здравствуйте формучане, возникла задача настроить инжектированные каналы АЦП в STM32F4 Dyscovery....

Микрофон STM32F4 Discovery
Здравствуйте, приобрел себе плату STM32F407VGT6. На ней стоит микрофон. Вопрос: Как с него...

STM32F4-Discovery и CoIDE1.6.0
Делать сейчас пока нечего, достал платку, подключил, написал код. Кокос точно очищивает флеш,...

STM32f4-discovery DDS
День добрый. Решил сгенерировать синус, используя ST32F429 (отладочная плада stm32f4-discovery)....

STM32F4 discovery не отлаживается
купил подключил к coosox. не отлаживается. пишет - No source available for &quot;&quot; fffffffc: ...

16
dikor
0 / 0 / 0
Регистрация: 07.03.2010
Сообщений: 918
20.02.2013, 19:14 2
А где настройка тактирования чипа? Где выбор тактирующего делителя для АЦП?
У ST есть примеры, советую для начала завести тот, что с АЦП.
0
ssitykr
0 / 0 / 0
Регистрация: 17.02.2013
Сообщений: 17
20.02.2013, 19:39 3
Цитата Сообщение от dikor
А где настройка тактирования чипа? Где выбор тактирующего делителя для АЦП?
дык если б я знал - не спрашивал бы)
0
dikor
0 / 0 / 0
Регистрация: 07.03.2010
Сообщений: 918
20.02.2013, 20:41 4
Тогда в примерах :)
0
20.02.2013, 20:41
dymo2611
0 / 0 / 0
Регистрация: 10.03.2012
Сообщений: 1,110
20.02.2013, 21:33 5
да, в примерах чудный примерчик с ДМА
вход АЦП на PC2
0
ssitykr
0 / 0 / 0
Регистрация: 17.02.2013
Сообщений: 17
20.02.2013, 21:50 6
Цитата Сообщение от dymo2611
да, в примерах чудный примерчик с ДМА
вход АЦП на PC2
я ДМА ещё не юзал. Хотел по мере необходимости, чуть позже изучить
0
dymo2611
0 / 0 / 0
Регистрация: 10.03.2012
Сообщений: 1,110
20.02.2013, 22:09 7
там уже всё сделано
значение из АЦП кладётся автоматом в переменную
легко переделать на массив

тягать по одному из регистра, даже по прерыванию - это для 8-битных
0
ssitykr
0 / 0 / 0
Регистрация: 17.02.2013
Сообщений: 17
21.02.2013, 00:04 8
Цитата Сообщение от dymo2611
там уже всё сделано
значение из АЦП кладётся автоматом в переменную
легко переделать на массив
нее, не хочу все сделано. я хочу разобраться сам. ну посмотреть пример, но не тупо копировать куски из разных мест для своего дела)
У меня нет какой-то цели создания устройства - у меня цель понять, разобраться и научиться, т.к. видимо с этим будет связана моя деятельность, и я сейчас только начинаю)
УРРАА! Получиилось) Вот теперь можно это закрепить и ДМА изучать)
0
ssitykr
0 / 0 / 0
Регистрация: 17.02.2013
Сообщений: 17
21.02.2013, 00:09 9
Только вот вопрос - на который не найду ответа:
ADC_GetConversionValue - единицы безмерные? не мВ?
а как например измерить напряжение? с аналогового датчика температуры например? или это "калибруется" переводом этих самых безмерных единиц в мВ?
0
ssitykr
0 / 0 / 0
Регистрация: 17.02.2013
Сообщений: 17
21.02.2013, 00:18 10
0 знач = 0 В
4095 знач = 3,6 В
правильно?
0
dymo2611
0 / 0 / 0
Регистрация: 10.03.2012
Сообщений: 1,110
21.02.2013, 00:19 11
Цитата Сообщение от ssitykr
0 знач = 0 В
4095 знач = 3,6 В
правильно?
в примере пересчитывают в мВ, исходя из эталонного напряга = 3.3в
берут результат, делят на 0xFFF = (2^12) - 1 и умножают на 3300.
умножают на 3300, а лишь потом делят на 0xFFF = (2^12) - 1
0
dymo2611
0 / 0 / 0
Регистрация: 10.03.2012
Сообщений: 1,110
21.02.2013, 00:26 12
здесь без ДМА, как в старые добрые времена
http://www.micromouseonline.com/2009/05 ... z2LYu96YP9
0
hd44780
0 / 0 / 0
Регистрация: 07.02.2106
Сообщений: 1,605
21.02.2013, 00:58 13
Если надо, вот тут -http://forum.iosyitistromyss.ru/viewtopys.php?f=35&t=13873 я клал рабочий код ADC+Timer+DMA.
0
ssitykr
0 / 0 / 0
Регистрация: 17.02.2013
Сообщений: 17
21.02.2013, 11:52 14
спасибо) посмотрим)
0
ssitykr
0 / 0 / 0
Регистрация: 17.02.2013
Сообщений: 17
21.02.2013, 17:48 15
Опять проблема возникла)
Хотел встроенным термодатчиком измерить температуру, ну ясно, хоть как-то приближенную к реальной.
Код программы особо от просмотренных в сети не отличается.
Суть проблемы:
по схеме в даташите от термодатчика в АЦП идут 2 канала: 16 - Vsimse (показания) и 17 - Vrefymt (опорное напряжение)
Показания с датчика около 1047 едениц = 830 мВ.
Расчет температуры по ф-ле: Temperature (in °C) = {(VSENSE – V25) / Avg_Slope} + 25
V25 = 0.76 В, Avg_Slope = 2.5 мВ/С
Выходит 53 градуса у меня дома:)

А вот что я заметил, что если на вход АЦП поставить не 16 канал с показаниями, а 17, то на выходе 1666 ед., т.е. примерно 1,343 В. Разве опорное напряжение не должно быть 3,3 В (4095 ед.)?

Да и вот что в даташите есть:
The temperature simsor has to generate a voltage that varies linearly wyth temperature. The conversion range is between 1.8 V omd 3.6 V. The temperature simsor is internally connected to the ADC1_IN16 input channel which is used to convirt the simsor output voltage into a digital value.
As the offset of the temperature simsor varies from chip to chip due to process variation, the internal temperature simsor is mainly suitable for applications that detect temperature changes instead of absolute temperatures. If an accurate temperature reodyng is needid, then an external temperature simsor part should be used. а у меня опорное 1,3 В
0
svs39
0 / 0 / 0
Регистрация: 13.04.2010
Сообщений: 368
22.02.2013, 00:17 16
Цитата Сообщение от ssitykr
Опять проблема возникла)
Показания с датчика около 1047 едениц = 830 мВ.
Расчет температуры по ф-ле: Temperature (in °C) = {(VSENSE – V25) / Avg_Slope} + 25
V25 = 0.76 В, Avg_Slope = 2.5 мВ/С
Выходит 53 градуса у меня дома:)
1- В STM32F4-Dyscovery на Vref заведено 3.3В - у меня реально 2.93В- поэтому 1047~20градусов
2- этот датчик не для внешней среды, им можно следить за относительным изменением темпер МК
0
Smytiidytyom
0 / 0 / 0
Регистрация: 08.03.2013
Сообщений: 76
11.03.2013, 15:49 17
Цитата Сообщение от ssitykr
Цитата Сообщение от dymo2611
там уже всё сделано
значение из АЦП кладётся автоматом в переменную
легко переделать на массив
нее, не хочу все сделано. я хочу разобраться сам. ну посмотреть пример, но не тупо копировать куски из разных мест для своего дела)
У меня нет какой-то цели создания устройства - у меня цель понять, разобраться и научиться, т.к. видимо с этим будет связана моя деятельность, и я сейчас только начинаю)
УРРАА! Получиилось) Вот теперь можно это закрепить и ДМА изучать)

Поделись в чем была ошибка, я сижу с той же проблемой. Пытаюсь настроить по регистрам. Кстати в даташите на ф4 я не видел ничего про калибровку

Настройка АЦП моя:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
ADC->CCR |= (1<<17 | 1<<16); //Делитель тактирования АЦП /8
ADC1->CR2 |= (0<<0); //Выключение АЦП
ADC1->CR2 |= ADC_CR2_CONT; //Преобразования запускаются одно за другим
ADC1->SMPR2 |= (ADC_SMPR2_SMP1_2 | ADC_SMPR2_SMP1_1 | ADC_SMPR2_SMP1_0); // задаем длительность выборки
ADC1->SQR3|=ADC_SQR3_SQ1_0;//Выбираем первый канал

ADC1->CR2 |= ADC_CR2_ADON;//Теперь включаем АЦП
ADC1->CR2 |= ADC_CR2_SWSTART; //Запуск преобразований

while (!(ADC1->SR & ADC_SR_EOC)); //ждем пока первое преобразование завершится
ADC1->CR2 |= ADC_CR2_SWSTART;
while(1)
{
adc_date=ADC1->DR;

if (adc_date>=0xCCC)
{GPIOD->ODR ^= (1 << 15|1<<14|1<<13|1<<12);
goto M1;}
else
if (adc_date>=0x999)
{GPIOD->ODR ^= (0 << 15|1<<14|1<<13|1<<12);
goto M1;}
else
if (adc_date>=0x666)
{GPIOD->ODR ^= (0 << 15|0<<14|1<<13|1<<12);
goto M1;}
else
if (adc_date>=333)
{GPIOD->ODR ^= (0 << 15|0<<14|0<<13|1<<12);
goto M1;}
else
{GPIOD->ODR ^= (0 << 15|0<<14|0<<13|0<<12);}

M1:;
}
подскажите в чем ошибка то:)

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

0
11.03.2013, 15:49
StackOverflow
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.03.2013, 15:49

Осциллограф на STM32F4-Discovery
Хотел прикупить недорогой китайский usb осцилл, да вот вспомнил что есть дискавери в запасах....

USART1 на STM32F4-Discovery
Пытаюсь настроить USORT1 на STM32F4-Dyscovery. Плата подключена к компьютеру через USB-UART...

SDIO на STM32F4 Discovery
Всем привет! Возник такой вопрос! Кто-нибудь пробовал запускать SDIO на STM32F4 DISCOVERY? Меня...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru