реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
Sirko
сообщение Jan 31 2013, 15:35
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795



Чип Mega48
Инициализирую вот так:
Код
ADCSRA =
    _BV(ADEN)      // Разрешить работу АЦП
  | _BV(ADIE)     // Разрешить прерывания
  | _BV(ADSC)     // Запустить преобразование (первое, дальше автоматом)
  | _BV(ADATE)    // Непрерывные последовательные преобразования, одно за другим.
  | _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0);     // Делитель частоты на 128
    
ADMUX =
    _BV(REFS0)     // Опорное напряжение AVCC 5V
  | _BV(ADLAR)     // Выравнивание по левому краю
  |  5;            //   Сигнал на вход идет с пятого канала АЦП

ISR(ADC_vect){//-------------------------------------------------------------------------------------
   u16 q = ADCW;
//  ADCSRA &=~_BV(ADIE);
}


Судя по поведению, при попадании в прерывание - выхода от туда нет.
Если в инициализации закоментировать разрешение прерывания АЦП или в обработчике его запретить, то остальной софт функционирует

В чем косяк?
Go to the top of the page
 
+Quote Post
arttab
сообщение Feb 1 2013, 01:12
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 432
Регистрация: 7-12-04
Из: Новосибирск
Пользователь №: 1 371



есть бит в регистре управления ацп включающий автозапуск ацп


--------------------
OrCAD, Altium,IAR, AVR....
Go to the top of the page
 
+Quote Post
Sirko
сообщение Feb 1 2013, 06:32
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795



Бит то есть, но при его задействовании нет выхода из прерывания. В том то и суть вопроса.
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Feb 1 2013, 07:11
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(Sirko @ Feb 1 2013, 10:32) *
нет выхода из прерывания.

Да он то есть, только проц постоянно обрабатывает только прерывание. Выже ему практически ни начто другое время не оставляете.


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
Sirko
сообщение Feb 1 2013, 07:36
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795



Дык вопрос то о том, как "это" ему дать.
Понятное дело, что я что то делаю не так.

Судя из строк "ADIF is cleared by hardware when executing the corresponding interrupt handling vector. " флаг должен сброситься при входе в прерывание, но что-то, где-то не стыкуется.
Go to the top of the page
 
+Quote Post
xemul
сообщение Feb 1 2013, 08:00
Сообщение #6



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(Sirko @ Feb 1 2013, 11:36) *
Понятное дело, что я что то делаю не так.

Угу - включив непрерывное преобразование, пытаетесь работать по прерываниям АЦП. Если Ваша программа в обработчике прерывания проводит время, соизмеримое или большее времени преобразования (программисты иногда вставляют в ISR что-нить вроде delay_ms() или printf()), то ...
Такая комбинация может иметь смысл, н-р, при низкой скорости тактирования АЦП и считывании результата преобразования по ещё более редкому прерыванию таймера, если время запуска преобразования не важно.
Цитата
Судя из строк "ADIF is cleared by hardware when executing the corresponding interrupt handling vector. " флаг должен сброситься при входе в прерывание, но что-то, где-то не стыкуется.

А где написано, что ADIF не может быть установлен, пока программа ковыряется внутри ISR(ADC_vect)? Вот и получается песня про Сусанина "он из лесу вышел, и снова вошёл".

Ещё вариант - разрешено более другое прерывание.
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Feb 1 2013, 08:04
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Так всё и происходит , только при выходе он успевает сделать одну - две команды основного цикла и снова туда -> в обработчик прерывания. Так доходчивее?


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
Sirko
сообщение Feb 1 2013, 09:01
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795



Цитата
пока программа ковыряется внутри

У меня в настоящий момент в обработчике единственное присваивание, причем код я привел с двухбайтным вариантом, а на самом деле я опрашиваю лишь ADCH.
Тактирование ацп - clk / (128 * 13). Так. что для "ногодрыга" в основном коде полторы тысячи тактов с лихвой.

Понятное дело - это то, что я ожидаю от проца. А что творится на самом деле, а главное, как и почему - я не понимаю.
Go to the top of the page
 
+Quote Post
doublekey
сообщение Feb 1 2013, 19:00
Сообщение #9


Участник
*

Группа: Свой
Сообщений: 71
Регистрация: 28-01-08
Из: Zelenograd
Пользователь №: 34 503



В даташите на странице 247 написано:
Код
When Auto Triggering is used, the prescaler is reset when the trigger event occurs

Насколько я понимаю у вас ADATE в 1, получается надо в прерывании задавать заново prescaler.

Да, похоже тут я не прав.
Попробуйте сбрасывать запрос прерывания в обработчике записывая 1 в ADIF.
Или такой вариант:
Изначально прерывание уже выставлено, и при инициализации включается автоматическое преобразование и происходит переход в обработчик прерывания, а prescaler не задаётся (хотя маловероятно).
Можно попробовать при инициализации ADCSRA также сбрасывать ADIF, а ADATE задавать в следующей команде.

Сообщение отредактировал doublekey - Feb 1 2013, 19:53
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Feb 1 2013, 22:05
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата
Попробуйте сбрасывать запрос прерывания в обработчике записывая 1 в ADIF
.
Цитата
Да, похоже тут я не прав.
ещё раз и далее по тексту


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
doublekey
сообщение Feb 2 2013, 07:39
Сообщение #11


Участник
*

Группа: Свой
Сообщений: 71
Регистрация: 28-01-08
Из: Zelenograd
Пользователь №: 34 503



Хм, но вот проверил у себя на плате, инициализирую АЦПшник вот так, и всё работает
Код
void
adc_init (void)
{
  // Включаем блок АЦП.
  ADCSRA = _BV(ADEN);
  // Выбираем внутренний источник опорного напряжения.
  // Выравнивание результата по правой границе.
  // В качестве входа используется ADC0.
  ADMUX = _BV(REFS0) | _BV(REFS1);
  // Выбираем предделитель частоты.
  // Разрешаем прерывание от АЦП.
  // Включаем режим автоматического преобразования.
  ADCSRA |= _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0) | _BV(ADIE) | _BV(ADATE);
  // Запускаем преобразование.
  ADCSRA |= _BV(ADSC);
}
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Feb 2 2013, 09:53
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Код
ADCSRA = _BV(ADEN);
ADCSRA |= _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0) | _BV(ADIE) | _BV(ADATE);
ADCSRA |= _BV(ADSC);

Охренеть!!! 15(минимум) команд для запуска ADC

to Sirko

Отключите непрерывное и проверьте что у Вас происходит в прерывании. Сделайте Single Conversion


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
doublekey
сообщение Feb 2 2013, 10:22
Сообщение #13


Участник
*

Группа: Свой
Сообщений: 71
Регистрация: 28-01-08
Из: Zelenograd
Пользователь №: 34 503



Код
   e:    80 e8           ldi    r24, 0x80; 128
  10:    86 b9           out    0x06, r24; 6
  12:    80 ec           ldi    r24, 0xC0; 192
  14:    87 b9           out    0x07, r24; 7
  16:    86 b1           in    r24, 0x06; 6
  18:    8f 62           ori    r24, 0x2F; 47
  1a:    86 b9           out    0x06, r24; 6
  1c:    36 9a           sbi    0x06, 6; 6

Команд всего 8, с учётом загрузки ADMUX, без загрузки - 6. Есть подозрение, что может быть косяк с выставлением ADSC одновременно с конфигурацией остальных битов в ADCSRA.
Ещё интересно, бит I в SREG выставляет до конфигурации АЦП или после.
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Feb 2 2013, 11:06
Сообщение #14


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



А должно быть -2


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
doublekey
сообщение Feb 2 2013, 11:45
Сообщение #15


Участник
*

Группа: Свой
Сообщений: 71
Регистрация: 28-01-08
Из: Zelenograd
Пользователь №: 34 503



ILYAUL, так тема про то, что человек написал инициализацию ADCSRA в 2 инструкции, и такой код оказывается неработоспособным, но вы настаиваете, что инициализация должна выполняться именно так.
Есть такой момент, что если производить запись в регистры АЦП когда бит ADEN ещё не установлен, не понятно, запишется что-нибудь или нет, ведь блок выключен и enable на регистры не подаётся. Так вот, если выставлять ADEN в ADCSRA в одной команде вместе с остальными битами, то запись в остальные биты может не производиться, поскольку enable ещё не выставлен (ведь он защёлкнется только в этом такте), именно поэтому ADCSRA = _BV(ADEN); вынесено в отдельную команду. И следующей командой может идти запись в остальные биты ADCSRA, поскольку в этом случае блок АЦП гарантированно включен.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st June 2025 - 11:41
Рейтинг@Mail.ru


Страница сгенерированна за 0.01597 секунд с 7
ELECTRONIX ©2004-2016