CodeVision AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
ELcat
Друг Кота
Сообщения: 3258
Зарегистрирован: Вт май 19, 2009 09:27:30
Откуда: Украина

Re: CodeVision AVR в вопросах и ответах

Сообщение ELcat »

Неужели никто ничего подобного не делал?
На данный момент работает функция:

TempL=OCR0B;
if (Nout>Nin) {TempL=(TempL-((Nout-Nin)*S_fact)); if (TempL<0) TempL=0;}
else {TempL=(TempL+((Nin-Nout)*S_fact)); if (TempL>255) TempL=255;}
OCR0B=TempL;

(Nin, Nout - unsigned int заданный и измеренный параметры. TempL - float)
Причём работает довольно коряво. S_fact имеет значение 0,08, при более высоком система заводится и идёт вразнос. Всё это крутится в прерывании с частотой ~1600Гц, частота ШИМ ~47кГц (12МГц/256). С выхода ШИМ сигнал поступает на R-C-R-C интегратор (номиналы резисторов по 10кОм, конденсаторов по 10мкФ).
Подскажите, пожалуйста, что-нибудь более добротное в качестве следящей функции.
Sch.png
(17.23 КБ) 442 скачивания
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6307
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Re: CodeVision AVR в вопросах и ответах

Сообщение Jack_A »

А МК успевает отработать в прерывании float ? Вообще в прерывании float - плохой тон, я думаю. Попробовать табличным способом, если свободный объем флеши позволяет. Там можно организовать и более сложную обратную связь - с гистерезисом, с насыщением и пр. И вообще, говорят - ПИД регулятор рулит... Тут по нему серьезные спецы есть, я не из них.
И вообще - может, это не на МК схема, а управляет большой ПК ?
denya
Родился
Сообщения: 9
Зарегистрирован: Сб ноя 15, 2014 22:19:21

Re: CodeVision AVR в вопросах и ответах

Сообщение denya »

Здравствуйте. Подскажите пожалуйста, при попытке подцепить lcd экран к atmega 8 через PORTC codevision выдает ошибки
в файле проекта с расширением .asm
ниже код программы и на месте, что ругается

include <mega8.h>
#asm
.equ __lcd_port=0x26
#endasm
#include <lcd.h>
void main(void)
{
PORTC=0x00;
DDRC=0x00;
lcd_init(24);
lcd_gotoxy(0,0);
lcd_putsf("proverka");
}

и вот на что ругается (выделено жирным)
Error: D:\...\ss1.asm(1284): Operand 1 out of range: 0x26

andi r26,0xf ;set as input
out __lcd_direction,r26
sbi __lcd_port,__lcd_rd ;RD=1
cbi __lcd_port,__lcd_rs ;RS=0
gis
Родился
Сообщения: 16
Зарегистрирован: Пт ноя 07, 2014 20:34:56

Re: CodeVision AVR в вопросах и ответах

Сообщение gis »

Подскажите, пожалуйста насчет файла spi.h, который содержится CVavr 3.12. Как я понял, судя по его содержанию, он реализует аппаратную поддержку SPI для контроллеров ATxmega. И у меня с ATmega328p аппаратный SPI не работает...
Аватара пользователя
ELcat
Друг Кота
Сообщения: 3258
Зарегистрирован: Вт май 19, 2009 09:27:30
Откуда: Украина

Re: CodeVision AVR в вопросах и ответах

Сообщение ELcat »

Jack_A писал(а):А МК успевает отработать в прерывании float ? Вообще в прерывании float - плохой тон, я думаю. Попробовать табличным способом, если свободный объем флеши позволяет.
МК успевает. Никакого ПК нет, флеши 2кБ (Тини2313). Хотелось именно что-то типа ПИД регулятора, но не знаю как это сделать.
Аватара пользователя
Pink-Pank
Опытный кот
Сообщения: 721
Зарегистрирован: Ср июн 11, 2014 09:43:13
Откуда: США
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение Pink-Pank »

В Гугле полно примеров ПИД-регуляторов на СИ
Fucking static initialization order fiasco
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение Аlex »

ELcat, Вы уверены, что Вам именно ПИД нужен ? В большинстве случаев достаточно 2-ух звеньев - "П" и "И".
Ну а вообще, там ничего сложного.
П (пропорциональная составляющая) - это разность между уставкой и текущем значением обратной связи. Она же - ошибка или рассогласование.
И (интегральная составляющая) - сумма этих самых ошибок за всё время работы регулятора. Нужна для установки на выходе некой постоянной составляющей, при которой ошибка равна нулю, или близка к нему.
Ну а Д (дифференциальная составляющая) - это разница между текущей ошибкой и предыдущей. Нужна для того, чтобы следить за скоростью изменения ошибки. Т.е. смягчать слишком быстрые изменения.

Ну и у каждой составляющей есть свои коэффициенты, которыми они настраиваются, или отключаются вовсе.
gis
Родился
Сообщения: 16
Зарегистрирован: Пт ноя 07, 2014 20:34:56

Re: CodeVision AVR в вопросах и ответах

Сообщение gis »

Подскажите, где ошибка, а то SPI не работает...

Код: Выделить всё

#include <mega328p.h>
#include <spi.h>

void main(void)
{
PORTB=0x00;
DDRB=0xB0;
SPCR=0x54;
SPSR=0x00;
while (1)
{
spi(0b01010101);   // Передоваймый байт
}
}
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение Аlex »

gis писал(а):Подскажите, где ошибка
В слове "передоваемый" :)
Аватара пользователя
ELcat
Друг Кота
Сообщения: 3258
Зарегистрирован: Вт май 19, 2009 09:27:30
Откуда: Украина

Re: CodeVision AVR в вопросах и ответах

Сообщение ELcat »

Pink-Pank писал(а):В Гугле полно примеров ПИД-регуляторов на СИ
На Си, к сожалению, не нашёл. Попадались в основном курсовые работы с мудрёным математическим изложением.

Аlex писал(а):ELcat, Вы уверены, что Вам именно ПИД нужен ? В большинстве случаев достаточно 2-ух звеньев - "П" и "И".
Ну а вообще, там ничего сложного.
Уверенным можно быть только тогда, когда чётко понимаешь о чём идёт речь. У меня такового понимания нет, поскольку столкнулся с этим впервые. Тем более я далёк от АСУ, да и знакомых нет, кто работает в этой сфере. Но "краем уха" слыхал, что есть нечто под названием "ПИД", как чудодейственная панацея на все случаи жизни.
В ходе самостоятельных экспериментов пришёл к формуле:

Код: Выделить всё

unsigned int Nout, Nin;
float TempL;
#define S_fact 0.01
...
if (Nout>Nin) {TempL=(TempL-((Nout-Nin)*S_fact)); if (TempL<0) TempL=0;}
     else {TempL=(TempL+((Nin-Nout)*S_fact)); if (TempL>255) TempL=255;}
OCR0B=TempL;
, которая имеет и пропорциональную составляющую, и ведёт накопление ошибки. На данный момент величины R уменьшены до 200 Ом, система работает стабильно и практически без нареканий. Захват параметра и его удержание стабильные. Самовозбуждение пока ещё есть, но лишь на одном маленьком участке. Думаю устранить правкой аппаратной части.
А главное был получен бесценный опыт. :)
Последний раз редактировалось ELcat Пн ноя 17, 2014 10:09:18, всего редактировалось 1 раз.
Аватара пользователя
Pink-Pank
Опытный кот
Сообщения: 721
Зарегистрирован: Ср июн 11, 2014 09:43:13
Откуда: США
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение Pink-Pank »

Подскажите, где ошибка, а то SPI не работает...

Может, потому, что Вы настроили его мастером, а ножки контроллера настроили как для слейва? ;)
Fucking static initialization order fiasco
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение Аlex »

Странные какие-то проверки на больше/меньше. Для чего ? Ошибка может быть и отрицательной, ничего страшного. Хотя бы для того, чтобы интегральная составляющая могла уменьшаться. Ну или получалось на выходе отрицательное значение, если регулятор инверсный.
Классический ПИ-регулятор :

Код: Выделить всё

int PI(int  out_val, int in_val ){
int E;               // Ошибка
static long I;     // Сумма ошибок
long out;            // Выходное значение

E =  in_val - out_val;
E*=kP;
I+=E;
out= E + I*kI;

if(out>MAX_OUT) out=MAX_OUT;
if(out<MIN_OUT) out = MIN_OUT;

return (int)out;
}
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение ARV »

ELcat писал(а):В ходе самостоятельных экспериментов пришёл к формуле:

Код: Выделить всё

unsigned int Nout, Nin;
float TempL;
#define S_fact 0.01
...
if (Nout>Nin) {TempL=(TempL-((Nout-Nin)*S_fact)); if (TempL<0) TempL=0;}
     else {TempL=(TempL+((Nin-Nout)*S_fact)); if (TempL>255) TempL=255;}
OCR0B=TempL;

маленький нюанс: Nout и Nin у вас unsigned int, в то время как если бы они были просто int, то ваш код заметно упростился бы:

Код: Выделить всё

TempL = TempL - (Nout-Nin)*S_fact;
if(TempL<0) TempL=0;
if(TempL>255) TempL=255;
OCR0B=TempL;
ну и вообще все можно в целых числах вычислять, что заметно ускорило бы работу и уменьшил объем требуемого flash-а...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6307
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Re: CodeVision AVR в вопросах и ответах

Сообщение Jack_A »

Аlex писал(а):И (интегральная составляющая) - сумма этих самых ошибок за всё время работы регулятора. Нужна для установки на выходе некой постоянной составляющей, при которой ошибка равна нулю, или близка к нему.

Статическая ошибка сводится к нулю, но за счет колебательного режима около точки нулевого рассогласования.
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение Аlex »

Мне кажется, я тоже самое сказал :)
Скажем "равна нулю", конечно, грубо сказано, не будет такого никогда. Но было сказано для понимания человеком играющей роли интегральной составляющей. Она стремится сравнять уставку с выходным значением ОС (т.е., как Вы сказали - свести ошибку к нулю).
Тем более, я подчеркнул - "или близка к нему" :)
gis
Родился
Сообщения: 16
Зарегистрирован: Пт ноя 07, 2014 20:34:56

Re: CodeVision AVR в вопросах и ответах

Сообщение gis »

Pink-Pank писал(а):
Подскажите, где ошибка, а то SPI не работает...

Может, потому, что Вы настроили его мастером, а ножки контроллера настроили как для слейва? ;)


Ну мне надо что бы МК был мастером. Соответственно в байте SPCR бит MSTR=1. А ножки PB3 и PB5, который являются, соответственно, MOSI и SCK, я делаю выходами, т. е. DDRB=0b00101000. Так?
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6307
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Re: CodeVision AVR в вопросах и ответах

Сообщение Jack_A »

Аlex писал(а): "равна нулю"... не будет такого никогда.

Будет, периодически, кратковременно -- в моменты перехода от + к - рассогласованию. :)
Аватара пользователя
Pink-Pank
Опытный кот
Сообщения: 721
Зарегистрирован: Ср июн 11, 2014 09:43:13
Откуда: США
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение Pink-Pank »

Так?

Так
Fucking static initialization order fiasco
gis
Родился
Сообщения: 16
Зарегистрирован: Пт ноя 07, 2014 20:34:56

Re: CodeVision AVR в вопросах и ответах

Сообщение gis »

Pink-Pank писал(а):
Так?

Так


Спасибо, передача пошла, и на осциллографе все выглядит правильно, но микросхема 74hc595, на которую я передаю байт, выдает у себя на выходах то, что я посылаю, но сдвигом вправо. Код выглядит вот так:

Код: Выделить всё

#include <mega328p.h>
#include <spi.h>
#include <delay.h>
void main(void)
{
DDRB=0b00101011;
PORTB=0b00000010;
DDRB=0xFF;
PORTB=0xFF;
SPCR=0b01010100;
SPSR=0x00;
while (1)
{
spi(PIND);   // Передаваймый байт
 PORTB.0=1;   //ST_SP защелка
 delay_us(10);
 PORTB.0=0;
}
}
Аватара пользователя
ELcat
Друг Кота
Сообщения: 3258
Зарегистрирован: Вт май 19, 2009 09:27:30
Откуда: Украина

Re: CodeVision AVR в вопросах и ответах

Сообщение ELcat »

ARV с знаковыми и беззнаковыми разберусь. А вот целочисленно считать... Как же тогда будет вестись накопление при крутизне 0,01? Или всё выражение умножать на 1000 и считать в long?
Ответить

Вернуться в «AVR»