[LCW_DIY]FOC电调学习板V1.1

2019-12-10 18:17发布

本帖最后由 lcw_swust 于 2018-11-13 13:59 编辑

1.1电路.rar (32.24 KB, 下载次数: 281) 2018-11-13 13:29 上传 点击文件名下载附件
1.1程序.rar (768.43 KB, 下载次数: 309) 2018-11-13 13:29 上传 点击文件名下载附件
器件.rar (1.84 MB, 下载次数: 212) 2018-11-13 13:29 上传 点击文件名下载附件
AN1299.pdf (994.49 KB, 下载次数: 333) 2018-11-13 13:29 上传 点击文件名下载附件
关于FOC电调的单电阻取样.pdf (247.88 KB, 下载次数: 365) 2018-11-13 13:29 上传 点击文件名下载附件
(上一版:https://www.amobbs.com/thread-5700742-1-1.html )
这是FOC1.0的改进型号,由三相半桥驱动芯片驱动6只NMOS,单电阻取样,取样加了放大。

主控                  STM32F103C8T6
三相半桥驱动        EG2133
MOS管                FDD6635
放大                  AD8051
(补充说明:在输出PWM时,EG2133的HIN、nLIN是同相的,EG2134的HIN、LIN是反相的)
定时中断占用CPU:16us/46us

现在只写了电压模式的程序,需要电流模式的可自行参考上一版本修改。
(主要程序都在 main.c 和 MOTFOC.C 里)

电路图、PCB:
6.jpg (170.7 KB, 下载次数: 1) 下载附件 2018-11-13 13:35 上传

下面看下程序,只看核心代码:
=========================================================
1.        ADC配置
ADC需配置为T4_CC4触发,触发后依次采集4、4、5、3通道,即可得到:-Iv、Iu、平均电流、供电电压。
当然,需要用DMA来配合。
  1. //ADC配置:扫描模式、单次模式、定时器4的CC4触发、使能DMA       
  2. void ADC_Conf(void)
  3. {   
  4.         ......
  5.         RCC_ADCCLKConfig(RCC_PCLK2_Div4);//56/4=14M
  6.         ADC_InitStructure.ADC_ScanConvMode = ENABLE;//扫描模式
  7.         ADC_InitStructure.ADC_ContinuousConvMode =DISABLE;//单次模式
  8.         ADC_InitStructure.ADC_ExternalTrigConv =ADC_ExternalTrigConv_T4_CC4;//定时器4的CC4触发
  9.         ADC_InitStructure.ADC_NbrOfChannel = 4;//扫描4次
  10.         ......
  11.         ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_7Cycles5);//adc4,第1次是-Iv
  12.         ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 2, ADC_SampleTime_7Cycles5);//adc4,第2次是Iu
  13.         ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 3, ADC_SampleTime_7Cycles5);//adc5,Isavg,硬件对取样电阻低通滤波
  14.         ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_7Cycles5);//adc3,AD_V,测量供电电压
  15.         ......
  16.         ADC_DMACmd(ADC1, ENABLE);//使能DMA       
  17.           ADC_ExternalTrigConvCmd(ADC1, ENABLE);//使能外部触发  
  18.         ......       
  19. }   
复制代码
2.        DMA配置
DMA的作用是配合ADC采样,将ADC1->DR的数据自动存入DMA_ADCBuf[]数组。
  1. //DMA配合ADC,普通模式,把ADC1->DR数据存入DMA_ADCBuf[]
  2. #define DMA_ADCBUFSIZE                 10
  3. U32 DMA_ADCBuf[DMA_ADCBUFSIZE];//用DMA采集多通道数据
  4. void DMA_Conf(void)
  5. {   
  6.         ......       
  7.         DMA_InitStructure.DMA_PeripheralBaseAddr =ADC1_DR_Address;//ADC1->DR
  8.         DMA_InitStructure.DMA_MemoryBaseAddr = (U32)DMA_ADCBuf;//数组
  9.         DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//普通模式
  10.         ......       
  11. }   
复制代码
3.        定时器配置
定时器用于产生三相PWM,且相互错开一定相位,使下降沿相差固定的时间;T4_CC4触发ADC采样;T4_CC3引发定时中断。
  1. //--------------------------------------------------
  2. //                定时器初始化
  3. //频率56M/10,PWM周期约256*10/56M 约=46us
  4. //向下计数模式
  5. //T4.1、T4.2:U相HIN、nLIN,同相
  6. //T3.1、T3.2:V相HIN、nLIN,同相
  7. //T2.1、T2.2:W相HIN、nLIN,同相
  8. //三相时间顺序:VWU,即T3T2T4
  9. //T4.4:触发ADC采样
  10. //T4.3:中断里进行数据处理,时间在ADC采样完成之后
  11. //--------------------------------------------------
  12. void Timer_Init(void)
  13. {
  14.         ......       
  15.         TIM_TimeBaseStructure.TIM_CounterMode= TIM_CounterMode_Down;//向下计数模式
  16.         ......       
  17.         TIM_SetCounter(TIM3,0);//计数初值也可用于控制相位差       
  18.         TIM_SetCounter(TIM2,8);//由于是向下计数,数字越大则越滞后
  19.         TIM_SetCounter(TIM4,16);
  20.         //启动时刻之差也会造成相位差,放在前面的相位越提前
  21.         TIM_Cmd(TIM3,ENABLE);        //使能定时器               
  22.         TIM_Cmd(TIM2,ENABLE);        //使能定时器       
  23.         TIM_Cmd(TIM4,ENABLE);        //使能定时器
  24.         ......       
  25.         TIM4->CCR3=255-60;//定时中断,在ADC扫描完成之后,就不需等待ADC转换完成了
  26.         TIM4->CCR4=15;//用于触发ADC同步采样,需要仔细调试,值越大,越提前       
  27. }   
复制代码
4.        T4.3中断
定时中断里,从DMA缓冲中读取ADC采样值,即可得到相电流,然后进行FOC相关算法的处理。
  1. //T4.3中断
  2. void TIM4_IRQHandler(void)
  3. {       
  4.         ......
  5.         //从DMA缓冲中读取ADC采样值                               
  6.         ad_v=DMA_ADCBuf[0];//-iv
  7.         ad_u=DMA_ADCBuf[1];//iu
  8.         ad_Iavg=DMA_ADCBuf[2];//Iavg
  9.         ad_Vbat=DMA_ADCBuf[3];//Vbat
  10.         DMA_start();//重启DMA
  11.        
  12.         Mot_IU=ad_u-zp_u;//有符号电流,减去零点偏置
  13.         Mot_IV=zp_v-ad_v;       
  14.         Mot_Iavg=(S32)(ad_Iavg-zp_Iavg)*3300/4096/5;//电流取样5毫欧,放大10倍,结果为0.1A单位
  15.         Mot_Vbat=(S32)ad_Vbat*33*11/4096;//电阻分压11倍,结果为0.1V单位
  16.         //下面为磁场定向处理
  17.         ......
  18. }   
复制代码
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
99条回答
sctwp
1楼-- · 2019-12-20 10:56
也怀疑过负电流但负电流对程序有用吗?感觉没有作用
lcw_swust
2楼-- · 2019-12-20 11:54
sctwp 发表于 2019-1-26 18:29
也怀疑过负电流但负电流对程序有用吗?感觉没有作用

相电流有正有负,如同三相交流电机。
TKZXJ
3楼-- · 2019-12-20 15:19
 精彩回答 2  元偷偷看……
孤独飞行
4楼-- · 2019-12-20 16:28

感谢楼主分享,加油
lcw_swust
5楼-- · 2019-12-20 21:24
本帖最后由 lcw_swust 于 2019-3-5 13:36 编辑

二轴飞行器试飞成功,但是飞起来噪声仍旧相当大,螺旋桨的声音远大于电机的声音。
看来还需要研究一下其它的办法。
(实验中整坏了三个STM32单片机,现象是ADC功能损坏,其它功能正常,很奇怪,可能是在刹车时发电造成的冲击所致)
电调程序:
user(FOC1.1)_电调36K.rar (121.26 KB, 下载次数: 64) 2019-3-5 13:22 上传 点击文件名下载附件

由于电机的KV值较大,FOC一个正弦周期至少大约需要十多个点,所以将PWM频率提高到了36K。
FOC算法也有改动,基本就和AN1078中的结构差不多了。(以前的程序省了一些滤波)
主要改动在“MOTFOC.C”里,由转速得到kslf,用kslf去调节低通滤波。


  1. //------------------------------根据转速得到低通滤波系数

  2. //fc/fpwm=Mot_Speed/10/256
  3. //kslf=fc/fpwm*PI2=Mot_Speed/10/256*PI2=Mot_Speed*0.628/256
  4. x=Mot_Speed;                       
  5. VLIM(x,10,400);
  6. kslf=x/4;        //0.01单位       

  7. //------------------------------根据估算电流与实测电流之差修正反电势*100
  8. err=Mot_IestU-Mot_IU;//如果估算电流大于实测电流,则反电势增加
  9.                
  10. Mot_Zu+=err*Mot_Kslide;                       
  11. Mot_EmfU+=(Mot_Zu-Mot_EmfU)*kslf/100;//Mot_Zu低通滤波得Mot_EmfU
  12. emfulp+=(Mot_EmfU-emfulp)*kslf/100;//Mot_EmfU低通滤波得emfulp                       
  13. err=Mot_IestV-Mot_IV;//如果估算电流大于实测电流,则反电势增加                       

  14. Mot_Zv+=err*Mot_Kslide;
  15. Mot_EmfV+=(Mot_Zv-Mot_EmfV)*kslf/100;//Mot_Zv低通滤波得Mot_EmfV
  16. emfvlp+=(Mot_EmfV-emfvlp)*kslf/100;//Mot_EmfV低通滤波得emfvlp

  17. Mot_EmfDeg=myatan(emfulp/50,emfvlp/50);//得到反电势角
  18. //Mot_EmfDeg=myatan(Mot_EmfU,Mot_EmfV);        //得到反电势角
  19. //------------------------------根据当前相电压、相电流、反电势计算下一周期的相电流                       
  20. //电机的电感电压=PWM电压-内阻上的电压-反电势
  21. //电流增量=电感电压/电感
  22. //Vu乘100是因为在获取Mot_L时乘了500                       
  23. /*Mot_IestU+=((S32)Vu*500-Mot_IestU*Mot_R-Mot_EmfU)/Mot_L;//电感两端电压/电感
  24. Mot_IestV+=((S32)Vv*500-Mot_IestV*Mot_R-Mot_EmfV)/Mot_L;*/
  25. Mot_IestU+=((S32)Vu*500-Mot_IestU*Mot_R-Mot_EmfU-Mot_Zu)/Mot_L;//电感两端电压/电感
  26. Mot_IestV+=((S32)Vv*500-Mot_IestV*Mot_R-Mot_EmfV-Mot_Zv)/Mot_L;               

复制代码

飞行器参数:
无牌1806电机,2280KV,一个正转,一个反转;
桨叶为:EMAX AVAN Long Range 6038,也是一正一反。
两个舵机是MG90S;
电池:3S,500mAh。
由于技术有限,未能使飞行器长时间悬停,感觉还是需要做成四轴才好飞。

6.jpg (225.15 KB, 下载次数: 1)

下载附件

2019-3-5 13:21 上传

TINXPST
6楼-- · 2019-12-20 21:34
多谢楼主分享!

一周热门 更多>