Страница 325 из 421
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вс ноя 16, 2014 00:58:06
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мкФ).
Подскажите, пожалуйста, что-нибудь более добротное в качестве следящей функции.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вс ноя 16, 2014 07:36:28
Jack_A
А МК успевает отработать в прерывании float ? Вообще в прерывании float - плохой тон, я думаю. Попробовать табличным способом, если свободный объем флеши позволяет. Там можно организовать и более сложную обратную связь - с гистерезисом, с насыщением и пр. И вообще, говорят - ПИД регулятор рулит... Тут по нему серьезные спецы есть, я не из них.
И вообще - может, это не на МК схема, а управляет большой ПК ?
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вс ноя 16, 2014 13:07:23
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
Re: CodeVision AVR в вопросах и ответах
Добавлено: Вс ноя 16, 2014 13:39:46
gis
Подскажите, пожалуйста насчет файла spi.h, который содержится CVavr 3.12. Как я понял, судя по его содержанию, он реализует аппаратную поддержку SPI для контроллеров ATxmega. И у меня с ATmega328p аппаратный SPI не работает...
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн ноя 17, 2014 02:03:28
ELcat
Jack_A писал(а):А МК успевает отработать в прерывании float ? Вообще в прерывании float - плохой тон, я думаю. Попробовать табличным способом, если свободный объем флеши позволяет.
МК успевает. Никакого ПК нет, флеши 2кБ (Тини2313). Хотелось именно что-то типа ПИД регулятора, но не знаю как это сделать.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн ноя 17, 2014 06:50:37
Pink-Pank
В Гугле полно примеров ПИД-регуляторов на СИ
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн ноя 17, 2014 06:58:37
Аlex
ELcat, Вы уверены, что Вам именно ПИД нужен ? В большинстве случаев достаточно 2-ух звеньев - "П" и "И".
Ну а вообще, там ничего сложного.
П (пропорциональная составляющая) - это разность между уставкой и текущем значением обратной связи. Она же - ошибка или рассогласование.
И (интегральная составляющая) - сумма этих самых ошибок за всё время работы регулятора. Нужна для установки на выходе некой постоянной составляющей, при которой ошибка равна нулю, или близка к нему.
Ну а Д (дифференциальная составляющая) - это разница между текущей ошибкой и предыдущей. Нужна для того, чтобы следить за скоростью изменения ошибки. Т.е. смягчать слишком быстрые изменения.
Ну и у каждой составляющей есть свои коэффициенты, которыми они настраиваются, или отключаются вовсе.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн ноя 17, 2014 08:27:30
gis
Подскажите, где ошибка, а то SPI не работает...
Код: Выделить всё
#include <mega328p.h>
#include <spi.h>
void main(void)
{
PORTB=0x00;
DDRB=0xB0;
SPCR=0x54;
SPSR=0x00;
while (1)
{
spi(0b01010101); // Передоваймый байт
}
}
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн ноя 17, 2014 09:26:17
Аlex
gis писал(а):Подскажите, где ошибка
В слове "перед
оваемый"

Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн ноя 17, 2014 10:02:16
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 Ом, система работает стабильно и практически без нареканий. Захват параметра и его удержание стабильные. Самовозбуждение пока ещё есть, но лишь на одном маленьком участке. Думаю устранить правкой аппаратной части.
А главное был получен бесценный опыт.

Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн ноя 17, 2014 10:09:10
Pink-Pank
Подскажите, где ошибка, а то SPI не работает...
Может, потому, что Вы настроили его мастером, а ножки контроллера настроили как для слейва?

Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн ноя 17, 2014 10:19:17
А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;
}
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн ноя 17, 2014 10:24:37
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-а...
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн ноя 17, 2014 11:21:32
Jack_A
Аlex писал(а):
И (интегральная составляющая) - сумма этих самых ошибок за всё время работы регулятора. Нужна для установки на выходе некой постоянной составляющей, при которой ошибка равна нулю, или близка к нему.
Статическая ошибка сводится к нулю, но за счет колебательного режима около точки нулевого рассогласования.
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн ноя 17, 2014 11:30:28
Аlex
Мне кажется, я тоже самое сказал
Скажем "равна нулю", конечно, грубо сказано, не будет такого никогда. Но было сказано для понимания человеком играющей роли интегральной составляющей. Она стремится сравнять уставку с выходным значением ОС (т.е., как Вы сказали - свести ошибку к нулю).
Тем более, я подчеркнул - "или близка к нему"

Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн ноя 17, 2014 11:33:30
gis
Pink-Pank писал(а):Подскажите, где ошибка, а то SPI не работает...
Может, потому, что Вы настроили его мастером, а ножки контроллера настроили как для слейва?

Ну мне надо что бы МК был мастером. Соответственно в байте SPCR бит MSTR=1. А ножки PB3 и PB5, который являются, соответственно, MOSI и SCK, я делаю выходами, т. е. DDRB=0b00101000. Так?
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн ноя 17, 2014 11:40:37
Jack_A
Аlex писал(а): "равна нулю"... не будет такого никогда.
Будет, периодически, кратковременно -- в моменты перехода от + к - рассогласованию.

Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн ноя 17, 2014 11:46:23
Pink-Pank
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн ноя 17, 2014 12:33:40
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;
}
}
Re: CodeVision AVR в вопросах и ответах
Добавлено: Пн ноя 17, 2014 17:06:05
ELcat
ARV с знаковыми и беззнаковыми разберусь. А вот целочисленно считать... Как же тогда будет вестись накопление при крутизне 0,01? Или всё выражение умножать на 1000 и считать в long?