Jak leptat plošné spoje tu bylo již uvedeno mnohokrát. Tento udělátor mě však dostal do kolen. Pro urychlení leptání totiž využívá bezkomutátorový motor ze starého pevného disku.

AT90S2313 řídí prostřednictvím tří polomůstků z tranzistorů vlastní motor. Firmware je v Cečku a zdá se být opravdu dost odfláknuté, ale to by snad pro místní odborníky neměl být žádný problém.

// hfuse = 0xD1  lfuse = 0x2F
//#define F_CPU         4000000

#include <avr/io.h>#include <avr/delay.h>#include <avr/interrupt.h>        // funkcje sei(), cli()
#include <avr/signal.h>           // definicje SIGNAL, INTERRUPT
#include <stdlib.h>#define set(port,bit) port|=_BV(bit)
#define clr(port,bit) port&=~_BV(bit)
#define swap(port,bit) port^=_BV(bit)

//portd
#define PORT_DRIVER PORTD

#define reset_driver()  PORTD = 0b00010101

#define w1_gnd() PORT_DRIVER |=  0b00000011
#define w1_vcc() PORT_DRIVER &=~ 0b00000011

#define w2_gnd() PORT_DRIVER |=  0b00001100
#define w2_vcc() PORT_DRIVER &=~ 0b00001100

#define w3_gnd() PORT_DRIVER |=  0b00110000
#define w3_vcc() PORT_DRIVER &=~ 0b00110000


//portc
#define S1 (!((PINB&_BV(0))>>0))
#define S2 (!((PINB&_BV(1))>>1))

#define pocz 12000


/////////////////////////////////////////////////////////////////////////
void next_step(void);

/////////////////////////////////////////////////////////////////////////
volatile unsigned int x=pocz;

int main(void){
  DDRB  = 0b00000000;            
  PORTB = 0b00000011;  
         
  DDRD  = 0b00111111;        
  PORTD = 0b00010101;

  TCNT0  = 0;
  TIMSK  = _BV(TOIE0)|_BV(TOIE1);          // włącz obsługę przerwań T/C0                   
  CR0B = _BV(CS02);                      //prescaler 256
        TCCR1B = _BV(CS11);                             //prescaler na 8
        sei();

  TCNT1=0xFFFF-1000;
  x=pocz;

//--------------------------------------------------------------------//
//---------------------- GŁÓWNA PETLA --------------------------------//
//--------------------------------------------------------------------//
  while(1){
  /*
  _delay_ms(10);
  reset_driver();
  next_step();
  */

  }
  return 0;
}//koniec funkcji main

//--------------------------------------------------------------------//
//---------------------- timer --------------------------------//
//--------------------------------------------------------------------//
ISR(TIMER0_OVF_vect){ //- obsługa przerwania
  static unsigned char a=0;
  unsigned int i;

  TCNT0 = 50;

        if(S2){
        if(S1){
                  i=1041;               //20rps
                }
                else{
                  i=1388;               //15rps
                }
        }
        else{
                if(S1){
                  i=2083;               //10rps
                }
                else{
                  i=4166;               //5rps
                }              
        }
  a++;
        if(x>i){
                if(x>5000){
                        {
                                a=0;
                                x-=30;
                        }
                }
                if((x<5001)&&(x>1500)){
                        {
                                a=0;
                                x-=10;
                        }
                }
                if((x<1501)&&(x>500)){
                        {
                                a=0;
                                x-=5;
                        }
                }
                if((x<501)&&(x>400)){
                        if(a==10){
                                a=0;
                                x--;
                        }
                }
                if((x<401)&&(x>350)){
                        if(a==10){
                                a=0;
                                if(S1){
                                        x--;
                                }
                        }
                }
                if((x<351)&&(x>250)){
                        if(a==30){
                                a=0;
                                x--;
                        }
                }
        }
}

//--------------------------------------------------------------------//
//---------------------- timer 1 --------------------------------//
//--------------------------------------------------------------------//

ISR(TIMER1_OVF_vect){ //- obsługa przerwania
  TCNT1=0xFFFF-x;

  reset_driver();
  next_step();
}

//--------------------------------------------------------------------//
//---------------------- krok silnika --------------------------------//
//--------------------------------------------------------------------//
void next_step(void){
 static unsigned char x=0;

  x++;
  if(x==7)
  x=1;

  _delay_us(10);
  switch (x){
        case 1: w2_vcc();
                  w3_gnd();
                  //do_led(x);
                  break;

        case 2: w2_vcc();
                  w1_gnd();
                  //do_led(x); 
                  break;

        case 3: w3_vcc();
                  w1_gnd();
                  //do_led(x);
                  break;

        case 4: w3_vcc();
                  w2_gnd();
                  //do_led(x);
                  break;

        case 5: w1_vcc();
                  w2_gnd();
                  //do_led(x);
                  break;

          case 6: w1_vcc();
                  w3_gnd();
                  //do_led(x);
                  break;

        default: x=1;
                   break;
  }
}