« SE4Binome2024-7 » : différence entre les versions
Aller à la navigation
Aller à la recherche
Ligne 8 : | Ligne 8 : | ||
#include <avr/interrupt.h> | #include <avr/interrupt.h> | ||
#include "ordonnanceur1.h" | #include "ordonnanceur1.h" | ||
#define CTC1 WGM12 | #define CTC1 WGM12 | ||
Ligne 174 : | Ligne 98 : | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== MACROS ==== | |||
<syntaxhighlight lang="c"> | |||
#define SAVE_REGISTERS() \ | |||
asm volatile ( \ | |||
"push r0 \n\t" \ | |||
"in r0, __SREG__ \n\t" \ | |||
"push r0 \n\t" \ | |||
"push r1 \n\t" \ | |||
"push r2 \n\t" \ | |||
"push r3 \n\t" \ | |||
"push r4 \n\t" \ | |||
"push r5 \n\t" \ | |||
"push r6 \n\t" \ | |||
"push r7 \n\t" \ | |||
"push r8 \n\t" \ | |||
"push r9 \n\t" \ | |||
"push r10 \n\t" \ | |||
"push r11 \n\t" \ | |||
"push r12 \n\t" \ | |||
"push r13 \n\t" \ | |||
"push r14 \n\t" \ | |||
"push r15 \n\t" \ | |||
"push r16 \n\t" \ | |||
"push r17 \n\t" \ | |||
"push r18 \n\t" \ | |||
"push r19 \n\t" \ | |||
"push r20 \n\t" \ | |||
"push r21 \n\t" \ | |||
"push r22 \n\t" \ | |||
"push r23 \n\t" \ | |||
"push r24 \n\t" \ | |||
"push r25 \n\t" \ | |||
"push r26 \n\t" \ | |||
"push r27 \n\t" \ | |||
"push r28 \n\t" \ | |||
"push r29 \n\t" \ | |||
"push r30 \n\t" \ | |||
"push r31 \n\t" \ | |||
) | |||
#define RESTORE_REGISTERS() \ | |||
asm volatile ( \ | |||
"pop r31 \n\t" \ | |||
"pop r30 \n\t" \ | |||
"pop r29 \n\t" \ | |||
"pop r28 \n\t" \ | |||
"pop r27 \n\t" \ | |||
"pop r26 \n\t" \ | |||
"pop r25 \n\t" \ | |||
"pop r24 \n\t" \ | |||
"pop r23 \n\t" \ | |||
"pop r22 \n\t" \ | |||
"pop r21 \n\t" \ | |||
"pop r20 \n\t" \ | |||
"pop r19 \n\t" \ | |||
"pop r18 \n\t" \ | |||
"pop r17 \n\t" \ | |||
"pop r16 \n\t" \ | |||
"pop r15 \n\t" \ | |||
"pop r14 \n\t" \ | |||
"pop r13 \n\t" \ | |||
"pop r12 \n\t" \ | |||
"pop r11 \n\t" \ | |||
"pop r10 \n\t" \ | |||
"pop r9 \n\t" \ | |||
"pop r8 \n\t" \ | |||
"pop r7 \n\t" \ | |||
"pop r6 \n\t" \ | |||
"pop r5 \n\t" \ | |||
"pop r4 \n\t" \ | |||
"pop r3 \n\t" \ | |||
"pop r2 \n\t" \ | |||
"pop r1 \n\t" \ | |||
"pop r0 \n\t" \ | |||
"out __SREG__, r0 \n\t" \ | |||
"pop r0 \n\t" \ | |||
) | |||
</syntaxhighlight> | |||
==== TACHE LED 1 ==== | ==== TACHE LED 1 ==== | ||
<syntaxhighlight lang="c"> | <syntaxhighlight lang="c"> |
Version du 15 octobre 2024 à 13:26
Code Source et autre programmes
Ordonnanceur
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "ordonnanceur1.h"
#define CTC1 WGM12
#define PERIODE 20
#define NB_TASKS 2
int currentTask = 0;
Task TaskList[NB_TASKS]={
{task_led1, 0x600, 1},
{task_led2, 0x700, 1}
};
void init_minuteur(int diviseur,long periode)
{
TCCR1A=0; // Le mode choisi n'utilise pas ce registre
TCCR1B=(1<<CTC1); // Réinitialisation du minuteur sur expiration
switch(diviseur)
{
case 8: TCCR1B |= (1<<CS11); break;
case 64: TCCR1B |= (1<<CS11 | 11<<CS10); break;
case 256: TCCR1B |= (1<<CS12); break;
case 1024: TCCR1B |= (1<<CS12 | 1<<CS10); break;
}
// Un cycle prend 1/F_CPU secondes.
// Un pas de compteur prend diviseur/F_CPU secondes.
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas
// soit (periode*F_CPU)/(1000*diviseur)
OCR1A=F_CPU/1000*periode/diviseur; // Calcul du pas
TCNT1=0; // Compteur initialisé
TIMSK1=(1<<OCIE1A); // Comparaison du compteur avec OCR1A
}
void ordonnanceur()
{
currentTask = (currentTask + 1) % NB_TASKS;
}
ISR(TIMER1_COMPA_vect, ISR_NAKED)
{
SAVE_REGISTERS();
TaskList[currentTask].SPointer = SP;
ordonnanceur();
SP = TaskList[currentTask].SPointer;
RESTORE_REGISTERS();
asm volatile ("reti");
}
void init_task(int n)
{
int saveSP = SP;
SP = TaskList[n].SPointer;
int16_t address = (uint16_t)TaskList[n].fonction;
asm volatile ("push %0 \n\t" : : "r" (address & 0x00ff));
asm volatile ("push %0 \n\t" : : "r" ((address & 0xff00) >> 8));
SAVE_REGISTERS();
TaskList[n].SPointer = SP;
SP = saveSP;
}
void task_led1()
{
DDRC |= 0b00000001;
while(1)
{
_delay_ms(100);
PORTC ^= 0b00000001;
}
}
void task_led2()
{
DDRC |= 0b00001000;
while(1)
{
_delay_ms(173);
PORTC ^= 0b00001000;
}
}
int main(void)
{
init_minuteur(256,PERIODE);
for(int i=1;i<NB_TASKS;i++) init_task(i);
sei();
SP = TaskList[currentTask].SPointer;
TaskList[currentTask].fonction();
return 0;
}
MACROS
#define SAVE_REGISTERS() \
asm volatile ( \
"push r0 \n\t" \
"in r0, __SREG__ \n\t" \
"push r0 \n\t" \
"push r1 \n\t" \
"push r2 \n\t" \
"push r3 \n\t" \
"push r4 \n\t" \
"push r5 \n\t" \
"push r6 \n\t" \
"push r7 \n\t" \
"push r8 \n\t" \
"push r9 \n\t" \
"push r10 \n\t" \
"push r11 \n\t" \
"push r12 \n\t" \
"push r13 \n\t" \
"push r14 \n\t" \
"push r15 \n\t" \
"push r16 \n\t" \
"push r17 \n\t" \
"push r18 \n\t" \
"push r19 \n\t" \
"push r20 \n\t" \
"push r21 \n\t" \
"push r22 \n\t" \
"push r23 \n\t" \
"push r24 \n\t" \
"push r25 \n\t" \
"push r26 \n\t" \
"push r27 \n\t" \
"push r28 \n\t" \
"push r29 \n\t" \
"push r30 \n\t" \
"push r31 \n\t" \
)
#define RESTORE_REGISTERS() \
asm volatile ( \
"pop r31 \n\t" \
"pop r30 \n\t" \
"pop r29 \n\t" \
"pop r28 \n\t" \
"pop r27 \n\t" \
"pop r26 \n\t" \
"pop r25 \n\t" \
"pop r24 \n\t" \
"pop r23 \n\t" \
"pop r22 \n\t" \
"pop r21 \n\t" \
"pop r20 \n\t" \
"pop r19 \n\t" \
"pop r18 \n\t" \
"pop r17 \n\t" \
"pop r16 \n\t" \
"pop r15 \n\t" \
"pop r14 \n\t" \
"pop r13 \n\t" \
"pop r12 \n\t" \
"pop r11 \n\t" \
"pop r10 \n\t" \
"pop r9 \n\t" \
"pop r8 \n\t" \
"pop r7 \n\t" \
"pop r6 \n\t" \
"pop r5 \n\t" \
"pop r4 \n\t" \
"pop r3 \n\t" \
"pop r2 \n\t" \
"pop r1 \n\t" \
"pop r0 \n\t" \
"out __SREG__, r0 \n\t" \
"pop r0 \n\t" \
)
TACHE LED 1
void task_led1()
{
DDRC |= 0b00000001;
while(1)
{
_delay_ms(100);
PORTC ^= 0b00000001;
}
}
TACHE LED 2
void task_led2()
{
DDRC |= 0b00001000;
while(1)
{
_delay_ms(173);
PORTC ^= 0b00001000;
}
}
Makefile
export CC = avr-gcc
export MCU = atmega328p
export TARGET_ARCH = -mmcu=$(MCU)
export CFLAGS = -Wall -I. -DF_CPU=16000000 -Os #-g
export LDFLAGS = -g $(TARGET_ARCH) -lm -Wl,--gc-sections # -Os
TARGET = ordonnanceur1
#TERM = /dev/ttyUSB0
TERM = /dev/ttyACM0
CPPFLAGS = -mmcu=$(MCU)
PGMER = -c arduino -b 115200 -P $(TERM)
PGMERISP = -c arduino -b 115200 -P $(TERM)
ARVDUDECONF= -C /usr/local/arduino/arduino-0021/hardware/tools/avrdude.conf
export DUDE = /usr/bin/avrdude -F -v -p $(MCU) $(AVRDUDECONF)
C_SRC = $(wildcard *.c)
OBJS = $(C_SRC:.c=.o)
all: $(TARGET).hex
ass:$(C_SRC)
$(CC) -S $(CPPFLAGS) $(CFLAGS) $< -o $@
clean:
rm -f *.o
%.o:%.c
$(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@
$(TARGET).elf: $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS)
$(TARGET).hex: $(TARGET).elf
avr-objcopy -j .text -j .data -O ihex $(TARGET).elf $(TARGET).hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex $(TARGET).elf eeprom.hex
upload: $(TARGET).hex
stty -F $(TERM) hupcl # reset
$(DUDE) $(PGMER) -U flash:w:$(TARGET).hex
# $(DUDE) $(PGMERISP) -U flash:w:$(TARGET).hex
size: $(TARGET).elf
avr-size --format=avr --mcu=$(MCU) $(TARGET).elf
Schéma, PCB & KiCAD
Carte soudée
La carte-mère soudée mais pas encore programmée |
---|