//---------------------------------------------------------------------- // Titel : SMC800 Ansteuerung //---------------------------------------------------------------------- // Funktion : SMC800 Schrittmotorplatine wird angesteuert // Schaltung : myAVRBoard SMC800 // PB.0 DATA1 // PB.1 DATA2 // PB.2 DATA4 // PB.3 DATA5 // PB.4 DATA7 // PB.5 DATA8 // PC.0 STROBE // PC.1 DATA3 // PC.2 DATA6 //---------------------------------------------------------------------- // Prozessor: ATMega8 // Takt : 3.6864 MHz // Sprache : C //---------------------------------------------------------------------- //Includes und Globale Einstellungen //---------------------------------------------------------------------- #define F_CPU 3686400 // Taktferquenz des myAVR-Boards #define F_max_motx 100 //für Plotterschrittmotoren (in Hz) //32 bis F_SMC800 #define F_max_moty 100 //für Plotterschrittmotoren (in Hz) //32 bis F_SMC800 #define F_max_motz 225 //32 bis F_SMC800 #define F_SMC800 4900 // Taktfrequenz für SMC800 (laut Datenblatt max 5000Hz) #define F_offset 0 //Offset für Freq-Berechnung, bei jedem Controller anders #define plot_max_x 2760 //2760 (genau ein viertel von HPGL DinA4) //sonst 2780 #define plot_max_y 1930 //1930 //sonst 2054 #define plot_max_z 2000 //#include //---------------------------------------------------------------------- // Globale Variablen //---------------------------------------------------------------------- #define F_TC0 256-(F_CPU/8/F_SMC800)+F_offset //Berechnung für Startwert TC0 #define F_motx 256-(F_SMC800/F_max_motx) //Berechnung für maxwert motx #define F_moty 256-(F_SMC800/F_max_moty) //Berechnung für maxwert moty #define F_motz 256-(F_SMC800/F_max_motz) //Berechnung für maxwert motz bool freq; bool freq_motx(0),freq_moty(0),freq_motz(0); unsigned char count_motx,count_moty,count_motz; #define mots_array_length 4 // Länge der Tabelle für die Motorsteuerung unsigned char mots[mots_array_length] = {0x99,0x33,0x66,0xCC};//Tabelle für die Abfolge der Signale für die Motorsteuerung int posx(0),posy(0),posz(0); //Positionen in Schritten für jeden Motor char motx(0),moty(0),motz(0); //Zähler für jeden Motor //---------------------------------------------------------------------- // Funktionen //---------------------------------------------------------------------- void strobe() //Funktion, die auf der STROBE Leitung des SMC800 //eine Positive Flanke erzeugt, um die Daten zu übernehmen //Interrupts MÜSSEN erlaubt sein, BEVOR diese Funktion ausgeführt wird! { while(freq!=false); //Warten bis Timer Compare Match, um nicht über 5kHz zu kommen freq = true; //freq-Flag auf true setzen (wird von Timer zurückgesetzt) PORTC &= ~(1< Daten werden übernommen) } void mot_tick(char motor,bool richtung) //Motor einen Schritt laufen lassen /0 = links/1 = rechts { //Interrupts MÜSSEN erlaubt sein, BEVOR diese Funktion ausgeführt wird, da das Programm sonst bei einem strobe() hängen bleibt! switch(motor) { case 'x': PORTB = 0b00000000; //Motor X auswählen if (richtung==true) { motx++; posx++; if (motx > mots_array_length-1) motx=0; } else { motx--; posx--; if (motx < 0) motx=mots_array_length-1; } PORTC &= 0b11111001; //Bits löschen PORTC |= mots[motx] & 0b00000110; //neuen Phasenschritt übernehmen while(freq_motx!=false); //Warten bis frequenzvariable für Motorx zurückgesetzt wird freq_motx = true; //freq-Flag auf true setzen (wird von Timer zurückgesetzt) strobe(); break; case 'y': PORTB = 0b00010000; if (richtung==true) { moty--; posy++; if (moty < 0) moty=mots_array_length-1; } else { moty++; posy--; if (moty > mots_array_length-1) moty=0; } PORTC &= 0b11111001;//Bits löschen PORTC |= mots[moty] & 0b00000110;//neuen Phasenschritt übernehmen while(freq_moty!=false); //Warten bis frequenzvariable für Motory zurückgesetzt wird freq_moty = true; //freq-Flag auf true setzen (wird von Timer zurückgesetzt) strobe(); break; case 'z': if (posz<=plot_max_z) { PORTB = 0b00100000; if (richtung==true) { motz++; posz++; if (motz > mots_array_length-1) motz=0; } else { motz--; posz--; if (motz < 0) motz=mots_array_length-1; } PORTC &= 0b11111001;//Bits löschen PORTC |= mots[motz] & 0b00000110;//neuen Phasenschritt übernehmen while(freq_motz!=false); //Warten bis frequenzvariable für Motorz zurückgesetzt wird freq_motz = true; //freq-Flag auf true setzen (wird von Timer zurückgesetzt) strobe(); } break; } /* //DEBUG-------------------------------------------------------------- char bufferx[10]={0}; sprintf( bufferx, "%d", posx); char buffery[10]={0}; sprintf( buffery, "%d", posy); uart_print("Pos: "); uart_print(bufferx); uart_putchar(','); uart_print(buffery); uart_print("\n"); //DEBUG ENDE---------------------------------------------------------- */ } void mot_init() { //------------------------------------------------------------------ // Initialisierungen //------------------------------------------------------------------ TCCR0 = 0x02; //Vorteiler für TC0 auf 8 TIMSK = 0x01; //Interrupt einschalten DDRB = 0xFF; //PortB auf Ausgang DDRC = 0b00001111; //PortC Ausgänge für Strobe und Phasenstromrichtung PORTC = 0b00110000; //PullUps } //---------------------------------------------------------------------- // Interrupt Service Routinen //---------------------------------------------------------------------- ISR (TIMER0_OVF_vect) //TC0 { freq = false; //TCNT0 = 167; //Wert für 5kHz (1356kHz bei 1MHz Systemtakt) //Frequenzen für jeden Motor überprüfen und ggf das Flag rücksetzen TCNT0 = F_TC0; count_motx++; count_moty++; count_motz++; if (count_motx==0) { freq_motx = false; count_motx = F_motx; } if (count_moty==0) { freq_moty = false; count_moty = F_moty; } if (count_motz==0) { freq_motz = false; count_motz = F_motz; } }