|
Analog Watchdog в STM32F103 |
|
|
|
 |
Ответов
(1 - 14)
|
Feb 17 2015, 19:28
|
Гуру
     
Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164

|
Спасибо, нашел. Но есть проблема - прерывание генерируется постоянно, независимот от показаний АЦП. Отключал прерывания и смотрел как работает АЦП - измерения правильные, шумов нет. Вот инициализация АЦП Код void adc_Init() {
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);// ʹÄÜ ADC1 ÖØÒª£¡£¡£¡
////////////////////////////// /* ADC1 Configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; 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 channel14 configuration */ ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_13Cycles5);
/* Configure high and low analog watchdog thresholds */ ADC_AnalogWatchdogThresholdsConfig(ADC1, 1000, 3902); /* Configure channel14 as the single analog watchdog guarded channel */ ADC_AnalogWatchdogSingleChannelConfig(ADC1, ADC_Channel_0); /* Enable analog watchdog on one regular channel */ ADC_AnalogWatchdogCmd(ADC1, ADC_AnalogWatchdog_SingleRegEnable);
/* Enable AWD interrupt */ ADC_ITConfig(ADC1, ADC_IT_AWD, 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));
/* Start ADC1 Software Conversion */ ADC_SoftwareStartConvCmd(ADC1, ENABLE); } Вот ножка и прерывание Код void ADC1_2_IRQHandler(void) {
if(ADC_GetITStatus(ADC1,ADC_IT_AWD)) {
} ADC_ClearITPendingBit(ADC1,ADC_IT_AWD);
}
/////////////////////////////////
/* Configure PA.0 (ADC Channel) as analog input -------------------------*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStructure); Еще раз повторюсь - показания АЦП правильные. Что я делаю не так?
Сообщение отредактировал zheka - Feb 17 2015, 19:34
|
|
|
|
|
Feb 17 2015, 20:49
|
Профессионал
    
Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528

|
Описание работы AWD занимает в реф. мануале меньше страницы. Читаем, пишем: Код #define guarded_channel (0) ADC1->CR1 |= ADC_CR1_AWDEN // enable on regular channels | ADC_CR1_AWDSGL // Enable the watchdog on a single channel in scan mode | ADC_CR1_AWDIE // Analog watchdog interrupt enable | guarded_channel; // #channel ADC1->LTR = 1000; ADC1->HTR = 3902; У меня работает. Добавлено: Цитата Но есть проблема - прерывание генерируется постоянно, независимот от показаний АЦП. Вот оно что: Цитата void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold, uint16_t LowThreshold) Сначала HighThreshold, потом LowThreshold !
Сообщение отредактировал SSerge - Feb 17 2015, 20:54
--------------------
Russia est omnis divisa in partes octo.
|
|
|
|
|
Feb 18 2015, 08:56
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(zheka @ Feb 18 2015, 05:48)  А как сделать наоборот? Чтобы прерывание срабатывало тогда, когда напряжение входит в определенную зону? Если эта зона одним концом упирается в землю или питание - настроить собаку на оставшуюся часть диапазона. В противном случае - никак: Цитата The AWD analog watchdog status bit is set if the analog voltage converted by the ADC is below a low threshold or above a high threshold.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Feb 28 2017, 09:15
|
Участник

Группа: Участник
Сообщений: 60
Регистрация: 23-07-09
Пользователь №: 51 492

|
А у меня проблема на f100RBT6, может чего-то упустил или вообще не знал? Вкратце, что и в каком порядке... Код gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO1);
nvic_set_priority(NVIC_ADC1_2_IRQ, 0); nvic_enable_irq(NVIC_ADC1_2_IRQ);
adc_enable_analog_watchdog_regular(ADC1); adc_enable_analog_watchdog_on_selected_channel(ADC1,1); adc_enable_awd_interrupt(ADC1); adc_set_watchdog_high_threshold(ADC1,4000); adc_set_watchdog_low_threshold(ADC1,2000); факт в том что в обработчик прерывания adc1_2_isr процесс не попадает... Можно конечно в другом прерывании читать значение из АЦП и сравнивать. Но это печально.
Сообщение отредактировал Ruslan.B - Feb 28 2017, 09:16
|
|
|
|
|
Feb 28 2017, 09:42
|
Участник

Группа: Участник
Сообщений: 60
Регистрация: 23-07-09
Пользователь №: 51 492

|
Цитата(ViKo @ Feb 28 2017, 15:27)  АЦП еще настроить надо и запустить. Как обычно, начиная с тактов. Извиняюсь. Это присутствует... Код rcc_periph_clock_enable(RCC_ADC1); rcc_periph_clock_enable(RCC_GPIOA); И вообще до этого взял из примера функцию: Код static void adc_setup(void) { gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO0); gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, GPIO1);
/* Make sure the ADC doesn't run during config. */ adc_off(ADC1);
/* We configure everything for one single conversion. */ adc_disable_scan_mode(ADC1); adc_set_single_conversion_mode(ADC1); adc_disable_external_trigger_regular(ADC1); adc_set_right_aligned(ADC1); adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC);
adc_power_on(ADC1);
/* Wait for ADC starting up. */ int i; for (i = 0; i < 800000; i++) /* Wait a bit. */ __asm__("nop");
adc_reset_calibration(ADC1); adc_calibration(ADC1); } И оно всё работало...
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|