Например TDA7294

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

Текущее время: Пт июл 25, 2025 23:40:05

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


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



Начать новую тему Ответить на тему  [ Сообщений: 10 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: AtMega16 - Проблема с кодом АЦП
СообщениеДобавлено: Вс ноя 11, 2012 03:38:44 
Первый раз сказал Мяу!
Аватар пользователя

Зарегистрирован: Вс фев 19, 2012 23:16:44
Сообщений: 20
Рейтинг сообщения: 0
Первый раз делаю код с использованием АЦП. В принципе выучил все регистры и биты по части АЦП.. Но все же не работает..

Код:
#include <avr/io.h>
#include <avr/interrupt.h>
#define StartConvAdc() ADCSRA |= (1<<ADSC) 
#define KEY_NULL  0
#define KEY_S1    1
#define KEY_S2    2
#define KEY_S3    3
#define KEY_S4    4

volatile unsigned char KeyBuf = 0;

int main(void)
{
DDRC = 0xff;
PORTC = 0xff;

unsigned char tmp;
 
ADMUX = (0<<REFS1)|(1<<REFS0)|(1<<ADLAR)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0);  //
ADCSRA = (1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); // вкл. ацп, режим одиночного преобр., разрешение прер., частота преобр. = FCPU/128

StartConvAdc();  // Запустить преобразование
 while(1)
  {
   tmp = KeyBuf;
    if (tmp)
    {
      tmp--;
      PORTC = ~(1<<tmp);
    }
    else
      PORTC = 0xff;
  }
  return 0;
}


#pragma vector=ADC_vect
_AVR_INTERRUPT_H_ void adc_my(void)

void adc_my(void)
{                                         //Ошибку в этом месте выдает
   sei();   
  unsigned char AdcBuf = ADCH;

  if (AdcBuf > 240)    //опеределяем в какой диапазон попадает его значение
    KeyBuf = KEY_S4;
  else if (AdcBuf > 180)
    KeyBuf = KEY_S3;
  else if (AdcBuf > 120)
    KeyBuf = KEY_S2;
  else if (AdcBuf > 35)
    KeyBuf = KEY_S1;
  else
    KeyBuf = KEY_NULL;
 

  StartConvAdc();  //запускаем преобразование и выходим
{
   
}


Взято с http://chipenable.ru/index.php/programm ... ast-2.html
Схема подключения


Не смотря на ошибку со открытой скобкой в конце (которой вроде как не должно быть, но без нее ошибка), выдается ошибка Error 2 expected '=', ',', ';', 'asm' or '__attribute__' before '{' token (обозначил это месте в коде).

В чем проблема?

Заменил только __interrupt на _AVR_INTERRUPT_H_, как в заголовочнике avr/interrupt.h (ибо код был писан вроде как на CodeVisionAVR ). Правильно же?
Даже если этот interrupt заменить на sei(); , и код без ошибок компилится, то схема не работает. При подключении питания мигнут быстро 2 светодиода из всех и дальше тишина.. (не смотря на изменения напряжений на входе АЦП).


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: AtMega16 - Проблема с кодом АЦП
СообщениеДобавлено: Вс ноя 11, 2012 23:18:55 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 21
Рейтинг сообщений: 143
Зарегистрирован: Сб фев 21, 2009 13:11:40
Сообщений: 1900
Откуда: Москва
Рейтинг сообщения: 0
объясните, зачем в основном цикле декрементируется переменная tmp?

функцию вот так перепишите:
Код:
void adc_my(void) 
{                                         //Ошибку в этом месте выдает
   sei();   
  unsigned char AdcBuf 
= ADCH;

  if (AdcBuf > 240)    //опеределяем в какой диапазон попадает его значение
    KeyBuf = KEY_S4;
  else if (AdcBuf > 180) 
    KeyBuf 
= KEY_S3;
  else if (AdcBuf > 120) 
    KeyBuf 
= KEY_S2;
  else if (AdcBuf > 35) 
    KeyBuf 
= KEY_S1;
  else 
    KeyBuf 
= KEY_NULL;  

  StartConvAdc
();  //запускаем преобразование и выходим   
} 


по поводу __interrupt вряд ли кто-то ответит точно, до того, как вы признаетесь каким компилятором пользуетесь.

_________________
Ставим плюсы: )


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: AtMega16 - Проблема с кодом АЦП
СообщениеДобавлено: Пн ноя 12, 2012 03:05:01 
Первый раз сказал Мяу!
Аватар пользователя

Зарегистрирован: Вс фев 19, 2012 23:16:44
Сообщений: 20
Рейтинг сообщения: 0
Спасибо за ответ!
Пардон, забыл написать что исполюзую AVR Studio.

Такой код:
Не работает. Вообще молчит.
Код:
#include <avr/io.h>
#include <avr/interrupt.h>
#define StartConvAdc() ADCSRA |= (1<<ADSC) 
#define KEY_NULL  0
#define KEY_S1    1
#define KEY_S2    2
#define KEY_S3    3
#define KEY_S4    4

volatile unsigned char KeyBuf = 0;

int main(void)
{
DDRC = 0xff;
PORTC = 0xff;

unsigned char tmp;
 
ADMUX = (0<<REFS1)|(1<<REFS0)|(1<<ADLAR)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0);  //
ADCSRA = (1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); // вкл. ацп, режим одиночного преобр., разрешение прер., частота преобр. = FCPU/128

sei();
StartConvAdc();  // Запустить преобразование
 while(1)
  {
   tmp = KeyBuf;
    if (tmp)
    {
      tmp--;
      PORTC = ~(1<<tmp);
    }
    else
      PORTC = 0xff;
  }
  return 0;
}


#pragma vector=ADC_vect

void adc_my(void)
{                                         //Ошибку в этом месте выдает
   sei();   
  unsigned char AdcBuf = ADCH;

  if (AdcBuf > 240)    //опеределяем в какой диапазон попадает его значение
    KeyBuf = KEY_S4;
  else if (AdcBuf > 180)
    KeyBuf = KEY_S3;
  else if (AdcBuf > 120)
    KeyBuf = KEY_S2;
  else if (AdcBuf > 35)
    KeyBuf = KEY_S1;
  else
    KeyBuf = KEY_NULL; 

  StartConvAdc();  //запускаем преобразование и выходим   
}




А вот такой код работает:
Код:

#include <avr/io.h>
#include <avr/interrupt.h>

ISR(ADC_vect)
{
 
   PORTD = ADCH;         // Output ADCH to PortD
   ADCSRA |= 1<<ADSC;      // Start Conversion
}
 
int main(void)
{
   DDRD = 0xFF;         // Configure PortD as output
   DDRA = 0x00;         // Configure PortA as input
                      // PA0 is ADC0 input
   ADCSRA = 0x8F;         // Enable the ADC and its interrupt feature
               // and set the ACD clock pre-scalar to clk/128
   ADMUX = 0xE0;         // Select internal 2.56V as Vref, left justify
               // data registers and select ADC0 as input channel
   sei();            // Enable Global Interrupts
   ADCSRA |= 1<<ADSC;      // Start Conversion
   while(1);         // Wait forever
}


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: AtMega16 - Проблема с кодом АЦП
СообщениеДобавлено: Пн ноя 12, 2012 03:07:44 
Первый раз сказал Мяу!
Аватар пользователя

Зарегистрирован: Вс фев 19, 2012 23:16:44
Сообщений: 20
Рейтинг сообщения: 0
Мне вот что посоветовали..

Цитата:
В модуле interrupts.h есть функции:
cli(); - глобально запрещает все прерывания.
sei(); - глобально разрешает все прерывания.
Тебе нужна вторая.
Вообще я рекомендовал бы тебе юзать эти функции в обработчике прерывания. То есть к примеру так:
SIGNAL(__vect_7)
{
cli();
...... //Что-то делаем
sei();

}


sei(); я использовал.. А вот с этим сигналом.. Не понимаю как его использовать..


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: AtMega16 - Проблема с кодом АЦП
СообщениеДобавлено: Пн ноя 12, 2012 03:25:16 
Первый раз сказал Мяу!
Аватар пользователя

Зарегистрирован: Вс фев 19, 2012 23:16:44
Сообщений: 20
Рейтинг сообщения: 0
ibiza11 писал(а):
объясните, зачем в основном цикле декрементируется переменная tmp?

Нуу.. Она содержит в себе данные с переменной KeyBuf.. Хотя если я Вас правильно понял, то можно и без нее..
немножко вырезать кода и получится:


PORTC = ~(1<<KeyBuf;);


if (AdcBuf > 240)
KeyBuf = KEY_S4;
else if (AdcBuf > 180)
KeyBuf = KEY_S3;
else if (AdcBuf > 120)
KeyBuf = KEY_S2;
else if (AdcBuf > 35)
KeyBuf = KEY_S1;
else
KeyBuf = KEY_NULL;

Только я не понимаю зачем tmp--




UPD.
Крутил, мутил, так у меня ничего и не вышло..
Помогите плс с кодом.. :)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: AtMega16 - Проблема с кодом АЦП
СообщениеДобавлено: Пн ноя 12, 2012 05:02:23 
Первый раз сказал Мяу!
Аватар пользователя

Зарегистрирован: Вс фев 19, 2012 23:16:44
Сообщений: 20
Рейтинг сообщения: 0
Прошу прощения за кучу постов, но я так разделяю свои... мыслы, скажем так..

PS.
Вот на этом коде работает.. На светодиоды выводятся значение рагистра ADCH Значит проблемы с кодом а не со схемой.. (на макетной плате собираю.. )

Код:
#include <avr/io.h>
#include <avr/interrupt.h>
int main(void)
{
DDRD = 0xFF;
PORTD = 0xFF;

PORTD = ADCH;

 ADMUX = (0<<REFS1)|(1<<REFS0)|(1<<ADLAR)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0);  //
 ADCSRA = (1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); // вкл. ацп, режим одиночного преобр., разрешение прер., частота преобр. = FCPU/128
 sei();
    ADCSRA |= 1<<ADSC;

   while(1);
}


Вернуться наверх
 
Распродажа паяльного оборудования ATTEN!
Паяльные станции, паяльники и аксессуары по самой выгодной цене.

По промокоду radiokot скидка 10%
Не в сети
 Заголовок сообщения: Re: AtMega16 - Проблема с кодом АЦП
СообщениеДобавлено: Пн ноя 12, 2012 10:29:39 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 21
Рейтинг сообщений: 143
Зарегистрирован: Сб фев 21, 2009 13:11:40
Сообщений: 1900
Откуда: Москва
Рейтинг сообщения: 0
в общем алгоритм программы такой:
1) инициализируем порты ввода/вывода
2) инициализируем АЦП, включаем прерывание окончания преобразования и запускаем преобразование
3) разрешаем глобальные прерывания
4) В безконечном цикле проверяем переменную KeyBuf ---> 4)

прерывание окончания преобразования АЦП:
1) чтение значения преобразования
2) сравнение его с границами значений
3) установка переменной KeyBuf
4) запуск очередного преобразования
5) выход

Вы разберитесь какой кусок кода за что из вышеприведенного списка отвечает и вставляйте последовательно в код. Вот и все)

_________________
Ставим плюсы: )


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: AtMega16 - Проблема с кодом АЦП
СообщениеДобавлено: Вт ноя 13, 2012 18:25:36 
Первый раз сказал Мяу!
Аватар пользователя

Зарегистрирован: Вс фев 19, 2012 23:16:44
Сообщений: 20
Рейтинг сообщения: 0
Спасибо за помощь!
Но сам код я знаю идеально, что и как делает. Ошибку в коде получилось найти.. Я решил сделать код попроще..

Код:
#include <avr/io.h>
#include <avr/interrupt.h>

int main(void)
{
DDRD = 0xFF;// Конфигурируем порт как выход
PORTD = 0xff; // Выключаем изначально светодиоды

 ADMUX = (0<<REFS1)|(1<<REFS0)|(1<<ADLAR)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0);  //питание AVcc с внешним кондером на AREF, дефолтная запись в реестр, данные с канала ADC0
 ADCSRA = (1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); // вкл. ацп, режим одиночного преобр., разрешение прер., частота преобр. = FCPU/128

sei(); // разрешаем глобальные прерывания
//ADCSRA |= 1<<ADSC;  // запускаем преобразование

 unsigned char AdcBuf = ADCH; // чтение значения преобразования и запись в переменную AdcBuf

 if (AdcBuf > 50) // Проверяем уровень сигнала и при совпадении включаем светодиод
   PORTD = 0xff;
 else
 PORTD = 0x00;

  //ADCSRA |= 1<<ADSC; // запуск очередного преобразования
  while(1);
} // выход


Код идеально работает..


Последние 2 вопроса.

1) Если мне не достаточно первых 8 бит преобразования ( ADCH) и я хочу использовать и (ADCL) для точности, то как быть? Писать как-то типа AdcBuf = ADCH+ADCL; ? Типа сумировать для более точной цифры..
2) Если у меня на одной микрухе будет и ШИМ, и АЦП и обычный код обрабатывается, то как сделать чтобы оно не тормозило? Ну то честь я читал что код запускается и обрабатывается последовательно (по порядку).. То есть должно быть если в коде ШИМ пауза стоит, то она будет останавливать (пока не пройдет пауза) весь ниже написанный код.. Или я не прав? Если и прав, то как сделать чтобы одно другого не тормозило? Писать всё не в main а разбить как-то на ф-ции.. Пфф.. Я не понимаю..

Спасибо.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: AtMega16 - Проблема с кодом АЦП
СообщениеДобавлено: Вт ноя 20, 2012 21:42:46 
Встал на лапы

Зарегистрирован: Вс авг 22, 2010 09:23:08
Сообщений: 95
Рейтинг сообщения: 0
stridemann писал(а):
Писать как-то типа AdcBuf = ADCH+ADCL; ? Типа сумировать для более точной цифры..

Спасибо.

ADCH= старший байт, надо умножить на 256 (режим 10 бит)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: AtMega16 - Проблема с кодом АЦП
СообщениеДобавлено: Вт ноя 20, 2012 23:03:12 
Первый раз сказал Мяу!
Аватар пользователя

Зарегистрирован: Вс фев 19, 2012 23:16:44
Сообщений: 20
Рейтинг сообщения: 0
svs39 писал(а):
ADCH= старший байт, надо умножить на 256 (режим 10 бит)


Дада, я это уже понял, спасибо :)


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 10 ] 

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


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

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


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

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


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