Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Помогите с АЦП
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Ogonik
Вобщем проблема следующая (только начал писать, так что вопрос может быть тупым):

работаю с mega16.
нужно поргнать через АЦП последовательность, которая читается из внешнего файла.
Для этого я цепляю немного измененный SetupAdvanced.mac из туториала. Изменения соответственно сделаны по адресу входного файла и по адресу прерывания.

После make ошибок и предупреждений нету.

Код:
Код
// enable use of extended keywords
#pragma language=extended
#include <iom16.h>
#include <stdio.h>
#include <inavr.h>
#include <main.h> // пользовательский хедер

#ifndef ENABLE_BIT_DEFINITIONS
#define ENABLE_BIT_DEFINITIONS
// Enable the bit definitions in the iom16.h file
#endif

void InitADC(void)
{//REFS1,REFS0,ADLAR,MUX4,MUX3,MUX2,MUX1,MUX0 reverse
  MUX = ((1<<0)|(0<<1)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6)|(0<<7));
//ADEN,ADSC,ADATE,ADIF,ADIE,ADPS2,ADPS1,ADPS0 reverse
  ADSR1= ((1<<0)|(0<<1)|(1<<2)|(1<<3)|(0<<4)|(0<<5)|(1<<6)|(1<<7));
}

void InitPort(void)
{
DDRA=0x00;
DDRB=0xff;
}

void do_foreground_process( void )
{
  putchar('.');
}

// The showstopper
int callCount = 0;

// IRQ handler
#pragma vector=ADC_vect
__interrupt void irqHandler(void)
{
  int a_1 = ADC;
  ADC=0;
  int out=a_1;
  
    unsigned int dec = 10, temp;

  putchar ( '\n' );//перенос строки
  //выделение десятков и единиц
  
  while ( dec <= out ) //10^x dec ближайшее значение
  dec *= 10;

  while ( (dec/=10) >= 10 )
  {
    temp = out/dec;
    putchar ( '0' + temp );
    out -= temp*dec;
  }

  putchar ( '0' + out );

  // increment the show stopper
  ++callCount;

}

main( void )
{
  InitADC();
  InitPort();  

  __enable_interrupt();

  /* now loop 'forever', taking input when interrupted */
  while (1)
  {
    do_foreground_process();
  }

}


проблема в следующем: функция Accsess() почему-то вызывается дважды при попадании на это прерывание, а нужно чтобы было один раз, поскольку значения в ADC складываются.
Код
Fri Dec 15 00:13:43 2006: Loaded macro file: E:\Учеба\MC\new\SetupAdvanced.mac
Fri Dec 15 00:13:43 2006: Loaded debugee: E:\Учеба\MC\new\Debug\Exe\new.d90
Fri Dec 15 00:13:43 2006: Target reset
Fri Dec 15 00:13:43 2006: execUserReset() called
Fri Dec 15 00:13:43 2006: execUserSetup() called
Fri Dec 15 00:13:45 2006: Access() called
Fri Dec 15 00:13:45 2006: ADC = 0x00000001
Fri Dec 15 00:13:45 2006: Access() called
Fri Dec 15 00:13:45 2006: ADC = 0x00000001
Fri Dec 15 00:13:45 2006: Breakpoint hit: Code @ main.c:39.7


Что посоветуете, может это можно как-нибудь по-другому сделать?
И если можно по-быстрее курсач на следующей неделе сдавать, а в AVR Studio писать не охота, да и очень хочется на С научиться нормально писать.

Заранее всем спасибо! smile.gif

p.s. Извиняюсь, что ошибся разделом... blush.gif
Artem-1.6E-19
Нет, убивать ложкой!!!
Код:
Код
// enable use of extended keywords
#pragma language=extended
#include <iom16.h>
#include <stdio.h>
#include <inavr.h>
#include <main.h> // пользовательский хедер

#ifndef ENABLE_BIT_DEFINITIONS
#define ENABLE_BIT_DEFINITIONS
// Enable the bit definitions in the iom16.h file
#endif

void InitADC(void)
{//REFS1,REFS0,ADLAR,MUX4,MUX3,MUX2,MUX1,MUX0 reverse
#define  REFS1 0
#define  REFS0 1
#define  ADLAR 2 бла-юла-бла
Тогда
  MUX = ((1<<REFS1)|(0<<REFS0)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6)|(0<<7));
А еще лучше
  MUX = (
               (1<<REFS1)| // Флаг готовки к перемене власти, один - к свержению текущей власти готов.
               (0<<REFS0)| // Готовность к свержению Фиделя Кастро. 1 - Отравленные сигары доставлены, ждем зеленого свистка.
               (0<<2)| // Признак счастья.  Когда один, значит что у меня прекрасная семья, умный начальник и много денег.

Ну неужели вы думаете что кому-то приятно лазить по PDF и разбираться что все же значит.
Насчет всего остального, скорее всего у вас ADC просто работает гораздо быстрее чем UART успевает все это выводить наружу.

И пишите человечески, что вы хотите выводить через последовательный порт (скорость итд) информацию. полученную. с АЦП в последовательном виде.
Ogonik
Цитата(Artem-1.6E-19 @ Dec 15 2006, 01:02) *
Код
void InitADC(void)
{//REFS1,REFS0,ADLAR,MUX4,MUX3,MUX2,MUX1,MUX0 reverse
#define  REFS1 0
#define  REFS0 1
#define  ADLAR 2 бла-юла-бла
Тогда
  MUX = ((1<<REFS1)|(0<<REFS0)|(0<<2)|(0<<3)|(0<<4)|(0<<5)|(0<<6)|(0<<7));
А еще лучше
  MUX = (

Насчет всего остального, скорее всего у вас ADC просто работает гораздо быстрее чем UART успевает все это выводить наружу.


За поправки в определении спасибо.. Но не в нем дело. Я же ясно указал на проблему, что АЦП вызывается два раза.

И в порт я вообще выводить пока ничего не собираюсь.
Правда если окно Terminal I/O является симулятором UART, тогда я не прав. Я хочу просто получить в этом окне (Terminal I/O) значения которые записаны в файле, и все. До вывода в порт я пока не добрался.
xemul
Неразумно выполнять в прерывании от АЦП кроме чтения результата еще и его преобразование в 10-тичку, и вывод куда-то. Если хочется результат выдать наружу, делайте это вместо вывода '.'
Как Вам уже сказали, АЦП может выдавливать из себя данные гораздо быстрее, чем УАРТ их передавать (действительно лень ползать по даташиту и считать, с какой частотой в Вашем случае запускается АЦП).
Ну и монструозное преобразование в 10-тичку - выполните профилирование (даже без "putchar ( '0' + temp );") и подивитесь его скорострельности.
BTW: 8-битовыми контроллерами unsigned int в арифметике обрабатывается быстрее, чем int.
Ogonik
Цитата
Неразумно выполнять в прерывании от АЦП кроме чтения результата еще и его преобразование в 10-тичку, и вывод куда-то. Если хочется результат выдать наружу, делайте это вместо вывода '.'

Видимо я просто не очень понимаю что делает функция putchar...

И еще, если я закомментирую все строчки с putchar, то при этом чтение из АЦП выполняться почему-то не будет, то есть не будет выхова процедуры Acceess().

И я что-то пока не сильно понимаю в какие моменты запускается simultaneous breakpoint, на котором у меня чтение и висит.

Цитата
Как Вам уже сказали, АЦП может выдавливать из себя данные гораздо быстрее, чем УАРТ их передавать...
Ну и монструозное преобразование в 10-тичку - выполните профилирование (даже без "putchar ( '0' + temp );") и подивитесь его скорострельности.


То есть получается что окошко Terminal I/O эмулирует UART?
И можно по подробнее что такое профилирование?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.