« SE4Binome2024-7 » : différence entre les versions

De projets-se.plil.fr
Aller à la navigation Aller à la recherche
Ligne 5 : Ligne 5 :


#include <avr/io.h>
#include <avr/io.h>
 
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/interrupt.h>
#include "ordonnanceur1.h"


#define CTC1            WGM12           // Meilleur nom pour le bit
#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" \
)


#define PERIODE         1000
#define CTC1            WGM12
#define PERIODE         20
#define NB_TASKS 2
int currentTask = 0;


void init_minuteur(int diviseur,long periode){
Task TaskList[NB_TASKS]={
  {task_led1, 0x600, 1},
  {task_led2, 0x700, 1}
};


TCCR1A=0;               // Le mode choisi n'utilise pas ce registre
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
}


TCCR1B=(1<<CTC1);       // Réinitialisation du minuteur sur expiration
void ordonnanceur()
{
  currentTask = (currentTask + 1) % NB_TASKS;
}


switch(diviseur){
ISR(TIMER1_COMPA_vect, ISR_NAKED)
{
  SAVE_REGISTERS();
  TaskList[currentTask].SPointer = SP;
  ordonnanceur();
  SP = TaskList[currentTask].SPointer;
  RESTORE_REGISTERS();
  asm volatile ("reti");
}


  case    8: TCCR1B |= (1<<CS11); break;
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;
}


  case   64: TCCR1B |= (1<<CS11 | 11<<CS10); break;
void task_led1()
 
{
  case  256: TCCR1B |= (1<<CS12); break;
    DDRC |= 0b00000001;
 
    while(1)
  case 1024: TCCR1B |= (1<<CS12 | 1<<CS10); break;
    {
 
      _delay_ms(100);
  }
      PORTC ^= 0b00000001;
 
    }
OCR1A=F_CPU/1000*periode/diviseur;
}
 
TCNT1=0;
 
TIMSK1=(1<<OCIE1A);


void task_led2()
{
    DDRC |= 0b00001000;
    while(1)
    {
      _delay_ms(173);
      PORTC ^= 0b00001000;
    }
}
}


ISR(TIMER1_COMPA_vect){
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;
}
}


int main(void){
DDRC &= 0b000000001;              // Chenillard sur 4 LED
PORTB ^= ~0b00000001;            // LED éteintes
init_minuteur(256,PERIODE);
sei();
while(1);
}
</syntaxhighlight>
</syntaxhighlight>



Version du 15 octobre 2024 à 13:17

Code Source et autre programmes

Ordonnanceur

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "ordonnanceur1.h"

#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" \
)

#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;
}

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

Shield soudé

Carte mère soudée

Carte Fille réseau RNDIS soudée

Ressources & Sources

Lien Git : https://gitea.plil.fr/rboursau/S8-Pico