Pour le schéma avec microcontrôleur, cela donnera un truc de ce style :
Il faut ajouter les transistors de pilotage du moteur (schéma Elektor par exemple, driver du schéma de Jeanpolanton, circuit spécialisé…).
L’alimentation peut être en 3V3 ou 5V (je dois vérifier selon les processeurs), un régulateur fera une bonne régulation simple. Tout oscillateur peut être utilisé, il suffit de changer le paramètre dans le soft.
Pour le câblage, vu la simplicité, le schéma se suffit à lui-même.
Je vérifie la compilation du code et je ferai des relevés demain pour montrer que cela fonctionne.
Voici le code. A deux détails près, c’est le programme que j’avais diffusé il y a 10 ans. Pas eu le temps de retester, et je n’ai que des PIC en boîtier cms, mais je ferai une adaptation en DIP pour faire les relevés à l’oscilloscope, et vérifier qu’il n’y a aucune erreur.
/********************************************************************************************************
*
- Programme de generation d’une frequence basse a partir d’un oscillateur
- FileName: Horloge.c
- Dependencies:
- Processor: PIC12F1840
- Compiler:
- Company:
- Author Date Comment
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- HD 30/11/2024
********************************************************************************************************/
#define _PICC
#include <xc.h>
/********************************************************************************************************
*
********************************************************************************************************/
// Bits de configuration
// LVP_OFF indispensable pour utiliser l’entrée 3 !!!
// Watchdog off, broche mclr libre, oscillateur externe 4 a 32 MHz
// CONFIG1
#pragma config FOSC = ECH // Oscillator Selection
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = OFF // MCLR Pin Function
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
//#pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
//#pragma config IESO = ON // Internal/External Switchover (Internal/External Switchover mode is enabled)
//#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF // PLL
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = OFF
/********************************************************************************************************
*
********************************************************************************************************/
#define FREQ_OSC (10000000) // 10MHz, prendre de preference cette frequence
//#define FREQ_OSC (8000000) // 8MHz
#define POSTSCALER ( 10 )
#define POST_REG ( POSTSCALER - 1 )
#define FREQ_IT ( 1000 ) // Pour avoir une interruption a 1kHz (1000ms)
#define FREQ_TIMER ( FREQ_OSC / 4 / POSTSCALER ) // 4 pour prescaler ou frequence entree timer
#define DIV_TIMER ( FREQ_TIMER / FREQ_IT )
#define LOAD_TIMER ( DIV_TIMER - 1 )
#define PULSE_WIDTH ( 300 ) // Largeur pulse de sortie, en ms
#define PER_PULSE ( 30000 ) // Periode pulse moteur en ms
#define NB_IT_PULSE ( PER_PULSE * ( FREQ_IT / 1000 ) )
#define PER_PULSE_REG ( 1000 )
#define NB_IT_PULSE_REG ( PER_PULSE_REG * ( FREQ_IT / 1000 ) )
#define LF FREQ_IT
#if ( NB_IT_PULSE <= PULSE_WIDTH )
#error "Pulse trop long"
#endif
#if ( LOAD_TIMER > 255 )
#error "Programmation timer impossible"
#endif
// Horloge sur RA5
// // Sorties commande
#define OUT_S1_TRIS TRISAbits.TRISA2
#define OUT_S1 LATA2
#define OUT_S2_TRIS TRISAbits.TRISA4
#define OUT_S2 LATA4
#define BOUTON RA3
/********************************************************************************************************
*
********************************************************************************************************/
void timer_init(void);
/********************************************************************************************************
*
********************************************************************************************************/
void main (void)
{
// Configuration des io, voir doc
ANSELA = 0; // IO en numérique
OPTION_REG = 0;
WPUAbits.WPUA3 = 1; // Pullup sur entree bouton
OUT_S1_TRIS = 0;
OUT_S2_TRIS = 0;
OUT_S1 = 0;
OUT_S2 = 0;
timer_init(); // initialisation timer !
while ( 1 ); // Rien a faire hors interruption !!!
}
/********************************************************************************************************
*
********************************************************************************************************/
void __interrupt() exec_int(void)
{
static unsigned short cptIt;
static unsigned char toggle = 0;
static unsigned short lf = 0;
// Seule l'it timer etant programmee, on peut se passer de la verification de l'origine
if ( BOUTON == 0 ) // Pour faciliter le test de derive en autorisant une synchronisation en debut de test sur le pps par exemple
{
cptIt = 0;
OUT_S1 = 0;
OUT_S2 = 0;
lf = 0;
}
cptIt++;
if ( cptIt >= NB_IT_PULSE || ( !BOUTON && cptIt >= NB_IT_PULSE_REG ) )
{
cptIt = 0;
if ( toggle )
{
OUT_S1 = 1;
toggle = 0;
}
else
{
OUT_S2 = 1;
toggle = 1;
}
}
else if ( cptIt >= PULSE_WIDTH )
{
OUT_S1 = 0;
OUT_S2 = 0;
}
PIR1bits.TMR2IF = 0; // Efface l'interruption
}
/********************************************************************************************************
*
********************************************************************************************************/
void timer_init(void)
{
T2CONbits.T2CKPS = 0; // prescaler = 1 ( 0 a 3 pour 1, 4, 16, 64) car horloge timer = fosc /4 ( mettre 1 si pllen)
T2CONbits.T2OUTPS = POST_REG; // postscaler
PR2 = LOAD_TIMER;
PIR1bits.TMR2IF = 0; // Efface l'interruption
T2CONbits.TMR2ON = 1; // Start timer
PIE1bits.TMR2IE = 1; // Autorisation interruption timer2 dans le groupe peripheriques
INTCONbits.PEIE = 1; // Autorisation des interruptions peripheriques
INTCONbits.GIE = 1; // Autorisation des interruptions
}