#include "foc.h"
#include "tim.h"
#include "math.h"
#include "arm_math.h"
#include "adc.h"
#define PAIRS 7 //Pole of Pairs
#define PART_NUM 3072 // 多少细分
#define MIN(a,b) a<b?a:b
uint16_t ADC_Values_Raw[4];
uint16_t ADC_Values_Raw2[4];
//#define PI 3.1415926f
typedef struct{
uint8_t a;
uint8_t b;
uint8_t c;
float theta;
float x;
float y;
}Uvect_Mos;
typedef struct{
float ccra;
float ccrb;
float ccrc;
}CCR_Duty;
Uvect_Mos U0={0,0,0,0};
Uvect_Mos U4={1,0,0,0};
Uvect_Mos U6={1,1,0,PI/3};
Uvect_Mos U2={0,1,0,PI/3*2};
Uvect_Mos U3={0,1,1,PI};
Uvect_Mos U1={0,0,1,PI/3*4};
Uvect_Mos U5={1,0,1,PI/3*5};
Uvect_Mos U7={1,1,1,0};
Uvect_Mos *Uvects[6]={&U1,&U2,&U3,&U4,&U5,&U6};
CCR_Duty CCR_Dutys={0};
static float theta=0;
float RPS=0.1; // 转速
void UVects_Init(){
for(int i=0;i<6;++i){
float v_theta=Uvects[i]->theta;
Uvects[i]->x=cosf(v_theta);
Uvects[i]->y=sinf(v_theta);
}
}
void Foc_Init(float rps){
// rps unit is r/s
int interupt_time=0;
int PSC=0;
//interupt_time=rps*PAIRS*PART_NUM;
//PSC=1281/interupt_time; //84000000/65535/interrupt_time
//TIM7->ARR=84000000/(PSC+1)/interupt_time;
//TIM7->PSC=PSC;
interupt_time=rps*PAIRS*PART_NUM;
PSC=1281/interupt_time;
//TIM8->ARR=168000000/(PSC+1)/interupt_time/2; // TIM8的初始化写在别处了,ARR值为3360,重复计数器设为1,定时器频率168Mhz,因此算下来,ARR=3360的中断频率就是25K
//TIM8->PSC=PSC;
//TIM8->ARR=6200;
//TIM8->PSC=0;
UVects_Init();
HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim8,TIM_CHANNEL_3);
HAL_TIMEx_PWMN_Start(&htim8,TIM_CHANNEL_1);
HAL_TIMEx_PWMN_Start(&htim8,TIM_CHANNEL_2);
HAL_TIMEx_PWMN_Start(&htim8,TIM_CHANNEL_3);
//HAL_TIM_Base_Start_IT(&htim7);
//ADC
HAL_ADC_Start_DMA(&hadc1,(uint32_t *)ADC_Values_Raw,2);
HAL_ADC_Start_DMA(&hadc2,(uint32_t *)ADC_Values_Raw2,3);
HAL_TIM_Base_Start_IT(&htim8);
}
uint8_t get_area(uint32_t now_theta){
return now_theta/60+1;
}
void get_area_u(uint8_t area,Uvect_Mos *u1,Uvect_Mos *u2){
switch (area)
{
case 1:
*u1=U4;
*u2=U6;
break;
case 2:
*u1=U6;
*u2=U2;
break;
case 3:
*u1=U2;
*u2=U3;
break;
case 4:
*u1=U3;
*u2=U1;
break;
case 5:
*u1=U1;
*u2=U5;
break;
case 6:
*u1=U5;
*u2=U4;
break;
default:
break;
}
}
void get_t(float theta,float * t1,float *t2){
/*
/ u2y x u2x y \
| ----------------- - ----------------- |
| u1x u2y - u2x u1y u1x u2y - u2x u1y |
| |
| u1x y u1y x |
| ----------------- - ----------------- |
\ u1x u2y - u2x u1y u1x u2y - u2x u1y /
*/
float temp_t1,temp_t2;
float theta_f; // 单位为rad
Uvect_Mos u1,u2;
float x,y;
get_area_u(get_area(theta),&u1,&u2);
//theta_f=(float)theta*2.0f*PI/360;
arm_sin_cos_f32(theta,&y,&x);
x*=0.86f;
y*=0.86f; // sqrt(3)/2 没错
//x=0.86f*cosf(theta_f);
//y=0.86f*sinf(theta_f);
temp_t1=u2.y*x/(u1.x*u2.y-u2.x*u1.y)-(u2.x*y)/(u1.x*u2.y-u2.x*u1.y);
temp_t2=u1.x*y/(u1.x*u2.y-u2.x*u1.y)-(u1.y*x)/(u1.x*u2.y-u2.x*u1.y);
*t1=temp_t1;
*t2=temp_t2;
}
CCR_Duty get_ccr_duty(float t1,float t2,Uvect_Mos u1,Uvect_Mos u2){
float t0,t3;
CCR_Duty result;
t0=(1-t1-t2)/2;
t3=t0;
result.ccra=U7.a*t3+u1.a*t1+u2.a*t2;
result.ccrb=U7.b*t3+u1.b*t1+u2.b*t2;
result.ccrc=U7.c*t3+u1.c*t1+u2.c*t2;
return result;
}
void SVPWM_Step(CCR_Duty duty){ // 此函数调用频率为25KHZ
TIM8->CCR1=duty.ccrc*TIM8->ARR;
TIM8->CCR2=duty.ccrb*TIM8->ARR;
TIM8->CCR3=duty.ccra*TIM8->ARR;
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if(htim->Instance==TIM7){
//svpwm();
}
if(htim->Instance==TIM8){
//svpwm();
SVPWM_Step(CCR_Dutys);
}
}
#define dealtK PAIRS*360.0f/1000.0f
void Theta_Handler(){ // 此函数1ms调用一次
Uvect_Mos u1,u2;
float t1,t2;
float dealt=RPS*dealtK;
theta+=dealt;
if(theta>360){
theta-=360;
}
uint8_t area=get_area((int)theta);
get_area_u(area,&u1,&u2);
get_t(theta,&t1,&t2);
CCR_Dutys=get_ccr_duty(t1,t2,u1,u2);
}