Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Anders Blomdell
processer
Commits
ccb57fb5
Commit
ccb57fb5
authored
Jan 16, 2009
by
Pontus Giselsson
Browse files
P-Current control sampling rate 0.5ms
parent
316030e8
Changes
5
Hide whitespace changes
Inline
Side-by-side
linear_pendulum_2009/avr/Makefile
0 → 100644
View file @
ccb57fb5
PROJECT
=
current_control
CHIP
=
atmega16
ARCH
=
avr
AVRSOURCE
=
AVRAUTO
=
compiled/
$(ARCH)
/
AVRARCH
=
compiled/
$(ARCH)
/
LIB_TARGET
=
$(AVRARCH)
lib
$(TARGET)
.a
CC
=
$(ARCH)
-gcc
CXX
=
$(ARCH)
-gcc
CCFLAGS
=
-mmcu
=
$(CHIP)
-O5
-I
.
-I
$(AVRAUTO)
AS
=
$(ARCH)
-as
ASFLAGS
=
-mmcu
=
$(CHIP)
AR
=
$(ARCH)
-ar
LD
=
$(ARCH)
-ld
OBJDUMP
=
$(ARCH)
-objdump
LDFLAGS
=
-T
$(CHIP)
.link
all
:
$(AVRARCH)$(PROJECT)
$(LIB_TARGET)(%.o)
:
$(AVRSOURCE)%.c Makefile
$(CC)
$(CCFLAGS)
-c
-o
$(AVRARCH)
$
(
%
)
-I
$(AVRSOURCE)
-I
$(AVRAUTO)
$
(
<
)
$(AR)
r
$
(
@
)
$(AVRARCH)
$
(
%
)
rm
$(AVRARCH)
$
(
%
)
$(LIB_TARGET)(%.o)
:
$(AVRSOURCE)%.cc Makefile
$(CXX)
$(CCFLAGS)
-c
-o
$(AVRARCH)
$
(
%
)
-I
$(AVRSOURCE)
-I
$(AVRAUTO)
$
(
<
)
$(AR)
r
$
(
@
)
$(AVRARCH)
$
(
%
)
rm
$(AVRARCH)
$
(
%
)
$(LIB_TARGET)(%.o)
:
$(AVRSOURCE)%.s Makefile
$(AS)
$(ASFLAGS)
-o
$(AVRARCH)
$
(
%
)
$(AVRSOURCE)
$
(
*
)
.s
$(AR)
r
$
(
@
)
$(AVRARCH)
$
(
%
)
rm
$(AVRARCH)
$
(
%
)
$(AVRARCH)%.o
:
$(AVRSOURCE)%.s Makefile
$(AS)
$(ASFLAGS)
-o
$@
$(AVRSOURCE)
$
(
*
)
.s
$(AVRARCH)%.o
:
$(AVRSOURCE)%.c Makefile
$(CC)
$(CCFLAGS)
-c
-o
$@
-I
.
-I
$(AVRAUTO)
$<
$(AVRARCH)%
:
$(AVRARCH)%.o Makefile
$(CC)
$(CCFLAGS)
-o
$@
$<
-lm
$(AVRARCH)%.sr
:
all $(AVRARCH)%
avr-objcopy
-O
srec
$(AVRARCH)
/
$
(
*
)
$@
%.sr
:
$(AVRARCH)%.sr
@
/bin/true
%.load
:
compiled/avr/%.sr
# /work/andersb/atmel/uisp/uisp-0.2b/src/uisp \
# -dno-poll -dstk200 --erase --upload if=$(AVRARCH)/$(*).sr
uisp
\
-dprog
=
stk200
\
--erase
\
--upload
if
=
compiled/avr/
$*
.sr
%.load.stk500
:
compiled/avr/%.sr
uisp
\
-dprog
=
stk500
\
--erase
\
--upload
if
=
compiled/avr/
$*
.sr
%.dump
:
all $(AVRARCH)/%
$(OBJDUMP)
-D
$(AVRARCH)
/
$
(
*
)
$(AVRARCH)fuse.sr
:
fuse.s
avr-gcc
-o
$(AVRARCH)
fuse.o
-c
fuse.s
avr-objcopy
-O
srec
$(AVRARCH)
fuse.o
$(AVRARCH)
fuse.sr
fuse.load
:
$(AVRARCH)fuse.sr
uisp
\
-dprog
=
stk200
\
--erase
\
--segment
=
fuse
\
--upload
if
=
compiled/avr/fuse.sr
load.stk500
:
$(PROJECT).load.stk500
\ No newline at end of file
linear_pendulum_2009/avr/compile.sh
0 → 100755
View file @
ccb57fb5
avr-gcc
-mmcu
=
atmega16
-g
-Wall
-o
current_control current_control.c
\ No newline at end of file
linear_pendulum_2009/avr/compileUpload.sh
0 → 100755
View file @
ccb57fb5
avr-gcc
-mmcu
=
atmega16
-g
-Wall
-o
current_control current_control.c
avr-objcopy
-Osrec
current_control current_control.sr
uisp
-dprog
=
stk200
--erase
--upload
if
=
current_control.sr
\ No newline at end of file
linear_pendulum_2009/avr/current_control
0 → 100755
View file @
ccb57fb5
File added
linear_pendulum_2009/avr/current_control.c
0 → 100644
View file @
ccb57fb5
/*********************************************
Current regulation - Aleks Ponjavic 18/09/07
for LTH - reglerteknik
Note that the voltage is actually a duty
cycle for the PWM. The PWM is running at
12V with a duty cycle set by a 10bit value
*********************************************/
//#include <math.h> //Only include if sin will be used, takes up memory!
#include
<avr/io.h>
#include
<avr/signal.h>
#include
<avr/interrupt.h>
#include
<inttypes.h>
volatile
int16_t
ref
=
20
;
volatile
int16_t
refCount
=
0
;
volatile
int8_t
refFlag
=
0
;
volatile
uint8_t
alt
=
1
;
/* Routine used to set the red LED */
void
setLED
(
uint8_t
on
)
{
if
(
on
)
PORTB
&=
0x7f
;
//Turn on
else
PORTB
|=
0x80
;
//Turn off
}
/* Routine used to set pin PD7 */
void
setPA4
(
uint8_t
on
)
{
if
(
on
==
0
)
PORTA
&=
0xef
;
//Turn off
else
PORTA
|=
0x10
;
//Turn on
}
/* Routine used to transmit bytes on the serial port */
static
void
putchar
(
unsigned
char
ch
)
{
while
((
inp
(
UCSRA
)
&
0x20
)
==
0
)
{};
outp
(
ch
,
UDR
);
while
((
inp
(
UCSRA
)
&
0x20
)
==
0
)
{};
}
/* Interrupt service routine for handling incoming bytes on the serial port
might be needed to catch incoming bytes */
SIGNAL
(
SIG_UART_RECV
){}
/* Read 10-bit input using the AD converter */
static
inline
int16_t
readInput
()
{
uint8_t
low
,
high
;
ADCSRA
|=
0x40
;
while
(
ADCSRA
&
0x40
);
low
=
ADCL
;
high
=
ADCH
;
return
((
high
<<
8
)
|
low
)
-
512
;
}
/* Write 8-bit output using the PWM-generator */
static
inline
void
writeOutput
(
int16_t
val
)
{
if
(
val
<
0
)
{
PORTC
=
0x80
+
(
PORTC
&
0x7F
);
OCR1BH
=
0
;
//(unsigned char) (-val)&0xff00;
OCR1BL
=
(
unsigned
char
)
(
-
val
)
&
0x00ff
;
}
else
{
PORTC
=
(
PORTC
&
0x7F
);
OCR1BH
=
0
;
//(unsigned char) (val&0xff00);
OCR1BL
=
(
unsigned
char
)
(
val
&
0x00ff
);
}
//unsigned char lbyte,hbyte;
//hbyte = ((val & 0xff00)>>8); //Get ADC result high byte
//lbyte = ((val & 0x00ff)); //Get ADC result low byte
//putchar(hbyte);
//putchar(lbyte);
}
/* Periodic timer interrupt */
SIGNAL
(
SIG_OUTPUT_COMPARE2
)
{
// PORTA &= 0xef;
unsigned
char
lbyte
,
hbyte
;
int16_t
result
;
int16_t
ctrl
;
int16_t
ctrl_out
;
int16_t
temp
;
setPA4
(
alt
);
result
=
readInput
();
setPA4
(
0
);
result
=
result
*
3
;
//!!!!!!!!!!!!!!!!!!!!!!!
// Compensate for offset in measurements
// result += 13;
//hbyte = (((ref-result) & 0xff00)>>8); //Get ADC result high byte
//lbyte = (((ref-result) & 0x00ff)); //Get ADC result low byte
// Transmit data
//putchar(hbyte); //high byte
//putchar(lbyte); //low byte
//hbyte = ((result & 0xff00)>>8); //Get ADC result high byte
//lbyte = ((result & 0x00ff)); //Get ADC result low byte
// Transmit data
//putchar(hbyte); //high byte
//putchar(lbyte); //low byte
// control
ctrl
=
ref
-
result
;
ctrl
=
((
ctrl
+
(
1
<<
2
))
>>
3
);
//saturation/rounding to 8 bit
if
(
ctrl
>
127
)
ctrl_out
=
127
;
else
if
(
ctrl
<
-
128
)
ctrl_out
=
-
128
;
else
ctrl_out
=
ctrl
;
//writeOutput(ctrl_out);
writeOutput
(
ref
);
temp
=
(
int16_t
)
ctrl_out
;
hbyte
=
((
temp
&
0xff00
)
>>
8
);
//Get ADC result high byte
lbyte
=
((
temp
&
0x00ff
));
//Get ADC result low byte
putchar
(
hbyte
);
putchar
(
lbyte
);
}
/* reference square- or triangle wave generator with timer 0 */
SIGNAL
(
SIG_OVERFLOW0
)
{
int8_t
rectangle
=
1
;
refCount
++
;
if
(
rectangle
==
1
)
{
if
(
refFlag
==
0
)
{
if
(
refCount
==
10
)
{
refFlag
=
1
;
ref
=
-
ref
;
refCount
=
0
;
}
}
else
{
if
(
refCount
==
20
)
{
ref
=
-
ref
;
refCount
=
0
;
}
}
}
else
{
if
(
refCount
<=
400
)
{
// ref*2
ref
-=
1
;
}
else
{
ref
+=
1
;
}
if
(
refCount
==
800
)
{
// ref*4
refCount
=
0
;
}
}
}
int
main
()
{
int
i
,
j
;
//Port directions
outp
(
0x80
,
PORTB
);
// LED off
outp
(
0x80
,
DDRB
);
// output on LED
outp
(
0x08
,
PORTC
);
// pull up on overtemp signals
outp
(
0xa0
,
DDRC
);
// output on dir and brake
outp
(
0x80
,
PORTD
);
// pull up on reset switch
outp
(
0x10
,
DDRD
);
// output on pwm for motor 1
outp
(
0x10
,
DDRA
);
// test pin output
/* Timer section */
// Enable TCNT2 (timer2) compare match interrupts, and timer0 overflow interrupts
outp
(
BV
(
OCIE2
)
|
BV
(
TOIE0
),
TIMSK
);
/* Timer 1, 8 bit fast PWM no prescaling -> h_pwm=17.35 micros */
outp
(
BV
(
COM1A1
)
|
BV
(
COM1B1
)
|
BV
(
WGM10
),
TCCR1A
);
// Fast PWM
// outp(BV(WGM12)|BV(CS10),TCCR1B);
// Phase and frequency correct pwm
outp
(
BV
(
CS10
),
TCCR1B
);
/* Reset Timer1*/
//outp(0x00,TCNT1H); // Reset TCNT1 high
//outp(0x00,TCNT1L); // Reset TCNT1 low
/* Timer 2 (control loop), prescaler 256, clear on compare match (28), -> h = 0.5 ms */
outp
(
BV
(
WGM21
)
|
BV
(
CS22
)
|
BV
(
CS21
),
TCCR2
);
outp
(
28
,
OCR2
);
/* Reset timer 2 */
outp
(
0
,
TCNT2
);
/* Timer 0 for reference generation, prescaler = 1024 periodic h = ? */
outp
(
BV
(
CS02
)
|
BV
(
CS00
),
TCCR0
);
//Serial communication
outp
(
0x00
,
UCSRA
);
// USART:
outp
(
0x98
,
UCSRB
);
// USART: RxIntEnable|RxEnable|TxEnable
outp
(
0x86
,
UCSRC
);
// USART: 8bit, no parity
outp
(
0x00
,
UBRRH
);
// USART: 115200 @ 14.7456MHz
outp
(
7
,
UBRRL
);
// USART: 115200 @ 14.7456MHz
/* AREF (AREF is 5V) pin external capacitor, MUX0 for current, MUX3?? for pendulum angle */
outp
(
BV
(
REFS0
)
|
BV
(
MUX0
),
ADMUX
);
// Enable ADC interrupts, start first conversion (what do adps0-2 do), prescaler 128
// outp(BV(ADEN)|BV(ADSC)|BV(ADPS2)|BV(ADPS1)|BV(ADPS0),ADCSRA);
// Enable ADC interrupts, start first conversion (what do adps0-2 do), prescaler 8
// outp(BV(ADEN)|BV(ADSC)|BV(ADPS1)|BV(ADPS0),ADCSRA);
// Enable ADC interrupts, start first conversion (what do adps0-2 do), prescaler 64
outp
(
BV
(
ADEN
)
|
BV
(
ADSC
)
|
BV
(
ADPS2
)
|
BV
(
ADPS1
),
ADCSRA
);
// outp(BV(ADEN)|BV(ADSC),ADCSRA);
/* Wait a little bit, probably not needed...*/
int
tmp
;
for
(
i
=
0
;
i
<
2000
;
i
++
)
for
(
j
=
0
;
j
<
400
;
j
++
)
tmp
=
j
*
j
*
j
;
//Enable interrupts
sei
();
// loop
while
(
1
)
{}
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment