Краткий Курс - программирование AVR - часть VII

 
1 6 7 8 9 10 11 12
RU termostat #21.11.2005 12:26
+
-
edit
 

termostat

аксакал

может задача 3new курса тебе поможет ? там про это.

=====

Если ты считаешь "срабатывание" таймера - прерывание или переполнение то это зависит и от делителя и от числа заносимового в регистр таймера - с этого числа таймер считает до 255.

Т.е. чем больше число тем быстрей переполняется таймер.


Всеже нужна модель конденсатора для ВМЛАБа - оказалось что его модель говно. Обнаружил я баг при отладке ПИД алгоритма.

SAA

втянувшийся

termostat> может задача 3new курса тебе поможет ? там про это.
termostat> =====
termostat> Если ты считаешь "срабатывание" таймера - прерывание или переполнение то это зависит и от делителя и от числа заносимового в регистр таймера - с этого числа таймер считает до 255.

А прерывание в чистом виде разве от таймера 0 возможно? Только по переполнению я полагаю?

Сейчас глянул AVRBuilder -
128000 ns (срабатывание таймера), 32768mcs (Overflow) (что я неосторожно принял за 32768 Гц)

Таким образом Fср. = 7812,5, и я все таки прав вычисляя Tср = Tck/1024

Но поскольку прерывания у меня получается сильно быстрее для OVERFLOW, чем я расчитываю (намного быстрее) то я уже и не знаю чего думать ;) Очевидно что я где то туплю, но понять не могу где.

termostat> Т.е. чем больше число тем быстрей переполняется таймер.

Угу именно так. Т.е. по моим расчетам получается одна цифра в таймере, а на практике получается гораздо меньше. Ощущение как будто внутренний RC лупит с частотой чуть ли не в двое большей.

termostat> ============
termostat> Всеже нужна модель конденсатора для ВМЛАБа - оказалось что его модель говно. Обнаружил я баг при отладке ПИД алгоритма. [»]


Подожди это ты про что, про твой алгоритм для VMLab? Или про алгоритм для Proteus-а?
 
RU termostat #21.11.2005 18:41
+
-
edit
 

termostat

аксакал

PID регулятор сделал - можно использовать в системах регулирования.

по АпНоуту Motorola AN1215.

конвертировал для CodeVisionAVR и симуляция в PROTEUS и в VMLAB

вычисление ПИД занимает ВСЕГО 640 мкС при кварце 8 МГц на ATmega16

======

Инерцию регулируемого объекта изображает конденсатор 0.1 мкФ (аналог массы или момента инерции)

Управляюще воздействие - это ток через резистор 1 МОм (аналог силе и моменту силы)

======

в VMLAB нашел баг - хотя симуляция идет правильно, но напряжение на конденсаторе не меняется если резистор превышает 250 КОм. Похоже это ошибка модели конденсатора.

======

Сделал симуляцию для PROTEUS - там все работает.

======

Результат в графиках Эксель

Верхний график показывает как проискодит установка из крайнего верхнего отклонения.

Нижний график показывает как меняется управляющий ШИМ сигнал.

Горизонтальная ось в 10-ках милиСек - т.е. 80 это 800 мСек.

======

точка куда надо привести регулируемую величину (напряжение на конденсаторе) - это результат АЦП = 500 при этом управляющий ШИМ сигнал имеет величину 503/1024

Форму кривой и колебательность процесса можно подстраивать меняя коэффициенты:

KP = 0.18; /* kp = .12, ki = 6.0, kd = .006, for 1 M ohm drive */
KI = 6.0;
KD = 0.009;

======


хорошая теория автоматических систем регулирования тут:

http://atm.h1.ru/root/theory/theory.html

настройка ПИД регулятора - тут:



Настройка параметров ПИД-регулятора || НПФ КонтрАвт. КИПиА для АСУ ТП: измерители температуры, пид-регуляторы, контроллеры, модули ввода-вывода


Разработка, производство и продажа оборудования КИПиА для автоматизации производства: терморегуляторы, пид-регуляторы и т.д.

// www.contravt.ru
 

Прикреплённые файлы:
 

ROOT

новичок
Народ, привет!

Сейчас собираю устройство на atmega128, столкнулся с проблемой
Это мой первый эксперимент создания устройств на МК.
Задача такая: получить данные с АЦП, обработать, вывести, начать цикл заново.
Проблема: не могу написать программу, корректно ждущую окончания получения нужного мне количества отсчетов. Какая-то ерунда происходит с глобальным переменными. Кажется, чего проще: завести глобальную переменную-флаг окончания оцифровки сигнала, в главном цикле программы while (!conv_ended), потом твои действия, потом опять в режим оцифровки.
Не получается :( Простой вывод значения прерывания АЦП в порт в обработчике прошел без проблем, но вот эта треклятая синхронизация...
Какие могуть быть ошибки? Уже неделю мучаю :)

Схема в proteus, программа в CodeVision.
 
+
-
edit
 

Serge77

модератор

ROOT> Проблема: не могу написать программу, корректно ждущую окончания получения нужного мне количества отсчетов.

Не знаю, поможет ли, но вот так это у меня:

Начало прерывания таймера, ожидание, пока АЦП накопит сумму 64 измерений:


timer0:

;Set Global Interrupt Flag
sei

clr r25
clr tmp
clr tmp1

wait_adc:
; Compare branch if nonEqual
cpi r25,64
brne wait_adc
..................



Обработчик прерывания АЦП:


adc_action:
cpi r25,64
breq end_adc

in r11,ADCL
in r12,ADCH
add tmp,r11
adc tmp1,r12

inc r25

end_adc:
reti



r25 - счётчик количества измерений
+
-
edit
 

termostat

аксакал

ROOT> Задача такая: получить данные с АЦП, обработать, вывести, начать цикл заново.

ROOT> Какие могуть быть ошибки? Уже неделю мучаю :)
ROOT> Схема в proteus, программа в CodeVision. [»]
 


посмотри задачу 5 и 8 курса МК и пример ПИД регулятора чуть выше архивчик.

ROOT

новичок
Serge, спасибо

У меня, в принципе, так же, только на С.

register static enum DEV_MODE
{
M_NONE,
M_FFT,
M_ADC
}
current_mode;

unsigned char last_adc_lo;
unsigned char last_adc_hi;
int last_adc_value;
extern struct cmp data[SAMPLES];
register unsigned char sample_index;

#pragma savereg-
interrupt [ADC_INT] void adc_isr(void)
{
if (current_mode == M_FFT)
return;

#asm
push r26
push r27
push r30
push r31
in r30, sreg
push r30
#endasm

last_adc_lo = ADCL;
last_adc_hi = ADCH;
data[sample_index].x = ADCW;
data[sample_index].y = 0;

// start conversion
ADCSRA |= ADEN;

sample_index++;

if (sample_index >= 8)
{
// go to fft mode
current_mode = M_FFT;
sample_index = 0;
}

#asm
pop r30
out sreg,r30
pop r31
pop r30
pop r27
pop r26
#endasm


PORTB = last_adc_lo;
PORTE = last_adc_hi;
}
#pragma savereg+

В начале, естественно, стандартная инициализация.
так вот, мне не удалось отловить момент (в Proteus), когда sample_index больше 1 (может, он сбрасывается после выхода из прерывания?).
 

ROOT

новичок
To Termostat
Сейчас гляну урок
 
+
-
edit
 

Serge77

модератор

ROOT> У меня, в принципе, так же, только на С

Ничего себе так же! Длинно и непонятно ;^))
RU termostat #21.11.2005 20:31
+
-
edit
 

termostat

аксакал

ROOT> Serge, спасибо
ROOT> У меня, в принципе, так же, только на С.
 


Ты пишешь на Си - это ГУД !

НаФИГА ж ты туда АСМа то напихрл ? ЗАЧЕМ ??? всякие "попы" "пуши" - компилятор то и нужен чтоб ими баловаться у себя "в уме".

Пример АЦП и в sample КодВижена есть.

RU termostat #21.11.2005 20:39
+
-
edit
 

termostat

аксакал

Из папки CVAVR\EXAMPLES\ADC8535

Вот так нужно - простенько:

code text
  1.  
  2.  
  3. // I/O register definitions for AT90S8535
  4. #include <90s8535.h>
  5. // delay functions
  6. #include <delay.h>
  7.  
  8. #define ADC_VREF_TYPE 0x00
  9. // ADC interrupt service routine
  10. interrupt [ADC_INT] void adc_isr(void)
  11. {
  12. // The LEDs will display the 8 most
  13. // semnificative ADC bits
  14. PORTB=(unsigned char) ~(ADCW>>2);
  15. // 20ms delay
  16. delay_ms(20);
  17. // Start a new AD conversion
  18. ADCSR|=0x40;
  19. }
  20.  
  21. void main(void)
  22. {
  23. // Port B initialization
  24. PORTB=0xFF; // all outputs
  25. DDRB=0xFF;  // all LEDs are initially off
  26.  
  27. // ADC initialization
  28. // ADC Clock frequency: 57.656 kHz
  29. // ADC Interrupts: On
  30. ADCSR=0x8E;
  31.  
  32. // Global enable interrupts
  33. #asm("sei")
  34.  
  35. // Select ADC input 0
  36. ADMUX=0;
  37.  
  38. // Start the first AD conversion
  39. ADCSR|=0x40;
  40.  
  41. // All the job is done by ADC interrupts
  42. while (1);
  43. }



=====

1) Начинать нужно всегда с поиска паки с примерами идущими с компилятторами и симуляторами !

2) Кроме того в ДШ на ATмеги есть куски кода и на Си
+
-
edit
 

Serge77

модератор

ROOT> // start conversion
ROOT> ADCSRA |= ADEN;

ROOT> так вот, мне не удалось отловить момент (в Proteus), когда sample_index больше 1

Я так понял, что измерение АЦП ты запускаешь вручную. Может ему просто не хватает времени на завершение?

У меня АЦП работает постоянно, я только данные считываю в прерывании.
RU termostat #22.11.2005 00:14
+
-
edit
 

termostat

аксакал

Увеличил (как бы) управляющее воздействие в 5 раз уменьшив резистор до 200 кОм (с таким резистором и в VMLAB симуляция будет работать) - результат симуляции в прицепе.

Видно что запаздывает изменение требуемого ШИМ = УпрВозд и возникают сильные колебания объекта регулирования. Т.е. нужно менять коэфиценты - настраивать ПИД.
Прикреплённые файлы:
 

SAA

втянувшийся

ROOT> #asm
ROOT> push r26
ROOT> push r27
ROOT> push r30
ROOT> push r31
ROOT> in r30, sreg
ROOT> push r30
ROOT> #endasm

Вот это зря ей богу, компилер сам должен такие вещи делать! Что за компилятор? Да и поздновато ты начал все таки ведь ранее ты уже успел что то проверить и сделать return. WinAVR делает это сразу в преамбуле. И, кроме того проверь ты входишь в обработчик с включенными прерываниями? WinAVR различает эти два случая, если прерывания остались включенными - значит тебе нужно обаботать АЦП как можно скорее.

ROOT> last_adc_lo = ADCL;
ROOT> last_adc_hi = ADCH;
ROOT> data[sample_index].x = ADCW;
ROOT> data[sample_index].y = 0;
ROOT> // start conversion
ROOT> ADCSRA |= ADEN;
ROOT> sample_index++;
ROOT> if (sample_index >= 8)
ROOT> {
ROOT> // go to fft mode
ROOT> current_mode = M_FFT;
ROOT> sample_index = 0;
ROOT> }


ROOT> #asm
ROOT> pop r30
ROOT> out sreg,r30
ROOT> pop r31
ROOT> pop r30
ROOT> pop r27
ROOT> pop r26
ROOT> #endasm

Это тоже здря. Да и не рановато то ли ты это делаешь ;) У тебя ниже еще порты идут.


ROOT> PORTB = last_adc_lo;
ROOT> PORTE = last_adc_hi;
ROOT> }
ROOT> #pragma savereg+

Сделай прерывание как можно короче, обработку вынеси в основной цикл в прерывании только считывание и инкремент. Остальное в главном цикле, не забудь в цикле уйти в "halt" slpeep-ом, тогда после каждого прерывания в системе ты будешь возвращаться в главный цикл и в спокойной обстановке делать обработку (можно даже выключить прерывания на время).


ROOT> В начале, естественно, стандартная инициализация.
ROOT> так вот, мне не удалось отловить момент (в Proteus), когда sample_index больше 1 (может, он сбрасывается после выхода из прерывания?). [»]

Да нет скорее всего ты получаешь вложенность. Какова тактовая частота?
 
Это сообщение редактировалось 22.11.2005 в 06:50

SAA

втянувшийся

Serge77> ----------------------------
Serge77> timer0:
Serge77> ;Set Global Interrupt Flag
Serge77> sei

Странно? Отрабатываешь при включенных прерываниях, а флаги не сохранил, можешь получить ситуацию когда двух коммандный бранч не выполнится потому что прервешься на сравнении например и флаг к возврату потеряешь.

Serge77> clr r25
Serge77> clr tmp
Serge77> clr tmp1
Serge77> wait_adc:
Serge77> ; Compare branch if nonEqual
Serge77> cpi r25,64
Serge77> brne wait_adc

в частности тут например. Нет? Или у тебя все остальные прерывания идут с сохранением флагов?

Serge77> ..................
Serge77> ----------------------------
Serge77> Обработчик прерывания АЦП:
Serge77> ---------------------------
Serge77> adc_action:
Serge77> cpi r25,64
Serge77> breq end_adc
Serge77> in r11,ADCL
Serge77> in r12,ADCH
Serge77> add tmp,r11
Serge77> adc tmp1,r12
Serge77> inc r25
Serge77> end_adc:
Serge77> reti
Serge77> ---------------------------
Serge77> r25 - счётчик количества измерений [»]

В обработчике АЦП тоже вроде не видно что флаги сохраняешь.

 

SAA

втянувшийся

termostat> ======
termostat> в VMLAB нашел баг - хотя симуляция идет правильно, но напряжение на конденсаторе не меняется если резистор превышает 250 КОм. Похоже это ошибка модели конденсатора.
termostat> ======

Это даже того который на общий? Ну что же видимо все таки придется делать конденсатор юзер компонент ;)

termostat> Сделал симуляцию для PROTEUS - там все работает.

Интересно а чем тебя Proteus не устраивает?


P.S. Почему то в своем проекте не могу Proteus заставить отрабатывать динамическую индикацию, загружаю правда hex. Мигнет разок сегмнтом и все, хотя на реальном устройстве отрабатывает нормально. Все настройки уже перешарил, ничего не понимаю. У тебя твоя собсвтенная модель для Proteus на 4 разрядный семисегментник есть на "Си"? Поделись не жалко если, в примерах есть tiny с защелками, но там исходник на asm и компилится из Proteus.

P.P.S. Хотя котрый раз уже убеждаюсь что для AVR лучше натурной модели не придумаешь "симулятора" ;), вот для ARM да трудновато упаковка не позволяет глупых эксперементов ;) и лучше пока чего то не знаешь точно пощупать на симуляторе.


 
+
-
edit
 

Serge77

модератор

SAA> Странно? Отрабатываешь при включенных прерываниях, а флаги не сохранил, можешь получить ситуацию когда двух коммандный бранч не выполнится потому что прервешься на сравнении например и флаг к возврату потеряешь.

Не сохраняю, потому что не знал, что это нужно. Пока ты не сказал.

У меня всего два прерывания работают - таймер и АЦП. Вроде всё в порядке.

А что такое "двух коммандный бранч" ?

SAA

втянувшийся

SAA>> Странно? Отрабатываешь при включенных прерываниях, а флаги не сохранил, можешь получить ситуацию когда двух коммандный бранч не выполнится потому что прервешься на сравнении например и флаг к возврату потеряешь.
Serge77> Не сохраняю, потому что не знал, что это нужно. Пока ты не сказал.
Serge77> У меня всего два прерывания работают - таймер и АЦП. Вроде всё в порядке.
Serge77> А что такое "двух коммандный бранч" ? [»]

Ну может я по деревенски выразился, имел ввиду что сначало ты флаги ставишь а потом по ним переход делаешь:

ставишь флаги любой коммандой которая это делает (CMP,TST....)
..... тут может прейти прерывание......
по результатам установки флагов делается бранч:
brXXX
а вдруг прерывание их изменило?

"Однокомандный" опять же по деревенски это когда сразу и то и другое обрабатывается за один маш.цикл:

CPSE Rd, Rr Compare, Skip if Equal if (Rd = Rr)
SBRC Rr, b Skip if Bit in Register Cleared if (Rr(b) = 0)
SBRS Rr, b Skip if Bit in Register is Set if (Rr(b) = 1)
SBIC P, b Skip if Bit in I/O Register Cleared if (P(b) = 0)
SBIS P, b Skip if Bit in I/O Register is Set


Когда пишу на AVRBuilder стараюсь использовать в обработчиках прерывания где прерывания не запрещены именн эти комманды.
 
+
-
edit
 

Serge77

модератор

SAA> по результатам установки флагов делается бранч:
SAA> brXXX
SAA> а вдруг прерывание их изменило?

Понял! Да, это хорошая мина в коде. Спасибо за подсказку!

SAA> CPSE Rd, Rr Compare, Skip if Equal if (Rd = Rr)

А что делать, если нужно Skip if NON-Equal ?

pokos

аксакал

SAA> Когда пишу на AVRBuilder стараюсь использовать в обработчиках прерывания где прерывания не запрещены именн эти комманды.
В обработчиках прерываний прерывания запрещены, если их специально не разрешить. Так что, предосторожность лишняя.

 
RU termostat #22.11.2005 10:44
+
-
edit
 

termostat

аксакал

"SAA":
Интересно а чем тебя Proteus не устраивает?
 


Да я только начал его юзать.

Но первое это конечно Убогийший осцилограф !!! просто мрак.

Убогийший терминал !

в VMLAB гораздо лучше и многофункциональней оба этих компонента.

======

вобщем Proteus пока только начинаю использовать. Есть конечно и +++

======

Вобщем реальная задача сделать хороший осцилограф для ROTEUSA по типу VMLAB овского, а точней OrCAD'овского. и продавать англоязычным юбителям симуляторов за малую денюжку.

Нужно только добавить некоторые функции.

======

Для VMLAB нужно сделать модель конденсатора (хоть даже связанного с землей! всесто штатного)


\\\\\\\

Вот пример 7-сегментного индикатора на Си

Еще смотри:

AVR241: Direct driving of LCD display using general IO

AVR242: 8-bit Microcontroller Multiplexing LED Drive and a 4x4 Keypad

Welcome to Freescale - Freescale Semiconductor AN2264 LIN 7seg 4dig Температурный дисплей.pdf на Си

и google.com "7 SEGMENT LED"
+
-
edit
 

Serge77

модератор

termostat> Но первое это конечно Убогийший осцилограф !!! просто мрак.

Это точно. Я долго не мог понять, это я не могу найти, как точно измерить напряжение сигнала в конкретной точке, или на самом деле программа этого не позволяет. Оказывается не позволяет.

SAA

втянувшийся

SAA>> Когда пишу на AVRBuilder стараюсь использовать в обработчиках прерывания где прерывания не запрещены именн эти комманды.
pokos> В обработчиках прерываний прерывания запрещены, если их специально не разрешить. Так что, предосторожность лишняя. [»]

Оно понятно, но если для мазохизма разрешить то возможны такие вещи внутри прерываний. Используя комманды CPSE, в основном цикле можно сэкономить на не обязательном сохраннении флагов в обработчиках и оградить себя от неучтенности по флагам - это преимущестов. Очень может быть что этим пользоваться (CPSE) вовсе и не нужно если флаги в каждом прерывании сохраняются ;), о чем вообщем то и шла речь. Но я все же сторонник полного использования ресурсов платформы.
 

SAA

втянувшийся

SAA>> CPSE Rd, Rr Compare, Skip if Equal if (Rd = Rr)
Serge77> А что делать, если нужно Skip if NON-Equal ? [»]

Сам шибко досадовал ;) что Atmel не включила такую полезную вешь в систему комманд, но и понятно почему она же не резиновая. Самое простое что приходит на ум:
CPSE r4,r3
jmp goto_if_NonEqual ; уходим если не равно

for_equla: ; исполняем в случае равно

Или такие же комманды на основе проверки битов SBRC/SBRS


 
AD Реклама Google — средство выживания форумов :)

SAA

втянувшийся

termostat> Вобщем реальная задача сделать хороший осцилограф для ROTEUSA по типу VMLAB овского, а точней OrCAD'овского. и продавать англоязычным юбителям симуляторов за малую денюжку.
termostat> Нужно только добавить некоторые функции.
termostat> ======

Я как то искал на протеус хелп по разработке компонент. Спрашивал у нашего отечественного товарища который написал доку по написанию компонент, но у него NonVisual (меня интересовало Visual), он говорит что раньше шел мануал со старыми пакетами протеуса, сейчас его из поставки исключили.

termostat> Для VMLAB нужно сделать модель конденсатора (хоть даже связанного с землей! всесто штатного)
termostat> \\\\\\\

Ну как я понимаю твоя модель реализует и то и то, или ты хочешь более упрощенную модель из одного единственного компонента для конденсатора с землей. В таком случае описывай как это надо делать. Ты им (VMLab) не пислал о баге?

От написания компонент я не отказываюсь, просто надеюсь ты меня поймещь, в моих предпочтениях в работе с ARM симулятором (ну сказочно интересное ядро, еще бы упаковка и SPI как у AVR и цены бы ему не было). К тому же заказал образцы микроконверторов AD-шных с ARM ядром, ну блеск просто, восхищен описаниями (самих еще не видел ADUC7024BSTZ62).
Хотя попытаюсь-ка я себя заставить на этой недели доделать кондер ;-)

termostat> Вот пример 7-сегментного индикатора на Си
termostat> Еще смотри:
termostat> AVR241: Direct driving of LCD display using general IO
termostat> AVR242: 8-bit Microcontroller Multiplexing LED Drive and a 4x4 Keypad
termostat> Welcome to Freescale - Freescale Semiconductor AN2264 LIN 7seg 4dig Температурный дисплей.pdf на Си
termostat> и google.com "7 SEGMENT LED" [»]

Ты не совсем меня понял, мне именно как проект написанный в Протеусе и на Си, так как не могу понять что делаю неверно в самом Протеусе - реальный то проект работает, а его симуляция в Протеусе фиговничает ничего не выводит.
 
1 6 7 8 9 10 11 12

в начало страницы | новое
 
Поиск
Настройки
Твиттер сайта
Статистика
Рейтинг@Mail.ru