Условия сравнения со сложными функциями не работают...

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
andrikll
Первый раз сказал Мяу!
Сообщения: 24
Зарегистрирован: Ср апр 24, 2013 22:27:51

Условия сравнения со сложными функциями не работают...

Сообщение andrikll »

Вопрос в заголовке. привожу текст целиком.. наверно так будет проще. В общем устройство.. Двигатель постоянного тока, на нем стоит оптический энкодер который долго настраивал но запустил. есть еще 2 регулятора... хотел одним регулятором (энкондер механика) крутить этот мотор а вторым (резистор через АЦП) регулировать положение мотора по прямолинейной функции. До этого дело не дошло. Когда я сравниваю просто положение мотора и энкодера, все супер, но стоит сделать что либо сложное и мотор начинает выполнять не предсказуемые перемещения при регулировании. (Определение функций портов сокращу....)

Chip type : ATmega48
Clock frequency : 1,000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 128
*****************************************************/

#include <mega48.h>

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Place your code here

}

#define ADC_VREF_TYPE 0x60

// Read the 8 most significant bits
// of the AD conversion result
unsigned char read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCH;
}

unsigned int reg=3000, mot=2500, cifra;
unsigned char display=1, pause, new_reg, old_reg, new_mot, old_mot, gas, b, a, shim, mot_reg;

// Declare your global variables here

void segment1(void)
{ PORTB.7=0;
PORTB.5=0;
PORTB.4=0;
PORTB.6=1;
if (cifra1==0) PORTD=0x88;
if (cifra1==1) PORTD=0xeb;
if (cifra1==2) PORTD=0x91;
if (cifra1==3) PORTD=0xc1;
if (cifra1==4) PORTD=0xe2;
if (cifra1==5) PORTD=0xc4;
if (cifra1==6) PORTD=0x84;
if (cifra1==7) PORTD=0xe9;
if (cifra1==8) PORTD=0x80;
if (cifra1==9) PORTD=0xc0;
}

void segment2(void)
{
PORTB.6=0;
PORTB.5=0;
PORTB.4=0;
PORTB.7=1;
if (cifra2==0) PORTD=0x88;
if (cifra2==1) PORTD=0xeb;
if (cifra2==2) PORTD=0x91;
if (cifra2==3) PORTD=0xc1;
if (cifra2==4) PORTD=0xe2;
if (cifra2==5) PORTD=0xc4;
if (cifra2==6) PORTD=0x84;
if (cifra2==7) PORTD=0xe9;
if (cifra2==8) PORTD=0x80;
if (cifra2==9) PORTD=0xc0;
}

void segment3(void)
{ PORTB.7=0;
PORTB.6=0;
PORTB.5=0;
PORTB.4=1;
if (cifra3==0) PORTD=0x88;
if (cifra3==1) PORTD=0xeb;
if (cifra3==2) PORTD=0x91;
if (cifra3==3) PORTD=0xc1;
if (cifra3==4) PORTD=0xe2;
if (cifra3==5) PORTD=0xc4;
if (cifra3==6) PORTD=0x84;
if (cifra3==7) PORTD=0xe9;
if (cifra3==8) PORTD=0x80;
if (cifra3==9) PORTD=0xc0;
}
void segment4(void)
{ PORTB.7=0;
PORTB.6=0;
PORTB.4=0;
PORTB.5=1;
if (cifra4==0) PORTD=0x88;
if (cifra4==1) PORTD=0xeb;
if (cifra4==2) PORTD=0x91;
if (cifra4==3) PORTD=0xc1;
if (cifra4==4) PORTD=0xe2;
if (cifra4==5) PORTD=0xc4;
if (cifra4==6) PORTD=0x84;
if (cifra4==7) PORTD=0xe9;
if (cifra4==8) PORTD=0x80;
if (cifra4==9) PORTD=0xc0;
}

void regul (void)
{
if (old_reg==0) {if(new_reg == 3) reg++; if(new_reg == 1) reg--; }
if (old_reg==1) {if(new_reg == 0) reg++; if(new_reg == 3) reg--; }
if (old_reg==3) {if(new_reg == 1) reg++; if(new_reg == 0) reg--; }
if (old_reg>3) display++;

}

void motor (void)
{
if (old_mot==1) {if (new_mot == 3) mot=mot+1;};
if (old_mot==3) {if (new_mot == 1) mot=mot-1;};
}


void motor_drive (void)
{

pause++;

if (mot_reg>20) shim=40; else shim=5;
if (pause>=255-shim) a=1; else a=0;
if (pause<=shim) b=1; else b=0;
if (mot > reg+10) mot_reg=mot-reg, PORTB.3=0, PORTB.2|=a;
if (mot < reg-3) mot_reg=reg-mot, PORTB.2=0, PORTB.3|=b;
if ((mot <= reg+10) && (mot >= reg-3)) PORTB.2=0, PORTB.3=0;

}

void main(void)
{

// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

PORTB=0x00;
DDRB=0xFD;

PORTC=0x00;
DDRC=0x00;

PORTD=0x00;
DDRD=0xFF;

// Timer/Counter 0 initialization// Clock source: System Clock// Clock value: 125,000 kHz
// Mode: Normal top=FFh// OC0A output: Disconnected// OC0B output: Disconnected
TCCR0A=0x00; TCCR0B=0x02; TCNT0=0x00; OCR0A=0x00; OCR0B=0x00;

// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x01;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
ADCSRB=0x00;

// ADC initialization// ADC Clock frequency: 7,813 kHz// ADC Voltage Reference: AVCC pin// ADC Auto Trigger Source: Free Running
// Only the 8 most significant bits of// the AD conversion result are used// Digital input buffers on ADC0: On, ADC1: On, ADC2: On, ADC3: On// ADC4: On, ADC5: On
DIDR0=0x00;
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0xA7;
ADCSRB&=0xF8;

// Global enable interrupts
#asm("sei")

while (1)
{
new_reg = 4*!PINB.1+2*!PINC.1+!PINC.0;
if (old_reg!=new_reg) regul();
old_reg=new_reg;

gas = read_adc(2);

if (display==4) display=1;
if (display==2) cifra=(reg-reg%10)/10;
if (display==1) cifra=(mot-mot%10)/10;
if (display==3) cifra=gas;

cifra1=cifra%10; // Описываем выбор значений для сегментов цифр 1
segment1() ; // переход в функцию сегмент для засветки сегмента 1

cifra2=(cifra%100-cifra%10)/10;
segment2() ;
new_mot = 2*PINC.5+PINC.4; //Obnovlenie znacheniya new_mot, obrabotka znacheniya povorota motora,
if (old_mot!=new_mot) motor();
old_mot=new_mot; // сброс значения олд_мот
motor_drive(); //obrabotka podachi signala na motor

cifra3=(cifra%1000-cifra%100)/100;
segment3() ;
cifra4=(cifra%10000-cifra%1000)/1000;
segment4() ;

}; //Для while

}
Реклама
andrikll
Первый раз сказал Мяу!
Сообщения: 24
Зарегистрирован: Ср апр 24, 2013 22:27:51

Re: Условия сравнения со сложными функциями не работают...

Сообщение andrikll »

Функция motor_drive.
Еще одна заметка если быстро крутить энкодер то двигатель может поменять направление вращения, при этом значения точно не выходят за диапазон (смотрю на экране).
Реклама
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Re: Условия сравнения со сложными функциями не работают...

Сообщение uk8amk »

Все условия работают, когда правильно написаны...

Энкодер как я понял квадратурный?
Не пробовали его обработку вытащить из главного цикла в прерывание? Туда же управление моторами.

И еще во это:
andrikll писал(а):Clock frequency : 1,000000 MHz
маловато может быть.
andrikll
Первый раз сказал Мяу!
Сообщения: 24
Зарегистрирован: Ср апр 24, 2013 22:27:51

Re: Условия сравнения со сложными функциями не работают...

Сообщение andrikll »

Прерывания не пробовал но хотел бы! не знаю что значит квадратурный.. если вы про регулятор то механика (как в магнитоллах на громкости).. если вы про энкодер мотора то оптический из мыши. Простое условие работает когда я напрямую сравниваю мот и рег... мотор крутит пока не получит значение рег.. как только ставлю что то посложнее..рег+гас уже начинает глючить. а если что либо с перемножением то атас!
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
ChipKiller
Сверлит текстолит когтями
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Re: Условия сравнения со сложными функциями не работают...

Сообщение ChipKiller »

andrikll - по-хорошему лучше все переписать. Писать все "в лоб" не стоит. например вместо

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

void segment1(void)
{ PORTB.7=0;
PORTB.5=0;
PORTB.4=0;
PORTB.6=1;
if (cifra1==0) PORTD=0x88;
if (cifra1==1) PORTD=0xeb;
if (cifra1==2) PORTD=0x91;
if (cifra1==3) PORTD=0xc1;
if (cifra1==4) PORTD=0xe2;
if (cifra1==5) PORTD=0xc4;
if (cifra1==6) PORTD=0x84;
if (cifra1==7) PORTD=0xe9;
if (cifra1==8) PORTD=0x80;
if (cifra1==9) PORTD=0xc0;
}
... и прочих segment_x

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

flash char table[10]=0x88,0xeb,0x91,0xc1,0xe2,0xc4,0x84,0xe9,0x80,0xc0;
....
PORTD=table[cifra];
... и делается это в обработчике прерывания по переполнению таймера, например.
Реклама
andrikll
Первый раз сказал Мяу!
Сообщения: 24
Зарегистрирован: Ср апр 24, 2013 22:27:51

Re: Условия сравнения со сложными функциями не работают...

Сообщение andrikll »

ChipKiller Спасибо огромное.. делал через свич.. фигня полная.. не знаю почему.. все засвечено остается. Мне нужен пример по прерываниям.. я сам не напишу.. пересмотрел много чего, как окнкретно использовать не понял до конца...
По таймеру тоже ничего не получается... Читал читал.. чтобы флаг ТОВ не сбрасывался, прерывания нужно отключить и вручную сбрасывать.. но никакими способами не получилось это использовать.

Стараюсь писать сам даже если смотрю на примеры.. по крайней мере так я знаю что к чему в программе. даташит по таймерам прочел и на русском и на английском. могу кинуть что я писал по таймерам..
То uk8amk
Поставил бы больше, но без кварца.. боюсь залочить.. пока все получается не дышу на схему...Использую пока с простым условием мот== рег и все работает. Вопрос именно почему если применить сложное уравнение или переменную являющуюся произведением и суммой других (фанк=рег*10+гэс и иф мот==фанк) то начинает "глючить"
Последний раз редактировалось andrikll Чт май 02, 2013 15:15:14, всего редактировалось 3 раза.
Реклама
mulder790
Первый раз сказал Мяу!
Сообщения: 33
Зарегистрирован: Вт окт 04, 2011 12:22:43
Откуда: Витебск

Re: Условия сравнения со сложными функциями не работают...

Сообщение mulder790 »

выложи файлом, (и если можно мне пришли проектом, я посмотрю и пришлю переработанную версию)
по поводу вывода согласен лучше в прерывании, или по if или по case.
это пример (прошу не пинать сильно писал по памяти)

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

flash char table[10]=0x88,0xeb,0x91,0xc1,0xe2,0xc4,0x84,0xe9,0x80,0xc0;
//массив обображения цифр на сегментном индикаторе
static unsigned int figure=0; //переменная номера отображаемого сегмента
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
if(figure=>3)figure=0; //цикл выбора цифры для обображения
else figure++;

	switch(figure)  //цикл с выводом информации на сегменты
	{
		case 0:
			segment1();
		break;
		case 1:
			segment2();
		break;
		case 2:
			segment3();
		break;
		case 3:
			segment4();
		break;
		
		}

}
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Re: Условия сравнения со сложными функциями не работают...

Сообщение uk8amk »

andrikll писал(а):почему если применить сложное уравнение или переменную являющуюся произведением и суммой других (фанк=рег*10+гэс и иф мот==фанк) то начинает "глючить"
Есть вероятность, что оптимизатор компилятора считает ваш код бредом и выбрасывает лишнее/перетасовывает инструкции. По крайней мере WinAVR или Keil при уровне выше -O0 так и поступают во многих случаях. CVAVR версий 1.хх имел не слишком продвинутый оптимизатор и почти ничего не выбрасывал. В любом случае вам следует предоставлять более формальные доказательсва в виде листинга, а не русскоязычного варианта (фанк=рег*10+гэс и иф мот==фанк) . И с указанием что конкретно глючит. Иначе мы ничем не поможем.
andrikll писал(а):По таймеру тоже ничего не получается... Читал читал.. чтобы флаг ТОВ не сбрасывался, прерывания нужно отключить и вручную сбрасывать.. но никакими способами не получилось это использовать.
Эмм, он(флаг) сам вобще-то сбрасывается вы выходу из прерывания.
• Bit 0 – TOV2: Timer/Counter2 Overflow Flag
The TOV2 bit is set (one) when an overflow occurs in Timer/Counter2. TOV2 is cleared
by hardware when executing the corresponding interrupt handling vector. Alternatively,
TOV2 is cleared by writing a logic one to the flag.
Тоесть можно и так и так.
Вообще CVAVR(а как я понял в нем вся работа идет) имеет очень дружелюбные мастеры кода.
А потренироваться можно на симуляторе AVR Studio или в Proteus-е. Это если аппаратного отладчика совсем нету.
andrikll
Первый раз сказал Мяу!
Сообщения: 24
Зарегистрирован: Ср апр 24, 2013 22:27:51

Re: Условия сравнения со сложными функциями не работают...

Сообщение andrikll »

что такое уровень -О0? (минус О ноль?) и как этого избежать? хотелось бы оперировать сложными математическими зависимостями в будущем! Ладно я трениться на железке... может кто то еще подкинеть что либо....Спасибо! появились мысли-идеи......
uk8amk условие по переполнению таймера, если я не использую прерывания, не происходит.. не пойму почему. К сожалению имею плохую привычку переписывать все в одной и той же проге... и не сохранил код в котором это вышло...
Аватара пользователя
ChipKiller
Сверлит текстолит когтями
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Re: Условия сравнения со сложными функциями не работают...

Сообщение ChipKiller »

andrikll писал(а):хотелось бы оперировать сложными математическими зависимостями в будущем!
.. не нужно забывать, что 8-ми битный AVR - это не Pentium. Поэтому, где только можно "сложных математических зависимостей" нужно избегать, так же как использования типа float.
andrikll
Первый раз сказал Мяу!
Сообщения: 24
Зарегистрирован: Ср апр 24, 2013 22:27:51

Re: Условия сравнения со сложными функциями не работают...

Сообщение andrikll »

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

Разобрался.. ошибки устранил.. шью. Проверяю идеи по перемножениям.
Вложения
ошибка.JPG
(57.92 КБ) 331 скачивание
Аватара пользователя
ChipKiller
Сверлит текстолит когтями
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Re: Условия сравнения со сложными функциями не работают...

Сообщение ChipKiller »

andrikll писал(а):не знаю почему.. все засвечено остается. Мне нужен пример по прерываниям.. я сам не напишу.. пересмотрел много чего, как окнкретно использовать не понял до конца...
как пример подойдет скачать
mulder790
Первый раз сказал Мяу!
Сообщения: 33
Зарегистрирован: Вт окт 04, 2011 12:22:43
Откуда: Витебск

Re: Условия сравнения со сложными функциями не работают...

Сообщение mulder790 »

Выложи весь проект так проще будет, и легче ошибки найти просто я пишу больше под gcc-avr.
Аватара пользователя
ChipKiller
Сверлит текстолит когтями
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Re: Условия сравнения со сложными функциями не работают...

Сообщение ChipKiller »

mulder790 писал(а):Выложи весь проект...
так там весь проект и есть ... единственное - он под CV AVR, но библиотеки не используются, так что переделать под gcc-avr не сложно...
mulder790
Первый раз сказал Мяу!
Сообщения: 33
Зарегистрирован: Вт окт 04, 2011 12:22:43
Откуда: Витебск

Re: Условия сравнения со сложными функциями не работают...

Сообщение mulder790 »

ChipKiller писал(а):
mulder790 писал(а):Выложи весь проект...
так там весь проект и есть ... единственное - он под CV AVR, но библиотеки не используются, так что переделать под gcc-avr не сложно...
я конечно понимаю что почти весь (благо пишу в обоих компиляторах).
просто что бы помочь и отладить проект проще его просто подгрузить как файл) хотя каждый делает так как ему удобнее)))
Аватара пользователя
ChipKiller
Сверлит текстолит когтями
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

Re: Условия сравнения со сложными функциями не работают...

Сообщение ChipKiller »

mulder790 писал(а):я конечно понимаю что почти весь
... а я не понимаю почему почти весь?
Изображение
Вложения
proj_adc.PNG
(3.21 КБ) 506 скачиваний
andrikll
Первый раз сказал Мяу!
Сообщения: 24
Зарегистрирован: Ср апр 24, 2013 22:27:51

Re: Условия сравнения со сложными функциями не работают...

Сообщение andrikll »

Спасибо огромное! Всё заработало.. Вобщем очень внимательно нужно смотреть (как бы мысли вслух) на тип данных с которыми оперируешь по "математике" и поменьше перемножений.. прерывания работают, экран на "свитче" отлично заработал.
Вложения
граф.JPG
(51.01 КБ) 348 скачиваний
Ответить

Вернуться в «Разные вопросы по МК»