Jump to content

    
Sign in to follow this  
Slavik_tz

АЦП и энергосберегающий режим

Recommended Posts

Вот код программы

void InitADC(void)

{

set_sleep_mode(SLEEP_MODE_ADC);//инициализировать енергосберегающий режим

uart_puts("\r MCUCR=");

uart_puti((int)MCUCR);

SET_FRENCH();//устанавливает частоту 112КГц (частота кварца 14 318 180Гц (ADCRA|=_BV(ADPS2)|_BV(ADPS1)|_BV(ADPS0)))

ADCCR|=_BV(ADEN);//Выбрать одиночное преобразования

ADMUX|=_BV(REFS0)|_BV(ADLAR);//результ преобразование выравнивается в левую сторону 8бит

ADCCR|=_BV(ADIE);//разрешить прерывание по окончанию преобразования АЦП

uart_puts("\r ADCCR=");

uart_puti((int)ADCCR);

uart_puts("\r ADMUX=");

uart_puti((int)ADMUX);

TCCR0|=_BV(CS01);

TCNT0=0;

ADCCR|=_BV(ADSC);//запустить АЦП

sleep_mode();//перйти в енергосберегающий режим

TCCR0=0;

uart_puts("\r Timer=");

uart_puti((int)TCNT0);

}

результат таков:

MCUCR=16 (00010000b)

ADCCR=143 (10001111b)

ADMUX=96 (01100000b)

Timer=5

вопрос: почему таймер =5, если должен быть равен 25(первое одиночное преобраз)*128(коеффициент деления АЦП)/8 mod(255)= 145 (прерываний от таймера нет), от чего может быть

 

и следующее вот функция

//Функция получения температуры, параметр kan=номер канала

unsigned int GetTemp(uint8_t kan)

{

volatile unsigned int Temp=0;//значение температуры возращаемое функцией

ADMUX+=kan;

TCCR0|=_BV(CS00);

TCNT0=0;

ADCCR|=_BV(ADSC);//запустить преобразование

//sleep_mode();//ждать пока не закончиться

TCCR0=0;

Temp=(unsigned int)ADCH;//результат в регистр

// _delay_us(1);

uart_puts(" Timer=");

uart_puti((int)TCNT0);

uart_puts(" Temp=");

uart_puti(Temp);

uart_puts(" ");

ADMUX&=~_BV(MUX0)&~_BV(MUX1)&~_BV(MUX2);

return Temp+170;// прибавить начальные установки

}

SIGNAL(SIG_ADC)

{

;

}

 

вопрос следующего характера если раскоментировать sleep_mode() вообще эта функции не работает,

от чего может возникать прерывание, в Proteus sleep вообще не работает, это его глюк или я что-то делаю не так

Share this post


Link to post
Share on other sites

А вы твердо уверены, что в sleep-моде АЦП должен продолжать нормально работать? Мне что-то кажется, что АЦП не должен работать (правильно оцифровывать напряжение), когда процессор погружен в спячку (энерго-сбегающий режим). Ведь работа АЦП это одна из больших статей расхода электроэнерии и со спящим режимом она врядли совместима.

Share this post


Link to post
Share on other sites
А вы твердо уверены, что в sleep-моде АЦП должен продолжать нормально работать? Мне что-то кажется, что АЦП не должен работать (правильно оцифровывать напряжение), когда процессор погружен в спячку (энерго-сбегающий режим). Ведь работа АЦП это одна из больших статей расхода электроэнерии и со спящим режимом она врядли совместима.

Вы меня не поняли, согласно документации на микроконтроллеры, для того, что бы данные были наиболее коректны, останавливается процессор (не создает шумов при преобразовании), а АЦП работает. И при возникновении прерывания от него или же от других источников возобновляет свою работу.

Share this post


Link to post
Share on other sites
Вы меня не поняли, согласно документации на микроконтроллеры...

 

Тогда будьте добры, назовите свой микроконтроллер. А то что-то я не найду ни одного, у которого был бы регистр ADCCR. Бывает регистр ADCR, но из него данные читают, а флаги интеррапта туда не кладут.

Share this post


Link to post
Share on other sites
Вы меня не поняли, согласно документации на микроконтроллеры,...

Посмотрите в документацию, насколько я помню, в режиме снижения шума АЦП преобразование запускается автоматически по входу в этот режим, т. е. после команды sleep (у Вас я так понимаю sleep_mode)

Еще посмотрите какой таймер работает в этом режиме, например у меги48, 88, 168 работает только таймер2 в асинхронном режиме (т. е. с внешним тактированием). Вы не указали модель Вашего контроллера, но по-моему у мег все достаточно одинаково.

Если то что я предположил верно, то таймер0 начнет считать когда контроллер проснется, соответственно насчитает как раз около 5.

Share this post


Link to post
Share on other sites

ADCCR определен макросом. если ATMega16, то ADCSRA, если Mega8 то ADCSR

вот именно что 5, если установить таймер=тактовой частоте процесоора, то 40, то получается что прерывание происходить не по оканчанию преобразования АЦП. И я задавал вопрос, может кто-то знает sleep в Proteus не обрабатывается, то есть после команды sleep, все идет так как б ее и не было. Это глюк в Протеусе?

На данный момент используется процессор ATMega16. Заранее спасибо

Share this post


Link to post
Share on other sites

если закоментровать //set_sleep_mode(SLEEP_MODE_ADC);//инициализировать енергосберегающий режим

то получится Idle (по умолчанию), и все начинает работать так как надо, просмотрев ассемблерный код то биты устанавливаються правельно, в чем траблы.

Share this post


Link to post
Share on other sites
если закоментровать //set_sleep_mode(SLEEP_MODE_ADC);//инициализировать енергосберегающий режим

то получится Idle (по умолчанию), и все начинает работать так как надо, просмотрев ассемблерный код то биты устанавливаються правельно, в чем траблы.

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

When the SM2..0 bits are written to 001, the SLEEP instruction makes the MCU enter ADC

Noise Reduction mode, stopping the CPU but allowing the ADC, the External Interrupts, the

Two-wire Serial Interface address watch, Timer/Counter2 and the Watchdog to continue operat-

ing (if enabled). This sleep mode basically halts clkI/O, clkCPU, and clkFLASH, while allowing the

other clocks to run.

Краткое содержание абзаца: режим ADC Noise Reduction останавливает ЦПУ, но позволяет фунциклировать АЦП, внешним прерываниям, TWI (в режиме слежения за адресом), Таймеру/Счетчику2 и Сторожевой_собаке (ясный пень если эти модули включены). В данном режиме останавливается тактирование ЦПУ, ввода-вывода (IO), и флеш, остальное тактирование работает.

 

Timer/Counter1 and Timer/Counter0 share the same prescaler module, but the Timer/Counters

can have different prescaler settings. The description below applies to both Timer/Counter1 and

Timer/Counter0

 

The Timer/Counter can be clocked directly by the system clock (by setting the CSn2:0 = 1). This

provides the fastest operation, with a maximum Timer/Counter clock frequency equal to system

clock frequency (fCLK_I/O). Alternatively, one of four taps from the prescaler can be used as a

clock source. The prescaled clock has a frequency of either fCLK_I/O/8, fCLK_I/O/64, fCLK_I/O/256, or

fCLK_I/O/1024.

Краткое содержание абзацев: таймер/счетчк0 и таймер/счетчик1 имеют один и тот же модуль предделителя, но могут иметь индивидуальные настройки предделителя. Следующее описание относится к таймеру/счетчику0 и к таймеру/счетчику1.

Таймер/счетчик может татктироаться как напрямую от системного тактового сигнала, так и от поделенного на 8, 64, 256 или 1024. Далее судя по обозначениям предделитель таймеров тактируется от тактового сигнала ввода-вывода, что подтверждает рисунок 39 на следующей (88-ой) странице названного даташита.

Ну и собственно выводы:

Поскольку тактовая ввода-вывода выключена в режиме ADC Noise Reduction, то и таймер считать не будет, ибо на его вход не приходят тактовые импульсы. Считать он начнет только когда эти пресловутые импульсы появятся на его входе, т. е. при выходе из котроллера из sleep. Соответственно таймер, судя по Вашему коду, насчитает совсем немного до того момента когда будет остановлен (ну может еще немного насчитает до момента входа контроллера в слип).

P. S. Наболело.

Edited by smac

Share this post


Link to post
Share on other sites
...

Насчет таймера, я понял, на спасибо за комент.

Но вопрос в другом, почему по разному ведет себя микроконтроллер с режимами Idle и ADC Noise Reduction (вот по этой причине был закручен таймер).

Edited by IgorKossak
Бездумное цитирование

Share this post


Link to post
Share on other sites
Насчет таймера, я понял, на спасибо за комент.

Но вопрос в другом, почему по разному ведет себя микроконтроллер с режимами Idle и ADC Noise Reduction (вот по этой причине был закручен таймер).

Вы что издеваетесь? Вы в документацию-то загляните, там написано, что он должен вести себя по разному т. к. Idle и ADC Noise Reduction это разные режимы.

Share this post


Link to post
Share on other sites
Вы что издеваетесь? Вы в документацию-то загляните, там написано, что он должен вести себя по разному т. к. Idle и ADC Noise Reduction это разные режимы.

А я не говорил что они одинаковые и заглядывал, а там написано что прерывание от АЦП в режиме ADC Noise Reduction

возможно.

Алгоритм програмы

1. Запускаем АЦП

2. переходим в енергосберг. режим (Idle, ADC Noise Reduction), ждем в спящем режиме прерывание от АЦП и продолжаем выполнение дальше (больше никакие прерывания не разрешены)

3. считываем данные из АЦП

4. меняем канал

5.. передаем данные на ПК через UART

6. возращаемся в 1

и в этом случае ведет по-разному

а на вопрос по Proteus: энергосберегающий режим симулируется в нем или нет, так никто и не ответил

Share this post


Link to post
Share on other sites
и в этом случае ведет по-разному
Вы не четко сформулировали свой вопрос. Я бы даже сказал: совсем не сформулировали. По всей видимости, Вы переводите МК то в Idle mode, то в ADC Noise Reduction mode и спрашиваете: "Почему МК ведёт себя по-разному?". На что получаете вполне ожидаемый ответ: "Потому, что режимы разные!". Попробуйте сформулировать свой вопрос, примерно, так: "Я делаю вот так. В соответствии с п.хх DS должен был получить то-то, у меня получилось вот так. Почему?"

 

а на вопрос по Proteus: энергосберегающий режим симулируется в нем или нет, так никто и не ответил
Проверять работу МК симуляторами - не лучшее решение. На вопрос "Почему у меня в симуляторе не работает?" - охотников отвечать найдётся немного...

Share this post


Link to post
Share on other sites
а на вопрос по Proteus: энергосберегающий режим симулируется в нем или нет, так никто и не ответил

 

Режим "ADC NOISE REDUCTION" для Attiny13 в протеусе 7.5 у меня симулировался. А вот например "POWER SAVE" на ATmega168 не захотел.

Share this post


Link to post
Share on other sites
просмотрев ассемблерный код то биты устанавливаються правельно, в чем траблы.

потому что протеус - правЕльный инструмент.

Если пользовать правЕльные инструменты, нарушать правЕла правопЕсания - пЕсать "правЕльно" и "пробЫвать", вместо того чтобы

1. читать документацию,

2. думать,

3. работать с железом,

4. писать на русском без ошибок,

то будет еще больше вопросов и, очевидно, "правЕльных".

 

PS: сорри наболело, от таких ошибок как "правельно и пробывал" уже в глазах рябит, а от протеуса - и проблем с ним просто тошнит.

Share this post


Link to post
Share on other sites

свои 5 коп. внесу по поводу протеусов etc..

Давно отказался от всевозможной симуляции.Посчитайте время потраченное на "сражения" с протеусом а потом ВНЕЗАПНО выясняется что после превращения в железо все равно всплывают некоторые "нюансы" на которые тоже нужно потратить время. Потому сразу собираю железо (ЛУТ технология ессно - ибо быстро и дешево) ,разбиваю программу на кусочки (если не были опробованы и отлажены в предыдущем проекте) и "гоняю" до выявления всевозможных неясностей\глюков (как правило глюки заключаются в собственной невнимательности).

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this