я вообще не понимаю смысл в фоторезисторе, тем более с намёками в коде на фотометрию.
есть копеечные готовые модули
цумбайшпиль https://aliexpress.ru/item/1005001572932920.html
куча плюсов
+ 16 разрядов разрешение, 120 мс измерение, калиброванная шкала.
+ функция режекции светового шума 50 гц
и т.д. и т.п.
https://cxem.net/izmer/files/izmer154_bh1750fvi-e.pdf
А обработчик прерывания остался прежний? Попробуйте великий инженерный подход "разделяй и властвуй" . Запретите прерывания, весь функционал из него перенесите в общий цикл, вставьте явную проверку готовности результата после запуска АЦП, добейтесь устойчивой работы. А потом подумайте о коммуникации между основным циклом и обработчиком, может явные флажки завести на каждый случай или еще чего захочется. После этого разделяйте функционал на обработчик и цикл, проверяя, что все срослось. Оно может дольше, но "широко шагаешь - штаны порвешь"
Спасибо от Ромм
Да, обработчик не менял...
Согласен с Вами, здравый подход для достижения результата, но хочется понять почему в таком виде то не работает.
Вроде бы все по даташиту:
- старт преобразования;
- прерывание по окончании преобразования и присвоение результата переменной;
- вывод на дисплей.
Казалось бы, чего проще? А не работает, зараза!
Кстати - комментарии к программе наводят на мысль, что речь идет о самодельном фотоэкспонометре ? Я бы для такой задачи вместо фоторезистора взял специализированный сенсор с цифровым выходом, можно ожидать лучшей стабильности и воспроизводимости результатов. BH1750, TSL2561 (доступны на ali за копейки, в виде модулей в том числе). Что, впрочем, не мешает разобраться с ADC микроконтроллера, потому что рано или поздно все равно пригодится.
upd - а, меня уже опередили !
Последний раз редактировалось rx3apf; 13.03.2021 в 10:22.
Спасибо от Ромм
Отложите выполнение дальше, пока не будет завершено измерение АЦП. В Вашем коде не контролируете то, что произошло.
или по крайней мере добавьтеКод:while(ADCSRA & (1<<ADSC));
Код:_delay_us(10);
Спасибо от Ромм
Огромное Вам спасибо!!! Работает.
Но как же быть с тем, что прерывание должно наступать ПО ОКОНЧАНИИ преоБразования?
while (1)
{
lcd_clear();
//lcd_puts("Privet!");
//delay_ms(1000);
//lcd_clear();
//delay_ms(1000);
//lcd_clear();
ADMUX=0b01000101; // выбор ADC5 фоторезистор
ADCSRA=0b11001111; // старт преобразования
delay_ms(10);
//A=adc_data*0.048; // вычисление значения измеренного напряжения
B=adc_data;
//lcd_gotoxy(1,1);
sprintf(temp,"%u", B);
lcd_puts(temp);
//A=0;
//B=0;
//adc_data=0;
//delay_ms(1000);
ADMUX=0b01000100; // ADC4 клавиатура
ADCSRA=0b11001111; // старт преобразования
delay_ms(10);
// A=adc_data*0.0048; // клавиатура
B=adc_data;
// B=floor(A);
lcd_gotoxy(1,1);
// sprintf(temp,"%5f", A);
sprintf(temp,"%u", B);
//delay_ms(5000);
//lcd_clear();
//sprintf(temp,"%05f", B);
lcd_puts(temp);
// A=0;
//adc_data=0;
delay_ms(100);
}
Эта переменая меняется из ISR и читается в main(). Следует добавить квалифайер volatile, иначе компилятор (особенно со включенной оптимизацией) может вычитывать один раз и на этом всё.
К слову, если у вас таки не получится победить - у меня был на другом компе мелкий проект под атмега8 с ацп, делал аналайзер на ад9851 и логдекторе из FM IF. Могу завтра порыться, правда он под gcc.
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)