- Главная
- Форум
- Микроконтроллеры и Системы на Модуле (SOM)
- Микроконтроллеры
- ищу пример использования 4 и более канала ADC в stm32f105/107
- Форум
- Микроконтроллеры и Системы на Модуле (SOM)
- Микроконтроллеры
- ищу пример использования 4 и более канала ADC в stm32f105/107
ищу пример использования 4 и более канала ADC в stm32f105/107
- super_puper
- Автор темы
- Посетитель
11 года 6 мес. назад #4316
от super_puper
super_puper создал тему: ищу пример использования 4 и более канала ADC в stm32f105/107
нужно на стд перифе 3.5.0.
нашел пример но он видимо для другой линейки контролеров и на моем не работает у меня линейка CL а он обращается почему то к файлам другой линейки.. визуально заметил что в моих работающих примерах пишется "структуре" а тут "структ" пробовал заменить не помогло.
RCC_ADCCLKConfig(RCC_PCLK2_Div4); //Устанавливаем предделитель тактовой АЦП.
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//Включаем тактирование.
// ADC1 configuration
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 2;
ADC_Init(ADC1, &ADC_InitStructure);
//Теперь, когда общая инициализация прошла успешно, нам надо настроить регистры инжекторных каналов, куда будут писаться наши данные. Ведь именно для этого мы их и используем.
//Устанавливаем количество каналов, которые мы собираемся считывать. Программа тогда сразу будет знать сколько вы в неё собираетесь записать каналов. Помните, что нельзя использовать одновременно более 4-х каналов, т.к. у инжекторных каналов только 4 различных регистра.
ADC_InjectedSequencerLengthConfig(ADC1, 2);
//Сопоставляем каналы регистрам. За регистры отвечает 3-й параметр. Параллельно настраиваем порты.
ADC_InjectedChannelConfig(ADC1, ADC_Channel_7, 1, ADC_SampleTime_71Cycles5);
ADC_InjectedChannelConfig(ADC1, ADC_Channel_16, 2, ADC_SampleTime_71Cycles5);
//ADC_InjectedChannelConfig(ADC1, ADC_Channel_14, 3, ADC_SampleTime_71Cycles5);
//Выключаем тригер.
ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_None);
// Enable automatic injected conversion start after regular one
ADC_AutoInjectedConvCmd(ADC1, ENABLE);//Это похоже запускает инжекторный канал вместе с регулярным. Т.е. в будущем будем запускать регулярный канал, а снимать с инжекторных. Хотя по поводу данной функции я могу ошибаться.
//Включили прерывания с инжекторного канала по окончании преобразования.
ADC_ITConfig(ADC1, ADC_IT_JEOC, ENABLE);
//Включили прерывания АЦП.
NVIC_EnableIRQ(ADC1_2_IRQn);
//Включили АЦП
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_SoftwareStartConvCmd(ADC1, ENABLE);
}
//Для чтения полученных данных:
//void ADC1_2_IRQHandler(void)//ADC interrupt
//{
//ADC1->SR&=~ADC_SR_JEOC;
//DataConvX = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_1);
//DataConvY = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_2);
//DataConvZ = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_3);
//ADC_Data_TX = EN;
//}
нашел пример но он видимо для другой линейки контролеров и на моем не работает у меня линейка CL а он обращается почему то к файлам другой линейки.. визуально заметил что в моих работающих примерах пишется "структуре" а тут "структ" пробовал заменить не помогло.
RCC_ADCCLKConfig(RCC_PCLK2_Div4); //Устанавливаем предделитель тактовой АЦП.
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//Включаем тактирование.
// ADC1 configuration
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 2;
ADC_Init(ADC1, &ADC_InitStructure);
//Теперь, когда общая инициализация прошла успешно, нам надо настроить регистры инжекторных каналов, куда будут писаться наши данные. Ведь именно для этого мы их и используем.
//Устанавливаем количество каналов, которые мы собираемся считывать. Программа тогда сразу будет знать сколько вы в неё собираетесь записать каналов. Помните, что нельзя использовать одновременно более 4-х каналов, т.к. у инжекторных каналов только 4 различных регистра.
ADC_InjectedSequencerLengthConfig(ADC1, 2);
//Сопоставляем каналы регистрам. За регистры отвечает 3-й параметр. Параллельно настраиваем порты.
ADC_InjectedChannelConfig(ADC1, ADC_Channel_7, 1, ADC_SampleTime_71Cycles5);
ADC_InjectedChannelConfig(ADC1, ADC_Channel_16, 2, ADC_SampleTime_71Cycles5);
//ADC_InjectedChannelConfig(ADC1, ADC_Channel_14, 3, ADC_SampleTime_71Cycles5);
//Выключаем тригер.
ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_None);
// Enable automatic injected conversion start after regular one
ADC_AutoInjectedConvCmd(ADC1, ENABLE);//Это похоже запускает инжекторный канал вместе с регулярным. Т.е. в будущем будем запускать регулярный канал, а снимать с инжекторных. Хотя по поводу данной функции я могу ошибаться.
//Включили прерывания с инжекторного канала по окончании преобразования.
ADC_ITConfig(ADC1, ADC_IT_JEOC, ENABLE);
//Включили прерывания АЦП.
NVIC_EnableIRQ(ADC1_2_IRQn);
//Включили АЦП
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_SoftwareStartConvCmd(ADC1, ENABLE);
}
//Для чтения полученных данных:
//void ADC1_2_IRQHandler(void)//ADC interrupt
//{
//ADC1->SR&=~ADC_SR_JEOC;
//DataConvX = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_1);
//DataConvY = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_2);
//DataConvZ = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_3);
//ADC_Data_TX = EN;
//}
- Денис Ягов
- Посетитель
11 года 6 мес. назад #4321
от Денис Ягов
Денис Ягов ответил в теме Re: ищу пример использования 4 и более канала ADC в stm32f105/107
В такой конфигурации:
Бесконечная работа АЦП поле запуска софтом проще обойтись без инжектированных каналов.
Просто настройте 4 регулярных канала. Получите тот же результат.
Бесконечная работа АЦП поле запуска софтом проще обойтись без инжектированных каналов.
Просто настройте 4 регулярных канала. Получите тот же результат.
- super_puper
- Автор темы
- Посетитель
11 года 6 мес. назад - 11 года 6 мес. назад #4323
от super_puper
super_puper ответил в теме Re: ищу пример использования 4 и более канала ADC в stm32f105/107
не дадите пример как это сделать?) хотелось бы чтоб данные складывались постоянно в 4 регистра когда хочу тогда и забираю
Последнее редактирование: 11 года 6 мес. назад пользователем .
- super_puper
- Автор темы
- Посетитель
11 года 6 мес. назад #4324
от super_puper
super_puper ответил в теме Re: ищу пример использования 4 и более канала ADC в stm32f105/107
вот ещё нашел пример но не на структурах тоже, не верные данные показывает
//vvvvvvvvv работа до 4х АЦП1 одновременно vvvvvvv
void up_to_4_chanel_ADC1_Configuration(void){
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; //подаем тактирование АЦП
RCC->CFGR &= ~RCC_CFGR_ADCPRE; //входной делитель
ADC1->CR1 = 0; //предочистка регистра
ADC1->CR2 |= ADC_CR2_CAL; //запуск калибровки
while (!(ADC1->CR2 & ADC_CR2_CAL)){}; //ждем окончания калибровки
ADC1->CR2 = ADC_CR2_JEXTSEL; //выбрать источником запуска разряд JSWSTART
ADC1->CR2 |= ADC_CR2_JEXTTRIG; //разр. внешний запуск инжектированной группы
ADC1->CR2 |= ADC_CR2_CONT; //режим непрерывного преобразования
ADC1->CR1 |= ADC_CR1_SCAN; //режим сканирования (т.е. несколько каналов)
ADC1->CR1 |= ADC_CR1_JAUTO; //автомат. запуск инжектированной группы
ADC1->JSQR = (uint32_t)(2-1)<<20; //задаем количество каналов в инжектированной группе
ADC1->JSQR |= (uint32_t)16<<(5*0); //номер канала для первого преобразования (16 )
ADC1->JSQR |= (uint32_t)7<<(5*1); //номер канала для второго преобразования (7)
//ADC1->JSQR |= (uint32_t)5<<(5*2); //номер канала для третьего преобразования
//ADC1->JSQR |= (uint32_t)6<<(5*3); //номер канала для четвертого преобразования
ADC1->CR2 |= ADC_CR2_ADON; //включить АЦП
ADC1->CR2 |= ADC_CR2_JSWSTART; //запустить процес преобразования
}
// пример считывания:
//temper = ADC1->JDR1; //прочитать результат первого преобразования (канал 16)
//adc7 = ADC1->JDR2; //прочитать результат второго преобразования (канал 7)
//tmp = ADC1->JDR3; //прочитать результат третьего преобразования (в нашем случае канал 5)
//tmp = ADC1->JDR4; //прочитать результат четвертого преобразования (в нашем случае канал 6)
// ADC_TempSensorVrefintCmd(ENABLE); //подключить температурный сенсор с каналу 16
u32 get_ADC1_ch_N(u8 nchanel){// возвращает данные с ацп канала 1-4
u32 adc_data;
switch (nchanel)
{
case 1: adc_data = ADC1->JDR1;return adc_data;
case 2: adc_data = ADC1->JDR2;return adc_data;
case 3: adc_data = ADC1->JDR3;return adc_data;
case 4: adc_data = ADC1->JDR4;return adc_data;
}
return 0xFFFF;
}
//vvvvvvvvv работа до 4х АЦП1 одновременно vvvvvvv
void up_to_4_chanel_ADC1_Configuration(void){
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; //подаем тактирование АЦП
RCC->CFGR &= ~RCC_CFGR_ADCPRE; //входной делитель
ADC1->CR1 = 0; //предочистка регистра
ADC1->CR2 |= ADC_CR2_CAL; //запуск калибровки
while (!(ADC1->CR2 & ADC_CR2_CAL)){}; //ждем окончания калибровки
ADC1->CR2 = ADC_CR2_JEXTSEL; //выбрать источником запуска разряд JSWSTART
ADC1->CR2 |= ADC_CR2_JEXTTRIG; //разр. внешний запуск инжектированной группы
ADC1->CR2 |= ADC_CR2_CONT; //режим непрерывного преобразования
ADC1->CR1 |= ADC_CR1_SCAN; //режим сканирования (т.е. несколько каналов)
ADC1->CR1 |= ADC_CR1_JAUTO; //автомат. запуск инжектированной группы
ADC1->JSQR = (uint32_t)(2-1)<<20; //задаем количество каналов в инжектированной группе
ADC1->JSQR |= (uint32_t)16<<(5*0); //номер канала для первого преобразования (16 )
ADC1->JSQR |= (uint32_t)7<<(5*1); //номер канала для второго преобразования (7)
//ADC1->JSQR |= (uint32_t)5<<(5*2); //номер канала для третьего преобразования
//ADC1->JSQR |= (uint32_t)6<<(5*3); //номер канала для четвертого преобразования
ADC1->CR2 |= ADC_CR2_ADON; //включить АЦП
ADC1->CR2 |= ADC_CR2_JSWSTART; //запустить процес преобразования
}
// пример считывания:
//temper = ADC1->JDR1; //прочитать результат первого преобразования (канал 16)
//adc7 = ADC1->JDR2; //прочитать результат второго преобразования (канал 7)
//tmp = ADC1->JDR3; //прочитать результат третьего преобразования (в нашем случае канал 5)
//tmp = ADC1->JDR4; //прочитать результат четвертого преобразования (в нашем случае канал 6)
// ADC_TempSensorVrefintCmd(ENABLE); //подключить температурный сенсор с каналу 16
u32 get_ADC1_ch_N(u8 nchanel){// возвращает данные с ацп канала 1-4
u32 adc_data;
switch (nchanel)
{
case 1: adc_data = ADC1->JDR1;return adc_data;
case 2: adc_data = ADC1->JDR2;return adc_data;
case 3: adc_data = ADC1->JDR3;return adc_data;
case 4: adc_data = ADC1->JDR4;return adc_data;
}
return 0xFFFF;
}
- Денис Ягов
- Посетитель
11 года 6 мес. назад #4328
от Денис Ягов
Смотрим стандартный пример связывания АЦП+DMA (скан вложил)
Отличие только в том, что здесь один канал, а вам надо 4.
Соответственно правим строки:
DMA_InitStructure.[iurl=http://structDMA__InitTypeDef.html#a999df57215b28b3b1b3b6836c4952ca5]DMA_BufferSize[/iurl] = 4; // 4 копирования, потом возврат в начало буфера
DMA_InitStructure.[iurl=http://structDMA__InitTypeDef.html#aaf69c680a297ec01a2ed613289e691a1]DMA_MemoryInc[/iurl] = [iurl=http://group__DMA__memory__incremented__mode.html#ga795a277c997048783a383b026f19a5ab]DMA_MemoryInc_Enable[/iurl]; // разрешаем сдвигать адрес назаначения
ADC_InitStructure.[iurl=http://structADC__InitTypeDef.html#ad6f39a12ac32a2767085ac94e9338bc3]ADC_NbrOfChannel[/iurl] = 4; // количество линий АЦП
[iurl=http://group__ADC__Exported__Functions.html#gac531adb577b648d4bb8881f2ed627d52]ADC_RegularChannelConfig[/iurl]([iurl=http://group__Peripheral__declaration.html#ga90d2d5c526ce5c0a551f533eccbee71a]ADC1[/iurl], [iurl=http://group__ADC__channels.html#gaf1830a03fe4a3820fde4f41ba907c394]ADC_Channel_14[/iurl], 1, [iurl=http://group__ADC__sampling__time.html#ga6a6fbbadc0e35a719fb749bf6b0704d6]ADC_SampleTime_55Cycles5[/iurl]);
[iurl=http://group__ADC__Exported__Functions.html#gac531adb577b648d4bb8881f2ed627d52]ADC_RegularChannelConfig[/iurl]([iurl=http://group__Peripheral__declaration.html#ga90d2d5c526ce5c0a551f533eccbee71a]ADC1[/iurl], [iurl=http://group__ADC__channels.html#gaf1830a03fe4a3820fde4f41ba907c394]ADC_Channel_14[/iurl], 2, [iurl=http://group__ADC__sampling__time.html#ga6a6fbbadc0e35a719fb749bf6b0704d6]ADC_SampleTime_55Cycles5[/iurl]);
[iurl=http://group__ADC__Exported__Functions.html#gac531adb577b648d4bb8881f2ed627d52]ADC_RegularChannelConfig[/iurl]([iurl=http://group__Peripheral__declaration.html#ga90d2d5c526ce5c0a551f533eccbee71a]ADC1[/iurl], [iurl=http://group__ADC__channels.html#gaf1830a03fe4a3820fde4f41ba907c394]ADC_Channel_14[/iurl], 3, [iurl=http://group__ADC__sampling__time.html#ga6a6fbbadc0e35a719fb749bf6b0704d6]ADC_SampleTime_55Cycles5[/iurl]);
[iurl=http://group__ADC__Exported__Functions.html#gac531adb577b648d4bb8881f2ed627d52]ADC_RegularChannelConfig[/iurl]([iurl=http://group__Peripheral__declaration.html#ga90d2d5c526ce5c0a551f533eccbee71a]ADC1[/iurl], [iurl=http://group__ADC__channels.html#gaf1830a03fe4a3820fde4f41ba907c394]ADC_Channel_14[/iurl], 4, [iurl=http://group__ADC__sampling__time.html#ga6a6fbbadc0e35a719fb749bf6b0704d6]ADC_SampleTime_55Cycles5[/iurl]);
//(какой канал АЦП будете замерять - установить по вкусу)
__IO uint16_t [iurl=http://group__ADC__ADC1__DMA.html#ga399eab5f75f61a6cf791b9433a90c9c9]ADCConvertedValue[/iurl][4]; // выделить массив для складывания измерений (таблица из 4-х измерений)
Вроде бы это всё.
Денис Ягов ответил в теме Re: ищу пример использования 4 и более канала ADC в stm32f105/107
Без проблем.не дадите пример как это сделать?) хотелось бы чтоб данные складывались постоянно в 4 регистра когда хочу тогда и забираю
Смотрим стандартный пример связывания АЦП+DMA (скан вложил)
Отличие только в том, что здесь один канал, а вам надо 4.
Соответственно правим строки:
DMA_InitStructure.[iurl=http://structDMA__InitTypeDef.html#a999df57215b28b3b1b3b6836c4952ca5]DMA_BufferSize[/iurl] = 4; // 4 копирования, потом возврат в начало буфера
DMA_InitStructure.[iurl=http://structDMA__InitTypeDef.html#aaf69c680a297ec01a2ed613289e691a1]DMA_MemoryInc[/iurl] = [iurl=http://group__DMA__memory__incremented__mode.html#ga795a277c997048783a383b026f19a5ab]DMA_MemoryInc_Enable[/iurl]; // разрешаем сдвигать адрес назаначения
ADC_InitStructure.[iurl=http://structADC__InitTypeDef.html#ad6f39a12ac32a2767085ac94e9338bc3]ADC_NbrOfChannel[/iurl] = 4; // количество линий АЦП
[iurl=http://group__ADC__Exported__Functions.html#gac531adb577b648d4bb8881f2ed627d52]ADC_RegularChannelConfig[/iurl]([iurl=http://group__Peripheral__declaration.html#ga90d2d5c526ce5c0a551f533eccbee71a]ADC1[/iurl], [iurl=http://group__ADC__channels.html#gaf1830a03fe4a3820fde4f41ba907c394]ADC_Channel_14[/iurl], 1, [iurl=http://group__ADC__sampling__time.html#ga6a6fbbadc0e35a719fb749bf6b0704d6]ADC_SampleTime_55Cycles5[/iurl]);
[iurl=http://group__ADC__Exported__Functions.html#gac531adb577b648d4bb8881f2ed627d52]ADC_RegularChannelConfig[/iurl]([iurl=http://group__Peripheral__declaration.html#ga90d2d5c526ce5c0a551f533eccbee71a]ADC1[/iurl], [iurl=http://group__ADC__channels.html#gaf1830a03fe4a3820fde4f41ba907c394]ADC_Channel_14[/iurl], 2, [iurl=http://group__ADC__sampling__time.html#ga6a6fbbadc0e35a719fb749bf6b0704d6]ADC_SampleTime_55Cycles5[/iurl]);
[iurl=http://group__ADC__Exported__Functions.html#gac531adb577b648d4bb8881f2ed627d52]ADC_RegularChannelConfig[/iurl]([iurl=http://group__Peripheral__declaration.html#ga90d2d5c526ce5c0a551f533eccbee71a]ADC1[/iurl], [iurl=http://group__ADC__channels.html#gaf1830a03fe4a3820fde4f41ba907c394]ADC_Channel_14[/iurl], 3, [iurl=http://group__ADC__sampling__time.html#ga6a6fbbadc0e35a719fb749bf6b0704d6]ADC_SampleTime_55Cycles5[/iurl]);
[iurl=http://group__ADC__Exported__Functions.html#gac531adb577b648d4bb8881f2ed627d52]ADC_RegularChannelConfig[/iurl]([iurl=http://group__Peripheral__declaration.html#ga90d2d5c526ce5c0a551f533eccbee71a]ADC1[/iurl], [iurl=http://group__ADC__channels.html#gaf1830a03fe4a3820fde4f41ba907c394]ADC_Channel_14[/iurl], 4, [iurl=http://group__ADC__sampling__time.html#ga6a6fbbadc0e35a719fb749bf6b0704d6]ADC_SampleTime_55Cycles5[/iurl]);
//(какой канал АЦП будете замерять - установить по вкусу)
__IO uint16_t [iurl=http://group__ADC__ADC1__DMA.html#ga399eab5f75f61a6cf791b9433a90c9c9]ADCConvertedValue[/iurl][4]; // выделить массив для складывания измерений (таблица из 4-х измерений)
Вроде бы это всё.
- Stepanov Ivan
- Посетитель
11 года 6 мес. назад #4329
от Stepanov Ivan
Stepanov Ivan ответил в теме Re: ищу пример использования 4 и более канала ADC в stm32f105/107
Эх, Денис, опередил только тоже самое выкладывал
- Форум
- Микроконтроллеры и Системы на Модуле (SOM)
- Микроконтроллеры
- ищу пример использования 4 и более канала ADC в stm32f105/107
Время создания страницы: 0.063 секунд