PWM Speed Control of DC Motor with PIC16F887

Control de velocidad pwm de un motor dc usando PIC16f887, PWM Speed Control of DC Motor with PIC16F887, calculo frecuencia pwm para motor dc

Objetives:

Use a pic16f887 to control in open loop speed an dc motor using a pwm signal controlled by a potentiometer.

Material:

  • Motor DC
  • LCD
  • Potenciometro
  • PIC16f887
  • ld293 ( Driver puente H )

Theory:



PWM Control 

It is a technique to modulate the power that is delivered to a motor by modulating the supply voltage. The voltage applied to the motor is a PWM signal, which is a periodic signal to which the pulse width is changed, the larger the pulse the greater the delivered power.



ADC module for Pic16f887

A pic of medium range like the pic16f887 incorporates a digital analog converter that can be configured of 8 or 10 bits.
folio 150946

Frecuencia de la señal PWM

La frecuencia de la señal PWM debe estar en un rango de 500 – 20K Hz, se recomienda una frecuencia alta para que la dinámica del motor la vea como si fuera una señal constante. Lo ideal es que se una frecuencia de 20k para que no produsca un ruido audible al ser humano.

Por ejemplo si queremos que nuestra señal PWM una frecuencia de 2kHz usando el oscilador interno del pic que es 8 M Hz se calcula con la siguiente formula

F_pwm  =  F_osc / [4 x PRE x (PR2+1)]

Donde:

 F_osc: Frecuencia del oscilación del PIC 

 PRE : Es el preescaler ( Un prescaler es un circuito que reduce la frecuencia que ingresa a un temporizador-contador dividiéndola para un determinado valor . Por ejemplo, si la relación es 1:8, el prescaler entrega una frecuencia igual a la octava parte de la frecuencia del oscilador)

PR2 es el valor de 8 bits del  registro TMR0

Si escogemos

F_osc = 8MHz

PRE = 4

F_PWM=4K Hz

Entonces el parámetro a despejar es PR2  

PR2 = ( F_osc / [4 x PRE x F_pwm ] )-1 =  ( 8 M Hz / 4 * 4 * 2k)-1 = 249

En este casa la función para configurar la frecuencia de la señal pwm es

setup_timer_2 (mode, period, postscale)

Mode puedes T2_DISABLED, T2_DIV_BY_1, T2_DIV_BY_4, T2_DIV_BY_16  ( es el preescaler)

Period is a int 0-255 that determines when the clock value is reset   ( es el PR2)

Postscale is a number 1-16 that determines how many timer overflows



PWM Module for pic

The pic has a module to generate a pwm signal which can be modulated the pulse width with a value of 8 bits

0 would be a zero pulse guess, a zero power
255 would be a complete pulse choke, the maximum power delivered

Functioning

The microcontroller reads the output voltage of the potentiometer using the ADC module converts it into a digital value, and depending on that value, the PIC generates a PWM signal with a given pulse width, this signal is connected to the ENABLE of a bridge driver H (LD293D) which in turn is connected to the DC motor.

Proteus Diagram

Dowloand PWM control DC motor

https://mega.nz/#!zpwnGIqY!RubugwkGmlAUkZNd0c3VeeC6x_Ni3SHW_-2X3_uz9tE





Code in pic16f887  

For compiler this code i use PIC C Compiler

#INCLUDE <16F887.H>
#DEVICE ADC=8 // resolucion del ADC de 8bits
#USE DELAY(CLOCK=8000000)
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOPUT //No Power Up Timer
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOCPD //No EE protection
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOWRT //Program memory not write protected
#FUSES BORV40 //Brownout reset at 4.0V
#include "lcd.c" // libreria para el control de LCD
 
void main(){
 
 
FLOAT pwmanalogica;
INT16 pwmdigital; //Variables para lectura de ADC y señal de Control a modulo CCP
 
lcd_init(); // Turn LCD ON, along with other initialization commands
 
lcd_gotoxy(1,1);
lcd_putc("PWM:");
 
// periodo reloj = 1/f ; periodo de ciclo maquina = 4/f ; preescaler 2,4, 8, 16 4/f / prescaler;
 
// F_pwm = F_osc / [4 x PRE x (PR2+1)]
 
 
setup_timer_2(t2_div_by_4,249,1);
setup_ccp1(ccp_pwm); //Configurar modulo CCP1 en modo PWM
 
 
setup_adc(adc_clock_internal); //Configurar ADC
setup_adc_ports(sAN0|VSS_VDD); // AN0 como entrada analogica
 
while(true){
 
 
set_adc_channel(0); //Seleccionar Canal 0 
delay_ms(1);
 
pwmdigital=read_adc(); //Leer ADC 
delay_ms(1);
 
 
 
pwmanalogica=pwmdigital;
 
 
lcd_gotoxy(5,1); // point LCD cursor to col5 row1
 
 
printf(lcd_putc,"%2.1f",pwmanalogica);
 
 
set_pwm1_duty(pwmanalogica); //
}
}

Download source code and machine file  .hex

https://mega.nz/#!zpwnGIqY!RubugwkGmlAUkZNd0c3VeeC6x_Ni3SHW_-2X3_uz9tE

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *