MPH102 Mini Ponte H

Programmazione

Funzioni in C per PIC con PWM avanzato

Ecco delle funzioni per l’uso del ponteH con i pic 18F4x31 scritte da Fabio Drago.

Le funzioni si compongono di due file:

motors.c

/* *****************************************************************************
Libreria per l'utilizzo dei ponti H realizzati da Mauro Soligo
Autore: 	Fabio Drago
Versione:	1.0
Data:	09 Giugno 2006
Note:Pic:	18f4x31
H-Bridge:	RoboPonte (HIP4081A) o MiniPonteH (L298)
Controllo:	Locked Anti Phase
Frequenza:	9.8kHz, 19.5kHz, 39.0kHz
Risoluzione:	12bits, 11bit, 10bit
***************************************************************************** */
 
#include"motors.h"
 
/* *****************************************************************************
initMotors ( unsigned int period )
period : Valore per la generazione del periodo. Tab 17-2 pagina 193
Note:
sono state definiti degli alias per le frequenze di lavoro piu' comuni:
    PWM_PER_10k = 9.8kHzPWM_PER_20K = 19.6kHzPWM_PER_40k = 39.0kHz
***************************************************************************** */
 
void initMotors(unsigned int period){
// Mette in Output i pin
PORTB = PORTB & 0b11000000;
// Power Timer Control
PTCON0 = 0b11110000;
// 1:16 postscaler, 1:1 prescale, free running
PTCON1 = 0b10000000;
// PWM time base ON, count up
PTPERH = (unsigned char) (period >> 8);
PTPERL = (unsigned char) (period);
 
// PWM Control
PWMCON0 = 0b01000000;   // PWM1:PWM5 Abilitati
PWMCON1 = 0b11110000;   // 1:16 postscaler, updates abilitati, override asincrono
DTCON = 0x00;           // dead time 0ns
 
// Output Override
OVDCOND = 0b00111111;	  // L'output è controllato dal DutyCycle e TimeBase
OVDCONS = 0b00000000;	  // Tutti i pin sono INACTIVE quando in override
 
// Fault Configuration
FLTCONFIG = 0x00;       // Fault A e B disabilitatireturn ;}
 
/******************************************************************************
setMotors ( unsigned char motor, int dc )
motor : Motore da impostare. motor = 1 | 2 | 3
dc :  valore di dutycycle nel range  -2048 < dc < +2048
il dutycycle da impostare viene definito tramite la formula:
        dutycycle = zero + dc * (risoluzione / 4096*)4096
perchè il range di dc è +/- 2048
 
Note:- Si è deciso di utlizzare il range +/- 2048 per il dutycycle passato alla funzione
in modo da avere una risoluzione di 12 bit indipendentemente dalla risoluzione
effettiva legata alla frequenza di lavoro.
In questo modo si puo' cambiare la frequenza di lavoro dei motori senza dover
ritarare tutti i valori di duty cycle precedentemente calcolati.
 
-	il terzo motore ha i canali PWM invertiti quindi bisogna invertire la
        direzione di rotazione rispetto agli altri due.
******************************************************************************/
 
unsigned char setMotor(unsigned char motor, int dc)
{
    unsigned int period;
    int dutycycle;		// nel range 0 - period
    // Controlla se i parametri sono corretti
    if ((motor < 0 ) || (motor > 3)) return 1;
    if ((dc > 2048) || (dc < -2048)) return 2;
 
    // Inverte il senso di rotazione del terzo canale
    if (motor ==3) dc = -1*dc;
 
    // legge la frequenza di lavoro per calcolare la risoluzione
    period = ((unsigned int)(PTPERH) << 8) + PTPERL;
 
    // calcola il dutycycle da applicare in base alla precisione
    switch ((unsigned int) period)
    {
      case 0x3ff : dutycycle = 2048 +  dc;
      break;  		// 12 bit (4096)
 
      case 0x1ff : dutycycle = 1024 + (dc / 2);
      break;	// 11 bit (2048)
 
      case 0x0ff : dutycycle = 512  + (dc / 4);
      break;	// 10 bit (1024)
    }
 
    // Aggiorna i registri relativi al motore interessato
    switch (motor)
    {
      case 1 :  PDC0H = dutycycle >> 8;
                PDC0L = dutycycle;
                break;
 
      case 2 :  PDC1H = dutycycle >> 8;
                PDC1L = dutycycle;
                break;
 
      case 3 :  PDC2H = dutycycle >> 8;
                PDC2L = dutycycle;
                break;
    }
  return 0;
}

motors.h

/******************************************************************************
Libreria per l'utilizzo dei ponti H realizzati da Mauro Soligo
Autore: Fabio DragoVersione:	1.0
Data:     09 Giugno 2006
Note:
Pic:      18f4x31
H-Bridge:	RoboPonte (HIP4081A)
          MiniPonteH (L298)
 
Controllo:	Locked Anti Phase
Frequenza:	9.8kHz, 19.5kHz, 39.0kHz
Risoluzione:	12bits, 11bit, 10bit
******************************************************************************/
 
// Valori di PTPER per le frequenze di lavoro piu' comuni
#define	PWM_PER_10k		0x03ff
#define PWM_PER_20k		0x01ff
#define PWM_PER_40k		0b00ff
 
/******************************************************************************
Special File Register del PIC
Abbiamo deciso di ridefinire i registri del PIC per evitare di dover cambiare,
all'interno del motors.c, l'include del file relativo al pic (i.e. p18f4431.h)
******************************************************************************/
 
extern volatile near unsigned char       PORTB;
extern volatile near unsigned char       PTCON0;
extern volatile near unsigned char       PTCON1;
extern volatile near unsigned char       PWMCON0;
extern volatile near unsigned char       PWMCON1;
extern volatile near unsigned char       OVDCONS;
extern volatile near unsigned char       OVDCOND;
extern volatile near unsigned char       DTCON;
extern volatile near unsigned char       FLTCONFIG;
extern volatile near unsigned char       PTPERH;
extern volatile near unsigned char       PTPERL;
extern volatile near unsigned char       PDC2H;
extern volatile near unsigned char       PDC2L;
extern volatile near unsigned char       PDC1H;
extern volatile near unsigned char       PDC1L;
extern volatile near unsigned char       PDC0H;
extern volatile near unsigned char       PDC0L;
 
/******************************************************************************
Prototipi delle Funzioni
******************************************************************************/
 
void initMotors(unsigned int period);
unsigned char setMotor(unsigned char motor, int vel);

main.c

/******************************************************************************
Programma Demo per l'utilizzo della libreria "motors.h"
Autore: 	Fabio DragoVersione:	1.0
Data:	09 Giugno 2006
Scopo:Questo programma inizializza i PWM per tre motori controllati in LAP.
Imposta i dutycycle a 1/4, 1/2 e 3/4 e poi attende all'infinito in mododa
poterli verificare con un analizzatore di stati logici.
Note:
******************************************************************************/
#include
 
#include "motors.h"
 
#pragma config OSC  = HSPLL  // Oscillatore PLL 4x attivo
#pragma config WDTEN = OFF  // Whatch dog disattivato
#pragma config PWRTEN = ON  // Power UP timer abilitato
#pragma config LVP  = OFF  // Programmazione LVP disabilitata
#pragma config BOREN = OFF  // Brown out Reset disabilitato
#pragma config BORV  = 42  // Tensione per Brown out Reset 4.2 Volt
#pragma config PWM4MX 	= RB5		// RB5 = PWM4
 
void initRB(void);
 
void main(void)
{
  initRB();
  initMotors( PWM_PER_20k);
  setMotor(1, 1024);
  setMotor(2, 0);
  setMotor(3, -1024);
  while(1);
  return;
}
 
void initRB(void)
{
// PINs Direction
TRISA = 0b11111111;		// Ananlogs and Encoder
TRISB = 0b11000000;		// uscite PWM e ICSP
TRISC = 0b10111001;		// I2C, RS232, pwm
TRISD = 0x00;			    // display lcd
TRISE = 0xf0;			    // led
 
// PINs Initial State
PORTA = 0xff;
PORTB = 0x00;
PORTC = 0x00;
PORTD = 0x00;
PORTE = 0x00;
INTCON  = 0;     		// Clear Interrupt
return;
}

Trucchi e consigli

I diodi

I 12 diodi D1-D12 devono essere dei diodi veloci in grado di sopportare correnti di picco di 2A, io personalmente ho provato diodi come gli mbr160, sb140/160 ma in teoria qualunque diodo veloce da 1A continuo può andare bene.
I diodi consigliati sono diodi da 60V che mi permettono di usare il ponte con tensioni fino a 24V senza problemi. Per sfruttare il ponte per tensioni superiori usare diodi con tensione di lavoro almeno doppia rispetto a quella a cui si vuole usare il ponte.

Dimensionamento

Nello schema ci sono due componenti che vanno dimensionati in base alle specifiche esigenze di lavoro e sono le due resistenze di shunt.

A queste si aggiunge il dimensionamento del dissipatore a cui fissare l’L298 che senza non dissipa pi๠di 2W.

Resistenze di Shunt

Le resistenze di SHUNT vengono attraversate dalla stessa corrente che pilota il motore e servono per poterla misurare potendo leggere ai loro capi una tensione proporzionale grazie alla legge di Ohm

   V = I * R

Nel dimensionamento delle due resistenze bisogna però tenere presente due problematiche, una legata alla dissipazione in potenza e una legata all’ampiezza del segnale da misurare.

Per quanto riguarda la dissipazione in potenza la formula che la lega alla corrente e alla resistenza è

   W = I^2 * R

E’ evidente quindi che all’aumentare della resistenza e a parità di corrente, la potenza dissipata aumenta.

àˆ da tenere presente che questa potenza poi viene sottratta al motore infatti, considerando Vbat la tensione di alimentazione, Vmot quella del motore e Vs quella di shunt, la tensione che andrà realmente a pilotare il motore sarà

   Vmot=Vbat-Vs

ed essendo sia la corrente che attraversa il motore e la resistenza sia Vbat fisse all’aumentare di Vs Vmot scenderà e scenderà la potenza erogabile dal motore

   Pmot=Vmot*I

A questo punto è evidente quindi che tanto pi๠piccola è la resistenza di shunt meglio è… ma non è del tutto vero, infatti questa resistenza ci serve per misurare la corrente e quindi deve essere tale da poter leggere con sufficente precisione la corrente ai suoi capi.

Dissipatore

Ora come ora non so bene come calcolare le dimensioni di un dissipatore per questo ponte… qualche suggerimento?

p>

Pagine: 1 2 3

Tags:  , ,

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.