ADC Attiny13 состояние после вкл\вкл

Обсуждаем контроллеры компании Atmel.
dds7sdd
Прорезались зубы
Сообщения: 207
Зарегистрирован: Чт дек 07, 2017 13:48:44

ADC Attiny13 состояние после вкл\вкл

Сообщение dds7sdd »

Приветствую!

Что то я запутался в старых граблях... Нужно включить АЦП, подождать завершения преобразования, получить 8-битный результат и сравнить его с заданным.
Если результат выше заданного - задать переменной power_limit значение "1", которое не должно изменяться на протяжении работы всей программы.
Сброс переменной power_limit в "0" должно происходить после отключения питания микроконтролера.

Но этого не происходит! В симуляторе естественно все работает. В живую - нет.
Ждал ADIF =0 в цикле, так же ждал ADSC=0 в цикле и не фига...
Курил SREG, но видимо мало...
Короче уже 3 часа ипусь...
Освежите плиз заскорузглою мою память)) Спс!

Тестовый код:

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

volatile unsigned int adc_val;
int power_limit=0;

int main(void){

DDRB=1<<DDB3|0<<DDB2|1<<DDB0;
PORTB=0<<PB3|1<<PB2|0<<PB0;

ADMUX=0<<REFS0|1<<ADLAR|1<<MUX0;
ADCSRA=1<<ADEN|1<<ADATE|1<<ADSC|1<<ADPS1|1<<ADPS2;

while(1){
ADCSRA|=1<<ADSC;
while ((ADCSRA & (1 << ADIF)) == 0) {
adc_val = ADCH;}
     
if(adc_val >150) { PORTB |=(1<<PB3); power_limit=1;} else {PORTB&=~(1<<PB3);power_limit=0;}
if (power_limit>=1) {PORTB|=1<<PB0; power_limit=0;} 

 }
}
Файл симуляции Proteus во вложении.

Если работать в 10-битном режиме (то бишь ADLAR=0 и читать изначально ADCL), - все то же самое.

Если подождать 30 мил. сек. , а затем принимать результат преобразования - то все работает.
Но это как то не есть правильно на мой взгляд.
Вопрос: Почему переменная АЦП, до начала преобразования, равна максимуму (то есть if ADC = 150 при запуске программы истинно, хотя физически это не так).
Точнее работает так: вкл. питания--запуск АЦП--получение результата--сравнение (adc_val >150)--если да-вкл светодиод. При первом запуске это работает. После наступления истинности (adc_val >150) и последующем выкл\вкл питания МК истинность (adc_val >150) остается (30 микросекунд) истинной, хотя в реальность adc_val<50 например...

Где то я проеб момент в Datashet аля SREG например, но потратив уже 3 часа на "это" утомилсО.

Короче, нужен свежий взгляж на даташит в сравнении с моей "творчестью")))
СПС

UPD: Еще проще по просьбе трудящихся: нужно что бы после наступления power_limit=1 и последующей перезагрузке микроконтроллера power_limit=0. УСЁ
Вложения
ADC_Attiny13.zip
(21.21 КБ) 100 скачиваний
Реклама
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15562
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: ADC Attiny13 состояние после вкл\вкл

Сообщение BOB51 »

После отключения питания в МК ничего не исполняется.
8)
Обычно есть флаги контроля подачи питания и статуса МК после сброса (по включению питания, по собаке, выходу из спящего режима и прочему) - то смотреть внимательно в документации на МК надо. Зачем что-то ещё выдумывать то?
Ежли уж очень хочется не имеющиеся флажки использовать, а переменную... Тогда ищем под флаговую переменную какой - нибудь регистр, что по сбросу согласно даташитины автоматически обнуляется и используем его (если такое использование не повредит чему то другому).
:tea:
Реклама
Paktok
Первый раз сказал Мяу!
Сообщения: 24
Зарегистрирован: Вт апр 23, 2024 11:36:23

Re: ADC Attiny13 состояние после вкл\вкл

Сообщение Paktok »

Есть практика после ресета обнулять все регистры, срам и тд. Ну всё. Срам особенно, там всякий хлам может остаться.
metan
Вымогатель припоя
Сообщения: 593
Зарегистрирован: Ср янв 06, 2010 10:01:46

Re: ADC Attiny13 состояние после вкл\вкл

Сообщение metan »

1. Привыкайте нормально форматировать код, как у вас - плохо читать
2. Непонятно, что это:

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

while ((ADCSRA & (1 << ADIF)) == 0) {
adc_val = ADCH;}
Зачем что-то читать, если результат еще не готов? Или я чего - то не понимаю...

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

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


#define ADC_VREF_TYPE 0x00  // заменить на свою настройку опорника

.....

// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input) {
  ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);

  // Delay needed for the stabilization of the ADC input voltage
  delay_us(50);

  // Start the AD conversion
  ADCSRA|=0x40;

  // Wait for the AD conversion to complete
  while ((ADCSRA & 0x10)==0);

  ADCSRA|=0x10;
  return ADCW;
}
Реклама
Эиком - электронные компоненты и радиодетали
veso74
Поставщик валерьянки для Кота
Сообщения: 1907
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: ADC Attiny13 состояние после вкл\вкл

Сообщение veso74 »

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

volatile unsigned int adc_val;
int power_limit = 0;

int main(void) {
  DDRB = 1 << DDB3 | 0 << DDB2 | 1 << DDB0;
  PORTB = 0 << PB3 | 1 << PB2 | 0 << PB0;

  ADMUX = 0 << REFS0 | 1 << ADLAR | 1 << MUX0;
  ADCSRA = 1 << ADEN | 1 << ADATE | 1 << ADSC | 1 << ADPS1 | 1 << ADPS2;

  while (1) {
    ADCSRA |= 1 << ADSC;

    while ((ADCSRA & (1 << ADIF)) == 0);

    adc_val = ADCH;

    if (adc_val > 150) {
      PORTB |= (1 << PB3);
      power_limit = 1;
    }
    else {
      PORTB &= ~(1 << PB3);
      power_limit = 0;
    }

    if (power_limit >= 1) {
      PORTB |= 1 << PB0;
      power_limit = 0;
    }
  }
}
Расположите код так, чтобы он был читаемым. И сразу видно. Просто дождитесь завершения преобразования. И результат -> в ADC есть.
---
Попробовал схему и код на реальном устройстве. После отключения питания (есть всего 100 nF к +5V) и через напр. секунду выходы в исходное состояние.
Реклама
dds7sdd
Прорезались зубы
Сообщения: 207
Зарегистрирован: Чт дек 07, 2017 13:48:44

Re: ADC Attiny13 состояние после вкл\вкл

Сообщение dds7sdd »

[uquote="metan",url="/forum/viewtopic.php?p=4611317#p4611317"]1. Привыкайте нормально форматировать код, как у вас - плохо читать
2. Непонятно, что это:
while ((ADCSRA & (1 << ADIF)) == 0) {
adc_val = ADCH;}
[/code]Зачем что-то читать, если результат еще не готов? Или я чего - то не понимаю...[/uquote]

1. То есть читать код с шестнадцатеричными значениями по вашему удобнее?))))
Это лучше уж вы привыкайте писать используя названия битов в регистрах.
2. А что тут непонятного? Цикл как раз и ждет когда флаг ADIF станет равен "0", что свидетельствует о завершении преобразования. После чего читаем значение в переменную.

Добавлено after 22 minutes 28 seconds:
[uquote="veso74",url="/forum/viewtopic.php?p=4611425#p4611425"]Расположите код так, чтобы он был читаемым. И сразу видно. Просто дождитесь завершения преобразования. И результат -> в ADC есть.
---
Попробовал схему и код на реальном устройстве. После отключения питания (есть всего 100 nF к +5V) и через напр. секунду выходы в исходное состояние.[/uquote]

Чем мой код менее читаем чем вы представили?)) Мне наоборот куча пробелов и расположение кода в столбик приносит дискомфорт.
Разве есть стандарт представления кода схожий с Вашим написанием?
Код идентичен и в моем случае не работает так как мне нужно. А нужно мне, что бы условие:

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

if (power_limit>=1) {PORTB|=1<<PB0; power_limit=0;} 
при перезагрузке МК было ложным, а оно остается истинным в течении 30 мс....

Повторю результат работы этого тестового кода:

1. Вкл. питания (power_limit в этот момент равно "0");
2. Перемещаем потенциометр пока adc_val не станет >150;
3. power_limit становится равным 1 и включается светодиод на PB0;
4. Возвращаем потенциометр в исходное состояние. adc_val <150, power_limit=1 и остается таким до отключения питания;
5. Откл. питание.
6. Вкл. питание и выражение if (power_limit>=1) {PORTB|=1<<PB0; power_limit=0;} есть истинным на протяжении 30 мс. Горит светодиод на PB0, А Я ЭТОГО ХОЧУ ИЗБЕЖАТЬ.

Товарищ выше использует delay (50). Я по другому, но это все задержки и влияет на скорость чтения.
Реклама
veso74
Поставщик валерьянки для Кота
Сообщения: 1907
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: ADC Attiny13 состояние после вкл\вкл

Сообщение veso74 »

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

while ((ADCSRA & (1 << ADIF)) == 0) {
adc_val = ADCH;}
и

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

while ((ADCSRA & (1 << ADIF)) == 0);
adc_val = ADCH;
Второк код более очевидно напишу так:

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

while ((ADCSRA & (1 << ADIF)) == 0) 
{};
adc_val = ADCH;
Между этими двумя строками есть разница.

Если хотите, напишите код всей программы в одну строку. В вашем случае это просто не видно издалека.
А компилятором все равно как написано.
Последний раз редактировалось veso74 Вт авг 06, 2024 20:16:13, всего редактировалось 1 раз.
dds7sdd
Прорезались зубы
Сообщения: 207
Зарегистрирован: Чт дек 07, 2017 13:48:44

Re: ADC Attiny13 состояние после вкл\вкл

Сообщение dds7sdd »

Простите, а в чем разница между написанием цикла со скобками и без?)))
Может просвещусь))
А почему Вас тогда главный цикл со скобками в вашем же коде не смущает?

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

while(1){some code;}
:facepalm:
Аватара пользователя
>TEHb<
Друг Кота
Сообщения: 5740
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Откуда: Воронеж
Контактная информация:

Re: ADC Attiny13 состояние после вкл\вкл

Сообщение >TEHb< »

Во втором случае цикл ждёт, а потом читает.
"Привет!" - соврал он.
dds7sdd
Прорезались зубы
Сообщения: 207
Зарегистрирован: Чт дек 07, 2017 13:48:44

Re: ADC Attiny13 состояние после вкл\вкл

Сообщение dds7sdd »

Специально для Вас скомпилировал - не работает, чего и следовало ожидать ибо писать цикл со скобками или без нет никакой разницы! Компилятору все равно! Это стандарт С. И это логично: пока не выполнится условие цикла не будет выполнен код последующий за ним (хоть в скобках хоть без).

А по теме Paktok прав, вопрос можно решить очисткой памяти SRAM после подачи питания на МК.
В целом же нужно перечитать еще раз даташит на АЦП AVR.

Добавлено after 1 minute 36 seconds:
[uquote=">TEHb<",url="/forum/viewtopic.php?p=4611775#p4611775"]Во втором случае цикл ждёт, а потом читает.[/uquote]

Поясните.
А в первом что? Ждет и читает одновременно?
Последний раз редактировалось dds7sdd Вт авг 06, 2024 20:26:24, всего редактировалось 1 раз.
Аватара пользователя
>TEHb<
Друг Кота
Сообщения: 5740
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Откуда: Воронеж
Контактная информация:

Re: ADC Attiny13 состояние после вкл\вкл

Сообщение >TEHb< »

Не так. Код в скобках выполняется пока условие верно. Как только становится неверно, тело цикла не выполняется, программа идёт дальше.
"Привет!" - соврал он.
veso74
Поставщик валерьянки для Кота
Сообщения: 1907
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: ADC Attiny13 состояние после вкл\вкл

Сообщение veso74 »

9,6 MHz
Вложения
adc_1_attiny13a_9600000L.hex
(410 байт) 78 скачиваний
dds7sdd
Прорезались зубы
Сообщения: 207
Зарегистрирован: Чт дек 07, 2017 13:48:44

Re: ADC Attiny13 состояние после вкл\вкл

Сообщение dds7sdd »

[uquote=">TEHb<",url="/forum/viewtopic.php?p=4611778#p4611778"]Не так. Код в скобках выполняется пока условие верно. Как только становится неверно, тело цикла не выполняется, программа идёт дальше.[/uquote]

Ха, да, то что я привел в качестве тестового кода имеет место где расположен цикл (в реальной программе чтение АЦП происходит в векторе прерывания таймера и там это не имеет значения). veso74 просто не объяснил в контексте конкретного кода.

Признаю. В конкретном, приведенном мною коде:

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

while (1) {
//---некий код 1---
whilе (ADIF==0) {
ADC-val=ADCH;
}
//--некий код 2---
}
В этом случае код 1 и код 2 выполняется пока не наступит условие ADIF=0. Далее выполняется только тело цикла (код 2 не выполняется), пока ADIF не станет равным "1".

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

while (1) 
//---некий код 1---
whilе (ADIF==0) 
ADC-val=ADCH;
//--некий код 2---
В этом случае будет код 1 и код 2 выполняется пока не наступит условие ADIF=0. Далее выполняется код 2, пока ADIF не станет равным "1".

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

Добавлено after 2 minutes 46 seconds:
[uquote="veso74",url="/forum/viewtopic.php?p=4611780#p4611780"]9,6 MHz[/uquote]

Нет, это не работает.
veso74
Поставщик валерьянки для Кота
Сообщения: 1907
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: ADC Attiny13 состояние после вкл\вкл

Сообщение veso74 »

Иногда мне сложно объяснить из-за языкового барьера. Частично пишу с переводчиком БГ -> РУ.
Работает. Вчера я вращал потенциометр на бредборде в течение напр. 10 минут. Выключал и включал питание. Оставил его включенным LED2 на долгое время, уже сработавшим и т. д. hex файл оттуда. И на симуляторе работает. Ищите причину в другом месте.
dds7sdd
Прорезались зубы
Сообщения: 207
Зарегистрирован: Чт дек 07, 2017 13:48:44

Re: ADC Attiny13 состояние после вкл\вкл

Сообщение dds7sdd »

Вот упростил до самого простого:

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

while(1){
ADCSRA|=1<<ADSC;
while ((ADCSRA & (1 << ADIF)) == 0); 
adc_val = ADCH;

if(adc_val>150) {power_limit=1;} 
if (power_limit>=1) {PORTB|=1<<PB0;} else {PORTB&=~1<<PB0;}
При включении питания светодиод PB0 светится, а не должен...
Аватара пользователя
Starichok51
Модератор
Сообщения: 19053
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: ADC Attiny13 состояние после вкл\вкл

Сообщение Starichok51 »

dds7sdd, поскольку у тебя не разрешено прерывание от АЦП, для проверки окончания преобразования неправильно использовать флаг прерывания ADIF.
следует использовать флаг ADSC. по окончания преобразования он автоматически сбрасывается в ноль.
поэтому следует записать так:
ADCSRA|=1<<ADSC;
while ((ADCSRA & (1 << ADSC)) == 1);
adc_val = ADCH;
пока флаг ADSC = 1, цикл топчется на месте, как только появится ADSC = 0, цикл завершится и произойдет чтение результата.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
veso74
Поставщик валерьянки для Кота
Сообщения: 1907
Зарегистрирован: Сб май 05, 2012 20:24:52
Откуда: KN34PC, Болгария
Контактная информация:

Re: ADC Attiny13 состояние после вкл\вкл

Сообщение veso74 »

Задавался вопросом себе, почему ADC там в Free Running Modе?
Бы использовал Single Conversion Modе.
metan
Вымогатель припоя
Сообщения: 593
Зарегистрирован: Ср янв 06, 2010 10:01:46

Re: ADC Attiny13 состояние после вкл\вкл

Сообщение metan »

Starichok51 писал(а):неправильно использовать флаг прерывания ADIF
почему же? Кто запрещает?
Просто если прерывание битом ADIE не разрешено, то никакого прерывания вызвано не будет. И бит ADIF в случае отсутствия прерывания нужно чистить ручками, как в коде, который я привел (у ТСа не чистится).
Аватара пользователя
Starichok51
Модератор
Сообщения: 19053
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: ADC Attiny13 состояние после вкл\вкл

Сообщение Starichok51 »

veso74, он установил бит ADATE (триггерный запуск), а регистр ADCSRB не инициализировал. поэтому у него получился Free Running Modе.
ему нельзя ставить бит ADATE, тогда будет Single Conversion Modе.
metan, в том и то и дело, что у него не чистится.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
dds7sdd
Прорезались зубы
Сообщения: 207
Зарегистрирован: Чт дек 07, 2017 13:48:44

Re: ADC Attiny13 состояние после вкл\вкл

Сообщение dds7sdd »

[uquote="Starichok51",url="/forum/viewtopic.php?p=4611887#p4611887"]поэтому следует записать так:
ADCSRA|=1<<ADSC;
while ((ADCSRA & (1 << ADSC)) == 1);
adc_val = ADCH;
пока флаг ADSC = 1, цикл топчется на месте, как только появится ADSC = 0, цикл завершится и произойдет чтение результата.[/uquote]

Прочитал об этом в даташите еще до создания поста. Пункт 14.4 даташита (стр. 90):
If Auto Triggering is enabled, single conversions can be started by writing ADSC in ADCSRA to
one. ADSC can also be used to determine if a conversion is in progress. The ADSC bit will be
read as one during a conversion, independently of how the conversion was started.
Пробовал в разных вариантах кода (и в обработчике, и в цикле и ифами) Не работает... Попробую вечером ещё, может где то натупил.
Достала меня эта вся история... Не получится - попробую перети в сингл мод, вкл. прерывания и буду использовать ADIF... Но тогда эти прерывания повлияют на всю программу... или буду ждать эти 30 мс, а потом читать ADCH, что тоже не ахти.
Ответить

Вернуться в «AVR»