利用MATLAB计算SPWM脉冲宽度与并应用STM32输出
来源:互联网 发布:淘宝达摩盘是什么 编辑:程序博客网 时间:2024/05/16 04:44
转自 光电科技协会 王诚博
http://blog.csdn.net/wcb425499094/article/details/76703042
先上一张spwm波形生成原理图:
首先利用MATLAB产生三角波与正弦波叠加:
- %% 产生正弦波与三角波叠加
- y1=abs(sawtooth(a*2*pi*m,0.5));%三角波
- y2=0.8*sin(a*pi);%正弦波
- figure(1)
- plot(a,y1,a,y2)
如图:
接着取交点,想了两种方法:
1.直接图片上取点,该方法不精确,毕竟只能目测和用鼠标点击。
- [X Y]=ginput(40)%图像中取点(不精确)
- save('kuan','X');
2.做差,使用阈值。
- for i=1:length(y1)%利用差值取点,设定阈值
- if(abs(y1(i)-y2(i))<0.01)
- X(P)=a(i);
- P=P+1;
- end
- end
阈值设置为0.001只取出20个点,但如上图应该有40个点,所以增大阈值,设为0.01。
取出了200个点,如图:
放大观察:
可知每个交点取出了5个点,40个点刚好200个,所以假设正弦波与三角波交点附近正弦波斜率不变,所以采用平均的方法:
- for i=0:m*4-1%取平均值
- x(i+1)=(X((i+1)*5)+X(i*5+1))/2;
- end
然后就可以画出spwm波形:
- %% 画出SPWM波形
- for n=1:m*2
- y3(1:floor(x(1)*10000))=0;
- y3(floor(x(2*n-1)*10000):floor(x(2*n)*10000))=0.8;
- if(n==20)
- break
- end
- y3(floor(x(2*n)*10000):floor(x(2*(n+1)-1)*10000))=0;
- y3(floor(x(40)*10000):length(y3))=0;
- end
- figure(4)
- plot(a,y3)
- axis([0 1 0 1])
如图:
最后,计算正弦波半个周期的spwm的周期和占空比(使用stm32输出比较器输出pwm波):
- %% 计算SPWM的周期,占空比(利用输出比较器)
- for i=1:m
- tp(i)=(x(2*(i+1)-1)-x(2*i-1))*th;%spwm周期
- ti(i)=(x(2*i)-x(2*i-1))*th;%脉冲宽度
- end
- tc=[floor(tp./max(tp)*255),fliplr(floor(tp./max(tp)*255))];%单片机定时器从1计到255(最大spwm周期)
- dlmwrite('cycle.c',tc);%写入c文件
- p=ti./tp;%计算spwm占空比
- p1=[p fliplr(p)];%半个正弦波周期spwm的占空比序列
- p1=floor(p1.*tc);%单片机定时器基准脉冲宽度
- dlmwrite('dac_sinWave.c',p1);
如果使用DAC描点:
- b=floor(linspace(0,1,258)*10000);
- for i=1:256
- y4(i)=floor(y3(b(i+1))*4095);
- end
- dlmwrite('dac_SPWM.c',y4);
但该方法速度太慢,而且单片机利用效率太低,所以舍弃。
下面粘上MATLAB源代码:
- %% 变量初始化
- t=0.02;%正弦波周期
- th=t/2;%半波周期
- m=10;%三角波周期数
- a=0:0.0001:1;
- y3=0:0.0001:1;
- P=1;
- x=zeros(1);%分配空间
- tp=zeros(1);
- ti=zeros(1);
- %% 产生正弦波与三角波叠加
- y1=abs(sawtooth(a*2*pi*m,0.5));%三角波
- y2=0.8*sin(a*pi);%正弦波
- figure(1)
- plot(a,y1,a,y2)
- %% 取点
- %[X Y]=ginput(40)%图像中取点(不精确)
- % save('kuan','X');
- for i=1:length(y1)%利用差值取点,设定阈值
- if(abs(y1(i)-y2(i))<0.01)
- X(P)=a(i);
- P=P+1;
- end
- end
- figure(2)
- plot(a,y1,a,y2,X,1,'*')
- for i=0:m*4-1%取平均值
- x(i+1)=(X((i+1)*5)+X(i*5+1))/2;
- end
- figure(3)
- plot(a,y1,a,y2,x,1,'*')
- %% 画出SPWM波形
- for n=1:m*2
- y3(1:floor(x(1)*10000))=0;
- y3(floor(x(2*n-1)*10000):floor(x(2*n)*10000))=0.8;
- if(n==20)
- break
- end
- y3(floor(x(2*n)*10000):floor(x(2*(n+1)-1)*10000))=0;
- y3(floor(x(40)*10000):length(y3))=0;
- end
- figure(4)
- plot(a,y3)
- axis([0 1 0 1])
- %% DAC描点法(速度太慢舍弃)
- % b=floor(linspace(0,1,258)*10000);
- % for i=1:256
- % y4(i)=floor(y3(b(i+1))*4095);
- % end
- % dlmwrite('dac_SPWM.c',y4);
- %% 计算SPWM的周期,占空比(利用输出比较器)
- for i=1:m
- tp(i)=(x(2*(i+1)-1)-x(2*i-1))*th;%spwm周期
- ti(i)=(x(2*i)-x(2*i-1))*th;%脉冲宽度
- end
- tc=[floor(tp./max(tp)*255),fliplr(floor(tp./max(tp)*255))];%单片机定时器从1计到255(最大spwm周期)
- dlmwrite('cycle.c',tc);%写入c文件
- p=ti./tp;%计算spwm占空比
- p1=[p fliplr(p)];%半个正弦波周期spwm的占空比序列
- p1=floor(p1.*tc);%单片机定时器基准脉冲宽度
- dlmwrite('dac_sinWave.c',p1);
stm32程序是用野火的例程改的,经过MATLAB计算得出周期与占空比(放入定时器的自动重装载寄存器ARR和比较寄存器CRR):
- uint8_t indexWave[] = {16,47,78,106,132,155,174,188,198,203,203,198,
- 188,174,155,132,106,78,47,16};
- uint8_t indexcycle[] = {241,241,242,243,244,246,248,250,252,255,255,
- 252,250,248,246,244,243,242,241,241};
在中断中改变寄存器的值(三路输出):
- TIM3->ARR = indexcycle[pwm_index];
- TIM3->CCR2 = indexWave[pwm_index];
- TIM3->CCR3 = indexWave[pwm_index];
- TIM3->CCR4 = indexWave[pwm_index];
- pwm_index++;
定时器配置
- /*基本定时器配置*/
- TIM_TimeBaseStructure.TIM_Period = 255;
- TIM_TimeBaseStructure.TIM_Prescaler = 0;
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
- /*PWM模式配置*/
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
- TIM_OCInitStructure.TIM_Pulse = 0;
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; <span style="font-family: Arial, Helvetica, sans-serif;"> </span>
- TIM_OC2Init(TIM3, &TIM_OCInitStructure);
- TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
- TIM_OC3Init(TIM3, &TIM_OCInitStructure);
- TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
- TIM_OC4Init(TIM3, &TIM_OCInitStructure);
- TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);
- TIM_ARRPreloadConfig(TIM3, ENABLE);
- /* TIM3 enable counter */
- TIM_Cmd(TIM3, ENABLE);
- TIM_ITConfig(TIM3,TIM_IT_Update, ENABLE);
- NVIC_Config_PWM();
使用示波器观察得到SPWM输出:
看出这是SPWM波形。
阅读全文
1 0
- 利用MATLAB计算SPWM脉冲宽度与并应用STM32输出
- 利用MATLAB计算SPWM脉冲宽度与并应用STM32输出
- STM32 输入捕获的脉冲宽度及频率计算
- Stm32学习笔记(1)-利用TIM1产生SPWM波
- STM32产生SPWM
- 【STM库应用】stm32 之 TIM (详解二 脉冲宽度、周期测量)
- 【STM库应用】stm32 之 TIM (详解二 脉冲宽度、周期测量)
- matlab与stm32之间利用串口通信记录
- 利用定时方式0,测量外部脉冲宽度(5到250ms),74HC595输出显示
- 基于matlab的SPWM光伏并网系统的效率计算
- [STM32F10x] 利用定时器测量脉冲宽度
- SPWM
- SPWM
- 单极性SPWM的两种控制方法与过零点输出特性分析比较
- 三相SPWM逆变,输出相电压有效值与调制度的关系
- MATLAB科学计算应用
- SPWM与SVPWM的比较
- 输入n值,并利用下列格里高里公式计算并输出圆周率
- 69 个经典 Spring 面试题和答案
- CC2530 环境搭建
- vyos
- Plsql问题及技巧汇总
- postgre数据库备份与恢复
- 利用MATLAB计算SPWM脉冲宽度与并应用STM32输出
- 《珠珠图案》教程四:文字创作要领一
- Java抽象类和接口的区别
- Lintcode111 ClimbingStairs solution 题解
- Android开发艺术探索读书笔记-IPC机制
- Python学习笔记2
- Python调用C/C++互相调用
- OpenCV2编程手册笔记之 5.5分水岭算法对图像进行分割
- Android studio微信支付官网demo