Условия сравнения со сложными функциями не работают...
Добавлено: Ср май 01, 2013 23:28:20
Вопрос в заголовке. привожу текст целиком.. наверно так будет проще. В общем устройство.. Двигатель постоянного тока, на нем стоит оптический энкодер который долго настраивал но запустил. есть еще 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
}
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
}