/*****************************************************
This program was produced by the
CodeWizardAVR V2.03.4 Standard
Automatic Program Generator
© Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.comProject : Подсос С АЦП и без таймеров
Version : 3-5
Date : 30.09.2009
Author :
Company :
Comments: Пропущенный участок работает в железе без проблем.
Chip type : ATmega164
Program type : Application
Clock frequency : 16.000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*****************************************************/
#pragma savereg- // Выключить автоматическое сохранение регистров
#include <mega164.h>
#include <delay.h>
#define start_ADC ADCSRA|=(1<<6);// Запуск АЦП
#define ADC_VREF_TYPE 0x60
char i=0,j_tec=0,j_max=130,t_i=0,adc_data=0,i_adc_buf,k;
//i - номер фазы коммутации обмоток ШД
//j-tec - текущее положение ротора ШД 0<=j_tec<=j_max
//j-max - максимальное число полушагов ротора
//t_i - период коммутации фаз (0-16ms,130-8,193-4,224-2,239-1)
//i_adc_buf - номер в буфере АЦП
signed char j=0;
//j=1 пр. часовой,j=-1 по часовой,иначе - координата.
char step[]={16,80,64,96,32,160,128,144};// комбинации фаз
char adc_buf[3]={0,0,0};// Кольцевой буфер для усреднения АЦП
void SW_step(void)
{
if (i==7)i=0;
else ++i;
PORTA=step[i];
}
void SSW_step(void)
{if (i==0)i=7;
else --i;
PORTA=step[i];
}
void poworot (void)
{
if (j==-1)goto L0;
if (j!=1)goto L3;
if (j_tec==j_max)return;
L1: SSW_step();
j_tec++;
return;
L0: if (j_tec==0)
{
return;
}
L2: SW_step();
j_tec--;
return;
L3: if(j<0)
{
return;
}
if(j>j_tec) goto L1;
if(j<j_tec) goto L2;
}
// ADC interrupt service routine
interrupt [ADC_INT] void adc_isr(void)
{
unsigned char adc_data;
// Read the 8 most significant bits
// of the AD conversion result
// Place your code here
adc_data=ADCH;
adc_data=(adc_data>>1); // j не больше 127
if(adc_data==1) adc_data=0;// j==1 исключается - особенность функции poworot
if(i_adc_buf>=2) i_adc_buf=0;
else ++i_adc_buf;
j=(adc_buf[0]+adc_buf[1]+adc_buf[2]+adc_data)/4; //рекурсия
adc_buf[i_adc_buf]=j;
}
// Declare your global variables here
void main(void)
{
// Declare your local variables here
// Input/Output Ports initialization
// Port A initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=In Func2=In Func1=In Func0=Out
// State7=0 State6=0 State5=0 State4=0 State3=T State2=T State1=T State0=0
PORTA=0x00;
DDRA=0xF1;
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;
// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;
// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=0 State6=0 State5=0 State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0xE0;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x00;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2A output: Disconnected
// OC2B output: Disconnected
ASSR=0x00;
TCCR2A=0x00;
TCCR2B=0x00;
TCNT2=0x00;
OCR2A=0x00;
OCR2B=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
// Interrupt on any change on pins PCINT0-7: Off
// Interrupt on any change on pins PCINT8-15: Off
// Interrupt on any change on pins PCINT16-23: Off
// Interrupt on any change on pins PCINT24-31: Off
EICRA=0x00;
EIMSK=0x00;
PCICR=0x00;
// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x00;
// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=0x00;
// Timer/Counter 2 Interrupt(s) initialization
TIMSK2=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
ADCSRB=0x00;
// ADC initialization
// ADC Clock frequency: 125.000 kHz
// ADC Voltage Reference: AVCC pin
// ADC Auto Trigger Source: None
// Only the 8 most significant bits of
// the AD conversion result are used
// Digital input buffers on ADC0: Off, ADC1: Off, ADC2: Off, ADC3: Off
// ADC4: Off, ADC5: Off, ADC6: Off, ADC7: Off
DIDR0=0xFF;
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x8F;
goto L11;
k=0;
j=1;
while(j_tec!=125)
{
poworot();
delay_ms(2);
}
delay_ms(2000);
j=-1;
while(j_tec!=20)
{
poworot();
delay_ms(50);
}
delay_ms(2000);
j=70;
while(k<200)
{
poworot();
delay_ms(1);
k++;
}
delay_ms(2000);
L11:
#asm("sei") // Разрешить прерывания
ADMUX=1;// Первый канал АЦП
start_ADC;
while (1)
{
poworot();
delay_ms(2);
start_ADC;
}
}