Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Тема закрыта

Аналоговый компаратор

Чт сен 03, 2009 13:30:39

Здравствуйте, снова я со своими вопросами :))) !!

Вобщем проблема в том, что не работает (или я балбес :)) ) аналоговый компаратор на MEGA8:

програмлю следующим образом:

Код:
#include (avr/interrupt.h)  // скобы конечно угловые
#include (util/delay.h)
#define F_CPU 1000000UL // 8 MHz


  ISR(ANA_COMP_vect){  //Обработчик прерывания
  PORTC = 0xff;
  }

int main(void){     
 
 DDRC = 0xff;
 
 ACSR=0x08; // аналоговый компаратор, прерывание по изменению

 sei();    // Разрешение прерываний глобально




В итоге как ни изменяю уровни на AIN0 AIN1, все бестолку, никакого прерывания не происходит (на порт С не выводится 1) :cry:

Чт сен 03, 2009 13:55:32

по-моему вы или кто-то другой буквально день назад уже наступали на эти же грабли: нельзя делать main без вечного цикла: при "выходе" из main запрещаются прерывания и происходит зацикливание, т.е. прерывания разрешены у вас ровно 1 машинный такт.

Чт сен 03, 2009 13:57:35

Да, я тож подумал об этом, сделал, все равно не рабит :cry:

Чт сен 03, 2009 14:01:01

ну потрудитесь расписать побитово, что вы там устанавливаете в ACSR: то, что вы пишите - не воспринимается

Чт сен 03, 2009 14:16:58

[/code]
#include <avr>
#include <util>
#define F_CPU 1000000UL // 8 MHz


ISR(ANA_COMP_vect){ //Обработчик прерывания
PORTC ^= (PINC | 0x01);




}

int main(void){


DDRC = 0xff;

ACSR=0x08; // аналоговый компаратор, прерывание по изменению

sei(); // Разрешение прерываний глобально
while(1){}

}

[/code]
Прошу прощения просто после while(1){} make clean не сделал! Все работает. Спасибо !!

Чт сен 03, 2009 14:23:38

я тут уже советовал другим, посоветую и вам: используйте макросы, типы и т.п., являющиеся "стандартными" для WinAVR - это позволит вам иметь более читаемый другими любителями WinAVR код, да и сами будете лучше понимать, что делаете.
Код:
ACSR = _BV(ACIE); // это ведь нагляднее, чем 0x08 - не так ли?
а это что бы означало:
Код:
ISR(ANA_COMP_vect){ //Обработчик прерывания
PORTC ^= (PINC | 0x01); }
если надо переключать уровень на порту, то надо делать проще:
Код:
PORТC ^= _BV(PC0); // переключаем 0 бит порта С

Чт сен 03, 2009 14:25:58

Хорошо, буду иметь ввиду.

Чт сен 03, 2009 16:16:34

-==MAXCELERON==- писал(а):Хорошо, буду иметь ввиду.


Не имей ввиду, все ты правильно делаешь, записывая в регистр конкретное число. Просто в коментах укажи какие биты в единицу, какие в ноль и все.

Почему? Потому что,

#define _BV(bit) (1 << (bit))

Это означает сдвиг единицы на определенное число, тем самым требуя на каждый сдвиг один такт. Если вы хотите установить седьмой бит в регистре, то знайте, уйдет семь тактов. А если просто 0x80 то всего один.
Эт я так, рекомендую.
А еще лучше, написать свои макросы типа
SET_ADC_ACIE = ACSR |= 0x80;


----------

Чт сен 03, 2009 16:26:40

__Alexander, я вам очень настоятельно рекомендую прежде чем давать рекомендации, хорошенько изучить язык Си... иначе вы можете попасть в глупое положение, когда ваши рекомендации не имеют ничего общего с реальностью...

в данном случае, вы забываете, что Си - это не бейсик, и все вычисления, которые могут быть сделаны на этапе компиляции, будут сделаны именно на этапе компиляции.
то есть все сдвиги сделает компилятор, а в код запишется только результат этих сдвигов. ведь не думаете же вы, что с = 2 * 8 + 16 / 4; приведет к генерации команд умножения, деления и сложения?! на самом деле в с сразу будет записано число 20.

кроме того, ваш совет на счет макросов - от него волосы поднимаются... в регистре 8 битов, устанавливать которые можно в разных комбинациях, т.е. всего 256 комбинаций... вы для каждой предлагаете написать макрос?! мой совет касался в соновном использования символьных имен битов для управляющих регистров, что имеет смысл - наглядность кода резко повышается... а ваш метод что дает?! только хуже сделает...

Чт сен 03, 2009 17:15:35

Мда, согласен, совет данного макроса был не совсем уместен.
Но вот когда в макросе происходят арифметические действия который будет получен после вызова функции... хотя, короче, чего это я. Это дело компилятора, я хотел сказать что макрос, это просто подставление его в код программы. А че с ним сделает компилятор - это другой вопрос.




----------

Re: Аналоговый компаратор

Ср май 30, 2012 20:48:40

Добрый день уважаемые. У меня тот же вопрос написал простой код для работы компоратора. В котором при изменении значения выхода ACO зажигается или тухнит светодиод PD7, а при изменении значения с 0 на 1 вызывается прерывание комп. Только вот почему то прерывание не вызывается, а PD7 горит не тухнит, при изменении значения входов с 0 до 2,5В.
Пробую пример в Proteuse 7 SP3
easy_analog_compor_1.rar
(33.96 KiB) Скачиваний: 203
и на плате Pinboard 1.1. Подскажите в чем дело.
Код:
#include<avr/io.h>
#include <avr/interrupt.h>

ISR (ANA_COMP_vect) {
   PORTD ^= (1<<PD4);
}
//ОСНОВНАЯ ФУНКЦИЯ
int main(void) {
//Инициализация переферии
DDRD=(1<<PD4)|(1<<PD7);//На выход сигнала
DDRB=(0<<PB2)|(0<<PB3);//На вход
PORTB=(0<<PB2)|(0<<PB3);
//ACIE-разрешаем прерывание от компаратора.ACIS1;ACIS0-Ловим 0-1
ACSR=(1<<ACIE)|(0<<ACIS1)|(0<<ACIS0);
asm("sei");//Разрешаем объявленные прерывания
while (1) {
   PORTD = (ACO<<PD7);//Заносим значение в PD7 значение ACO
}
}

Re: Аналоговый компаратор

Чт май 31, 2012 06:44:56

У Вас все нормально работает. Просто Вы неверно подключили приборы. Резистором RV2 устанавливается порог срабатывания компаратора, а срабатывание компаратора определяется движком резистора RV1 (или наоборот, это как Вам больше нравиться). Исправленная схема во вложении.
Вложения
easy_analog_compor_1.rar
Компаратор
(34.35 KiB) Скачиваний: 228

Re: Аналоговый компаратор

Чт май 31, 2012 22:32:05

siamds писал(а):У Вас все нормально работает. Просто Вы неверно подключили приборы. Резистором RV2 устанавливается порог срабатывания компаратора, а срабатывание компаратора определяется движком резистора RV1 (или наоборот, это как Вам больше нравиться). Исправленная схема во вложении.

Спасибо за ответ, действительно не правильно собрал схему.
Ваша схема у меня работает, только почему то с 55 секунды, тоесть до 55 с меняю значения на сопротивлениях и все молчит. Вы меняли что нибудь в коде?(Просто мой код прошивки тот который я привел не работает, а ваш работает)..... или может просто очередной баг Proteusa.

Re: Аналоговый компаратор

Пт июн 01, 2012 06:18:56

EmDmAl писал(а): с 55 секунды, тоесть до 55 с меняю значения на сопротивлениях и все молчит.

Вероятно это происходит потому что у Вас между портом и светодиодом не стоит токоограничительное сопротивление. Светодиоды нельзя напрямую подключать на выход порта. Поставьте резистор порядка 300ом и проблема должна исчезнуть.

Re: Аналоговый компаратор

Сб июн 02, 2012 11:23:46

По ошибки я выкладывал hex файл, в главном теле которого
Код:
while (1) {
   if (ACSR&(1<<ACO)) {//Если в ACO = 1
      PORTD = (1<<PD7);
   } else { PORTD = (0<<PD7);}
}

поэтому вариант PORTD = (ACO<<PD7); не работает.
Значит надо использовать связку выше.
Тема закрыта