Ansicht mit Mikrocontroller - 12 Volt ~1..2 A erforderlich
Gabel Lichtschranke
Mnemonische Kommandos
Mnemonische Befehle für Schrittmotorsteuerung mit Atmel ATMega16
BAUD = 9600, 8 bit, 1 Stopbit . PUTTY ist eine gutes Terminalprogramm
für Tests
Befehle sind dann jeweils für den entsprechenden Modus aktiv
BEFEHL[,][WERT]
Bsp: mopd,100,1
{notwendig}oder []=optional. (default). 0=Voreingestellt bei
Weglassung von [WERT]Mnemonic
Bedeutung ?-> =Frage --> Anwort erwartet
?? Menü, Befehlsliste Ausgabe für Putty
Terminal Programm
ping Reponse PONG - DrehFilter
VER Version mit Datum
SCI = Scan Index --> Startet Indexsuche
?-> GIDX --> Get index get
gsStatus.IndexOK_Flag
GOTOD,{grad 0.360} Go to Degree
TAR_OK?
gsStatus.TargetSMPOS_Erreicht_F 1= Am Ziel angekommen
?-> BWGP gfBigWeel_GradPos
?-> BWTP gfBigWeel_Target_GradPos
IDXO SET IndexOffset
SIX Set Position to Indexpoint
?-> LICHTSCHRANKE -->( Aktive = high = 1 ) '
?-> IDXCHANGE Für Putty : Lese
Optokopllerfunktion
TRX,{0..1} Debugtraffic für PUTTY
0=0ff 1= on
CR_CRLF{0..1} 0= CR ONLY, 1 = CRLF
SMON[,1..nnn] Motor ON [,mit Set Frequenz]
=Pulse/Sekunde
Bsp: 1.Aufruf „SMON,123“ = 123 Clocks/Sek
PREDEF_STEPFREQUENZ 100
MOPD,{1..nn},[0/1] Motor N Pulse mit Direction Motor
On [, Pulszahl]
SMOFF Motor OFF und Freigabe
SMSTOP Motor Stop, !!nach 1 Sek. Motorfreigabe
SFR,{nnn} Sfr,100 Set Frequenz = Steps/Sekunde
SDIR,[(0)..1] Set Direction 1=links 0=rechts
Default ( unidirection )
HALF Halbschritt Modus ( STANDARD )
FULL Vollschritt Modus
sdp SEND Degree Position
spo Send Position
SIT,[1..nn] Set Set Index Timeout ~200 Seconds
sci Scan Index automatic MCA_SCI_CMD
SPR Set Steps per Rotation
Schriottmotor -->100
SETO Set ENBALE TIMEOUT if Stop
SIT SET Scan_Index_Timeout
SIENA,{1,0} ScanIDX_Start_EnaF
?--> COF gsStMPar.iIndexOffset
?--> COFBIN gsStMPar.u8StepMConditionFlag mit
Binärausgabe für Putty
?--> POF gsStMPar.u8SM_PostionFlag
?--> POFBIN gsStMPar.u8SM_PostionFlag mit
Binärausgabe für Putty
?-> BWFR gfBigWeel_FullRotCnt
?-> SPD gfStepsPerDegree
?-> DPS gfDegreePerStep
?-> GPOS glSM_RotPosition
?-> CPOSID,{SMpos) CalcPostionInDegree
?-> CDISMPOS,{grad} CalcDegreeIn_SMPos
?-> FLAGS Zeigt eine Liste von Flags ( use Putty )
?-> POS Zeigt eine Liste von Flags (
use Putty )
?-> TT TickTimer
Print_PStr(
PSTR("SCI,GIDX,GOTOD,TAR_OK?SIX,TRX,GIDX,IDXO") );
Print_PStr( PSTR("SMON,MOPD,SMSTOP,SMSOFF,SFR,SDIR")
); Print_PStr(
PSTR("HALF,FULL,SPR,SIENA,SIX,SIDXFRQ,SETO,SIT") );
Print_PStr( PSTR("SPO,SDP,GOD,COF,COFBIN,POF,POFBIN,POS,SIENA")
); Print_PStr(
PSTR("BWFR,SPD,DPS,GPOS,BWGP,BWTP,CPOSID,CDISMPOS")
); Print_PStr(
PSTR("LICHTSCHRANKE,IDXCHANGE,Flags,Ping,VER,CR_CRLF,TRX,TT")
);
QUELLFILES
MAIN.C
//------------------------------------------------------------------------------
// Programmed by Christof Ermer
// Regensburg 01.2006 und ab 27.09.2024
//------------------------------------------------------------------------------
///SYSINFO
#define VERSION "Drehfilter mit
SonderKeyfunktion ( Not STANDARD)"
#define DATUM
"08.10.2024" //"15.3.2007"
#define INSTITUT "UNI-Regensburg"
#define AUTOR "Christof Ermer"
// TEST DEVCPP
//B:\Drive\NASDrive\DEV_Cpp_NAS\DrehfilterTest_DEVCPP__LWC_07.10.24_1
// SCHALTER
//IN MAIN.H
/*HiSTORY
Rückbau der LED INdexxer,
'Einbau eines Gabelkopplers am PC0, HIGH = Gesachlossen
#define AVR_ATmega16
FUSE H=xBF L=x89 09.24
SET COPT IN FUSE BITS TO ENABLE XTAL
BAUDRATE = 9600,8,N,1
ICTRL = PD6
Neuer Indexer, Gabelkkoppler Wird high an PINC.0 09.24
NEUE AVRDUDE Version in make
# Program the device.
program: $(TARGET).hex $(TARGET).eep
# $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)
$(AVRDUDE_WRITE_EEPROM)
"C:\AVRDUDE\avrdude.exe" $(AVRDUDE_FLAGS)
$(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
Strom nicht sofort auf Low geschaltet, sondern nach DelayTime
The maximal possible delay is 262.14 ms / F_CPU in MHz. = 16,39625
ÄNDERUNG ENABLE IMMER AN !!!
PIN 33 PA7=ADC7 wird Enable ICtrl über BUZ 11 wird ein Widerstand 2*4R7
5W auf GND Kurzgesloosen
% Modulo geht nur mit 2 Hoch N Reihen als Modulo..
char gcaRxStr[RX_STRMAX + 1]; //+1 for the 0
char gcaNumStr[NUMMAX + 1]; //+1 for the 0
char gcaStr[STRMAX + 1]; //+1 for the 0
COMMAND_TYPE gsCmd;
char* gpcRxPars;
//STEP MOTOR RELATED
volatile STEPMPARTYPE gsStMPar;
//SPEICHERT DIE PARAMETER //deklarion in Main.H
volatile uint8_t gu8StepBitMusterPars; //+1 or -1 for the
Bitpatternselect
volatile uint8_t gu8ModePatternModulo; // Modulo selector
(HALF/FULLSTEP..)
PGM_P gpmpaStepPattern; // PGM_P PGM_VOID_P
volatile uint32_t gulMovedSteps; //compare with
MovedSteps //Wieviel hat sich der Motor gedreht..
uint32_t gulSM_ToRunCnt; //PULSE die der Motor laufen
soll
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
long glSM_RotPosition; //Single_Rotation-Haupztähler
der Position! MUSS NEGATIV WERDEN KÖNNEN
volatile float gfBigWeel_FullRotCnt; //200*2* (40/12)
= 666.66666
volatile float gfStepsPerDegree;// WeelFullRotationsteps= 666.666/360 =
1,851851667.............
volatile float gfDegreePerStep;// 360/666.666 WeelFullRotationsteps / =
0.54000054
volatile float gfBigWeel_GradPos;
volatile float gfBigWeel_Target_GradPos ;
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// ****************************************************************
ISR(TIMER1_COMPA_vect)// signal handler
//#define SIG_OUTPUT_COMPARE1A _VECTOR(6)
// ******************
{
//static uint8_t ucBitpattern;
//I_SREG automtaic clear by Interrupt and Enabled by
RETI
//cli();f
if( gsStMPar.u8StepMConditionFlag & STEPM_RUN_FLAG )
{
//Target ->meint Target in einer Rotation
if( (gsStMPar.u8SM_PostionFlag &
POSITION_STOP_ON_TARGET_MODE_FLAG)// &&
//Ziel so nahe wie möglich erreicht ? Also kleiner 1
Step...==40/12=3.3333
)
{
gsStMPar.u8SM_PostionFlag &=
~POSITION_STOP_ON_TARGET_MODE_FLAG; //SCHON In StepMotorStop();
StepMotorStop();
gsStMPar.u8SM_PostionFlag |=
POSITION_STOP_ON_TARGET_OK; //Meldung für main schon in motorstop
return;
};
// *************************************
void SetMotorDirection(uint8_t ucVal)
// *************************************
{//0= Rechts 1=Linksrum
//Nur wenn nicht schon so eingestellt
//Geht nur, weil #define STEPM_DIRECTION_FLAG
0x01= NULL Bit --> Sonst Shift Bit
if(ucVal) //1 == links
{
gsStMPar.u8StepMConditionFlag |=
STEPM_DIRECTION_FLAG;
}
else//dir == 0 == rechts
{
gsStMPar.u8StepMConditionFlag &=
~STEPM_DIRECTION_FLAG;
};
//Falls Motor grad aktiv ist,,halt in an,und ändere die
Richtung
if( gsStMPar.u8StepMConditionFlag & STEPM_RUN_FLAG )
{
StepMotorStop();
StepMotorOn();
};
};
// *************************************
void StepMotorOn(void)
// *************************************
{
//CPU_ICTRL_ONOFFLAG steuert ob dauerstrom oder PWM
//Verriegelung, falls der Motor an den
Anschlagschalterns steht,
//das er in die falsche Richtung
anstartet
//0x10 Wert des EXtswitch via INT1 = LINKS
//define MODE_FULLSTEP 0x00 define
MODE_HALFSTEP 0x01
//1. Warte auf Stop --> Ist der Auftrag erledigt,
(verhindert widersprechnede Befehle)
//2.Warte nach Stop
//Set_StepMotor_Mode( gsStMPar.ucSM_Mode
);
ICTRL_HIGHPWR(); //Lege die letzen
Bits an...
gulMovedSteps = 0; //COUNTSZÄHLER
!!!!!!!
wdt_reset(); //WATCHDOG
//Unbedingt warten damit Magnetfeld sich aufbauen
und fangen kann.
if( !(gsStMPar.u8StepMConditionFlag &
STEPM_ENABLE_FLAG) )
{
STEPCTRL_PORTX =
//Aktueller Stepper..Enabel
((
STEPCTRL_PORTX ) & ~STEPAMP_ALLCTRL_MASK) |
//ODER . clear SMbit und erhalte alle anderen Bits
(pgm_read_byte_near( (PGM_P)(gpmpaStepPattern + gu8StepBitMusterPars) )
);
};
wdt_reset();
_delay_ms( 1 ); //Unbedingt warten
damit Magnetfeld sich aufbauen und fangen kann.
gsStMPar.u32SM_ActiveStartTime = gulT2_Ticks;
if( READ_SENS_INDEX_ACTIVE_ISHIGH() ) // == 1// Lasche steht im
Optokoppler
{
Set_StepFRQ( gsStMPar.fStepMot_FRQ );
// 200*3,333 = 666.666 aber etwas weniger, also
nicht ganz rum!
Print_PStrCRLF( PSTR("Drive near Index->") );
gsStatus.ScanIndexRunning_F = 0;
char * pStrTok; // für strtok_r
char * pucCh = &pcStrOrder[ strlen(pcStrOrder) ]; // Stelle POINTER
auf \0 Ende // kein unsigned char*
strcpy(gcaStr, pcStrOrder);
#if LCD_4Bit_Module_USED == 1
WriteLCD(LCD_SHOW_CMD_LINE, gcaStr);//Füllt mit Sapce auf Vorsicht
umkopieren.. //ZEIGE DAs Commando an
#endif
// Print_StrCRLF( pcStrOrder ); /Rausmachen da zuvile Trffic
dabei entsteht.
gsCmd.fCmdVal_1 = gsCmd.fCmdVal_2 = 0;
if( (pStrTok = strtok_r( NULL, gcaNumStr, &pucCh)) !=
NULL)//Hole nun einen Value nach "$$$1,COMMAND,VALUE
{
gsCmd.fCmdVal_1 = atof(pStrTok);// Und dann TO
Float
};
if( (pStrTok = strtok_r( NULL, gcaNumStr, &pucCh)) !=
NULL)//Hole nun einen Value nach "$$$1,COMMAND,VALUE
{
gsCmd.fCmdVal_2 = atof(pStrTok);// Und dann TO
Float
};
//MM
// ************ MAIN LOOP FOR EVER *********************
int main(void)
// **********************************************************
{
uint32_t ulMainCnt = 0; //Speed watch
cli();//The global interrupt flag is maintained in the I bit of the
status register (SREG).
//INITS
wdt_reset(); //WATCHDOG!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//Wichtige Schritte.. so bald wie möglich
typedef struct
{
uint8_t IndexOK_F : 1; // gsStatus.IndexOK_F
uint8_t TargetSMPOS_Erreicht_F : 1;
//gsStatus.TargetSMPOS_Erreicht_F
uint8_t SMRUN_To_absoluteTarget_GradPOS_F : 1;
//gsStatus.SMRUN_To_absoluteTarget_GradPOS_F
uint8_t SM_NowSTOPed_Msg_F : 1; // gsStatus.SM_NowSTOPed_Msg_F //
Damit kein Text im Interrupt getriggert wird
uint8_t SM_Running_Msg_F : 1; // gsStatus.SM_Running_Msg_F //
Damit kein Text im Interrupt getriggert wird
uint8_t SM_NowOFF_F : 1; // gsStatus.SM_NowOFF_F // Damit kein
Text im Interrupt getriggert wird
//Es wird unterschieden nach CTRL und Condition Flags
//STEP FRQ
#define FRQ_OFF 0
#define FRQ_ON 1
// Das muss größer sein als MotorONTime, sonst verhacken sich die
Werte..
#define SCAN_INDEX_PULS_DELAY_MS 20 // 50aber 10* da delay nicht so
lang ist
//in STRUCT STEPMPARTYPE;
// uint8_t ucCPUModeFlag;
//COM OUT enabled etc....
//gsStMPar.ucCPUModeFlag
//#define CPUMODEFLAG_COMOUT_ENABLED
0x01 ///Com TX ENABLED
//gsStMPar.ucSysModeFlag
#define SYSTEM STATUS FLAGS
#define SYS_UART_TX_ENABLED
0x01 //übtragen der
StartUpInformationen
#define SYS_INFORMATION_FLAG
0x02 //übtragen der
StartUpInformationen