CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

PWM

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
O_R_E
Guest







PWM
PostPosted: Thu Jun 29, 2006 2:14 pm     Reply with quote

Hello very good, I am making a regulator PID, and with himself not to generate duty cicle by sideburn CCP1 of the PIC16F877. If I use it in a smaller program if than it loads duty, but in the main program no. That I am making bad? Gracias

Important this in negrita . This is the code:

#include "C:\15 - Program Files C\control_PID.h"
#include <max187.c> // Subrutina de tratamiento conversor A/D MAX187.
#include <hd44780u.c> // Subrutina de tratamiento display 16x2 HD44780U.
#include <max4534.c> // Subrutina de tratamiento multiplexor MAX4534.

#use fast_io (A) // Directiva para el manejo normal de puertos.
#use standard_io (B)
#use fast_io (C)
#use fast_io (D)
#use fast_io (E)
#byte port_a=0X05 // Declarando la direccion de los puertos.
#byte port_b=0X06
#byte port_c=0X07
#byte port_d=0X08
#byte port_e=0X09

byte const NInts=11; // Numero de interrupciones Timer 0 para 300 ms

byte const Ts=10; // Numero de interrupciones Timer 1 para 100 ms

////////////////////////////////////////////////////////////////////////////////
//Variables globales.
////////////////////////////////////////////////////////////////////////////////

char C_Ints=0; // Contador de Interrupciones ocurridas Timer 0

char cont_Ts=0; // Contador de Interrupciones ocurridas Timer 1

int i=0, opcion=0, unidad=0;

int periodo=255;

int duty_pwm2=0;

// Variables en punto flotante de 32 bits.

float j=0.00, k=10, Ti=0.1, Td=0.1, set_point=50, process_value, ki, kd;

float BP_min, BP_max;

float Vinmin=0, Vinmax=1500, Min=0, Max=150;

float error=0, serror=0, errant=0, value=0;

float masa, vref, temperatura;

float salida_PID;

////////////////////////////////////////////////////////////////////////////////
//Funcion visualización datos por LCD HD44780U
////////////////////////////////////////////////////////////////////////////////

visualizar(){
lcd_putc("\f");
//Primera Línea display
lcd_gotoxy(1,1);
printf(lcd_putc,"%i",duty_pwm2);
lcd_gotoxy(1,2);
printf(lcd_putc,"%01.1f",salida_PID);
lcd_gotoxy(10,1);
printf(lcd_putc,"%01.1f",set_point);
lcd_gotoxy(14,1);
if ( unidad==0 ) lcd_putc("'C");
else if ( unidad==1 ) lcd_putc("pH");
else if ( unidad==2 ) lcd_putc("'K");
else if ( unidad==3 ) lcd_putc("l");
else if ( unidad==4 ) lcd_putc("km");

//Segunda Línea display
lcd_gotoxy(10,2);
printf(lcd_putc,"%01.1f",process_value);
lcd_gotoxy(14,2);
if ( unidad==0 ) lcd_putc("'C");
else if ( unidad==1 ) lcd_putc("pH");
else if ( unidad==2 ) lcd_putc("'K");
else if ( unidad==3 ) lcd_putc("l");
else if ( unidad==4 ) lcd_putc("km");
}

////////////////////////////////////////////////////////////////////////////////
//Interrupcion Timer 0 cada 300 mS
////////////////////////////////////////////////////////////////////////////////

#int_RTCC // Interrupción por desbordamiento del TIMER0 RTCC
RTCC_isr(){
if(C_Ints > NInts){ // Si las ints ocurridas > ints para 0.3 seg.
visualizar(); // Llamada a visualización
output_high(PIN_B7); // Se activa el rele
delay_ms(50);
output_low(PIN_B7);
C_Ints=0; // Reinicializo Contador de Ints
}
// Incremento el número de interrupciones ocurridas
++C_Ints;
}

////////////////////////////////////////////////////////////////////////////////
//Interrupcion Timer 1 cada 100 mS
////////////////////////////////////////////////////////////////////////////////

#int_TIMER1
// Indica que la siguiente funcion es de atencion a interrupcion del timer1.
Timer1()
{
set_timer1(~34286); // Carga TMR1 con 34286
cont_Ts++;
// Cuando contador valga Ts, se ejecutara el control del duty cicle
if(cont_Ts>=Ts){
cont_Ts=0;
output_high(PIN_B5); // Se activa el rele
delay_ms(10);
output_low(PIN_B5);
delay_ms(10);
}
}

////////////////////////////////////////////////////////////////////////////////
//Funcion de inicializacion.
////////////////////////////////////////////////////////////////////////////////

inicializar(){
port_b_pullups(FALSE);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
// Inicializando la operacion analogica de los puertos
set_tris_a(0x00); // Puerto A como salida.
port_a=0; // Valor inicial del puerto.
set_tris_b(0x0F); // Puerto B como entrada/salida.
port_b=0; // Valor inicial del puerto.
set_tris_c(0x10); // RC7/Rx entrada, RC6/Tx salida
port_c=0; // Valor inicial del puerto.
set_tris_d(0xFF); // RD0...RD7 salidas display.
port_d=0; // Valor inicial del puerto.
set_tris_e(0x00); // RE0...RE2 entradas display.
port_e=0;
// Inicializando timers y habilitando interrupciones
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32);
// Inicializando el timer0 como reloj interno
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
// Inicializando el timer1 como reloj interno
enable_interrupts(INT_RTCC);
// Habilito Interrupción RTCC
enable_interrupts(INT_TIMER1);
// Habilito Interrupción TIMER 1
enable_interrupts(global);
// Habilito Interrupciones Globales
lcd_init();
// Comandos de inicialización del LCD.
lcd_putc("\f");
// Borramos pantalla.
init_ext_mux();
// Inicializamos MAX434
init_ext_adc();
// Inicializamos MAX187
}
// Fin inicializar.

////////////////////////////////////////////////////////////////////////////////
//Funcion de adquisicion de datos.
////////////////////////////////////////////////////////////////////////////////

#SEPARATE adquisicion_datos(){
// Selección del canal del mux MAX4534
select_channel (opcion);
i=0;
value=0;
for(i=0;i<=10;++i) value+=read_ext_adc();
value=value/10;
}

////////////////////////////////////////////////////////////////////////////////
//Funcion Alarma por rele.
////////////////////////////////////////////////////////////////////////////////

#SEPARATE alarma_rele(){
BP_min=set_point-((set_point*k)/100); // Variable minima Band Gap
BP_max=set_point+((set_point*k)/100); // Variable máxima Band Gap
if(process_value>=BP_max || process_value<=BP_min){
output_high(PIN_B6); // Se activa el rele
delay_ms(50);
output_low(PIN_B6);
delay_ms(50);
}
else output_low(PIN_B6); // Se desactiva el rele
}

////////////////////////////////////////////////////////////////////////////////
//Funcion del controlador PID
////////////////////////////////////////////////////////////////////////////////

Control_PID(){
// Cargamos en modulo PWM el valor absoluto de la señal de control obtenida.
if (process_value<BP_max && process_value>BP_min){
// Si esta dentro de la banda proporcional actuo en función PID
errant=error;
// Guardamos error de iteracion anterior, usado en parte D.
error = set_point - process_value;
// Calculo del error actual=set_point-process_value=unidad_fisica.
serror+=error;
// Error acumulativo.
ki = (k*periodo)/Ti;
// Calculo ganancia intregal
kd = (k*Td)/periodo;
// Calculo Ganancia derivativa
salida_PID=k*error+Ti*serror+Td*(error-errant);
// Señal de control, duty cycle para PWM
duty_pwm2 = (int) salida_PID;
//Cambiando de tipo de dato float a 8 bits sin signo.
setup_ccp2(CCP_PWM);
// Inicializando el modo PWM del modulo CCP2.
setup_timer_2(T2_DIV_BY_16, periodo,1);
set_pwm2_duty(duty_pwm2);
output_high(PIN_B4); // Se activa el rele
delay_ms(10);
output_low(PIN_B4);
delay_ms(10);
}
if (process_value>BP_max)
{
setup_ccp2(CCP_PWM);
// Inicializando el modo PWM del modulo CCP2.
setup_timer_2(T2_DIV_BY_16, periodo,1);
set_pwm2_duty(0);
}
if (process_value<BP_min)
{
setup_ccp2(CCP_PWM);
// Inicializando el modo PWM del modulo CCP2.
setup_timer_2(T2_DIV_BY_16, periodo,1);
set_pwm2_duty(254);
}


} // Fin control PID.

////////////////////////////////////////////////////////////////////////////////
//Programa principal.
////////////////////////////////////////////////////////////////////////////////

void main(void){
// Inicio programa principal.
inicializar(); // Llamada a funcion inicializar.
while (TRUE){ // Inicio ciclo continuo.
opcion=0;
adquisicion_datos(); // Llamada a adquisicion de datos.
masa = value; // Adquisición señal de masa (0 V).
opcion++; // Incrementamos opcion.
adquisicion_datos(); // Llamada a adquisicion de datos.
vref = value;
// Adquisición señal de referencia (1,032 V).
opcion++; // Incrementamos opcion.
adquisicion_datos(); // Llamada a adquisicion de datos.
temperatura = value;
// Adquisición señal sensor temperatura LM35.
opcion++; // Incrementamos opcion.
adquisicion_datos();
// Llamada a funcion de adquisicion de datos.
process_value = (value/2);
// Adquisición señal de entrada INA114.
process_value=(1032/vref)*process_value+masa;
process_value = (Max/Vinmax)*(process_value);
// Conversion process_value a unidad_fisica.
alarma_rele(); // Llamada a funcion alarma.
Control_PID(); // Llamada al controlador PID.
} // Fin while.
} // Fin main.

O_R_E
Guest







PWM
PostPosted: Fri Jun 30, 2006 1:44 pm     Reply with quote

Hello,

The problem is this:

#use fast_io (C);

I have change for this:

#use standard_io (C);

And the program rule perfect

Bye
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group