Cours:SAM3X : Différence entre versions
(Page créée avec « ={{Rouge|PWM}}= Le µcontrôleur se compose de 8 "voies" PWM. =={{Bleu|Choix de l'horloge}}== Chaque voie PWM peut choisir parmis 2 horloges clkA et clkB dont le résul... ») |
m |
||
| (3 révisions intermédiaires par le même utilisateur non affichées) | |||
| Ligne 1 : | Ligne 1 : | ||
| + | |||
| + | ={{Rouge|IO}}= | ||
| + | |||
| + | =={{Bleu|Patte comme sortie}}== | ||
| + | |||
| + | ==={{Vert|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 | ||
| + | |||
| + | |||
| + | |||
| + | ==={{Vert|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 | ||
| + | |||
| + | |||
| + | |||
| + | ==={{Vert|Exemple}}=== | ||
| + | |||
| + | Le code suivant permet de faire clignoter la led associée à la patte "13" arduino : | ||
| + | |||
| + | <source lang=c> | ||
| + | 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 | ||
| + | } | ||
| + | </source> | ||
={{Rouge|PWM}}= | ={{Rouge|PWM}}= | ||
| Ligne 68 : | Ligne 112 : | ||
|} | |} | ||
| + | |||
| + | |||
| + | |||
| + | =={{Bleu|Exemple d'utilisation trouvé sur le net}}== | ||
| + | |||
| + | <source lang=c> | ||
| + | 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; | ||
| + | } | ||
| + | </source> | ||
Version actuelle datée du 24 février 2015 à 19:44
Sommaire
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;
}