Cours:SAM3X

De troyesGEII
Aller à : navigation, rechercher

IO

Patte comme sortie

Configuration

Chaque patte peut-être associée à 3 fonctions :

  • PIO (entrée ou sortie logique)
  • fonction (ou périphérique) A
  • fonction (ou périphérique) B

2 étapes sont nécessaires pour activer la sortie :

  • Mettre un 1 dans le registre PIOx_PER pour activer le module PIO
  • Mettre un 1 dans le registre PIOx_OER pour placer la patte en sortie


Affectation valeur

La modification de la valeur de sortie s'effectue par l'utilisation de 2 registres :

  • PIOx_SODR : mise à 1 de la sortie
  • PIOx_CODR : mise à 0 de la sortie


Exemple

Le code suivant permet de faire clignoter la led associée à la patte "13" arduino :

void setup() {
  //Configuration de la sortie PB27 => correspond à la led 13 arduino !
  REG_PIOB_PER|=1<<27;
  REG_PIOB_OER|=1<<27;
}

void loop() {
  REG_PIOB_SODR|=1<<27;     // mise à 1 de PB27
  delay(1000);              // wait for a second
  REG_PIOB_CODR|=1<<27;     // mise à 0 de PB27
  delay(1000);              // wait for a second
}

PWM

Le µcontrôleur se compose de 8 "voies" PWM.

Choix de l'horloge

Chaque voie PWM peut choisir parmis 2 horloges clkA et clkB dont le résultat provient de l'horloge du µcontrôleur suivit de 2 prédiviseurs.

cf datasheet p989

DIVA/DIVB Valeur de CLKA/CLKB
0 CLKA/CLKB arrêtée
1 CLKA/CLKB de fréquence donnée par CLKA/CLKB
2-255 CLKA/CLKB de fréquence donnée par CLKA/CLKB divisée par DIVA/DIVB


PREA,PREB
0000 MCK
0001 MCK/2
0010 MCK/4
0011 MCK/8
0100 MCK/16
0101 MCK/32
0110 MCK/64
0111 MCK/128
1000 MCK/256
1001 MCK/512
1010 MCK/1024
autres réservé

Le registre PWM_CLK permet de configurer ces valeurs de la façon suivante :


PWM_CLK 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Fonction - - - - PREB DIVB - - - - PREA DIVA


Exemple d'utilisation trouvé sur le net

unsigned short duty0 = 15000;
unsigned short duty1 = 30000;
unsigned short duty2 = 45000;
unsigned short duty3 = 60000;

void setup() {
  pwmc_setup();
}

void loop() {
  pwmc_duty(duty0, duty1, duty2, duty3);
}

void pwmc_setup()
{
  //Configure PWM channels 0,1,2,3 (PWML0,PWMH0,PWML1,PWMH1,PWML2,PWMH2,PWML3,PWMH3), (port C.2,C.3,C.4,C.5,C.6,C.7,C.8,C.9), (pins P34,P35,P36,P37,P38,P39,P40,P41)
  REG_PIOC_PDR = 0x3FC;  //B1111111100, PIO Disable Register
  REG_PIOC_ABSR = REG_PIOC_ABSR | 0x3FCu; //B1111111100, Peripheral AB Select Register
  REG_PMC_PCER1 = REG_PMC_PCER1 | 16; //Peripheral Clock Enable Register 1 (activate clock for PWM, id36, bit5 of PMC_PCSR1)
  REG_PWM_ENA = REG_PWM_SR | B1111; //PWM Enable Register | PWM Status Register (activate channels 0,1,2,3)

  REG_PWM_CMR0 = 0x10000; //Channe0 Mode Register: Dead Time Enable DTE=1
  REG_PWM_CMR1 = 0x10000; //Channe1 Mode Register: Dead Time Enable DTE=1
  REG_PWM_CMR2 = 0x10000; //Channe2 Mode Register: Dead Time Enable DTE=1
  REG_PWM_CMR3 = 0x10000; //Channe3 Mode Register: Dead Time Enable DTE=1

  REG_PWM_DT0 = 0xA800A8; //Channe0 Dead Time Register (168=2us for outputs PWML0,PWMH0)
  REG_PWM_DT1 = 0xA800A8; //Channe1 Dead Time Register (168=2us for outputs PWML1,PWMH1)
  REG_PWM_DT2 = 0xA800A8; //Channe2 Dead Time Register (168=2us for outputs PWML2,PWMH2)
  REG_PWM_DT3 = 0xA800A8; //Channe3 Dead Time Register (168=2us for outputs PWML3,PWMH3)

  REG_PWM_CPRD0 = 65535; //Channe0 Period Register (84mhz/65535=1.281khz=780.64us period)
  REG_PWM_CPRD1 = 65535; //Channe1 Period Register (84mhz/65535=1.281khz=780.64us period)
  REG_PWM_CPRD2 = 65535; //Channe2 Period Register (84mhz/65535=1.281khz=780.64us period)
  REG_PWM_CPRD3 = 65535; //Channe3 Period Register (84mhz/65535=1.281khz=780.64us period)
}

//Set the PWM duty-cycle
inline void pwmc_duty(unsigned short duty0, unsigned short duty1, unsigned short duty2, unsigned short duty3) {
  REG_PWM_CDTY0 = duty0;
  REG_PWM_CDTY1 = duty1;
  REG_PWM_CDTY2 = duty2;
  REG_PWM_CDTY3 = duty3;
}