本帖最后由 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来配合。
- //ADC配置:扫描模式、单次模式、定时器4的CC4触发、使能DMA
- void ADC_Conf(void)
- {
- ......
- RCC_ADCCLKConfig(RCC_PCLK2_Div4);//56/4=14M
- ADC_InitStructure.ADC_ScanConvMode = ENABLE;//扫描模式
- ADC_InitStructure.ADC_ContinuousConvMode =DISABLE;//单次模式
- ADC_InitStructure.ADC_ExternalTrigConv =ADC_ExternalTrigConv_T4_CC4;//定时器4的CC4触发
- ADC_InitStructure.ADC_NbrOfChannel = 4;//扫描4次
- ......
- ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_7Cycles5);//adc4,第1次是-Iv
- ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 2, ADC_SampleTime_7Cycles5);//adc4,第2次是Iu
- ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 3, ADC_SampleTime_7Cycles5);//adc5,Isavg,硬件对取样电阻低通滤波
- ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_7Cycles5);//adc3,AD_V,测量供电电压
- ......
- ADC_DMACmd(ADC1, ENABLE);//使能DMA
- ADC_ExternalTrigConvCmd(ADC1, ENABLE);//使能外部触发
- ......
- }
复制代码
2. DMA配置
DMA的作用是配合ADC采样,将ADC1->DR的数据自动存入DMA_ADCBuf[]数组。
- //DMA配合ADC,普通模式,把ADC1->DR数据存入DMA_ADCBuf[]
- #define DMA_ADCBUFSIZE 10
- U32 DMA_ADCBuf[DMA_ADCBUFSIZE];//用DMA采集多通道数据
- void DMA_Conf(void)
- {
- ......
- DMA_InitStructure.DMA_PeripheralBaseAddr =ADC1_DR_Address;//ADC1->DR
- DMA_InitStructure.DMA_MemoryBaseAddr = (U32)DMA_ADCBuf;//数组
- DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//普通模式
- ......
- }
复制代码
3. 定时器配置
定时器用于产生三相PWM,且相互错开一定相位,使下降沿相差固定的时间;T4_CC4触发ADC采样;T4_CC3引发定时中断。
- //--------------------------------------------------
- // 定时器初始化
- //频率56M/10,PWM周期约256*10/56M 约=46us
- //向下计数模式
- //T4.1、T4.2:U相HIN、nLIN,同相
- //T3.1、T3.2:V相HIN、nLIN,同相
- //T2.1、T2.2:W相HIN、nLIN,同相
- //三相时间顺序:VWU,即T3T2T4
- //T4.4:触发ADC采样
- //T4.3:中断里进行数据处理,时间在ADC采样完成之后
- //--------------------------------------------------
- void Timer_Init(void)
- {
- ......
- TIM_TimeBaseStructure.TIM_CounterMode= TIM_CounterMode_Down;//向下计数模式
- ......
- TIM_SetCounter(TIM3,0);//计数初值也可用于控制相位差
- TIM_SetCounter(TIM2,8);//由于是向下计数,数字越大则越滞后
- TIM_SetCounter(TIM4,16);
- //启动时刻之差也会造成相位差,放在前面的相位越提前
- TIM_Cmd(TIM3,ENABLE); //使能定时器
- TIM_Cmd(TIM2,ENABLE); //使能定时器
- TIM_Cmd(TIM4,ENABLE); //使能定时器
- ......
- TIM4->CCR3=255-60;//定时中断,在ADC扫描完成之后,就不需等待ADC转换完成了
- TIM4->CCR4=15;//用于触发ADC同步采样,需要仔细调试,值越大,越提前
- }
复制代码
4. T4.3中断
定时中断里,从DMA缓冲中读取ADC采样值,即可得到相电流,然后进行FOC相关算法的处理。
- //T4.3中断
- void TIM4_IRQHandler(void)
- {
- ......
- //从DMA缓冲中读取ADC采样值
- ad_v=DMA_ADCBuf[0];//-iv
- ad_u=DMA_ADCBuf[1];//iu
- ad_Iavg=DMA_ADCBuf[2];//Iavg
- ad_Vbat=DMA_ADCBuf[3];//Vbat
- DMA_start();//重启DMA
-
- Mot_IU=ad_u-zp_u;//有符号电流,减去零点偏置
- Mot_IV=zp_v-ad_v;
- Mot_Iavg=(S32)(ad_Iavg-zp_Iavg)*3300/4096/5;//电流取样5毫欧,放大10倍,结果为0.1A单位
- Mot_Vbat=(S32)ad_Vbat*33*11/4096;//电阻分压11倍,结果为0.1V单位
- //下面为磁场定向处理
- ......
- }
复制代码
相电流有正有负,如同三相交流电机。
感谢楼主分享,加油
二轴飞行器试飞成功,但是飞起来噪声仍旧相当大,螺旋桨的声音远大于电机的声音。
看来还需要研究一下其它的办法。
(实验中整坏了三个STM32单片机,现象是ADC功能损坏,其它功能正常,很奇怪,可能是在刹车时发电造成的冲击所致)
电调程序:
由于电机的KV值较大,FOC一个正弦周期至少大约需要十多个点,所以将PWM频率提高到了36K。
FOC算法也有改动,基本就和AN1078中的结构差不多了。(以前的程序省了一些滤波)
主要改动在“MOTFOC.C”里,由转速得到kslf,用kslf去调节低通滤波。
- //------------------------------根据转速得到低通滤波系数
- //fc/fpwm=Mot_Speed/10/256
- //kslf=fc/fpwm*PI2=Mot_Speed/10/256*PI2=Mot_Speed*0.628/256
- x=Mot_Speed;
- VLIM(x,10,400);
- kslf=x/4; //0.01单位
- //------------------------------根据估算电流与实测电流之差修正反电势*100
- err=Mot_IestU-Mot_IU;//如果估算电流大于实测电流,则反电势增加
-
- Mot_Zu+=err*Mot_Kslide;
- Mot_EmfU+=(Mot_Zu-Mot_EmfU)*kslf/100;//Mot_Zu低通滤波得Mot_EmfU
- emfulp+=(Mot_EmfU-emfulp)*kslf/100;//Mot_EmfU低通滤波得emfulp
- err=Mot_IestV-Mot_IV;//如果估算电流大于实测电流,则反电势增加
- Mot_Zv+=err*Mot_Kslide;
- Mot_EmfV+=(Mot_Zv-Mot_EmfV)*kslf/100;//Mot_Zv低通滤波得Mot_EmfV
- emfvlp+=(Mot_EmfV-emfvlp)*kslf/100;//Mot_EmfV低通滤波得emfvlp
- Mot_EmfDeg=myatan(emfulp/50,emfvlp/50);//得到反电势角
- //Mot_EmfDeg=myatan(Mot_EmfU,Mot_EmfV); //得到反电势角
- //------------------------------根据当前相电压、相电流、反电势计算下一周期的相电流
- //电机的电感电压=PWM电压-内阻上的电压-反电势
- //电流增量=电感电压/电感
- //Vu乘100是因为在获取Mot_L时乘了500
- /*Mot_IestU+=((S32)Vu*500-Mot_IestU*Mot_R-Mot_EmfU)/Mot_L;//电感两端电压/电感
- Mot_IestV+=((S32)Vv*500-Mot_IestV*Mot_R-Mot_EmfV)/Mot_L;*/
- Mot_IestU+=((S32)Vu*500-Mot_IestU*Mot_R-Mot_EmfU-Mot_Zu)/Mot_L;//电感两端电压/电感
- 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 上传
一周热门 更多>