X-Git-Url: https://rtime.felk.cvut.cz/gitweb/fpga/rpi-motor-control.git/blobdiff_plain/0db7b4491e1b1a1621cd35255aa4ad91652e1e85..694d7155f582476ae9c042258e98fc867eb6b1ba:/pmsm-control/test_sw/main_pmsm.c diff --git a/pmsm-control/test_sw/main_pmsm.c b/pmsm-control/test_sw/main_pmsm.c index 4c51f51..56b926a 100644 --- a/pmsm-control/test_sw/main_pmsm.c +++ b/pmsm-control/test_sw/main_pmsm.c @@ -24,8 +24,8 @@ #include "pmsm_state.h" #include "cmd_proc.h" -#define MAX_DUTY 128 -#define PID_P 0.1 +#define MAX_DUTY 170 +#define PID_P 0.3 #define PRIOR_KERN 50 #define PRIOR_HIGH 49 @@ -69,6 +69,24 @@ int clk_init() inline void clk_disable(){ termClock(0); } +/* + * \brief + * Count minimum value of three numbers. + * Input values must be in range <-2^28;2^28>. + */ +int32_t min(int32_t x, int32_t y, int32_t z){ + int32_t diff,sign; + + diff=x-y; /*rozdil*/ + sign=(*((uint32_t*)&diff))>>31; /*znamenko -> detekuje, ze y je vetsi*/ + x=y+sign*diff; /*ulozime mensi cislo, pokud sign>0, pak diff<0 */ + + diff=x-z; /*rozdil*/ + sign=(*((uint32_t*)&diff))>>31; /*znamenko -> detekuje, ze z je vetsi*/ + x=z+sign*diff; /*ulozime mensi cislo, pokud sign>0, pak diff<0 */ + + return x; +} /** * \brief Signal handler pro Ctrl+C @@ -95,10 +113,32 @@ void dq2alphabeta(int32_t *alpha, int32_t *beta, int d, int q, int32_t sin, int3 *beta=-sin*d+cos*q; return; } -void alphabeta2pwm3(int32_t * pwma, int32_t * pwmb, int32_t *pwmc,int32_t alpha, int32_t beta){ - *pwma=alpha; - *pwmb=-alpha/2+beta*887/1024; - *pwmc=-alpha/2-beta*887/1024; +void alphabeta2pwm3(int32_t * ia, int32_t * ib, int32_t *ic,int32_t alpha, int32_t beta){ + *ia=alpha; + *ib=-alpha/2+beta*887/1024; + *ic=-alpha/2-beta*887/1024; +} +/* + * \brief + * Preocita napeti na jednotlivych civkach na napeti, + * ktera budou privedena na svorky motoru. + * Tedy na A(yel)-pwm1, B(red)-pwm2, C(blk)-pwm3 + */ +void transDelta(int32_t * u1, int32_t * u2, int32_t *u3, int32_t ub , int32_t uc){ + int32_t t; + + /*vypocte napeti tak, aby odpovidaly rozdily*/ + *u1=uc; + *u2=uc+ub; + *u3=0; + + /*najde zaporne napeti*/ + t=min(*u1,*u2,*u3); + + /*dorovna zaporna napeti na nulu*/ + *u1-=t; + *u2-=t; + *u3-=t; } void inv_trans_comm(int duty){ uint32_t pos; @@ -121,11 +161,42 @@ void inv_trans_comm(int duty){ if (pwmc<0) pwmc=0; - rps.pwm1=(uint16_t)pwma; - rps.pwm3=(uint16_t)pwmb; - rps.pwm2=(uint16_t)pwmc; + rps.t_pwm1=(uint16_t)pwma; + rps.t_pwm3=(uint16_t)pwmb; + rps.t_pwm2=(uint16_t)pwmc; } +void inv_trans_comm_2(int duty){ + uint32_t pos; + int32_t sin, cos; + int32_t alpha, beta; + int32_t ua,ub,uc; + int32_t ia,ib,ic; + int32_t u1,u2,u3; + pos=rps.index_dist; + + pos+=960; /*zarovnani faze 'a' s osou 'alpha'*/ + + /*pro výpočet sin a cos je pouzita 32-bit cyklicka logika*/ + pos*=4294967; + pxmc_sincos_fixed_inline(&sin, &cos, pos, 16); + + dq2alphabeta(&alpha, &beta,0,duty, sin, cos); + alpha>>=16; + beta>>=16; + + alphabeta2pwm3(&ia,&ib, &ic,alpha,beta); + + ua=ia; + ub=ib; + uc=ic; + + transDelta(&u1,&u2, &u3,ub,uc); + + rps.pwm1=(uint16_t)u1; + rps.pwm2=(uint16_t)u2; + rps.pwm3=(uint16_t)u3; +} void prepare_tx(uint8_t * tx){ /*Data format: @@ -478,6 +549,7 @@ void * read_data(void* param){ /*simple_ind_dist_commutator(rps.duty);*/ /*sin_commutator(rps.duty);*/ inv_trans_comm(rps.duty); + inv_trans_comm_2(rps.duty); }else if(!rps.index_ok && rps.commutate){ simple_hall_commutator(rps.duty); }