STM8S + ADC + Multichanel

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
ССтанислав
Это не хвост, это антенна
Сообщения: 1355
Зарегистрирован: Вт май 20, 2014 18:14:20
Откуда: Белгород
Контактная информация:

STM8S + ADC + Multichanel

Сообщение ССтанислав »

День добрый.

Имеем STM8S105. Есть необходимость считать несколько каналов ADC, конкретно AIN2, AIN3, AIN4, AIN5.

в main.c пишу:

Код: Выделить всё

	ADC1_DeInit();
	ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS, ADC1_SCHMITTTRIG_CHANNEL5, ADC1_PRESSEL_FCPU_D8, ADC1_EXTTRIG_GPIO, DISABLE, ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_ALL, DISABLE);
	ADC1_ITConfig(ADC1_IT_EOCIE ,ENABLE);
	ADC1_DataBufferCmd(ENABLE);
	ADC1_Cmd(ENABLE);
	ADC1_ScanModeCmd(ENABLE);
	ADC1_StartConversion();
	enableInterrupts();
в stm8s_it.c

Код: Выделить всё

 INTERRUPT_HANDLER(ADC1_IRQHandler, 22)
 {
	adc1_0=ADC1_GetBufferValue(ADC1_CHANNEL_0);
	adc1_1=ADC1_GetBufferValue(ADC1_CHANNEL_1);
	adc1_2=ADC1_GetBufferValue(ADC1_CHANNEL_2);
	adc1_3=ADC1_GetBufferValue(ADC1_CHANNEL_3);
	adc1_4=ADC1_GetBufferValue(ADC1_CHANNEL_4);
	adc1_5=ADC1_GetBufferValue(ADC1_CHANNEL_5);
	ADC1_ClearITPendingBit(ADC1_IT_EOC);
}
Не считывается AIN5, до него все ОК, 5 нет!

в main.c делаю замену ADC1_PRESSEL_FCPU_D8 -> ADC1_PRESSEL_FCPU_D6 - могу читать и 5 канал?!
Путем несложный переборов выяснил, что AIN5 читается при ADC1_PRESSEL_FCPU_D3 и ADC1_PRESSEL_FCPU_D6, во всех остальных случаях нет.

Собственно вопрос - почему так?!
Дорогу осилит идущий.
Реклама
Аватара пользователя
GARMIN
Держит паяльник хвостом
Сообщения: 954
Зарегистрирован: Вс дек 02, 2012 16:58:33
Откуда: от туда
Контактная информация:

Re: STM8S + ADC + Multichanel

Сообщение GARMIN »

Всё более чем просто:
Спойлер

Код: Выделить всё

/*****************************************************************************
* Настройка АЦП
*****************************************************************************/
void init_adc (void)
{
// входы процессора
	GPIO_ConfigInput (ADC0_PORT, ADC0_PIN, PinFloating, PinIrqOff);
	GPIO_ConfigInput (ADC1_PORT, ADC1_PIN, PinFloating, PinIrqOff);
	GPIO_ConfigInput (ADC2_PORT, ADC2_PIN, PinFloating, PinIrqOff);
	GPIO_ConfigInput (ADC3_PORT, ADC3_PIN, PinFloating, PinIrqOff);
	GPIO_ConfigInput (ADC4_PORT, ADC4_PIN, PinFloating, PinIrqOff);
	GPIO_ConfigInput (ADC5_PORT, ADC5_PIN, PinFloating, PinIrqOff);
	GPIO_ConfigInput (ADC6_PORT, ADC6_PIN, PinFloating, PinIrqOff);


// Инициализация АЦП
	ADC1->CR1 &= ~ADC1_CR1_ADON;	// выключить АЦП для изменения настроек
	ADC1->TDRH = ADC1_TDRH_MASK;	// маска используемых входов
	ADC1->TDRL = ADC1_TDRL_MASK;	// маска используемых входов

	ADC1->CSR = 6 						// измерять до входа 6
				| ADC1_CSR_AWDIE	* 0		// запретить прерывания аналогового вочдога
				| ADC1_CSR_EOCIE	* 1;	// Разрешить прерывание по окончании измерения
	ADC1->CR1 = ADC1_CR1_SPSEL4				// частота преобразования 16МГц / 4 = 4 МГц
				| ADC1_CR1_CONT 	* 0		// режим однократного измерения
				| ADC1_CR1_ADON		* 0;
	ADC1->CR2 = ADC1_CR2_EXTTRIG	* 0		// внутренний триггер
				| ADC1_CR2_EXTSEL	* 0		// внешний триггер не используется
				| ADC1_CR2_ALIGN 	* 0		// выравнивание влево
				| ADC1_CR2_SCAN 	* 1;	// Режим сканирования
	ADC1->CR3 = ADC1_CR3_DBUF		* 1;	// с использованием буфера

	ADC1->CR1 |= ADC1_CR1_ADON;				// включить АЦП
}



/*****************************************************************************
* прерывание по окончании измерения
*****************************************************************************/
INTERRUPT_HANDLER (ADC1_End_of_conversion_ISR, 22)
{
	u8 flags = ADC1->CSR;
	flags &= ~ADC1_CSR_EOC;		// снять флаг прерывания
	ADC1->CSR = flags;
	// Для 10 разрядов
	 g.adc = (ADC1->DB0RH) << 8;
 	g.adc += ADC1->DB0RL;
	g.adc >>= 6;	// 10 разрядов
	
//	buf[0] = ADC1->DB0RH;	// в другом месте
	buf[1] = ADC1->DB1RH;	// сохраняем значения
	buf[2] = ADC1->DB2RH;
	buf[3] = ADC1->DB3RH;
	buf[4] = ADC1->DB4RH;
	buf[5] = ADC1->DB5RH;
	buf[6] = ADC1->DB6RH;

	control_func ();
}


/*******************************************************************************
* настройка приоритетов прерываний
*******************************************************************************/
void init_interrupts (void)
{
	ITC->ISPR6 = (ITC->ISPR6 & ~ITC_SPR6_TIM4OVF_MSK) | ITC_SPR6_TIM4OVF_LVL3;	// установить высокий приоритет прерывания системного таймера
	ITC->ISPR6 = (ITC->ISPR6 & ~ITC_SPR6_ADC1_MSK) | ITC_SPR6_ADC1_LVL2;		// В АЦП проводится много вычислений, пусть они смогут прерываться
	ITC->ISPR7 = (ITC->ISPR7 & ~ITC_SPR7_FLASH_MSK) | ITC_SPR7_FLASH_LVL1;		// прерывание записи во флеш может подождать

	ITC->ISPR1 &= ~ITC_SPR1_PORTA_MSK;
	ITC->ISPR2 &= ~ITC_SPR2_PORTB_MSK
				& ~ITC_SPR2_PORTC_MSK
				& ~ITC_SPR2_PORTD_MSK
				& ~ITC_SPR2_PORTE_MSK;	// сбросить биты маски приоритета прерывания для порта A,B,С,D,E

}


Достаточно прочитать мануал на чип
Реклама
ССтанислав
Это не хвост, это антенна
Сообщения: 1355
Зарегистрирован: Вт май 20, 2014 18:14:20
Откуда: Белгород
Контактная информация:

Re: STM8S + ADC + Multichanel

Сообщение ССтанислав »

Спасибо, буду разбираться :beer:
Дорогу осилит идущий.
Ответить

Вернуться в «Разные вопросы по МК»