Например TDA7294

Форум РадиоКот • Просмотр темы - АЦП в режиме Auto Triggering
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Вс дек 14, 2025 22:32:39

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 7 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: АЦП в режиме Auto Triggering
СообщениеДобавлено: Вс янв 07, 2024 12:58:31 
Родился

Зарегистрирован: Вс янв 07, 2024 12:31:51
Сообщений: 7
Рейтинг сообщения: 0
Уважаемые форумчане, всех с праздниками!
Пытаюсь использовать АЦП AVR в режиме периодического автозапуска от таймера.
Код пытается работать, опрос АЦП осуществляется, но почему-то ровно 2 раза, а не до бесконечности, как планировалось.
После этого код висит в вечном цикле (проверял, тестовый код в вечном цикле корректно выполняется), а прерывание АЦП не вызывается более 2 раз.

Тестирую на ATmega16, тактовая частота 4МГц, на входе потенциометр, результат наблюдаю в программе-читалке COM-порта.
По задумке должно возникать событие Compare Match B таймера 1 с частотой 2Гц (проверял, возникает c нужной частотой),
которое автотриггерит АЦП, запуская прерывание АЦП по окончанию преобразования (запускается, но ровно 2 раза, если жать на Reset, то снова 2 раза и дальше тишина до Reset),
в прерывании АЦП результат отправляю по UART (результат корректный, по UART доходит)
Использую Microchip Studio 7.0, оптимизация отключена.

Помогите, товарищи! Сломал всю голову, скурил весь даташит, ничего не понимаю! Возможно, глаз замылился, но не настолько же! Четвертые сутки бьюсь с простеньким, вроде бы, кодом (

Код ниже:
Код:
#include <avr/io.h>
#include <avr/interrupt.h>

void init();
void uart_init();
void timer1_init();
void adc_init();
void uart_send( char x );

ISR( ADC_vect )
{
    uart_send( ADCH );
}

int main(void)
{
   init();
      
    while (1){}
}

void init()
{
    uart_init();
   timer1_init();
   adc_init();
   
   sei();
}

void uart_init()
{
    UBRRL = 25; // 9600bod at CLK = 4MHz
    UCSRB = 1 << TXEN;       
}

void timer1_init()
{
   OCR1A   = 31250;
   OCR1B   = OCR1A;
   TCCR1B  = ( 1 << WGM12 ) | ( 1 << CS11 ) | ( 1 << CS10 ); // /64 2Hz at CLK=4MHz
}

void adc_init()
{
    ADMUX  = ( 1 << REFS0 ) | ( 1 << ADLAR ); // PA0, AVCC, PA0
   SFIOR  = ( 1 << ADTS2 ) | ( 1 << ADTS0 ); // COMPB
   ADCSRA = ( 1 << ADEN )  | ( 1 << ADSC ) | ( 1 << ADATE ) | ( 1 << ADIE ) | ( 1 << ADPS2 ) | ( 1 << ADPS0 ); //COMPB, ADCclk=125kHz
   
}

void uart_send( char x )                           
{
    while ( !( UCSRA & ( 1 << UDRE ) ) );       
    UDR = x;                                     
}


Вложения:
Комментарий к файлу: Исходник в виде файла
main.c [978 байт]
Скачиваний: 53
Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: АЦП в режиме Auto Triggering
СообщениеДобавлено: Вс янв 07, 2024 15:01:40 
Модератор
Аватар пользователя

Карма: 153
Рейтинг сообщений: 2926
Зарегистрирован: Сб авг 14, 2010 15:05:51
Сообщений: 18891
Откуда: г. Озерск, Челябинская обл.
Рейтинг сообщения: 0
Медали: 1
Лучший человек Форума 2017 (1)
первый запуск АЦП происходит потому, что ты при инициализации АЦП сразу задал ADSC - старт преобразования.
второй запуск, видимо, происходит по заданному триггеру.
убери (1 << ADSC), должен остаться один запуск.
но почему нет повторов "до бесконечности" я сказать не могу.

_________________
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: АЦП в режиме Auto Triggering
СообщениеДобавлено: Вс янв 07, 2024 15:23:43 
Родился

Зарегистрирован: Вс янв 07, 2024 12:31:51
Сообщений: 7
Рейтинг сообщения: 0
Если убрать (1 << ADSC) при инициализации, то запуск только один, я пробовал. Что тоже странно, ибо, как я понимаю даташит, опрос АЦП стартует только после выставления start conversion (если не брать во внимание энергосберегающие режимы).
Попа какая-то, простите за физиологию.. Уже в errata полез от горя, но не нашел там поддержки(

Добавлено after 4 minutes 31 second:
Пробовал выставлять ADSC <- 1 в main(), после разрешения глобальных прерываний, давал длинные задержки перед этим (даташит говорит, что модули АЦП могут инициализироваться 1 * CLKadc + какое-то там время), результат идентичен

Добавлено after 8 minutes 5 seconds:
Можно, конечно, в прерывании таймера руками выставлять ADSC - режим однократного опроса, так работает, но какого x***, если есть заявленный автотриггер? Понять бы, кто тупой, я, или микрочип?! Начинаю сомневаться .. в микрочипе


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: АЦП в режиме Auto Triggering
СообщениеДобавлено: Вс янв 07, 2024 16:02:31 
Модератор
Аватар пользователя

Карма: 153
Рейтинг сообщений: 2926
Зарегистрирован: Сб авг 14, 2010 15:05:51
Сообщений: 18891
Откуда: г. Озерск, Челябинская обл.
Рейтинг сообщения: 0
Медали: 1
Лучший человек Форума 2017 (1)
после задания (1 << ADSC) АЦП стартует сразу же, не ожидая запуска по триггеру.
у тебя же старт должен происходить по триггеру, без установки этого бита.
в даташите на АТмега16 я не нашел, чтобы бит ADATE сам сбрасывался. но по поведению похоже, что бит сбрасывается и запуск по триггеру происходит однократно.
но ты можешь попробовать в прерывании от АЦП заново установить этот бит ADATE, и посмотреть, будет ли автостарт повторяться.

_________________
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.


Вернуться наверх
 
Эиком - электронные компоненты и радиодетали
Не в сети
 Заголовок сообщения: Re: АЦП в режиме Auto Triggering
СообщениеДобавлено: Вс янв 07, 2024 16:11:02 
Открыл глаза
Аватар пользователя

Карма: -8
Рейтинг сообщений: -43
Зарегистрирован: Ср дек 06, 2023 23:51:29
Сообщений: 51
Откуда: 48
Рейтинг сообщения: 2
Флаг OC1B надо вручную сбрасывать, т.к. обработчик отсутствует.
Добавьте
Код:
TIFR |= (1 <<  OCF1B);
в обработчик ADC.
Иначе, OC1B так и продолжает висеть, и новый строб не проходит.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: АЦП в режиме Auto Triggering
СообщениеДобавлено: Вс янв 07, 2024 16:45:14 
Родился

Зарегистрирован: Вс янв 07, 2024 12:31:51
Сообщений: 7
Рейтинг сообщения: 0
Флаг OC1B надо вручную сбрасывать, т.к. обработчик отсутствует.
Добавьте
Код:
TIFR |= (1 <<  OCF1B);
в обработчик ADC.
Иначе, OC1B так и продолжает висеть, и новый строб не проходит.


Мать моя, женщина, точно, просохатил! Спасибо огромное, заработало! :)

Добавлено after 4 minutes 33 seconds:
после задания (1 << ADSC) АЦП стартует сразу же, не ожидая запуска по триггеру.
у тебя же старт должен происходить по триггеру, без установки этого бита.
в даташите на АТмега16 я не нашел, чтобы бит ADATE сам сбрасывался. но по поведению похоже, что бит сбрасывается и запуск по триггеру происходит однократно.
но ты можешь попробовать в прерывании от АЦП заново установить этот бит ADATE, и посмотреть, будет ли автостарт повторяться.


И тоже верно, я неправильно прочитал даташит, понял так, что на самое первое преобразование надо ставить ADSC, но нет

Вот верный код, если кого-то заинтересует:
Код:
#include <avr/io.h>
#include <avr/interrupt.h>

void init();
void uart_init();
void timer1_init();
void adc_init();
void uart_send( char x );

ISR( ADC_vect )
{
    uart_send( ADCH );
   
   TIFR |= (1 <<  OCF1B);
}

int main(void)
{
   init();
      
    while (1){}
}

void init()
{
    uart_init();
   timer1_init();
   adc_init();
   
   sei();
}

void uart_init()
{
    UBRRL = 25; // 9600bod at CLK = 4MHz
    UCSRB = 1 << TXEN;       
}

void timer1_init()
{
   OCR1A   = 31250;
   OCR1B   = OCR1A;
   TCCR1B  = ( 1 << WGM12 ) | ( 1 << CS11 ) | ( 1 << CS10 ); // /64 2Hz at CLK=4MHz
}

void adc_init()
{
    ADMUX  = ( 1 << REFS0 ) | ( 1 << ADLAR ); // PA0, AVCC, PA0
   SFIOR  = ( 1 << ADTS2 ) | ( 1 << ADTS0 ); // COMPB
   ADCSRA = ( 1 << ADEN )  | ( 1 << ADATE ) | ( 1 << ADIE ) | ( 1 << ADPS2 ) | ( 1 << ADPS0 ); //COMPB, ADCclk=125kHz
   
}

void uart_send( char x )                           
{
    while ( !( UCSRA & ( 1 << UDRE ) ) );       
    UDR = x;                                     
}


Добавлено after 2 minutes 10 seconds:
Спасибо всем огромное !
Да, Старик, прочитал, независимо от автотриггера можно ставить ADSC и будет лишь внеочередной опрос, все так! При автотриггере, действительно, устанавливать ADSC не требуется
Братцы, вы - мозг!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: АЦП в режиме Auto Triggering
СообщениеДобавлено: Вс янв 07, 2024 20:32:17 
Открыл глаза
Аватар пользователя

Карма: -8
Рейтинг сообщений: -43
Зарегистрирован: Ср дек 06, 2023 23:51:29
Сообщений: 51
Откуда: 48
Рейтинг сообщения: 0
Не забывайте, что у Вас время оцифровывания всего-лишь 1-го канала 124 микросекунды.
Изображение
Изображение
Это я хочу дополнить, к дальнейшему развитию Вашего проекта.


Вложения:
Комментарий к файлу: Calculator
Безымянный1.png [6.69 KiB]
Скачиваний: 178
Комментарий к файлу: Conversion time
Безымянный.png [20.42 KiB]
Скачиваний: 181
Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 7 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 32


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y