|
|
  |
ищу пример использования 4 и более канала ADC в stm32f105/107, поделитесь наработками кому не жалко.. |
|
|
|
May 8 2013, 04:51
|
Местный
  
Группа: Участник
Сообщений: 222
Регистрация: 14-12-12
Из: новосибирск
Пользователь №: 74 845

|
нужно на стд перифе 3.5.0. нашел пример но он видимо для другой линейки контролеров и на моем не работает у меня линейка CL а он обращается почему то к файлам другой линейки.. визуально заметил что в моих работающих примерах пишется "структуре" а тут "структ" пробовал заменить не помогло. CODE 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; //}
и вот ещё классный пример!! только не на структурах( http://mycontroller.ru/stm32-adc-primeryi-...annyie-kanalyi/
Сообщение отредактировал super_puper - May 8 2013, 06:25
|
|
|
|
|
May 9 2013, 04:39
|
Знающий
   
Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594

|
Кусок инициализации. Данные ловишь в прерывании DMA, обработчики тут не приведены. Включение тактирования и глобальные переменные так же за пределами этого примера. CODE // инициализация линий ввода-вывода GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_InitStructure.GPIO_Pin = PIN_ACC_VOLT; GPIO_Init(PORT_ACC_VOLT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = PIN_POWER_VOLT; GPIO_Init(PORT_POWER_VOLT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = PIN_ACC_CURRENT; GPIO_Init(PORT_ACC_CURRENT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = PIN_POWER_CURRENT; GPIO_Init(PORT_POWER_CURRENT, &GPIO_InitStructure); //GPIO_InitStructure.GPIO_Pin = PIN_MODEM_ANALOG_IN; GPIO_Init(PORT_MODEM_ANALOG_IN, &GPIO_InitStructure);
// DMA1 channel1 configuration ---------------------------------------------- DMA_DeInit(DMA1_Channel1); DMA_InitTypeDef DMA_InitStructure; DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (unsigned long)dmaarray; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = sizeof(dmaarray)/sizeof(*dmaarray); DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure);
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC | DMA_IT_HT, ENABLE); DMA_Cmd(DMA1_Channel1, ENABLE); // ADC SETUP----------------------------------------------------------------- ADC_Cmd(ADC1, DISABLE);
ADC_DeInit(ADC1); // ADCx Configuration (ADC1CLK = 14 MHz) ----------------------------------- 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 = 5; ADC_Init(ADC1, &ADC_InitStructure);
// Enable ADCx ADC_Cmd(ADC1, ENABLE); ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1) == SET); ADC_StartCalibration(ADC1); while (ADC_GetCalibrationStatus(ADC1) == SET);
// термоканал ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, CH_ACC_CURREN, 2, ADC_SampleTime_239Cycles5); ADC_RegularChannelConfig(ADC1, CH_ACC_VOLT, 3, ADC_SampleTime_239Cycles5); ADC_RegularChannelConfig(ADC1, CH_POWER_CURREN, 4, ADC_SampleTime_239Cycles5); ADC_RegularChannelConfig(ADC1, CH_POWER_VOLT, 5, ADC_SampleTime_239Cycles5);
ADC_DMACmd(ADC1, ENABLE); ADC_SoftwareStartConvCmd(ADC1, ENABLE);
// датчик температуры включили ADC_TempSensorVrefintCmd(ENABLE);
// Configure and enable ADC interrupt NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 15; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);
|
|
|
|
|
May 13 2013, 02:26
|
Местный
  
Группа: Участник
Сообщений: 222
Регистрация: 14-12-12
Из: новосибирск
Пользователь №: 74 845

|
вот как я сделал без прерываний удобно, работает норм, заметил что датчик температуру показывает правильно только при этом значении "циклосов" при других ахинею показывает. CODE //VVVVVVVVVVVVVVVV ADC VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV //vvvvvvvvv работа до 4х АЦП1 одновременно vvvvvvv void up_to_4_chanel_ADC1_Configuration(void){ RCC_ADCCLKConfig(RCC_PCLK2_Div8); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE ); // Конфигурация АЦП1 ADC_InitTypeDef ADC_InitStructure; ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = ENABLE; //We will convert single channel only ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//we will convert many times ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //select no external triggering ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //right 12-bit data alignment in ADC data register ADC_InitStructure.ADC_NbrOfChannel = 2;//single channel conversion ADC_Init(ADC1, &ADC_InitStructure);//load structure values to control and status registers
//wake up temperature sensor //ADC_TempSensorVrefintCmd(ENABLE); ADC_InjectedSequencerLengthConfig(ADC1, 2);
//ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_13Cycles5); //ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 2, ADC_SampleTime_13Cycles5); ADC_InjectedChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_13Cycles5); ADC_InjectedChannelConfig(ADC1, ADC_Channel_7, 2, ADC_SampleTime_13Cycles5); /* ADC1 injected external trigger configuration */ ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_None);
/* Enable automatic injected conversion start after regular one */ ADC_AutoInjectedConvCmd(ADC1, ENABLE); // Разрешаем АЦП1 ADC_Cmd(ADC1, ENABLE); // Сбрасываем калибровку АЦП1 ADC_ResetCalibration(ADC1); // Ждём окончания процедуры сброса калибровки АЦП1 while(ADC_GetResetCalibrationStatus(ADC1));
// Калибруем АЦП1 ADC_StartCalibration(ADC1); // Ждём окончания калибровки while(ADC_GetCalibrationStatus(ADC1)); // Запускаем АЦП1 ADC_SoftwareStartConvCmd(ADC1, ENABLE); } // пример считывания: //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; }
u32 Celsius_degrees(){// переводит данные с АЦП в градусы цельсия u32 adc_data; u32 TemperatureC; const uint16_t V25 = 1750;// when V25=1.41V at ref 3.3V const uint16_t Avg_Slope = 5; //when avg_slope=4.3mV/C at ref 3.3V adc_data = ADC1->JDR1; TemperatureC = (V25-adc_data)/Avg_Slope+25; return TemperatureC; }
Сообщение отредактировал super_puper - May 13 2013, 02:34
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|