|
|
View previous topic :: View next topic |
Author |
Message |
gianhenrique
Joined: 20 Dec 2010 Posts: 8
|
update period of the POWER PWM in PIC18F4431 |
Posted: Mon Dec 20, 2010 4:28 pm |
|
|
hey guys
I'm from Brazil and I'm desperate because I can not update the values of the period (PTPER) quickly, this function requires a time of 10ms, which impairs my motor ..
how I set this function correctly PWM POWER, and how do I update the value of frequency (period) without delay by one?
please help me!
tnk's |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
gianhenrique
Joined: 20 Dec 2010 Posts: 8
|
|
Posted: Mon Dec 20, 2010 5:11 pm |
|
|
Code: |
void front_d()
{
enable_interrupts(int_pwmtb);
do{
setup_power_pwm(PWM_CLOCK_DIV_16 | PWM_FREE_RUN | PWM_DEAD_CLOCK_DIV_4, 1, 0, freq, 0, 0, 0);
output_high(pin_b0);
set_power_pwm0_duty(PWM_UPDATE_ENABLE|duty);
set_power_pwm2_duty(PWM_UPDATE_disable);
delay_ms(10); //the problem is that delay
}while(input_d()==0b00000100);
do{
setup_power_pwm(PWM_CLOCK_DIV_16 | PWM_FREE_RUN | PWM_DEAD_CLOCK_DIV_4, 1, 0, freq, 0, 0, 0);
output_high(pin_b0);
set_power_pwm0_duty(PWM_UPDATE_ENABLE|duty);
set_power_pwm2_duty(PWM_UPDATE_disable);
delay_ms(10); // and that
}while(freq<4095);
|
the treatment interruption is below ... noting that the code is not all here... Code: |
#INT_PWMTB
void trata_pwm()
{
if(prog==1){
if(pulso1==255){
pulso2++;
pulso1=0;
}
else pulso1++;
if(ace==1){
if((freq==4095) | (freq>2047)){
freq=freq-4;
duty=duty-8;
}
if((freq==2047) | (freq>1023)){
freq=freq-2;
duty=duty-4;
}
if((freq==1023)|(freq>800)){
freq=freq-1;
duty=duty-2;
}
if((freq==800)|(freq>750)){
if(exp4==4){
exp4=0;
freq=freq-1;
duty=duty-2;
}
if(exp4<4)exp4=exp4+1;
}
if((freq==750)|(freq>700)){
if(exp8==8){
exp8=0;
freq=freq-1;
duty=duty-2;
}
if(exp8<8)exp8=exp8+1;
}
if((freq==700)|(freq>620)){
if(exp16==8){
exp16=0;
freq=freq-1;
duty=duty-2;
}
if(exp16<16)exp16=exp16+1;
}
if((freq==620)){
freq=620;
duty=1240;
}
}
if(des==1){
if((freq==650)|(freq<2698)){
freq=freq+1;
duty=duty+2;
}
if((freq==2698)|(freq<3722)){
freq=freq+2;
duty=duty+4;
}
if((freq==3722)|(freq<3946)){
freq=freq+1;
duty=duty+2;
}
if((freq==3946)|(freq<3996)){
freq=freq+1;
duty=duty+2;
}
if((freq==3996)|(freq<4046)){
freq=freq+1;
duty=duty+2;
}
if((freq==4046)|(freq<4095)){
freq=freq+1;
duty=duty+2;
}
}
} |
which always changes how can you realize, is that the variable FREQ is
time ...
I'm developing is an acceleration to a robot that needs
acceleration so as not to slip and therefore not lose the precision!
tnks |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Dec 21, 2010 1:06 pm |
|
|
You didn't give me a short test program that I can run on my PicDem2-
Plus board. If you do that, and post your compiler version, then I can
look at the problem in hardware.
Again, here is an example of a complete (but short) test program:
http://www.ccsinfo.com/forum/viewtopic.php?t=37206&start=2 |
|
|
gianhenrique
Joined: 20 Dec 2010 Posts: 8
|
|
Posted: Tue Dec 21, 2010 1:34 pm |
|
|
eu vou postar o codigo inteiro entao, para que vc possa dar uma olhada...
o fato é que eu só queria arranjar uma forma de atualizar a frequencia sem ter que configurar a função do Power_PWM denovo...
mas, muito obrigado pela ajuda que vc esta me dando PCM
PS: the comments are in Brazilian Portuguese excuse the flaws in English also
Abaixo se encontra o codigo:
Code: |
#include <18f4431.h>
#use delay(clock=20000000)
#fuses NOLVP, HS, NOWDT, NOPROTECT, PUT, BROWNOUT,BORV27,NOMCLR, NOFCMEN
//PAGINA 67 DO DATASHEET ENDEREÇO DOS REGISTRADORES
#BYTE pwmcon0=0XF6F //Registrador de PWMCON0, define quais os pinos de pwm irao operar
#priority PWMTB
/******************************************************************************/
/**************** VARIÁVEIS DE CONTROLE ***********************************/
/******************************************************************************/
int1 ace=0; //FLAG QUE SINALIZA ACELERAÇÃO NA FUNÇÃO DE MOVIMENTOS
int1 des=0; //FLAG QUE SINALIZA DESACELERAÇÃO NA FUNÇÃO DE MOVIMENTOS
int1 prot=0; //FLAG QUE IMPEDE DE GRAVAR NO PROTOCOLO OUTRO MOVIMENTO SEM ENCERRAR O QUE FOI FEITO ANTES
int1 REC=0; //QUANDO REC FOR ZERO, ELE FARA COM QUE SOMENTE SOME OU SUBTRAIA O MOVIMENTO, IMPEDINDO DE FAZER MOVIMENTOS SEM DECIDIR O QUE IRÁ FAZER
int1 play=0; //FLAG QUE FAZ O RUN TER INICIO, SE ESSE FLAG FOR ZERO, NAO EXECUTARÁ NADA
int1 prog; //FLAG PRA SABER SE É MODO DE PROGRAMAÇÃO DO CHIP
int1 run; //FLAG PRA SABER SE É MODO DE EXECUÇÃO DO CHIP
int8 exp4=0; //VARIÁVEL RESPONSÁVEL PELA ACELERAÇÃO, POR EXEMPLO, QUANDO ESSA VARIAVEL FOR 4, DECREMENTARA 1 EM FREQ, FAZENDO-O ACELERAR
int8 exp8=0; //MESMA FUNÇÃO DE EXP4 MAS, CONTA ATÉ 8 PULSOS
int8 exp16=0; //MESMA FUNÇÃO de EXP4 E EXP8, MAS CONTA ATÉ 16
int8 pulso1=0; //VARIÁVEL DE 8 BITS PARA CONTAR PULSOS DO PWM (PARTE BAIXA LSB)
int8 pulso2=0; //VARIAVEL DE 8 BITS PARA CONTAR PULSOS DO PWM (PARTE ALTA MSB)
int8 local=0; //VARIAVEL RESPONSÁVEL PELO ENDEREÇO DE GRAVAÇÃO NA MEMORIA(SEMPRE INCREMENTADA)
int8 protocolo=0; //VARIAVEL DE PROTOCOLO QUE DIZ AO CHIP NO MODO RUN, O QUE FAZER
int8 Res_pulso1=0; //VARIÁVEL RESPONSAVEL PELA METADE DE C_PULSOS
int8 Res_pulso2=0; // VARIÁVEL RESPONSÁVEL PELA OUTRA METADE DE C_PULSOS
int16 pulso=0; //RESULTADO DA ARITMÉTICA PARA SABER A QUANTIDADE REAL DE PULSOS
int16 C_pulso=0; // Cópia do valor de pulsos do movimento, para aceleração modo RUN
int16 deb=400; //DEBUNSEN
int16 Freq_P=4095; //VARIÁVEL RESPONSÁVEL PELA FREQUENCIA DESTINADA AOS MOTORES
int16 duty_P=8190; //VARIÁVEL RESPONSÁVEL PELO DUTY CYCLE DO PWM DESTINADO AOS MOTORES, O VALOR DE DUTY TEM SEMPRE QUE SER O DOBRO DA FREQ
int16 Freq_R=3000; // VARIÁVEL RESPONSÁVEL PELA FREQUENCIA DESTINADA AOS MOTORES NO MODO RUN
int16 duty_R=6000; // VARIÁVEL RESPONSÁVEL PELO DUTY DO PWM DESTINADO AOS MOTORES EM MODO RUN
int16 y=0; //ARMAZENA AS DUAS PARTES DE PULSOS TEMPORARIAMENTE, ATÉ SER SOMADO, E PREPARADO PARA GRAVAR O MOVIMENTO, ARMAZENA A PARTE ALTA E BAIXA DE PULSO, PARA SE TORNAR PULSO DENOVO DEPOIS DE GRAVADO
/******************************************************************************/
/************** TRATAMENTO DE INTERRUPÇÕES **************************/
/******************************************************************************/
#INT_PWMTB
void trata_pwm()
{
if(prog==1){
if(pulso1==255){
pulso2++;
pulso1=0;
}
else pulso1++;
if(ace==1){
if((Freq_P==4095) | (Freq_P>2047)){
Freq_P=Freq_P-16;
duty_P=duty_P-32;
}
if((Freq_P==2047) | (Freq_P>1023)){
Freq_P=Freq_P-2;
duty_P=duty_P-4;
}
if((Freq_P==1023)|(Freq_P>800)){
Freq_P=Freq_P-2;
duty_P=duty_P-4;
}
if((Freq_P==800)|(Freq_P>750)){
if(exp4==4){
exp4=0;
Freq_P=Freq_P-1;
duty_P=duty_P-2;
}
if(exp4<4)exp4=exp4+1;
}/*
if((Freq_P==750)|(Freq_P>700)){
if(exp8==8){
exp8=0;
Freq_P=Freq_P-1;
duty_P=duty_P-2;
}
if(exp8<8)exp8=exp8+1;
}
if((Freq_P==700)|(Freq_P>620)){
if(exp16==8){
exp16=0;
Freq_P=Freq_P-1;
duty_P=duty_P-2;
}
if(exp16<16)exp16=exp16+1;
}*/
}
if(des==1){
if((Freq_P==750)|(Freq_P<3722)){
Freq_P=Freq_P+2;
duty_P=duty_P+4;
}
if((Freq_P==3722)|(Freq_P<3946)){
Freq_P=Freq_P+4;
duty_P=duty_P+8;
}
if((Freq_P==3946)|(Freq_P<3996)){
Freq_P=Freq_P+4;
duty_P=duty_P+8;
}
if((Freq_P==3996)|(Freq_P<4095)){
Freq_P=Freq_P+4;
duty_P=duty_P+8;
}
/* if((Freq_P==750)|(Freq_P<2698)){
Freq_P=Freq_P+1;
duty_P=duty_P+2;
}
if((Freq_P==2698)|(Freq_P<3722)){
Freq_P=Freq_P+2;
duty_P=duty_P+4;
}
if((Freq_P==3722)|(Freq_P<3946)){
Freq_P=Freq_P+1;
duty_P=duty_P+2;
}
if((Freq_P==3946)|(Freq_P<3996)){
Freq_P=Freq_P+1;
duty_P=duty_P+2;
}
if((Freq_P==3996)|(Freq_P<4046)){
Freq_P=Freq_P+1;
duty_P=duty_P+2;
}
if((Freq_P==4046)|(Freq_P<4095)){
Freq_P=Freq_P+1;
duty_P=duty_P+2;
}*/
}
}
if(run==1){
if(ace==1){
if((Freq_R==4095) | (Freq_R>2047)){
Freq_R=Freq_R-16;
duty_R=duty_R-32;
}
if((Freq_R==2047) | (Freq_R>1023)){
Freq_R=Freq_R-2;
duty_R=duty_R-4;
}
if((Freq_P==1023)|(Freq_P>800)){
Freq_R=Freq_R-2;
duty_R=duty_R-4;
}
if((Freq_R==800)|(Freq_R>750)){
if(exp4==4){
exp4=0;
Freq_R=Freq_R-1;
duty_R=duty_R-2;
}
if(exp4<4)exp4=exp4+1;
}
if(Freq_R<=750){
freq_R=750;
duty_R=1500;
}
/*
if((Freq_P==750)|(Freq_P>700)){
if(exp8==8){
exp8=0;
Freq_P=Freq_P-1;
duty_P=duty_P-2;
}
if(exp8<8)exp8=exp8+1;
}
if((Freq_P==700)|(Freq_P>620)){
if(exp16==8){
exp16=0;
Freq_P=Freq_P-1;
duty_P=duty_P-2;
}
if(exp16<16)exp16=exp16+1;
}*/
}
if(des==1){
if((Freq_R==750)|(Freq_R<1000)){
Freq_R=Freq_R+2;
duty_R=duty_R+4;
}
if((Freq_R==1250)|(Freq_R<1500)){
Freq_R=Freq_R+4;
duty_R=duty_R+8;
}
if((Freq_R==1500)|(Freq_R<2000)){
Freq_R=Freq_R+4;
duty_R=duty_R+8;
}
if((Freq_R==2000)|(Freq_R<3000)){
Freq_R=Freq_P+4;
duty_R=duty_P+8;
}
if(Freq_R==3000){
Freq_R=3000;
duty_R=3000;
}
/* if((Freq_R==750)|(Freq_R<2698)){
Freq_R=Freq_R+1;
duty_R=duty_R+2;
}
if((Freq_R==2698)|(Freq_R<3722)){
Freq_R=Freq_R+2;
duty_R=duty_R+4;
}
if((Freq_R==3722)|(Freq_R<3946)){
Freq_R=Freq_R+1;
duty_R=duty_R+2;
}
if((Freq_R==3946)|(Freq_R<3996)){
Freq_R=Freq_R+1;
duty_R=duty_R+2;
}
if((Freq_R==3996)|(Freq_R<4046)){
Freq_R=Freq_R+1;
duty_R=duty_R+2;
}
if((Freq_R==4046)|(Freq_R<4095)){
Freq_R=Freq_R+1;
duty_R=duty_R+2;
}*/
}
if(res_pulso1!=0){
res_pulso1--;
}
if(res_pulso1==0){
res_pulso2--;
}
}
CLEAR_INTERRUPT(INT_PWMTB);
}
#INT_TIMER0
void trata_t0()
{
output_toggle(pin_c3);
SET_TIMER0(15535);
CLEAR_INTERRUPT(INT_TIMER0);
}
/******************************************************************************/
/******************* PROTOTIPOS DE ROTINAS ********************************/
/******************************************************************************/
void FRENTE_D(void); // Roda da DIREITA para Frente
void FRENTE_E(void); // Roda da ESQUERDA para Frente
void TRAS_D(void); // Roda da Direita para Tras
void TRAS_E(void); // Roda da Esquerda para Tras
void FRENTE(void); // As duas rodas para Frente
void TRAS(void); // As duas rodas para Tras
void EE(void); // Girar no proprio Eixo (Esquerda)
void ED(void); // Girar no proprio Eixo (Direita)
void PARA(void); // Desliga os 2 pinos de PWM
void F_run(void); // FRENTE no modo run
void T_run(void); // TRAS no modo run
void EE_run(void); // Eixo esquerdo no modo run
void ED_run(void); // Eixo Direito no modo run
void TD_run(void); // Tras direita no modo run
void te_run(void); // Tras esquerda no modo run
void fd_run(void); // Frente Direita no modo run
void fe_run(void); // Frente Esquerda no modo Run
void PISCA(void); // Rotina para sinalizar gravação, soma,subtração
void decide(void); // Rotina para decidir se vai somar ou subtrair movimento
void grava(void); // Rotina para gravar movimento
void fim(void); // coloca Chip em modo Sleep
/******************************************************************************/
/***************** MAIN ************************************************/
/******************************************************************************/
void main(){
enable_interrupts(GLOBAL);
SETUP_TIMER_0(RTCC_INTERNAL|RTCC_DIV_64);
SET_TIMER0(15535);
protocolo=0; local=0; pulso1=0; pulso2=0; pulso=0; y=0;
if(input(pin_e2)==1){
prog=1;
run=0;}
else{
prog=0;
run=1;}
/******************************************************************************/
/***************** PROG ************************************************/
/******************************************************************************/
while(prog==1 && run==0)
{
pwmcon0 = 0b01101111;
switch(input_d())
{
case 0b00000001:{
delay_ms(deb);
if(input_d()==0b00000001)frente_e();
}
break;
case 0b00001000:{
delay_ms(deb);
if(input_d()==0b00001000)tras_e();
}
break;
case 0b00000100:{
delay_ms(deb);
if(input_d()==0b00000100)frente_d();
}
break;
case 0b00000010:{
delay_ms(deb);
if(input_d()==0b00000010)tras_d();
}
break;
case 0b00001010:{
delay_ms(deb);
if(input_d()==0b00001010)tras();
}
break;
case 0b00000101:{
delay_ms(deb);
if(input_d()==0b00000101)frente();
}
break;
case 0b00000011:{
delay_ms(deb);
if(input_d()==0b00000011)ee();
}
break;
case 0b00001100:{
delay_ms(deb);
if(input_d()==0b00001100)ed();
}
break;
case 0b00010000:{
delay_ms(1000);
if(input_d()==0b00010000)fim();
else grava();
}
break;
default:para();
}
}
/******************************************************************************/
/***************** RUN ************************************************/
/******************************************************************************/
while(run==1 && prog==0)
{
pwmcon0 = 0b01101111;
//setup_power_pwm(PWM_CLOCK_DIV_4 | PWM_FREE_RUN | PWM_DEAD_CLOCK_DIV_4, 1, 0, Freq_P, 0, 0, 0);
Enable_interrupts(INT_TIMER0);
if(input(pin_a0)==1 && play==0)play=1;
if(play==1){
delay_ms(1000);
protocolo=0; pulso1=0; pulso2=0; pulso=0;
protocolo=read_eeprom(local);
local++;
pulso1=read_eeprom(local);
local++;
pulso2=read_eeprom(local);
local++;
pulso=((pulso2*256)+pulso1);
pisca();
c_pulso=pulso;
res_pulso1=c_pulso/2;
res_pulso2%=c_pulso/2;
switch(protocolo){
case 0b00111101:F_run(); break;
case 0b00001101:T_run(); break;
case 0b00010101:EE_run(); break;
case 0b00100101:ED_run(); break;
case 0b00001001:TD_run(); break;
case 0b00000001:Te_run(); break;
case 0b00111001:fd_run(); break;
case 0b00110001:fe_run(); break;
case 0b11111111:fim(); break;
}
}
}
}
/******************************************************************************/
/*************** ROTINAS DE MOVIMENTOS E CONTROLE **********************/
/******************************************************************************/
void frente_d()
{
enable_interrupts(int_pwmtb);
do{
ace=1;
setup_power_pwm(PWM_CLOCK_DIV_16 | PWM_FREE_RUN | PWM_DEAD_CLOCK_DIV_4, 1, 0, Freq_P, 0, 0, 0);
output_high(pin_b0);
set_power_pwm0_duty(PWM_UPDATE_ENABLE|duty_P);
set_power_pwm2_duty(PWM_UPDATE_disable);
delay_ms(6);
}
while(input_d()==0b00000100);
do{
ace=0;
des=1;
setup_power_pwm(PWM_CLOCK_DIV_16 | PWM_FREE_RUN | PWM_DEAD_CLOCK_DIV_4, 1, 0, Freq_P, 0, 0, 0);
output_high(pin_b0);
set_power_pwm0_duty(PWM_UPDATE_ENABLE|duty_P);
set_power_pwm2_duty(PWM_UPDATE_disable);
delay_ms(6);
}
while(Freq_P<4095);
para();
if (prot==0){
protocolo=0b00111001;
prot=1;
}
REC=1;
decide();
}
void tras_d()
{
enable_interrupts(int_pwmtb);
do{
ace=1;
setup_power_pwm(PWM_CLOCK_DIV_16 | PWM_FREE_RUN | PWM_DEAD_CLOCK_DIV_4, 1, 0, Freq_P, 0, 0, 0);
output_low(pin_b0);
set_power_pwm0_duty(PWM_UPDATE_ENABLE|duty_P);
set_power_pwm2_duty(PWM_UPDATE_disable);
delay_ms(6);
}
while(input_d()==0b00000010);
do{
ace=0;
des=1;
setup_power_pwm(PWM_CLOCK_DIV_16 | PWM_FREE_RUN | PWM_DEAD_CLOCK_DIV_4, 1, 0, Freq_P, 0, 0, 0);
output_low(pin_b0);
set_power_pwm0_duty(PWM_UPDATE_ENABLE|duty_P);
set_power_pwm2_duty(PWM_UPDATE_disable);
delay_ms(6);
}
while(Freq_P<4095);
para();
if (prot==0){
protocolo=0b00001001;
prot=1;
}
REC=1;
decide();
}
void frente_e()
{
enable_interrupts(int_pwmtb);
do{
ace=1;
setup_power_pwm(PWM_CLOCK_DIV_16 | PWM_FREE_RUN | PWM_DEAD_CLOCK_DIV_4, 1, 0, Freq_P, 0, 0, 0);
output_low(pin_b2);
set_power_pwm2_duty(PWM_UPDATE_ENABLE|duty_P);
set_power_pwm0_duty(PWM_UPDATE_disable);
delay_ms(6);
}
while(input_d()==0b00000001);
do{
ace=0;
des=1;
setup_power_pwm(PWM_CLOCK_DIV_16 | PWM_FREE_RUN | PWM_DEAD_CLOCK_DIV_4, 1, 0, Freq_P, 0, 0, 0);
output_low(pin_b2);
set_power_pwm2_duty(PWM_UPDATE_ENABLE|duty_P);
set_power_pwm0_duty(PWM_UPDATE_disable);
delay_ms(6);
}
while(Freq_P<4095);
para();
if (prot==0){
protocolo=0b00110001;
prot=1;
}
REC=1;
decide();
}
void tras_e()
{
enable_interrupts(int_pwmtb);
do{
ace=1;
setup_power_pwm(PWM_CLOCK_DIV_16 | PWM_FREE_RUN | PWM_DEAD_CLOCK_DIV_4, 1, 0, Freq_P, 0, 0, 0);
output_high(pin_b2);
set_power_pwm2_duty(PWM_UPDATE_ENABLE|duty_P);
set_power_pwm0_duty(PWM_UPDATE_disable);
delay_ms(6);
}
while(input_d()==0b00001000);
do{
ace=0;
des=1;
setup_power_pwm(PWM_CLOCK_DIV_16 | PWM_FREE_RUN | PWM_DEAD_CLOCK_DIV_4, 1, 0, Freq_P, 0, 0, 0);
output_high(pin_b2);
set_power_pwm2_duty(PWM_UPDATE_ENABLE|duty_P);
set_power_pwm0_duty(PWM_UPDATE_disable);
delay_ms(6);
}
while(Freq_P<4095);
para();
if (prot==0){
protocolo=0b00000001;
prot=1;
}
REC=1;
decide();
}
void tras()
{
enable_interrupts(int_pwmtb);
do{
ace=1;
setup_power_pwm(PWM_CLOCK_DIV_16 | PWM_FREE_RUN | PWM_DEAD_CLOCK_DIV_4, 1, 0, Freq_P, 0, 0, 0);
output_low(pin_b0);
output_high(pin_b2);
set_power_pwm0_duty(PWM_UPDATE_ENABLE|duty_P);
set_power_pwm2_duty(PWM_UPDATE_ENABLE|duty_P);
delay_ms(6);
}
while(input_d()==0b00001010);
do{
ace=0;
des=1;
setup_power_pwm(PWM_CLOCK_DIV_16| PWM_FREE_RUN | PWM_DEAD_CLOCK_DIV_4, 1, 0, Freq_P, 0, 0, 0);
output_low(pin_b0);
output_high(pin_b2);
set_power_pwm0_duty(PWM_UPDATE_ENABLE|duty_P);
set_power_pwm2_duty(PWM_UPDATE_ENABLE|duty_P);
delay_ms(6);
}
while(Freq_P<4095);
para();
if (prot==0){
protocolo=0b00001101;
prot=1;
}
REC=1;
decide();
}
void frente()
{
enable_interrupts(int_pwmtb);
do{
ace=1;
setup_power_pwm(PWM_CLOCK_DIV_16 | PWM_FREE_RUN | PWM_DEAD_CLOCK_DIV_4, 1, 0, Freq_P, 0, 0, 0);
output_low(pin_b2);
output_high(pin_b0);
set_power_pwm0_duty(PWM_UPDATE_ENABLE|duty_P);
set_power_pwm2_duty(PWM_UPDATE_ENABLE|duty_P);
delay_ms(6);
}
while(input_d()==0b00000101);
do{
ace=0;
des=1;
setup_power_pwm(PWM_CLOCK_DIV_16 | PWM_FREE_RUN | PWM_DEAD_CLOCK_DIV_4, 1, 0, Freq_P, 0, 0, 0);
output_low(pin_b2);
output_high(pin_b0);
set_power_pwm0_duty(PWM_UPDATE_ENABLE|duty_P);
set_power_pwm2_duty(PWM_UPDATE_ENABLE|duty_P);
delay_ms(6);
}
while(Freq_P<4095);
para();
if (prot==0){
protocolo=0b00111101;
prot=1;
}
REC=1;
decide();
}
void ee()
{
enable_interrupts(int_pwmtb);
do{
ace=1;
setup_power_pwm(PWM_CLOCK_DIV_16 | PWM_FREE_RUN | PWM_DEAD_CLOCK_DIV_4, 1, 0, Freq_P, 0, 0, 0);
output_low(pin_b0);
output_low(pin_b2);
set_power_pwm0_duty(PWM_UPDATE_ENABLE|duty_P);
set_power_pwm2_duty(PWM_UPDATE_ENABLE|duty_P);
delay_ms(6);
}
while(input_d()==0b00000011);
do{
ace=0;
des=1;
setup_power_pwm(PWM_CLOCK_DIV_16 | PWM_FREE_RUN | PWM_DEAD_CLOCK_DIV_4, 1, 0, Freq_P, 0, 0, 0);
output_low(pin_b0);
output_low(pin_b2);
set_power_pwm0_duty(PWM_UPDATE_ENABLE|duty_P);
set_power_pwm2_duty(PWM_UPDATE_ENABLE|duty_P);
delay_ms(6);
}
while(Freq_P<4095);
para();
if (prot==0){
protocolo=0b00010101;
prot=1;
}
REC=1;
decide();
}
void ed()
{
enable_interrupts(int_pwmtb);
do{
ace=1;
setup_power_pwm(PWM_CLOCK_DIV_16 | PWM_FREE_RUN | PWM_DEAD_CLOCK_DIV_4, 1, 0, Freq_P, 0, 0, 0);
output_high(pin_b0);
output_high(pin_b2);
set_power_pwm0_duty(PWM_UPDATE_ENABLE|duty_P);
set_power_pwm2_duty(PWM_UPDATE_ENABLE|duty_P);
delay_ms(6);
}
while(input_d()==0b00001100);
do{
ace=0;
des=1;
setup_power_pwm(PWM_CLOCK_DIV_16 | PWM_FREE_RUN | PWM_DEAD_CLOCK_DIV_4, 1, 0, Freq_P, 0, 0, 0);
output_high(pin_b0);
output_high(pin_b2);
set_power_pwm0_duty(PWM_UPDATE_ENABLE|duty_P);
set_power_pwm2_duty(PWM_UPDATE_ENABLE|duty_P);
delay_ms(6);
}
while(Freq_P<4095);
para();
if (prot==0){
protocolo=0b00100101;
prot=1;
}
REC=1;
decide();
}
/******************************************************************************/
/***************** ROTINAS RUN **************************************/
/******************************************************************************/
void F_run()
{
enable_interrupts(int_pwmtb);
do{
ace=1;
setup_power_pwm(PWM_CLOCK_DIV_16 | PWM_FREE_RUN | PWM_DEAD_CLOCK_DIV_4, 1, 0, Freq_R, 0, 0, 0);
output_low(pin_b2);
output_high(pin_b0);
set_power_pwm0_duty(PWM_UPDATE_ENABLE|duty_R);
set_power_pwm2_duty(PWM_UPDATE_ENABLE|duty_R);
delay_ms(6);
}
while(res_pulso1!=0);
do{
ace=0;
des=1;
setup_power_pwm(PWM_CLOCK_DIV_16 | PWM_FREE_RUN | PWM_DEAD_CLOCK_DIV_4, 1, 0, Freq_R, 0, 0, 0);
output_low(pin_b2);
output_high(pin_b0);
set_power_pwm0_duty(PWM_UPDATE_ENABLE|duty_R);
set_power_pwm2_duty(PWM_UPDATE_ENABLE|duty_R);
delay_ms(6);
}
while(res_pulso2!=0);
para();
}
void T_run()
{
output_low(pin_b0);
output_high(pin_b2);
set_power_pwm0_duty(PWM_UPDATE_ENABLE|duty_R);
set_power_pwm2_duty(PWM_UPDATE_ENABLE|duty_R);
while(pulso!=0);
para();
}
void EE_run()
{
output_low(pin_b0);
output_low(pin_b2);
set_power_pwm0_duty(PWM_UPDATE_ENABLE|duty_R);
set_power_pwm2_duty(PWM_UPDATE_ENABLE|duty_R);
while(pulso!=0);
para();
}
void ED_run()
{
output_high(pin_b0);
output_high(pin_b2);
set_power_pwm0_duty(PWM_UPDATE_ENABLE|duty_R);
set_power_pwm2_duty(PWM_UPDATE_ENABLE|duty_R);
while(pulso!=0);
para();
}
void TD_run()
{
output_low(pin_b0);
set_power_pwm0_duty(PWM_UPDATE_ENABLE|duty_R);
set_power_pwm2_duty(PWM_UPDATE_disable);
while(pulso!=0);
para();
}
void te_run()
{
output_high(pin_b2);
set_power_pwm2_duty(PWM_UPDATE_ENABLE|duty_R);
set_power_pwm0_duty(PWM_UPDATE_disable);
while(pulso!=0);
para();
}
void fd_run()
{ enable_interrupts(int_pwmtb);
output_high(pin_b0);
set_power_pwm0_duty(PWM_UPDATE_ENABLE|duty_R);
set_power_pwm2_duty(PWM_UPDATE_disable);
while(pulso!=0);
para();
}
void fe_run()
{
output_low(pin_b2);
set_power_pwm2_duty(PWM_UPDATE_ENABLE|duty_R);
set_power_pwm0_duty(PWM_UPDATE_disable);
while(pulso!=0);
para();
}
/********************************************************************************/
/************************* ROTINAS DE CONTROLE DE MOVIMENTOS *****************/
/********************************************************************************/
void para()
{
ace=0;
des=0;
set_power_pwm0_duty(PWM_UPDATE_DISABLE);
set_power_pwm2_duty(PWM_UPDATE_DISABLE);
disable_interrupts(int_pwmtb);
if(prog==1){
Freq_P=4095;
duty_P=8190;
}
if(run==1){
Freq_P=3000;
duty_P=6000;
}
}
void pisca()
{
output_high(pin_e1);
delay_ms(100);
output_low(pin_e1);
delay_ms(100);
}
void fim()
{
disable_interrupts(INT_TIMER0);
write_eeprom(local,0b11111111);
output_high(pin_c3);
delay_ms(2000);
output_low(pin_c3);
sleep();
sleep();
}
void grava(){
pulso1=make8(y,0);
pulso2=make8(y,1);
write_eeprom(local,protocolo);
local++;
write_eeprom(local,pulso1);
local++;
write_eeprom(local,pulso2);
local++;
pulso1=0; pulso2=0; protocolo=0; y=0; prot=0; REC=0;
pisca();
pisca();
pisca();
}
void decide()
{
while(REC==1){
if(input_d()==0b10000000)delay_ms(20); //SOMA
if(input_d()==0b10000000){
while(input_d()==0b10000000);
y=y+((pulso2*256)+pulso1);
pulso1=0; pulso2=0; REC=0;
pisca();
}
if(input_d()==0b00100000)delay_ms(20); //SUBTRAI
if(input_d()==0b00100000){
while(input_d()==0b00100000);
y=y-((pulso2*256)+pulso1);
pulso1=0; pulso2=0; REC=0;
pisca();
pisca();
}
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Dec 21, 2010 1:37 pm |
|
|
That is not a short test program. Try to remove a large amount of the
code, but still have a program that demonstrates the problem.
If it's a short program (that compiles OK), I have a better chance to
quickly find the problem. |
|
|
gianhenrique
Joined: 20 Dec 2010 Posts: 8
|
|
Posted: Tue Dec 21, 2010 1:54 pm |
|
|
sorry
I'll put part of the program that works too.
I believe that works right ...
Code: |
#include <18f4431.h>
#use delay(clock=20000000)
#fuses NOLVP, HS, NOWDT, NOPROTECT, PUT, BROWNOUT,BORV27,NOMCLR, NOFCMEN
//PAGINA 67 DO DATASHEET ENDEREÇO DOS REGISTRADORES
#BYTE pwmcon0=0XF6F //Registrador de PWMCON0, define quais os pinos de pwm irao operar
#priority PWMTB
/******************************************************************************/
/**************** VARIÁVEIS DE CONTROLE ***********************************/
/******************************************************************************/
int1 ace=0; //FLAG QUE SINALIZA ACELERAÇÃO NA FUNÇÃO DE MOVIMENTOS
int1 des=0; //FLAG QUE SINALIZA DESACELERAÇÃO NA FUNÇÃO DE MOVIMENTOS
int16 deb=400; //DEBUNSEN
int1 prog=0;
int8 exp4=0;
int16 Freq_P=4095; //VARIÁVEL RESPONSÁVEL PELA FREQUENCIA DESTINADA AOS MOTORES
int16 duty_P=8190; //VARIÁVEL RESPONSÁVEL PELO DUTY CYCLE DO PWM DESTINADO AOS MOTORES, O VALOR DE DUTY TEM SEMPRE QUE SER O DOBRO DA FREQ
/******************************************************************************/
/************** TRATAMENTO DE INTERRUPÇÕES **************************/
/******************************************************************************/
#INT_PWMTB
void trata_pwm()
{
if(ace==1){
if((Freq_P==4095) | (Freq_P>2047)){
Freq_P=Freq_P-16;
duty_P=duty_P-32;
}
if((Freq_P==2047) | (Freq_P>1023)){
Freq_P=Freq_P-2;
duty_P=duty_P-4;
}
if((Freq_P==1023)|(Freq_P>800)){
Freq_P=Freq_P-2;
duty_P=duty_P-4;
}
if((Freq_P==800)|(Freq_P>750)){
if(exp4==4){
exp4=0;
Freq_P=Freq_P-1;
duty_P=duty_P-2;
}
if(exp4<4)exp4=exp4+1;
}
}
if(des==1){
if((Freq_P==750)|(Freq_P<3722)){
Freq_P=Freq_P+2;
duty_P=duty_P+4;
}
if((Freq_P==3722)|(Freq_P<3946)){
Freq_P=Freq_P+4;
duty_P=duty_P+8;
}
if((Freq_P==3946)|(Freq_P<3996)){
Freq_P=Freq_P+4;
duty_P=duty_P+8;
}
if((Freq_P==3996)|(Freq_P<4095)){
Freq_P=Freq_P+4;
duty_P=duty_P+8;
}
}
CLEAR_INTERRUPT(INT_PWMTB);
}
#INT_TIMER0
void trata_t0()
{
output_toggle(pin_c3);
SET_TIMER0(15535);
CLEAR_INTERRUPT(INT_TIMER0);
}
/******************************************************************************/
/******************* PROTOTIPOS DE ROTINAS ********************************/
/******************************************************************************/
void FRENTE_D(void); // Roda da DIREITA para Frente
void PARA(void); // Desliga os 2 pinos de PWM
/******************************************************************************/
/***************** MAIN ************************************************/
/******************************************************************************/
void main(){
enable_interrupts(GLOBAL);
SETUP_TIMER_0(RTCC_INTERNAL|RTCC_DIV_64);
SET_TIMER0(15535);
prog=1;
/******************************************************************************/
/***************** PROG ************************************************/
/******************************************************************************/
while(prog==1)
{
pwmcon0 = 0b01101111;
switch(input_d())
{
case 0b00000100:{
delay_ms(deb);
if(input_d()==0b00000100)frente_d();
}
break;
default: para();
}
}
}
/******************************************************************************/
/*************** ROTINAS DE MOVIMENTOS E CONTROLE **********************/
/******************************************************************************/
void frente_d()
{
enable_interrupts(int_pwmtb);
do{
ace=1;
setup_power_pwm(PWM_CLOCK_DIV_16 | PWM_FREE_RUN | PWM_DEAD_CLOCK_DIV_4, 1, 0, Freq_P, 0, 1, 0);
output_high(pin_b0);
set_power_pwm0_duty(PWM_UPDATE_ENABLE|duty_P);
set_power_pwm2_duty(PWM_UPDATE_disable);
delay_ms(6);
}
while(input_d()==0b00000100);
do{
ace=0;
des=1;
setup_power_pwm(PWM_CLOCK_DIV_16 | PWM_FREE_RUN | PWM_DEAD_CLOCK_DIV_4, 1, 0, Freq_P, 0, 1, 0);
output_high(pin_b0);
set_power_pwm0_duty(PWM_UPDATE_ENABLE|duty_P);
set_power_pwm2_duty(PWM_UPDATE_disable);
delay_ms(6);
}
while(Freq_P<4095);
para();
}
/********************************************************************************/
/************************* ROTINAS DE CONTROLE DE MOVIMENTOS *****************/
/********************************************************************************/
void para()
{
ace=0;
des=0;
set_power_pwm0_duty(PWM_UPDATE_DISABLE);
set_power_pwm2_duty(PWM_UPDATE_DISABLE);
disable_interrupts(int_pwmtb);
if(prog==1){
Freq_P=4095;
duty_P=8190;
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Dec 21, 2010 5:00 pm |
|
|
Code: |
if(ace==1){
if((Freq_P==4095) | (Freq_P>2047)){
Freq_P=Freq_P-16;
duty_P=duty_P-32;
}
if((Freq_P==2047) | (Freq_P>1023)){
Freq_P=Freq_P-2;
duty_P=duty_P-4;
}
if((Freq_P==1023)|(Freq_P>800)){
Freq_P=Freq_P-2;
duty_P=duty_P-4;
}
if((Freq_P==800)|(Freq_P>750)){
if(exp4==4){
exp4=0;
Freq_P=Freq_P-1;
duty_P=duty_P-2;
}
if(exp4<4)exp4=exp4+1;
}
|
I don't understand your logic in this code. Suppose 'Freq_P' is 2048.
Then all of the if() statements will be executed. Is that what
you want it to do ?
What is the purpose of your code above ? Do you want to detect
one specific range of Freq_P, and then subtract a number from Freq_P ?
Also, it's not normal programming to use the bitwise OR operator '|'
in a logical statement. The logical OR operator '||' should be used.
However, I'm not sure what you want to do. I suspect that you want
to detect several ranges. If that's true, the following code would work
better:
Code: |
if(ace==1){
if((Freq_P <= 4095) && (Freq_P > 2047)){ // Range: 2048 to 4095
Freq_P=Freq_P-16;
duty_P=duty_P-32;
}
if((Freq_P <= 2047) && (Freq_P > 1023)){ // Range: 1024 to 2047
Freq_P=Freq_P-2;
duty_P=duty_P-4;
}
if((Freq_P <= 1023) && (Freq_P > 800)){ // Range: 801 to 1023
Freq_P=Freq_P-2;
duty_P=duty_P-4;
}
if((Freq_P <= 800) && (Freq_P > 750)){ // Range: 751 to 800
if(exp4==4){
exp4=0;
Freq_P=Freq_P-1;
duty_P=duty_P-2;
}
if(exp4<4)exp4=exp4+1;
}
|
The code above could be made much more simple by using "else if"
statements. For example, here's a test program that you can run
in MPLAB simulator, using "else if" statements:
Code: |
#include <18F452.h>
#fuses HS,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock = 20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
//======================================
void main(void)
{
int16 Freq_P;
for(Freq_P = 600; Freq_P < 4100; Freq_P += 100)
{
if(Freq_P > 2047)
{
printf("Freq_P=%lu, range = 2048 to 4095 \r", Freq_P);
}
else if(Freq_P > 1023)
{
printf("Freq_P=%lu, range = 1024 to 2047 \r", Freq_P);
}
else if(Freq_P > 800)
{
printf("Freq_P=%lu, range = 801 to 1023 \r", Freq_P);
}
else if(Freq_P > 750)
{
printf("Freq_P=%lu, range = 751 to 800 \r", Freq_P);
}
}
} |
Here's the output of the program above. You can study how the program
works by running it in MPLAB simulator:
Quote: |
Freq_P=800, range = 751 to 800
Freq_P=900, range = 801 to 1023
Freq_P=1000, range = 801 to 1023
Freq_P=1100, range = 1024 to 2047
Freq_P=1200, range = 1024 to 2047
Freq_P=1300, range = 1024 to 2047
Freq_P=1400, range = 1024 to 2047
Freq_P=1500, range = 1024 to 2047
Freq_P=1600, range = 1024 to 2047
Freq_P=1700, range = 1024 to 2047
Freq_P=1800, range = 1024 to 2047
Freq_P=1900, range = 1024 to 2047
Freq_P=2000, range = 1024 to 2047
Freq_P=2100, range = 2048 to 4095
Freq_P=2200, range = 2048 to 4095
Freq_P=2300, range = 2048 to 4095
Freq_P=2400, range = 2048 to 4095
Freq_P=2500, range = 2048 to 4095
Freq_P=2600, range = 2048 to 4095
Freq_P=2700, range = 2048 to 4095
Freq_P=2800, range = 2048 to 4095
Freq_P=2900, range = 2048 to 4095
Freq_P=3000, range = 2048 to 4095
Freq_P=3100, range = 2048 to 4095
Freq_P=3200, range = 2048 to 4095
Freq_P=3300, range = 2048 to 4095
Freq_P=3400, range = 2048 to 4095
Freq_P=3500, range = 2048 to 4095
Freq_P=3600, range = 2048 to 4095
Freq_P=3700, range = 2048 to 4095
Freq_P=3800, range = 2048 to 4095
Freq_P=3900, range = 2048 to 4095 |
Last edited by PCM programmer on Tue Dec 21, 2010 5:15 pm; edited 2 times in total |
|
|
gianhenrique
Joined: 20 Dec 2010 Posts: 8
|
|
Posted: Tue Dec 21, 2010 5:19 pm |
|
|
sorry again!
I do this part of the code, is to compare the value of this one OR the other ...
there was a mistake, because the code is not posted an updated code ...
I've moved this logic to the bitwise logical OR comparison '| |'
not understand what the 'range' is ...
is a function of the ccs? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Dec 21, 2010 5:42 pm |
|
|
'Range' is a programming concept. A "range" of numbers:
A range between a lower number and a higher number.
I don't really know what you want to do. I'm not sure if
I want to work on this problem any more. |
|
|
gianhenrique
Joined: 20 Dec 2010 Posts: 8
|
|
Posted: Tue Dec 21, 2010 5:47 pm |
|
|
What I want is to change the period of the pwm.
Just tell me if you like me to update the frequency PWM mode by another without use the function setup_power_pwm ()...
How to update only the value of the frequency without having to upgrade all the time other settings
have? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Dec 22, 2010 2:20 pm |
|
|
I made a test program that smoothly changes the PWM frequency from
1 KHz to 2 KHz, and back down to 1 KHz again, continuously. You can
see the waveform on Pin B1 with your oscilloscope.
Code: |
#include<18F4431.h>
#fuses INTRC_IO, NOWDT, NOPROTECT, NOBROWNOUT, PUT, NOLVP
#use delay(clock=8000000)
#define MAX_PWM_PERIOD 1999 // 1 KHz pwm freq with 8 MHz osc.
#define MIN_PWM_PERIOD 1000
#byte PTPERL = getenv("SFR:PTPERL")
#byte PTPERH = getenv("SFR:PTPERH")
#INT_PWMTB
void pwmtb_isr(void)
{
static int16 period = MAX_PWM_PERIOD;
static int8 period_increasing = FALSE;
// Ramp the PWM period down and up, continuously.
if(period_increasing)
{
if(period < MAX_PWM_PERIOD)
period++;
else
period_increasing = FALSE;
}
else // period is decreasing
{
if(period > MIN_PWM_PERIOD)
period--;
else
period_increasing = TRUE;
}
// Set period in hardware register to new value.
PTPERL = make8(period, 0);
PTPERH = make8(period, 1);
}
//=======================================
void main()
{
// Setup the 4 Power PWM channels as ordinary pwm channels.
setup_power_pwm_pins(PWM_ODD_ON, PWM_ODD_ON, PWM_ODD_ON, PWM_ODD_ON);
// Mode = Free Run
// Postscale = 1 (1-16) Timebase output postscaler
// TimeBase = 0 (0-65355) Initial value of PWM Timebase
// Period = 2000 (0-4095) Max value of PWM TimeBase
// Compare = 0 (Timebase value for special event trigger)
// Compare Postscale = 1 (Postscaler for Compare value)
// Dead Time
setup_power_pwm(PWM_FREE_RUN, 1, 0, MAX_PWM_PERIOD, 0, 1,0);
set_power_pwm0_duty((int16)((MAX_PWM_PERIOD *4) * .1)); // 10%
clear_interrupt(INT_PWMTB);
enable_interrupts(INT_PWMTB);
enable_interrupts(GLOBAL);
while(1);
} |
|
|
|
gianhenrique
Joined: 20 Dec 2010 Posts: 8
|
|
Posted: Mon Jan 03, 2011 5:09 am |
|
|
PCM programmer Thanks for the help, your help was amazing utility!
Sorry for any faux pas I made.
Graciously
Gian Correa
|
|
|
|
|
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
|