CodeVision AVR в вопросах и ответах
Re: CodeVision AVR в вопросах и ответах
Неужели никто ничего подобного не делал?
На данный момент работает функция:
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мкФ).
Подскажите, пожалуйста, что-нибудь более добротное в качестве следящей функции.
На данный момент работает функция:
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мкФ).
Подскажите, пожалуйста, что-нибудь более добротное в качестве следящей функции.
Re: CodeVision AVR в вопросах и ответах
А МК успевает отработать в прерывании float ? Вообще в прерывании float - плохой тон, я думаю. Попробовать табличным способом, если свободный объем флеши позволяет. Там можно организовать и более сложную обратную связь - с гистерезисом, с насыщением и пр. И вообще, говорят - ПИД регулятор рулит... Тут по нему серьезные спецы есть, я не из них.
И вообще - может, это не на МК схема, а управляет большой ПК ?
И вообще - может, это не на МК схема, а управляет большой ПК ?
Re: CodeVision AVR в вопросах и ответах
Здравствуйте. Подскажите пожалуйста, при попытке подцепить 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
в файле проекта с расширением .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
Re: CodeVision AVR в вопросах и ответах
Подскажите, пожалуйста насчет файла spi.h, который содержится CVavr 3.12. Как я понял, судя по его содержанию, он реализует аппаратную поддержку SPI для контроллеров ATxmega. И у меня с ATmega328p аппаратный SPI не работает...
Re: CodeVision AVR в вопросах и ответах
МК успевает. Никакого ПК нет, флеши 2кБ (Тини2313). Хотелось именно что-то типа ПИД регулятора, но не знаю как это сделать.Jack_A писал(а):А МК успевает отработать в прерывании float ? Вообще в прерывании float - плохой тон, я думаю. Попробовать табличным способом, если свободный объем флеши позволяет.
- Pink-Pank
- Опытный кот
- Сообщения: 721
- Зарегистрирован: Ср июн 11, 2014 09:43:13
- Откуда: США
- Контактная информация:
Re: CodeVision AVR в вопросах и ответах
В Гугле полно примеров ПИД-регуляторов на СИ
Fucking static initialization order fiasco
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: CodeVision AVR в вопросах и ответах
ELcat, Вы уверены, что Вам именно ПИД нужен ? В большинстве случаев достаточно 2-ух звеньев - "П" и "И".
Ну а вообще, там ничего сложного.
П (пропорциональная составляющая) - это разность между уставкой и текущем значением обратной связи. Она же - ошибка или рассогласование.
И (интегральная составляющая) - сумма этих самых ошибок за всё время работы регулятора. Нужна для установки на выходе некой постоянной составляющей, при которой ошибка равна нулю, или близка к нему.
Ну а Д (дифференциальная составляющая) - это разница между текущей ошибкой и предыдущей. Нужна для того, чтобы следить за скоростью изменения ошибки. Т.е. смягчать слишком быстрые изменения.
Ну и у каждой составляющей есть свои коэффициенты, которыми они настраиваются, или отключаются вовсе.
Ну а вообще, там ничего сложного.
П (пропорциональная составляющая) - это разность между уставкой и текущем значением обратной связи. Она же - ошибка или рассогласование.
И (интегральная составляющая) - сумма этих самых ошибок за всё время работы регулятора. Нужна для установки на выходе некой постоянной составляющей, при которой ошибка равна нулю, или близка к нему.
Ну а Д (дифференциальная составляющая) - это разница между текущей ошибкой и предыдущей. Нужна для того, чтобы следить за скоростью изменения ошибки. Т.е. смягчать слишком быстрые изменения.
Ну и у каждой составляющей есть свои коэффициенты, которыми они настраиваются, или отключаются вовсе.
Re: CodeVision AVR в вопросах и ответах
Подскажите, где ошибка, а то 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 в вопросах и ответах
В слове "передоваемый"gis писал(а):Подскажите, где ошибка
Re: CodeVision AVR в вопросах и ответах
На Си, к сожалению, не нашёл. Попадались в основном курсовые работы с мудрёным математическим изложением.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;А главное был получен бесценный опыт.
Последний раз редактировалось ELcat Пн ноя 17, 2014 10:09:18, всего редактировалось 1 раз.
- Pink-Pank
- Опытный кот
- Сообщения: 721
- Зарегистрирован: Ср июн 11, 2014 09:43:13
- Откуда: США
- Контактная информация:
Re: CodeVision AVR в вопросах и ответах
Подскажите, где ошибка, а то SPI не работает...
Может, потому, что Вы настроили его мастером, а ножки контроллера настроили как для слейва?
Fucking static initialization order fiasco
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: CodeVision AVR в вопросах и ответах
Странные какие-то проверки на больше/меньше. Для чего ? Ошибка может быть и отрицательной, ничего страшного. Хотя бы для того, чтобы интегральная составляющая могла уменьшаться. Ну или получалось на выходе отрицательное значение, если регулятор инверсный.
Классический ПИ-регулятор :
Классический ПИ-регулятор :
Код: Выделить всё
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 в вопросах и ответах
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;если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: CodeVision AVR в вопросах и ответах
Аlex писал(а):И (интегральная составляющая) - сумма этих самых ошибок за всё время работы регулятора. Нужна для установки на выходе некой постоянной составляющей, при которой ошибка равна нулю, или близка к нему.
Статическая ошибка сводится к нулю, но за счет колебательного режима около точки нулевого рассогласования.
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: CodeVision AVR в вопросах и ответах
Мне кажется, я тоже самое сказал
Скажем "равна нулю", конечно, грубо сказано, не будет такого никогда. Но было сказано для понимания человеком играющей роли интегральной составляющей. Она стремится сравнять уставку с выходным значением ОС (т.е., как Вы сказали - свести ошибку к нулю).
Тем более, я подчеркнул - "или близка к нему"
Скажем "равна нулю", конечно, грубо сказано, не будет такого никогда. Но было сказано для понимания человеком играющей роли интегральной составляющей. Она стремится сравнять уставку с выходным значением ОС (т.е., как Вы сказали - свести ошибку к нулю).
Тем более, я подчеркнул - "или близка к нему"
Re: CodeVision AVR в вопросах и ответах
Pink-Pank писал(а):Подскажите, где ошибка, а то SPI не работает...
Может, потому, что Вы настроили его мастером, а ножки контроллера настроили как для слейва?
Ну мне надо что бы МК был мастером. Соответственно в байте SPCR бит MSTR=1. А ножки PB3 и PB5, который являются, соответственно, MOSI и SCK, я делаю выходами, т. е. DDRB=0b00101000. Так?
Re: CodeVision AVR в вопросах и ответах
Аlex писал(а): "равна нулю"... не будет такого никогда.
Будет, периодически, кратковременно -- в моменты перехода от + к - рассогласованию.
Re: CodeVision AVR в вопросах и ответах
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;
}
}
Re: CodeVision AVR в вопросах и ответах
ARV с знаковыми и беззнаковыми разберусь. А вот целочисленно считать... Как же тогда будет вестись накопление при крутизне 0,01? Или всё выражение умножать на 1000 и считать в long?