Bonsoir,
et merci pour la réponse !
J'avoue que non, tout n'est pas bien clair mais ça tient à moi. Je n'ai par exemple pas idée de ce qu'est un SPI hardware, pas plus que lent ou rapide)
Mais... on est tout de même assez bien synchronisés puisque pour cadencer le SPI des 74HC j'ai utilisé un timer (le 2), avec un réglage de la fréquence PWM par bascule du registre TCNT2
(mais pas en mode CTC... erreur ?
Je joins le code. Que j'ai pu greffer dans mon code principal sans occasionner le moindre souci ni ralentissement. Et avec un cahier des charges respecté :
- 40 PWM possiblement générées
- 125 pas de réglage (avec un talon à 53, valeur empirique personnelle, ce qui donne une plage de réglage effective entre 53 et 178 et par conséquent un pas de réglage plus fin)
Ainsi régulée, la fréquence "shiftPWM" est totalement indépendante du nombre de 74HC pilotés, du moins dans la limite du "cahier des charges" et dans la plage 30Hz-100Hz (et peut-être au delà ?)
Voici le code. Les variables consigne PWM sont fixes et auraient aussi bien pu être déclarées comme constantes... dans la réalité, c'est bien sûr au code de les déterminer en temps réel.
/* ARDUINO MEGA */
const int SS_PIN = 25; // SS(slaveSelect)/slave - pin 14 (DS / Serial Data Input) on the 74hc595
const int MOSI_PIN = 26; // MOSI (Master Out Slave Inv- The Master line for sending data to the peripherals) - pin 12 (ST_CP / Storage Register Clock Input (latch)) on the 74hc595
const int MISO_PIN = 29; // MISO (Master In Slave Out - The Slave line for sending data to the master) - pin 11 (SH_CP / shift register clock input) on the 74hc595
const int8_t number_of_74hc595 = 1;
const int8_t numOfRegisterPins = number_of_74hc595 * 8;
boolean pin74hc[numOfRegisterPins] = { 0 }; // data-table, matching with the state of the 74HC595 ouputs
// pseudos PWM à simuler - pour chaque PWM, le tableau donne le cran entre 20 et 120
uint8_t PWM[40] = { 54, 64, 105, 94, 70, 34, 73, 0, 54, 64, 105, 94, 109, 34, 73, 0, 54, 64, 105, 94, 109, 34, 73, 0, 54, 64, 105, 94, 109, 34, 73, 0, 54, 64, 105, 94, 109, 34, 73, 0 };
byte tcnt = 192; // le timer commute tous les (256-tcnt) cycles
/*
avec PRESCALER à 32 (TCCR2B = 0b00000011)
tcnt=126 => 30Hz (les valeurs de tcnt sont empiriques faute de linéarité dans les valeurs de fréquence obtenues)
tcnt=160 => 40Hz
tcnt=180 => 50Hz
tcnt=192 => 60Hz
tcnt=208 => 80Hz
tcnt=218 => 100Hz
*/
byte cran = 0;
void setup() {
Serial.begin(115200);
pinMode(SS_PIN, OUTPUT);
pinMode(MOSI_PIN, OUTPUT);
pinMode(MISO_PIN, OUTPUT);
bitClear (TCCR2A, WGM20); // WGM20 = 0
bitClear (TCCR2A, WGM21); // WGM21 = 0
TCCR2B = 0b00000011;
TIMSK2 = 0b00000001; // Interruption locale autorisée par TOIE2
}
void writeRegisters() {
PORTA &= ~_BV(PA4); // pin 26
for (int8_t i((number_of_74hc595)*8-1) ; i>=0 ; i--) {
PORTA &= ~_BV(PA7); // pin 29
if (pin74hc[i]==0) /*=>*/ PORTA &= ~_BV(PA3); // pin 25
else /*=>*/ PORTA |= _BV(PA3);
PORTA |= _BV(PA7); // pin 29
}
PORTA |= _BV(PA4);
}
void setRegisterPins(byte cran) { //Place les pins du 74HC595 à l'état HAUT ou BAS
for(uint8_t engine(0) ; engine<numOfRegisterPins ; engine++) {
pin74hc[engine] = cran<PWM[engine];
}
writeRegisters();
}
ISR(TIMER2_OVF_vect) {
TCNT2 = tcnt ;
cran++;
setRegisterPins(cran);
if (cran==178) cran=53;
}
void loop() {
/* CODE PRINCIPAL ICI */
}
Le SPI dédié aux 74HC est maintenant sur les broches 26-29 du MEGA... parce que j'utilisais déjà les 50-52 pour le bus CAN et parce que je n'y ai vu aucune différence.
Mais voilà bien une zone d'ombre pour moi qui a résistée à mes questions à Google. Si quelqu'un peut m'indiquer le début de la piste, ça sera apprécié !
(Le Teensy à venir : un 3.5)