Before Single conversion
This commit is contained in:
@@ -1,40 +1,39 @@
|
||||
#include "floating_avg.h"
|
||||
|
||||
void InitFloatAvg(tFloatAvgFilter * io_pFloatAvgFilter,
|
||||
tFloatAvgType i_DefaultValue)
|
||||
|
||||
void InitFloatAvg (tFloatAvgFilter * io_pFloatAvgFilter, tFloatAvgType i_DefaultValue)
|
||||
{
|
||||
// Den Buffer mit dem Initialisierungswert fuellen:
|
||||
gFloatAvgSum = 0;
|
||||
// Init Buffer with initValue
|
||||
for (uint8_t i = 0; i < (1 << SIZE_OF_AVG); ++i)
|
||||
{
|
||||
io_pFloatAvgFilter->aData[i] = i_DefaultValue;
|
||||
gFloatAvgSum += i_DefaultValue;
|
||||
}
|
||||
// Der naechste Wert soll an den Anfang des Buffers geschrieben werden:
|
||||
io_pFloatAvgFilter->IndexNextValue = 0;
|
||||
}
|
||||
|
||||
|
||||
void AddToFloatAvg(tFloatAvgFilter * io_pFloatAvgFilter,
|
||||
tFloatAvgType i_NewValue)
|
||||
void AddToFloatAvg(tFloatAvgFilter * io_pFloatAvgFilter, tFloatAvgType i_NewValue)
|
||||
{
|
||||
// Neuen Wert an die dafuer vorgesehene Position im Buffer schreiben.
|
||||
io_pFloatAvgFilter->aData[io_pFloatAvgFilter->IndexNextValue] =
|
||||
i_NewValue;
|
||||
// Der naechste Wert wird dann an die Position dahinter geschrieben.
|
||||
// 1st remove oldest Value from Sum and than add new and store it
|
||||
gFloatAvgSum -= io_pFloatAvgFilter->aData[io_pFloatAvgFilter->IndexNextValue];
|
||||
gFloatAvgSum += i_NewValue;
|
||||
io_pFloatAvgFilter->aData[io_pFloatAvgFilter->IndexNextValue] = i_NewValue;
|
||||
io_pFloatAvgFilter->IndexNextValue++;
|
||||
// Wenn man hinten angekommen ist, vorne wieder anfangen.
|
||||
io_pFloatAvgFilter->IndexNextValue %= (1 << SIZE_OF_AVG);
|
||||
if (io_pFloatAvgFilter->IndexNextValue == SIZE_OF_AVG)
|
||||
io_pFloatAvgFilter->IndexNextValue = 0;
|
||||
//io_pFloatAvgFilter->IndexNextValue %= (1 << SIZE_OF_AVG);
|
||||
}
|
||||
|
||||
|
||||
tFloatAvgType GetOutputValue(tFloatAvgFilter * io_pFloatAvgFilter)
|
||||
{
|
||||
tTempSumType TempSum = 0;
|
||||
// Durchschnitt berechnen
|
||||
for (uint8_t i = 0; i < (1 << SIZE_OF_AVG); ++i)
|
||||
{
|
||||
TempSum += io_pFloatAvgFilter->aData[i];
|
||||
}
|
||||
// Der cast is OK, wenn tFloatAvgType und tTempSumType korrekt gewaehlt wurden.
|
||||
tFloatAvgType o_Result = (tFloatAvgType) (TempSum >> SIZE_OF_AVG);
|
||||
tFloatAvgType o_Result = (tFloatAvgType) (gFloatAvgSum >> SIZE_OF_AVG);
|
||||
return o_Result;
|
||||
}
|
||||
|
||||
tFloatAvgType GetSum(tFloatAvgFilter * io_pFloatAvgFilter)
|
||||
{
|
||||
return gFloatAvgSum;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
// Ueber wieviele Werte soll der gleitende Mittelwert berechnet werden?
|
||||
// 2**n Werte, da die Division als shift implementiert wird
|
||||
#define SIZE_OF_AVG 3
|
||||
#define SIZE_OF_AVG 2
|
||||
|
||||
// Datentyp, ueber den der gleitende Mittelwert berechnet werden soll.
|
||||
typedef uint16_t tFloatAvgType;
|
||||
@@ -16,6 +16,8 @@ typedef uint16_t tFloatAvgType;
|
||||
typedef uint32_t tTempSumType;
|
||||
// typedef float tTempSumType;
|
||||
|
||||
|
||||
|
||||
// Die Struktur, in der die Daten zwischengespeichert werden
|
||||
typedef struct
|
||||
{
|
||||
@@ -23,6 +25,8 @@ typedef struct
|
||||
uint8_t IndexNextValue;
|
||||
} tFloatAvgFilter;
|
||||
|
||||
volatile tTempSumType gFloatAvgSum;
|
||||
|
||||
|
||||
// Initialisiert das Filter mit einem Startwert.
|
||||
void InitFloatAvg(tFloatAvgFilter * io_pFloatAvgFilter,
|
||||
@@ -35,4 +39,5 @@ void AddToFloatAvg(tFloatAvgFilter * io_pFloatAvgFilter,
|
||||
// Berechnet den Durchschnitt aus den letzten SIZE_OF_AVG eingetragenen Werten.
|
||||
tFloatAvgType GetOutputValue(tFloatAvgFilter * io_pFloatAvgFilter);
|
||||
|
||||
tFloatAvgType GetSum(tFloatAvgFilter * io_pFloatAvgFilter);
|
||||
#endif
|
||||
|
||||
@@ -36,4 +36,7 @@ void set_cursor (uint8_t x, uint8_t y);
|
||||
#ifndef LCD_EN
|
||||
#define LCD_EN PC6
|
||||
#endif
|
||||
#ifndef LCD_LED
|
||||
#define LCD_LED PC7
|
||||
#endif
|
||||
// DB4 bis DB7 des LCD sind mit PC0 bis PC3 des AVR verbunden
|
||||
|
||||
@@ -1 +1 @@
|
||||
<AVRStudio><MANAGEMENT><ProjectName>CSAMPLE</ProjectName><Created>21-Feb-2010 12:55:22</Created><LastEdit>02-May-2010 07:21:22</LastEdit><ICON>241</ICON><ProjectType>0</ProjectType><Created>21-Feb-2010 12:55:22</Created><Version>4</Version><Build>4, 18, 0, 685</Build><ProjectTypeName>AVR GCC</ProjectTypeName></MANAGEMENT><CODE_CREATION><ObjectFile>default\screwer.elf</ObjectFile><EntryFile></EntryFile><SaveFolder>E:\AVR\screwer\</SaveFolder></CODE_CREATION><DEBUG_TARGET><CURRENT_TARGET>AVR Simulator</CURRENT_TARGET><CURRENT_PART>AT90S8515.xml</CURRENT_PART><BREAKPOINTS></BREAKPOINTS><IO_EXPAND><HIDE>false</HIDE></IO_EXPAND><REGISTERNAMES><Register>R00</Register><Register>R01</Register><Register>R02</Register><Register>R03</Register><Register>R04</Register><Register>R05</Register><Register>R06</Register><Register>R07</Register><Register>R08</Register><Register>R09</Register><Register>R10</Register><Register>R11</Register><Register>R12</Register><Register>R13</Register><Register>R14</Register><Register>R15</Register><Register>R16</Register><Register>R17</Register><Register>R18</Register><Register>R19</Register><Register>R20</Register><Register>R21</Register><Register>R22</Register><Register>R23</Register><Register>R24</Register><Register>R25</Register><Register>R26</Register><Register>R27</Register><Register>R28</Register><Register>R29</Register><Register>R30</Register><Register>R31</Register></REGISTERNAMES><COM>Auto</COM><COMType>0</COMType><WATCHNUM>0</WATCHNUM><WATCHNAMES><Pane0></Pane0><Pane1></Pane1><Pane2></Pane2><Pane3></Pane3></WATCHNAMES><BreakOnTrcaeFull>0</BreakOnTrcaeFull></DEBUG_TARGET><Debugger><modules><module></module></modules><Triggers></Triggers></Debugger><AVRGCCPLUGIN><FILES><SOURCEFILE>lcd-routines.c</SOURCEFILE><SOURCEFILE>floating_avg.c</SOURCEFILE><SOURCEFILE>screwer.c</SOURCEFILE><HEADERFILE>lcd-routines.h</HEADERFILE><HEADERFILE>floating_avg.h</HEADERFILE></FILES><CONFIGS><CONFIG><NAME>default</NAME><USESEXTERNALMAKEFILE>NO</USESEXTERNALMAKEFILE><EXTERNALMAKEFILE></EXTERNALMAKEFILE><PART>atmega8535</PART><HEX>1</HEX><LIST>1</LIST><MAP>1</MAP><OUTPUTFILENAME>screwer.elf</OUTPUTFILENAME><OUTPUTDIR>default\</OUTPUTDIR><ISDIRTY>1</ISDIRTY><OPTIONS><OPTION><FILE>floating_avg.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>lcd-routines.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>screwer.c</FILE><OPTIONLIST></OPTIONLIST></OPTION></OPTIONS><INCDIRS/><LIBDIRS/><LIBS><LIB>libprintf_flt.a</LIB><LIB>libm.a</LIB></LIBS><LINKOBJECTS/><OPTIONSFORALL>-Wall -gdwarf-2 -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums</OPTIONSFORALL><LINKEROPTIONS>-Wl,-u,vfprintf</LINKEROPTIONS><SEGMENTS/></CONFIG></CONFIGS><LASTCONFIG>default</LASTCONFIG><USES_WINAVR>1</USES_WINAVR><GCC_LOC>C:\Programme\WinAVR-20100110\bin\avr-gcc.exe</GCC_LOC><MAKE_LOC>C:\Programme\WinAVR-20100110\utils\bin\make.exe</MAKE_LOC></AVRGCCPLUGIN><IOView><usergroups/><sort sorted="0" column="0" ordername="0" orderaddress="0" ordergroup="0"/></IOView><Files><File00000><FileId>00000</FileId><FileName>screwer.c</FileName><Status>1</Status></File00000><File00001><FileId>00001</FileId><FileName>floating_avg.h</FileName><Status>1</Status></File00001></Files><Events><Bookmarks></Bookmarks></Events><Trace><Filters></Filters></Trace></AVRStudio>
|
||||
<AVRStudio><MANAGEMENT><ProjectName>screwer</ProjectName><Created>21-Feb-2010 12:55:22</Created><LastEdit>02-May-2010 12:26:11</LastEdit><ICON>241</ICON><ProjectType>0</ProjectType><Created>21-Feb-2010 12:55:22</Created><Version>4</Version><Build>4, 18, 0, 685</Build><ProjectTypeName>AVR GCC</ProjectTypeName></MANAGEMENT><CODE_CREATION><ObjectFile>default\screwer.elf</ObjectFile><EntryFile></EntryFile><SaveFolder>E:\AVR\screwer\</SaveFolder></CODE_CREATION><DEBUG_TARGET><CURRENT_TARGET>AVR Simulator</CURRENT_TARGET><CURRENT_PART>AT90S8515.xml</CURRENT_PART><BREAKPOINTS></BREAKPOINTS><IO_EXPAND><HIDE>false</HIDE></IO_EXPAND><REGISTERNAMES><Register>R00</Register><Register>R01</Register><Register>R02</Register><Register>R03</Register><Register>R04</Register><Register>R05</Register><Register>R06</Register><Register>R07</Register><Register>R08</Register><Register>R09</Register><Register>R10</Register><Register>R11</Register><Register>R12</Register><Register>R13</Register><Register>R14</Register><Register>R15</Register><Register>R16</Register><Register>R17</Register><Register>R18</Register><Register>R19</Register><Register>R20</Register><Register>R21</Register><Register>R22</Register><Register>R23</Register><Register>R24</Register><Register>R25</Register><Register>R26</Register><Register>R27</Register><Register>R28</Register><Register>R29</Register><Register>R30</Register><Register>R31</Register></REGISTERNAMES><COM>Auto</COM><COMType>0</COMType><WATCHNUM>0</WATCHNUM><WATCHNAMES><Pane0></Pane0><Pane1></Pane1><Pane2></Pane2><Pane3></Pane3></WATCHNAMES><BreakOnTrcaeFull>0</BreakOnTrcaeFull></DEBUG_TARGET><Debugger><modules><module></module></modules><Triggers></Triggers></Debugger><AVRGCCPLUGIN><FILES><SOURCEFILE>lcd-routines.c</SOURCEFILE><SOURCEFILE>floating_avg.c</SOURCEFILE><SOURCEFILE>screwer.c</SOURCEFILE><HEADERFILE>lcd-routines.h</HEADERFILE><HEADERFILE>floating_avg.h</HEADERFILE><OTHERFILE>default\screwer.lss</OTHERFILE><OTHERFILE>default\screwer.map</OTHERFILE></FILES><CONFIGS><CONFIG><NAME>default</NAME><USESEXTERNALMAKEFILE>NO</USESEXTERNALMAKEFILE><EXTERNALMAKEFILE></EXTERNALMAKEFILE><PART>atmega8535</PART><HEX>1</HEX><LIST>1</LIST><MAP>1</MAP><OUTPUTFILENAME>screwer.elf</OUTPUTFILENAME><OUTPUTDIR>default\</OUTPUTDIR><ISDIRTY>1</ISDIRTY><OPTIONS><OPTION><FILE>floating_avg.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>lcd-routines.c</FILE><OPTIONLIST></OPTIONLIST></OPTION><OPTION><FILE>screwer.c</FILE><OPTIONLIST></OPTIONLIST></OPTION></OPTIONS><INCDIRS/><LIBDIRS/><LIBS><LIB>libprintf_flt.a</LIB><LIB>libm.a</LIB></LIBS><LINKOBJECTS/><OPTIONSFORALL>-Wall -gdwarf-2 -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums</OPTIONSFORALL><LINKEROPTIONS>-Wl,-u,vfprintf</LINKEROPTIONS><SEGMENTS/></CONFIG></CONFIGS><LASTCONFIG>default</LASTCONFIG><USES_WINAVR>1</USES_WINAVR><GCC_LOC>C:\Programme\WinAVR-20100110\bin\avr-gcc.exe</GCC_LOC><MAKE_LOC>C:\Programme\WinAVR-20100110\utils\bin\make.exe</MAKE_LOC></AVRGCCPLUGIN><IOView><usergroups/><sort sorted="0" column="0" ordername="1" orderaddress="1" ordergroup="1"/></IOView><Files><File00000><FileId>00000</FileId><FileName>screwer.c</FileName><Status>1</Status></File00000></Files><Events><Bookmarks></Bookmarks></Events><Trace><Filters></Filters></Trace></AVRStudio>
|
||||
|
||||
@@ -1 +1 @@
|
||||
<AVRWorkspace><IOSettings><CurrentRegisters/></IOSettings><part name="AT90S8515"/><Files><File00000 Name="E:\AVR\screwer\screwer.c" Position="613 71 1437 658" LineCol="131 27" State="Maximized"/><File00001 Name="E:\AVR\screwer\floating_avg.h" Position="749 226 1389 610" LineCol="22 25" State="Maximized"/></Files></AVRWorkspace>
|
||||
<AVRWorkspace><IOSettings><CurrentRegisters/></IOSettings><part name="AT90S8515"/><Files><File00000 Name="E:\AVR\screwer\screwer.c" Position="229 77 1000 775" LineCol="242 27" State="Maximized"/></Files></AVRWorkspace>
|
||||
|
||||
300
screwer.c
300
screwer.c
@@ -10,10 +10,12 @@ nst, 07.11.2005
|
||||
#include "lcd-routines.h"
|
||||
#include "floating_avg.h"
|
||||
|
||||
|
||||
//Constants
|
||||
#define ADC_CURRENT 0
|
||||
#define ADC_SETPOINT_SPEED 2
|
||||
#define ADC_SETPOINT_TORQUE 1
|
||||
#define USED_ADC_CHANNELS 3
|
||||
#define ADC_CURRENT 1
|
||||
#define ADC_SETPOINT_SPEED 0
|
||||
#define ADC_SETPOINT_TORQUE 2
|
||||
|
||||
//LCD Settings
|
||||
#define LCD_PORT PORTC
|
||||
@@ -23,45 +25,89 @@ nst, 07.11.2005
|
||||
|
||||
//Devel
|
||||
//#define CURRENT_RAW
|
||||
//#define TORQUE_DEBUG
|
||||
//#define ADC_DEBUG
|
||||
|
||||
//Prototypes
|
||||
void pwm_init (void);
|
||||
void tc0_init (void);
|
||||
void ADC_init (void);
|
||||
uint16_t ReadADC (uint8_t mux);
|
||||
|
||||
//global Vars
|
||||
volatile uint16_t uiSpeedDelay;
|
||||
//global Vars for ISR Access
|
||||
volatile unsigned char gcStopped;
|
||||
volatile uint16_t gu16SpeedDelay;
|
||||
volatile uint16_t gu16Test;
|
||||
volatile double gfSetSpeed;
|
||||
volatile uint16_t gu16AdcRes[USED_ADC_CHANNELS];
|
||||
volatile tFloatAvgFilter FilterCurrent;
|
||||
|
||||
//ISR Timer 0 - Counter for smooth start
|
||||
|
||||
//ISR Timer 0 - for future usage
|
||||
ISR (TIMER0_OVF_vect)
|
||||
{
|
||||
if (uiSpeedDelay > 0)
|
||||
{
|
||||
uiSpeedDelay --;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//ISR Timer 1 - measure current
|
||||
//ISR Timer 1 - measure current on Bottom of PWM
|
||||
ISR (TIMER1_OVF_vect)
|
||||
{
|
||||
|
||||
//uint16_t u16Speed = (uint16_t)(gfSetSpeed / (double) gu16AdcRes [ADC_CURRENT]);
|
||||
//AddToFloatAvg (&FilterCurrent, gu16AdcRes [ADC_CURRENT] / gu16Test);
|
||||
gu16Test = gu16AdcRes [ADC_CURRENT];
|
||||
}
|
||||
|
||||
|
||||
//ISR ADC Converision complete
|
||||
ISR (ADC_vect)
|
||||
{
|
||||
uint8_t u8ActChannel = (ADMUX & 0x1F);
|
||||
gu16AdcRes[u8ActChannel] = ADCL;
|
||||
gu16AdcRes[u8ActChannel] += (ADCH << 8);
|
||||
if (u8ActChannel == ADC_CURRENT)
|
||||
{
|
||||
if (gu16AdcRes [ADC_CURRENT] > 512)
|
||||
{
|
||||
gu16AdcRes [ADC_CURRENT] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
gu16AdcRes [ADC_CURRENT] = 512 - gu16AdcRes [ADC_CURRENT];
|
||||
}
|
||||
}
|
||||
|
||||
u8ActChannel += 1;
|
||||
if (gcStopped)
|
||||
{
|
||||
if (u8ActChannel == 3)
|
||||
u8ActChannel = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (u8ActChannel == 2)
|
||||
u8ActChannel = 0;
|
||||
}
|
||||
ADMUX = (ADMUX & 0xE0) | u8ActChannel;
|
||||
}
|
||||
|
||||
//==========================================================
|
||||
int main (void)
|
||||
{
|
||||
//++++++++++++++++++++++++++++++++++++
|
||||
//declaration
|
||||
char sBuffer [20];
|
||||
char sState [3];
|
||||
unsigned char bTorqueReached = 0;
|
||||
uint16_t uiCurrent, uiSetpointSpeed;
|
||||
double fTorque, fSetpointTorque;
|
||||
unsigned char bStarted, bMotorLeft, bTorqueReached = 0;
|
||||
uint16_t uiCurrent, uiCurrentMin, uiCurrentMax, uiCurrentReached, u16SetSpeed, uiSetpointSpeed = 0, u16LCDTrigger = 1;
|
||||
double fTorque, fSetpointTorque, fReachedTorque;
|
||||
|
||||
uint16_t uiCurrentZero = 100;
|
||||
const double fCurrentStep = 0.03699;
|
||||
const double fTorqueConstant = 0.630; //MN/A
|
||||
const double fCurrentStep = 0.02466;
|
||||
const double fTorqueConstant = 0.630; //Nm/A from Motortype
|
||||
const double fTorqueSetpointStep = 0.00615234; //From Sensortype 0.009885
|
||||
const double fSetpintTorqueMax = 6.0; //From Sensortype Nm
|
||||
double fCurrTorqueConst = fCurrentStep * fTorqueConstant;
|
||||
const double fTorqueSetpointStep = 0.009885;
|
||||
//Portsetup
|
||||
//LCD on Port C !!!
|
||||
lcd_init ();
|
||||
@@ -72,123 +118,179 @@ int main (void)
|
||||
|
||||
//Lock Low Side of H-Bride !!!!
|
||||
PORTD = (1 << PD6) | (1 << PD7);
|
||||
DDRD = (1 << PD4) | (1 << PD5) | (1 << PD6) | (1 << PD7) ; //Set PBD5 (OC1A) as Write
|
||||
|
||||
DDRD = (1 << PD0) | (1 << PD4) | (1 << PD5) | (1 << PD6) | (1 << PD7) ; //Set PBD5 (OC1A) as Write
|
||||
|
||||
//Enable Interrupts
|
||||
sei ();
|
||||
|
||||
//Init PWM
|
||||
pwm_init ();
|
||||
|
||||
//Set Timer 0 and Enable Interrupts
|
||||
sei ();
|
||||
tc0_init ();
|
||||
|
||||
|
||||
// Datenstruktur anlegen:
|
||||
tFloatAvgFilter FilterCurrent;
|
||||
//Set Timer 0
|
||||
//tc0_init ();
|
||||
|
||||
//ADC initialisieren
|
||||
ADC_init ();
|
||||
|
||||
// initialisieren und mit aktuellem wert fuellen
|
||||
uiCurrentZero = ReadADC (ADC_CURRENT);
|
||||
uiCurrentZero = gu16AdcRes [ADC_CURRENT];
|
||||
InitFloatAvg (&FilterCurrent, uiCurrentZero);
|
||||
|
||||
|
||||
//Compare
|
||||
OCR1A = 0x0;
|
||||
OCR1B = 0x0;
|
||||
|
||||
|
||||
|
||||
//LDC Light ON
|
||||
LCD_PORT|= (1 << LCD_LED);
|
||||
|
||||
while (1)
|
||||
{
|
||||
//Read Analog values
|
||||
{
|
||||
|
||||
//Read Current Vallue fom IC
|
||||
uiCurrent = ReadADC (ADC_CURRENT);
|
||||
if (((PIND & (1 << PD1)) == 0) && ((PIND & (1 << PD2)) == 0))
|
||||
//Floating Average
|
||||
//uiCurrent = GetOutputValue (&FilterCurrent);
|
||||
uiCurrent = gu16AdcRes [ADC_CURRENT];
|
||||
|
||||
//Calculate Speed
|
||||
u16SetSpeed = (uiSetpointSpeed - gu16SpeedDelay) >> 2; //TOP 0xff
|
||||
gu16Test = 0xff / u16SetSpeed ;
|
||||
//gfSetSpeed = (double) u16SetSpeed / 255.0;
|
||||
|
||||
|
||||
//Debug limits of Torque
|
||||
#ifdef TORQUE_DEBUG
|
||||
if (!gu16SpeedDelay)
|
||||
{
|
||||
if (gu16AdcRes [ADC_CURRENT] > uiCurrentMax)
|
||||
uiCurrentMax = gu16AdcRes [ADC_CURRENT];
|
||||
if (gu16AdcRes [ADC_CURRENT] < uiCurrentMin)
|
||||
uiCurrentMin = gu16AdcRes [ADC_CURRENT];
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
gcStopped = ((PIND & (1 << PD2)) == 0);
|
||||
if (gcStopped)
|
||||
{
|
||||
bMotorLeft = PIND & (1 << PD3);
|
||||
uiCurrentMax = 0;
|
||||
//Motor stopped so recalibrate
|
||||
uiCurrentZero = uiCurrent;
|
||||
//FixMe bad idea uiCurrentZero = uiCurrent;
|
||||
//Get potis
|
||||
uiSetpointSpeed = ReadADC (ADC_SETPOINT_SPEED);
|
||||
fSetpointTorque = ReadADC (ADC_SETPOINT_TORQUE) * fTorqueSetpointStep;
|
||||
uiSetpointSpeed = gu16AdcRes [ADC_SETPOINT_SPEED];
|
||||
fSetpointTorque = (double) gu16AdcRes [ADC_SETPOINT_TORQUE] * fTorqueSetpointStep;
|
||||
//Minumum Torque
|
||||
if (fSetpointTorque < 0.5)
|
||||
fSetpointTorque = 0.5;
|
||||
if (fSetpointTorque > fSetpintTorqueMax)
|
||||
fSetpointTorque = fSetpintTorqueMax;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gu16SpeedDelay > 0)
|
||||
gu16SpeedDelay --;
|
||||
}
|
||||
|
||||
|
||||
uiCurrent -= uiCurrentZero;
|
||||
|
||||
//Floating Average
|
||||
AddToFloatAvg (&FilterCurrent, uiCurrent);
|
||||
uiCurrent = GetOutputValue (&FilterCurrent);
|
||||
|
||||
|
||||
if (uiCurrent < uiCurrentZero)
|
||||
uiCurrent = 0;
|
||||
else
|
||||
uiCurrent -= uiCurrentZero;
|
||||
|
||||
fTorque = (double)(uiCurrent) * fCurrTorqueConst;
|
||||
|
||||
//Start Motor left
|
||||
if ((PIND & (1 << PD1)) && !bTorqueReached)
|
||||
if ((PIND & (1 << PD2)) && bMotorLeft && !bTorqueReached)
|
||||
{
|
||||
OCR1B = 0;
|
||||
|
||||
PORTD |= (1 << PD7);
|
||||
PORTD &= ~(1 << PD6);
|
||||
|
||||
////PORTD |= (1 << PD5);
|
||||
////PORTD &= ~(1 << PD4);
|
||||
OCR1A = (uiSetpointSpeed - uiSpeedDelay) >> 2; //TOP = 0xff
|
||||
// strcpy (sState, "Li");
|
||||
OCR1A = u16SetSpeed;
|
||||
if (!bStarted)
|
||||
{
|
||||
strcpy (sState, "Li");
|
||||
bStarted = 1;
|
||||
}
|
||||
}
|
||||
//Start Motor right
|
||||
else if ((PIND & (1 << PD2)) && !bTorqueReached)
|
||||
else if ((PIND & (1 << PD2)) && !bMotorLeft && !bTorqueReached)
|
||||
{
|
||||
|
||||
OCR1A = 0;
|
||||
|
||||
PORTD |= (1 << PD6);
|
||||
PORTD &= ~(1 << PD7);
|
||||
|
||||
//PORTD |= (1 << PD4);
|
||||
//PORTD &= ~(1 << PD5);
|
||||
OCR1B = (uiSetpointSpeed - uiSpeedDelay) >> 2; //TOP = 0xff
|
||||
// strcpy (sState, "Re");
|
||||
OCR1B = u16SetSpeed;
|
||||
if (!bStarted)
|
||||
{
|
||||
strcpy (sState, "Re");
|
||||
bStarted = 1;
|
||||
}
|
||||
}
|
||||
else if (((PIND & (1 << PD1)) == 0) && ((PIND & (1 << PD2)) == 0))
|
||||
else if (gcStopped)
|
||||
{
|
||||
//Stop - no operation
|
||||
OCR1A = 0;
|
||||
OCR1B = 0;
|
||||
//smooth stop
|
||||
PORTD |= (1 << PD6) | (1 << PD7);
|
||||
uiSpeedDelay = uiSetpointSpeed;
|
||||
gu16SpeedDelay = uiSetpointSpeed;
|
||||
bTorqueReached = 0;
|
||||
bStarted = 0;
|
||||
strcpy (sState, "St");
|
||||
}
|
||||
|
||||
if ((fTorque > fSetpointTorque) && !uiSpeedDelay)
|
||||
if ((fTorque > fSetpointTorque) && !gu16SpeedDelay && !bTorqueReached)
|
||||
{
|
||||
//Torque Stop after start ramp
|
||||
OCR1A = 0x00;
|
||||
OCR1B = 0x00;
|
||||
//Fast Stop
|
||||
PORTD |= (1 << PD6) | (1 << PD7);
|
||||
//Fast Stop
|
||||
//PORTD &= ~(1 << PD6);
|
||||
//PORTD &= ~(1 << PD7);
|
||||
bTorqueReached = 1;
|
||||
fReachedTorque = fTorque;
|
||||
uiCurrentReached = uiCurrent;
|
||||
strcpy (sState, "ST");
|
||||
}
|
||||
|
||||
//LCD
|
||||
u16LCDTrigger ++;
|
||||
if (u16LCDTrigger == 2500)
|
||||
{
|
||||
#ifdef ADC_DEBUG
|
||||
set_cursor (0, 1);
|
||||
sprintf (sBuffer, "M%d v%d I%d" ,gu16AdcRes [ADC_SETPOINT_TORQUE], gu16AdcRes [ADC_SETPOINT_SPEED], gu16AdcRes [ADC_CURRENT]);
|
||||
lcd_string (sBuffer);
|
||||
#else
|
||||
if (gcStopped)
|
||||
{
|
||||
set_cursor (0, 1);
|
||||
#ifdef TORQUE_DEBUG
|
||||
sprintf (sBuffer, "m%d M%d", uiCurrentMin, uiCurrentMax);
|
||||
#else
|
||||
sprintf (sBuffer, "v=%3d%% M=%03.1fNm", ((uiSetpointSpeed - (uiSetpointSpeed /1000) * uiSetpointSpeed %1000)/ 10), fSetpointTorque);
|
||||
#endif
|
||||
lcd_string (sBuffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
set_cursor (0, 1);
|
||||
sprintf (sBuffer, "v=%d%% M=%04.2fNm", (uiSetpointSpeed / 10), fSetpointTorque);
|
||||
lcd_string (sBuffer);
|
||||
set_cursor (0, 2);
|
||||
#ifdef CURRENT_RAW
|
||||
sprintf (sBuffer, "%s I=%dA", sState, (uiCurrent + uiCurrentZero));
|
||||
#else
|
||||
//sprintf (sBuffer, "%s I=%8.2fA", sState, );
|
||||
sprintf (sBuffer, "%s M=%04.2fNm", sState, (fTorque));
|
||||
#endif
|
||||
lcd_string (sBuffer);
|
||||
set_cursor (0, 2);
|
||||
if (bTorqueReached)
|
||||
{
|
||||
sprintf (sBuffer, "%s M=%03.2fNm ", sState, fReachedTorque);
|
||||
sprintf (sBuffer, "%s I%dA M%04.2fN", sState, uiCurrentReached, fReachedTorque);
|
||||
}
|
||||
else
|
||||
sprintf (sBuffer, "%s M=%04.2f I=%d ", sState, fTorque, uiCurrent);
|
||||
|
||||
}
|
||||
lcd_string (sBuffer);
|
||||
u16LCDTrigger = 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
}
|
||||
@@ -196,17 +298,20 @@ int main (void)
|
||||
/*==========================================*/
|
||||
void pwm_init (void)
|
||||
{
|
||||
//Compare values to zero
|
||||
OCR1A = 0x0;
|
||||
OCR1B = 0x0;
|
||||
// Set timer 1
|
||||
// OC1A/OC1B clear on Match, Set on Top
|
||||
// 8 bit resolution , Phase Correct PWM
|
||||
TCCR1A = (1 << COM1A1) | (0 << COM1A0) | \
|
||||
(1 << COM1B1) | (0 << COM1B1) | \
|
||||
(1 << COM1B1) | (0 << COM1B0) | \
|
||||
(0 << WGM13) | (0 << WGM12) | (0 << WGM11) | (1 << WGM10);
|
||||
// Pre divisor of Timer 1
|
||||
TCCR1B = (0 << CS12) | (0 << CS11) | (1 << CS10);
|
||||
|
||||
//Enable overflow interrupt
|
||||
//TIMSK |= (1 << TOIE1);
|
||||
//Enable overflow interrupt
|
||||
TIMSK |= (1 << TOIE1);
|
||||
|
||||
|
||||
//Set TOP value
|
||||
@@ -220,47 +325,26 @@ void tc0_init (void)
|
||||
// Set timer 0
|
||||
// normal operation
|
||||
TCCR0 = (0 << WGM01) | (0 << WGM00) | \
|
||||
(0 << CS02) | (1 << CS01) | (1 << CS00);
|
||||
(0 << CS02) | (1 << CS01) | (0 << CS00);
|
||||
|
||||
//Enable overflow interrupt
|
||||
TIMSK |= (1 << TOIE0);
|
||||
//TIMSK |= (1 << TOIE0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*==========================================*/
|
||||
uint16_t ReadADC (uint8_t mux)
|
||||
void ADC_init (void)
|
||||
{
|
||||
uint8_t i;
|
||||
uint16_t result;
|
||||
|
||||
//Seclect Channel
|
||||
ADMUX = mux;
|
||||
//set Reference Voltage to external
|
||||
ADMUX |= (0 << REFS1) | (0 << REFS0);
|
||||
|
||||
//Prescaler 50kHz < CLK / Prescaler < 200 kHz !!!
|
||||
//also enaable ADC
|
||||
ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
|
||||
ADMUX = (0 << REFS1) | (0 << REFS0);
|
||||
//Prescaler 50kHz < CLK / Prescaler < 200 kHz otherwise errors in LSBs!!!
|
||||
//enaable ADC and interupt
|
||||
//Enable freeruning mode,
|
||||
ADCSRA = (1 << ADEN) | (1 << ADIE) | (1 << ADATE)| (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
|
||||
ADCSRA |= (1 << ADSC);
|
||||
|
||||
}
|
||||
|
||||
//1st Dummy Readout
|
||||
ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
|
||||
while ( ADCSRA & (1 << ADSC))
|
||||
{//wait for convertion
|
||||
}
|
||||
result = ADCW;
|
||||
|
||||
result = 0;
|
||||
for (i = 0; i < 4; i ++)
|
||||
{
|
||||
ADCSRA |= (1 << ADSC);// eine Wandlung "single conversion"
|
||||
while (ADCSRA & (1 << ADSC))
|
||||
{//wait for convertion
|
||||
}
|
||||
result += ADCW;
|
||||
}
|
||||
ADCSRA &= ~(1 << ADEN);
|
||||
return (result >> 2);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user